X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=c0009b4013e74d852eeeec8dabba46579c1691e2;hb=14b5ed161164a42c7513700fe101c4bd2e3b63e3;hp=5b32c1c2cc83eff3b40b65ebaa1266f18ab34ed0;hpb=2e61fe84534a7798c987553cc0f4bb5a4f0c264a;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index 5b32c1c2..c0009b40 100644 --- a/src/tools.c +++ b/src/tools.c @@ -58,7 +58,7 @@ static struct DoorPartOrderInfo door_part_order[MAX_DOOR_PARTS]; struct DoorPartControlInfo { - int door_nr; + int door_token; int graphic; struct DoorPartPosInfo *pos; }; @@ -5326,16 +5326,179 @@ static int compareDoorPartOrderInfo(const void *object1, const void *object2) return compare_result; } +void InitGraphicCompatibilityInfo_Doors() +{ + struct + { + int door_token; + int part_1, part_8; + struct DoorInfo *door; + } + doors[] = + { + { DOOR_1, IMG_DOOR_1_GFX_PART_1, IMG_DOOR_1_GFX_PART_8, &door_1 }, + { DOOR_2, IMG_DOOR_2_GFX_PART_1, IMG_DOOR_2_GFX_PART_8, &door_2 }, + + { -1, -1, -1, NULL } + }; + struct Rect door_rect_list[] = + { + { DX, DY, DXSIZE, DYSIZE }, + { VX, VY, VXSIZE, VYSIZE } + }; + int i, j; + + for (i = 0; doors[i].door_token != -1; i++) + { + int door_token = doors[i].door_token; + int door_index = DOOR_INDEX_FROM_TOKEN(door_token); + int part_1 = doors[i].part_1; + int part_8 = doors[i].part_8; + int part_2 = part_1 + 1; + int part_3 = part_1 + 2; + struct DoorInfo *door = doors[i].door; + struct Rect *door_rect = &door_rect_list[door_index]; + boolean door_gfx_redefined = FALSE; + + /* check if any door part graphic definitions have been redefined */ + + for (j = 0; door_part_controls[j].door_token != -1; j++) + { + struct DoorPartControlInfo *dpc = &door_part_controls[j]; + struct FileInfo *fi = getImageListEntryFromImageID(dpc->graphic); + + if (dpc->door_token == door_token && fi->redefined) + door_gfx_redefined = TRUE; + } + + /* check for old-style door graphic/animation modifications */ + + if (!door_gfx_redefined) + { + if (door->anim_mode & ANIM_STATIC_PANEL) + { + door->panel.step_xoffset = 0; + door->panel.step_yoffset = 0; + } + + if (door->anim_mode & (ANIM_HORIZONTAL | ANIM_VERTICAL)) + { + struct GraphicInfo *g_part_1 = &graphic_info[part_1]; + struct GraphicInfo *g_part_2 = &graphic_info[part_2]; + int num_door_steps, num_panel_steps; + + /* remove door part graphics other than the two default wings */ + + for (j = 0; door_part_controls[j].door_token != -1; j++) + { + struct DoorPartControlInfo *dpc = &door_part_controls[j]; + struct GraphicInfo *g = &graphic_info[dpc->graphic]; + + if (dpc->graphic >= part_3 && + dpc->graphic <= part_8) + g->bitmap = NULL; + } + + /* set graphics and screen positions of the default wings */ + + g_part_1->width = door_rect->width; + g_part_1->height = door_rect->height; + g_part_2->width = door_rect->width; + g_part_2->height = door_rect->height; + g_part_2->src_x = door_rect->width; + g_part_2->src_y = g_part_1->src_y; + + door->part_2.x = door->part_1.x; + door->part_2.y = door->part_1.y; + + if (door->width != -1) + { + g_part_1->width = door->width; + g_part_2->width = door->width; + + // special treatment for graphics and screen position of right wing + g_part_2->src_x += door_rect->width - door->width; + door->part_2.x += door_rect->width - door->width; + } + + if (door->height != -1) + { + g_part_1->height = door->height; + g_part_2->height = door->height; + + // special treatment for graphics and screen position of bottom wing + g_part_2->src_y += door_rect->height - door->height; + door->part_2.y += door_rect->height - door->height; + } + + /* set animation delays for the default wings and panels */ + + door->part_1.step_delay = door->step_delay; + door->part_2.step_delay = door->step_delay; + door->panel.step_delay = door->step_delay; + + /* set animation draw order for the default wings */ + + door->part_1.sort_priority = 2; /* draw left wing over ... */ + door->part_2.sort_priority = 1; /* ... right wing */ + + /* set animation draw offset for the default wings */ + + if (door->anim_mode & ANIM_HORIZONTAL) + { + door->part_1.step_xoffset = door->step_offset; + door->part_1.step_yoffset = 0; + door->part_2.step_xoffset = door->step_offset * -1; + door->part_2.step_yoffset = 0; + + num_door_steps = g_part_1->width / door->step_offset; + } + else // ANIM_VERTICAL + { + door->part_1.step_xoffset = 0; + door->part_1.step_yoffset = door->step_offset; + door->part_2.step_xoffset = 0; + door->part_2.step_yoffset = door->step_offset * -1; + + num_door_steps = g_part_1->height / door->step_offset; + } + + /* set animation draw offset for the default panels */ + + if (door->step_offset > 1) + { + num_panel_steps = 2 * door_rect->height / door->step_offset; + door->panel.start_step = num_panel_steps - num_door_steps; + } + else + { + num_panel_steps = door_rect->height / door->step_offset; + door->panel.start_step = num_panel_steps - num_door_steps / 2; + door->panel.step_delay *= 2; + } + } + } + } +} + void InitDoors() { int i; - for (i = 0; door_part_controls[i].door_nr != -1; i++) + for (i = 0; door_part_controls[i].door_token != -1; i++) { struct DoorPartControlInfo *dpc = &door_part_controls[i]; struct DoorPartOrderInfo *dpo = &door_part_order[i]; - /* fill structure for door part draw order */ + /* initialize "start_step_opening" and "start_step_closing", if needed */ + if (dpc->pos->start_step_opening == 0 && + dpc->pos->start_step_closing == 0) + { + // dpc->pos->start_step_opening = dpc->pos->start_step; + dpc->pos->start_step_closing = dpc->pos->start_step; + } + + /* fill structure for door part draw order (sorted below) */ dpo->nr = i; dpo->sort_priority = dpc->pos->sort_priority; @@ -5490,6 +5653,7 @@ unsigned int MoveDoor(unsigned int door_state) if (door_state & DOOR_ACTION) { boolean door_panel_drawn[NUM_DOORS]; + boolean door_part_skip[MAX_DOOR_PARTS]; boolean door_part_done[MAX_DOOR_PARTS]; boolean door_part_done_all; int num_steps[MAX_DOOR_PARTS]; @@ -5503,9 +5667,10 @@ unsigned int MoveDoor(unsigned int door_state) { struct DoorPartControlInfo *dpc = &door_part_controls[i]; struct GraphicInfo *g = &graphic_info[dpc->graphic]; - int door_token = dpc->door_nr; + int door_token = dpc->door_token; - door_part_done[i] = (!(door_state & door_token) || + door_part_done[i] = FALSE; + door_part_skip[i] = (!(door_state & door_token) || !g->bitmap); } @@ -5523,13 +5688,21 @@ unsigned int MoveDoor(unsigned int door_state) for (i = 0; i < MAX_DOOR_PARTS; i++) { - struct DoorPartControlInfo *dpc = &door_part_controls[i]; - struct GraphicInfo *g = &graphic_info[dpc->graphic]; + int nr = door_part_order[i].nr; + struct DoorPartControlInfo *dpc = &door_part_controls[nr]; struct DoorPartPosInfo *pos = dpc->pos; + struct GraphicInfo *g = &graphic_info[dpc->graphic]; + int door_token = dpc->door_token; + boolean is_panel = DOOR_PART_IS_PANEL(nr); int step_xoffset = ABS(pos->step_xoffset); int step_yoffset = ABS(pos->step_yoffset); - int start_step = pos->start_step; int step_delay = pos->step_delay; + int current_door_state = door_state & door_token; + boolean door_opening = ((current_door_state & DOOR_OPEN) != 0); + boolean door_closing = ((current_door_state & DOOR_CLOSE) != 0); + boolean part_opening = (is_panel ? door_closing : door_opening); + int start_step = (part_opening ? pos->start_step_opening : + pos->start_step_closing); float move_xsize = (step_xoffset ? g->width : 0); float move_ysize = (step_yoffset ? g->height : 0); int move_xsteps = (step_xoffset ? ceil(move_xsize / step_xoffset) : 0); @@ -5539,13 +5712,13 @@ unsigned int MoveDoor(unsigned int door_state) move_xsteps ? move_xsteps : move_ysteps) - start_step; int move_delay = move_steps * step_delay; - if (door_part_done[i]) + if (door_part_skip[nr]) continue; max_move_delay = MAX(max_move_delay, move_delay); max_step_delay = (max_step_delay == 0 ? step_delay : euclid(max_step_delay, step_delay)); - num_steps[i] = move_steps; + num_steps[nr] = move_steps; #if 0 #if 0 @@ -5573,6 +5746,8 @@ unsigned int MoveDoor(unsigned int door_state) for (k = 0; k < num_move_steps; k++) { + door_part_done_all = TRUE; + for (i = 0; i < NUM_DOORS; i++) door_panel_drawn[i] = FALSE; @@ -5580,22 +5755,25 @@ unsigned int MoveDoor(unsigned int door_state) { int nr = door_part_order[i].nr; struct DoorPartControlInfo *dpc = &door_part_controls[nr]; - int door_token = dpc->door_nr; + struct DoorPartPosInfo *pos = dpc->pos; + struct GraphicInfo *g = &graphic_info[dpc->graphic]; + int door_token = dpc->door_token; int door_index = DOOR_INDEX_FROM_TOKEN(door_token); boolean is_panel = DOOR_PART_IS_PANEL(nr); - struct GraphicInfo *g = &graphic_info[dpc->graphic]; - struct DoorPartPosInfo *pos = dpc->pos; struct XY *panel_pos = &panel_pos_list[door_index]; struct Rect *door_rect = &door_rect_list[door_index]; Bitmap *bitmap = (is_panel ? bitmap_db_door : g->bitmap); int current_door_state = door_state & door_token; boolean door_opening = ((current_door_state & DOOR_OPEN) != 0); - boolean door_closing = ((current_door_state & DOOR_CLOSE) != 0); - boolean mode_opening = (is_panel ? door_closing : door_opening); + boolean door_closing = !door_opening; + boolean part_opening = (is_panel ? door_closing : door_opening); + boolean part_closing = !part_opening; + int start_step = (part_opening ? pos->start_step_opening : + pos->start_step_closing); int step_delay = pos->step_delay; int step_factor = step_delay / max_step_delay; int k1 = (step_factor ? k / step_factor + 1 : k); - int k2 = (mode_opening ? k1 : num_steps[nr] - k1); + int k2 = (part_opening ? k1 + start_step : num_steps[nr] - k1); int kk = (k2 < 0 ? 0 : k2); int src_x, src_y, src_xx, src_yy; int dst_x, dst_y, dst_xx, dst_yy; @@ -5613,12 +5791,18 @@ unsigned int MoveDoor(unsigned int door_state) #if 0 // !!! TEST !!! - if (nr != 0) + if (nr != 16 && nr != 0) continue; #endif #if 0 - if (door_part_done[nr]) + // !!! TEST !!! + if (!is_panel) + continue; +#endif + +#if 1 + if (door_part_skip[nr]) continue; #endif @@ -5713,6 +5897,14 @@ unsigned int MoveDoor(unsigned int door_state) dst_x = door_rect->x + dst_xx; dst_y = door_rect->y + dst_yy; +#if 0 + if (DOOR_PART_IS_PANEL(nr)) + { + printf("::: width == %d, height == %d [%d, %d] [%d, %d]\n", + width, height, g->width, g->height, src_x, src_y); + } +#endif + if (width >= 0 && width <= g->width && height >= 0 && height <= g->height) { @@ -5744,9 +5936,24 @@ unsigned int MoveDoor(unsigned int door_state) redraw_mask |= REDRAW_DOOR_FROM_TOKEN(door_token); +#if 1 + if ((part_opening && (width < 0 || height < 0)) || + (part_closing && (width >= g->width && height >= g->height))) + door_part_done[nr] = TRUE; +#else if ((door_opening && (width < 0 || height < 0)) || (door_closing && (width >= g->width && height >= g->height))) door_part_done[nr] = TRUE; +#endif + + // continue door part animations, but not panel after door has closed + if (!door_part_done[nr] && !(is_panel && door_closing)) + door_part_done_all = FALSE; + +#if 0 + if (!door_part_done[nr]) + printf("::: k == %d, nr == %d\n", k, nr); +#endif } if (!(door_state & DOOR_NO_DELAY)) @@ -5761,14 +5968,18 @@ unsigned int MoveDoor(unsigned int door_state) current_move_delay += max_step_delay; } +#if 0 door_part_done_all = TRUE; for (i = 0; i < MAX_DOOR_PARTS; i++) - if (!door_part_done[i]) + if (!door_part_done[i] && + !(DOOR_PART_IS_PANEL(i) && door_closing)) door_part_done_all = FALSE; - +#endif +#if 1 if (door_part_done_all) break; +#endif } } @@ -5777,6 +5988,12 @@ unsigned int MoveDoor(unsigned int door_state) if (door_state & DOOR_ACTION_2) door2 = door_state & DOOR_ACTION_2; +#if 0 + printf("::: DOORS DONE %08x\n", door_state); + Delay(3000); + printf("::: GO!\n"); +#endif + return (door1 | door2); } @@ -6531,8 +6748,8 @@ void CreateToolButtons() gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_INFO_TEXT, toolbutton_info[i].infotext, - GDI_X, dx + pos->x, - GDI_Y, dy + pos->y, + GDI_X, dx + GDI_ACTIVE_POS(pos->x), + GDI_Y, dy + GDI_ACTIVE_POS(pos->y), GDI_WIDTH, gfx->width, GDI_HEIGHT, gfx->height, GDI_TYPE, GD_TYPE_NORMAL_BUTTON, @@ -6691,8 +6908,8 @@ void CreateToolButtons() gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_INFO_TEXT, toolbutton_info[i].infotext, - GDI_X, DX + toolbutton_info[i].x, - GDI_Y, DY + toolbutton_info[i].y, + GDI_X, DX + GDI_ACTIVE_POS(toolbutton_info[i].x), + GDI_Y, DY + GDI_ACTIVE_POS(toolbutton_info[i].y), GDI_WIDTH, toolbutton_info[i].width, GDI_HEIGHT, toolbutton_info[i].height, GDI_TYPE, GD_TYPE_NORMAL_BUTTON, @@ -11165,7 +11382,9 @@ void ChangeViewportPropertiesIfNeeded() InitGfxBuffers(); #endif +#if 0 if (gfx_game_mode == GAME_MODE_MAIN) +#endif { #if 1 init_gadgets_and_toons = TRUE;