X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=0348f112c4f07abe7a21c31f2eb9b2178bb20afe;hb=6f7fa5b602dab7836b186970577d82995bdb23d1;hp=c590f455e92ab1ffd95208000e47548b0fc94c3c;hpb=003b12cf2b0484b5ce952af7c89eae0bedef61d9;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index c590f455..0348f112 100644 --- a/src/tools.c +++ b/src/tools.c @@ -11,6 +11,8 @@ * tools.c * ***********************************************************/ +#include + #include "libgame/libgame.h" #include "tools.h" @@ -39,7 +41,11 @@ /* constants for number of doors and door parts */ #define NUM_DOORS 2 -#define MAX_NUM_DOOR_PARTS 8 +#define NUM_PANELS NUM_DOORS +// #define NUM_PANELS 0 +#define MAX_PARTS_PER_DOOR 8 +#define MAX_DOOR_PARTS (NUM_DOORS * MAX_PARTS_PER_DOOR + NUM_PANELS) +#define DOOR_PART_IS_PANEL(i) ((i) >= NUM_DOORS * MAX_PARTS_PER_DOOR) struct DoorPartOrderInfo @@ -48,7 +54,7 @@ struct DoorPartOrderInfo int sort_priority; }; -static struct DoorPartOrderInfo door_part_order[NUM_DOORS * MAX_NUM_DOOR_PARTS]; +static struct DoorPartOrderInfo door_part_order[MAX_DOOR_PARTS]; struct DoorPartControlInfo { @@ -99,6 +105,7 @@ static struct DoorPartControlInfo door_part_controls[] = IMG_DOOR_1_GFX_PART_8, &door_1.part_8 }, + { DOOR_2, IMG_DOOR_2_GFX_PART_1, @@ -140,6 +147,17 @@ static struct DoorPartControlInfo door_part_controls[] = &door_2.part_8 }, + { + DOOR_1, + IMG_BACKGROUND_PANEL, + &door_1.panel + }, + { + DOOR_2, + IMG_BACKGROUND_TAPE, + &door_2.panel + }, + { -1, -1, @@ -5330,7 +5348,7 @@ void InitDoors() } /* sort door part controls according to sort_priority and graphic number */ - qsort(door_part_order, NUM_DOORS * MAX_NUM_DOOR_PARTS, + qsort(door_part_order, MAX_DOOR_PARTS, sizeof(struct DoorPartOrderInfo), compareDoorPartOrderInfo); } @@ -5407,13 +5425,8 @@ unsigned int MoveDoor(unsigned int door_state) }; static int door1 = DOOR_OPEN_1; static int door2 = DOOR_CLOSE_2; -#if 1 unsigned int door_delay = 0; unsigned int door_delay_value; -#endif -#if 0 - int stepsize = 1; -#endif int i; #if 1 @@ -5477,29 +5490,38 @@ unsigned int MoveDoor(unsigned int door_state) if (door_state & DOOR_ACTION) { boolean door_panel_drawn[NUM_DOORS]; - boolean door_part_done[NUM_DOORS * MAX_NUM_DOOR_PARTS]; + boolean door_part_done[MAX_DOOR_PARTS]; boolean door_part_done_all; -#if 0 - int num_xsteps[NUM_DOORS * MAX_NUM_DOOR_PARTS]; - int num_ysteps[NUM_DOORS * MAX_NUM_DOOR_PARTS]; -#endif + int num_steps[MAX_DOOR_PARTS]; int max_move_delay = 0; // delay for complete animations of all doors int max_step_delay = 0; // delay (ms) between two animation frames int num_move_steps = 0; // number of animation steps for all doors + int current_move_delay = 0; int k; - for (i = 0; i < NUM_DOORS * MAX_NUM_DOOR_PARTS; i++) + for (i = 0; i < MAX_DOOR_PARTS; i++) { - int nr = door_part_order[i].nr; - struct DoorPartControlInfo *dpc = &door_part_controls[nr]; + struct DoorPartControlInfo *dpc = &door_part_controls[i]; struct GraphicInfo *g = &graphic_info[dpc->graphic]; int door_token = dpc->door_nr; - door_part_done[nr] = (!(door_state & door_token) || - !g->bitmap); + door_part_done[i] = (!(door_state & door_token) || + !g->bitmap); } - for (i = 0; i < NUM_DOORS * MAX_NUM_DOOR_PARTS; i++) +#if 0 + for (i = 0; i < MAX_DOOR_PARTS; i++) + { + struct DoorPartControlInfo *dpc = &door_part_controls[i]; + struct DoorPartPosInfo *pos = dpc->pos; + int start_step = pos->start_step; + + printf("::: ---> %d: start_step == %d [%d]\n", + i, start_step, door_part_done[i]); + } +#endif + + for (i = 0; i < MAX_DOOR_PARTS; i++) { struct DoorPartControlInfo *dpc = &door_part_controls[i]; struct GraphicInfo *g = &graphic_info[dpc->graphic]; @@ -5507,34 +5529,33 @@ unsigned int MoveDoor(unsigned int door_state) int step_xoffset = ABS(pos->step_xoffset); int step_yoffset = ABS(pos->step_yoffset); int step_delay = pos->step_delay; - int move_xsize = (step_xoffset ? g->width : 0); - int move_ysize = (step_yoffset ? g->height : 0); - /* - int move_size = (move_xsize && move_ysize ? - MIN(move_xsize, move_ysize) : - move_xsize ? move_xsize : move_ysize); - */ - int move_xsteps = (step_xoffset ? CEIL(move_xsize, step_xoffset) : 0); - int move_ysteps = (step_yoffset ? CEIL(move_ysize, step_yoffset) : 0); - /* - int move_xdelay = move_xsteps * step_delay; - int move_ydelay = move_ysteps * step_delay; - int move_delay = (move_xdelay && move_ydelay ? - MIN(move_xdelay, move_ydelay) : - move_xdelay ? move_xdelay : move_ydelay); - */ + int start_step = pos->start_step; + 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); + int move_ysteps = (step_yoffset ? ceil(move_ysize / step_yoffset) : 0); int move_steps = (move_xsteps && move_ysteps ? MIN(move_xsteps, move_ysteps) : - move_xsteps ? move_xsteps : move_ysteps); + move_xsteps ? move_xsteps : move_ysteps) - start_step; int move_delay = move_steps * step_delay; - // int move_delay = MAX(move_xsize, move_ysize) * step_delay; + + if (door_part_done[i]) + 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; + +#if 0 #if 0 - num_xsteps[i] = move_xsteps; - num_ysteps[i] = move_ysteps; + printf("::: %d: move_delay == %d, start_step == %d [%d]\n", + i, move_delay, start_step, door_part_order[i].nr); +#else + if (DOOR_PART_IS_PANEL(i)) + printf("::: %d: move_delay == %d, start_step == %d\n", + i, move_delay, start_step); +#endif #endif } @@ -5543,14 +5564,11 @@ unsigned int MoveDoor(unsigned int door_state) door_delay_value = max_step_delay; #if 0 - printf("::: max_move_delay == %d, max_step_delay == %d, num_move_steps == %d\n", - max_move_delay, max_step_delay, num_move_steps); + door_delay_value *= 10; #endif #if 0 - for (i = 0; i < NUM_DOORS * MAX_NUM_DOOR_PARTS; i++) - printf("::: door_part_done[%d] == %d\n", i, door_part_done[i]); - printf("\n"); + printf("::: num_move_steps == %d, max_move_delay == %d, max_step_delay == %d\n", num_move_steps, max_move_delay, max_step_delay); #endif for (k = 0; k < num_move_steps; k++) @@ -5558,22 +5576,52 @@ unsigned int MoveDoor(unsigned int door_state) for (i = 0; i < NUM_DOORS; i++) door_panel_drawn[i] = FALSE; - for (i = 0; i < NUM_DOORS * MAX_NUM_DOOR_PARTS; i++) + for (i = 0; i < MAX_DOOR_PARTS; i++) { int nr = door_part_order[i].nr; struct DoorPartControlInfo *dpc = &door_part_controls[nr]; int door_token = dpc->door_nr; 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]; - int src_xx, src_yy; - int dst_xx, dst_yy; + 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); + int start_step = pos->start_step; + 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 + 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; int width, height; +#if 0 + if (DOOR_PART_IS_PANEL(nr)) + { + int start_step = pos->start_step; + + k2 = (door_closing ? k1 : num_steps[nr] - k1);// - start_step; + kk = (k2 < 0 ? 0 : k2); + } +#endif + +#if 0 + // !!! TEST !!! + if (nr != 16 && nr != 0) + continue; +#endif + +#if 0 if (door_part_done[nr]) continue; +#endif if (!(door_state & door_token)) continue; @@ -5581,167 +5629,134 @@ unsigned int MoveDoor(unsigned int door_state) if (!g->bitmap) continue; +#if 0 + if (current_move_delay % step_delay) + continue; +#endif + + // draw door panel + if (!door_panel_drawn[door_index]) { +#if 1 + ClearRectangle(drawto, door_rect->x, door_rect->y, + door_rect->width, door_rect->height); +#else BlitBitmap(bitmap_db_door, drawto, panel_pos->x, panel_pos->y, door_rect->width, door_rect->height, door_rect->x, door_rect->y); +#endif door_panel_drawn[door_index] = TRUE; } -#if 1 - if ((door_state & door_token) & DOOR_OPEN) - { -#if 0 - // !!! TEST !!! - if (nr != 2) - continue; -#endif + // draw opening or closing door parts -#if 0 - if (k == 0) - printf("::: step_xoffset == %d, step_yoffset == %d\n", - pos->step_xoffset, pos->step_yoffset); -#endif - - if (pos->step_xoffset < 0) - { -#if 1 - src_xx = 0; - dst_xx = pos->x + ABS(k * pos->step_xoffset); - width = g->width; - - if (dst_xx + width > door_rect->width) - width = door_rect->width - dst_xx; -#else - src_xx = 0; - width = g->width + k * pos->step_xoffset; + if (pos->step_xoffset < 0) // door part on right side + { + src_xx = 0; + dst_xx = pos->x + ABS(kk * pos->step_xoffset); + width = g->width; - if (width > door_rect->width) - width = door_rect->width; + if (dst_xx + width > door_rect->width) + width = door_rect->width - dst_xx; + } + else // door part on left side + { + src_xx = 0; + dst_xx = pos->x - kk * pos->step_xoffset; - dst_xx = door_rect->width - width; -#endif - } - else + if (dst_xx < 0) { - src_xx = 0; - dst_xx = pos->x - k * pos->step_xoffset; - - if (dst_xx < 0) - { - src_xx = ABS(dst_xx); - dst_xx = 0; - } - - width = g->width - src_xx; + src_xx = ABS(dst_xx); + dst_xx = 0; } - if (pos->step_yoffset < 0) - { -#if 1 - src_yy = 0; - dst_yy = pos->y + ABS(k * pos->step_yoffset); - height = g->height; - - if (dst_yy + height > door_rect->height) - height = door_rect->height - dst_yy; -#else - src_yy = 0; - height = g->height + k * pos->step_yoffset; - - if (height > door_rect->height) - height = door_rect->height; - - dst_yy = door_rect->height - height; -#endif - } - else - { - src_yy = 0; - dst_yy = pos->y - k * pos->step_yoffset; + width = g->width - src_xx; - if (dst_yy < 0) - { - src_yy = ABS(dst_yy); - dst_yy = 0; - } + // printf("::: k == %d [%d] \n", k, start_step); + } - height = g->height - src_yy; - } + if (pos->step_yoffset < 0) // door part on bottom side + { + src_yy = 0; + dst_yy = pos->y + ABS(kk * pos->step_yoffset); + height = g->height; - if (width < 0 || height < 0) - door_part_done[nr] = TRUE; + if (dst_yy + height > door_rect->height) + height = door_rect->height - dst_yy; } - else // DOOR_CLOSE + else // door part on top side { -#if 1 - // !!! TEST !!! - - door_part_done[nr] = TRUE; + src_yy = 0; + dst_yy = pos->y - kk * pos->step_yoffset; - BlitBitmapMasked(g->bitmap, drawto, g->src_x, g->src_y, - g->width, g->height, - door_rect->x + pos->x, door_rect->y + pos->y); + if (dst_yy < 0) + { + src_yy = ABS(dst_yy); + dst_yy = 0; + } - redraw_mask |= REDRAW_DOOR_FROM_TOKEN(door_token); -#else - src_xx = (num_xsteps[nr] - k) * pos->step_xoffset; - src_yy = (num_ysteps[nr] - k) * pos->step_yoffset; - dst_xx = pos->x; - dst_yy = pos->y; - width = g->width - src_xx; height = g->height - src_yy; + } - // if (width < ABS(pos->step_xoffset) - - - - - src_xx = g->width - k * pos->step_xoffset; - src_yy = g->height - k * pos->step_yoffset; - dst_xx = pos->x; - dst_yy = pos->y; - - if (width < 0 || height < 0) - door_part_done[nr] = TRUE; -#endif + if (is_panel) + { + src_x = panel_pos->x + src_xx; + src_y = panel_pos->y + src_yy; + } + else + { + src_x = g->src_x + src_xx; + src_y = g->src_y + src_yy; } - if (door_part_done[nr]) - continue; + dst_x = door_rect->x + dst_xx; + dst_y = door_rect->y + dst_yy; #if 0 - // !!! TEST !!! - if (nr != 7) - continue; + 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 - BlitBitmapMasked(g->bitmap, drawto, - g->src_x + src_xx, g->src_y + src_yy, width, height, - door_rect->x + dst_xx, door_rect->y + dst_yy); -#else - // !!! TEST !!! - if (!((door_state & door_token) & DOOR_CLOSE)) - continue; + if (width >= 0 && width <= g->width && + height >= 0 && height <= g->height) + { + if (is_panel || !pos->draw_masked) + BlitBitmap(bitmap, drawto, src_x, src_y, width, height, + dst_x, dst_y); + else + BlitBitmapMasked(bitmap, drawto, src_x, src_y, width, height, + dst_x, dst_y); + } - BlitBitmapMasked(g->bitmap, drawto, g->src_x, g->src_y, - g->width, g->height, - door_rect->x + pos->x, door_rect->y + pos->y); +#if 0 + if (DOOR_PART_IS_PANEL(nr)) + { + bitmap = bitmap_db_door; + src_x = panel_pos->x + src_xx; + src_y = panel_pos->y + src_yy; + + printf("::: width == %d, height == %d [%d, %d] [%d, %d]\n", + width, height, g->width, g->height, src_x, src_y); + + if (width >= 0 && width <= g->width && + height >= 0 && height <= g->height) + BlitBitmap(bitmap, drawto, src_x, src_y, + width, height, + dst_x, dst_y); + } #endif redraw_mask |= REDRAW_DOOR_FROM_TOKEN(door_token); - } - - door_part_done_all = TRUE; - - for (i = 0; i < NUM_DOORS * MAX_NUM_DOOR_PARTS; i++) - if (!door_part_done[i]) - door_part_done_all = FALSE; - if (door_part_done_all) - break; + if ((door_opening && (width < 0 || height < 0)) || + (door_closing && (width >= g->width && height >= g->height))) + door_part_done[nr] = TRUE; + } if (!(door_state & DOOR_NO_DELAY)) { @@ -5751,12 +5766,23 @@ unsigned int MoveDoor(unsigned int door_state) DoAnimation(); WaitUntilDelayReached(&door_delay, door_delay_value); + + current_move_delay += max_step_delay; } + + door_part_done_all = TRUE; + + for (i = 0; i < MAX_DOOR_PARTS; i++) + if (!door_part_done[i]) + door_part_done_all = FALSE; + +#if 0 + if (door_part_done_all) + break; +#endif } } - redraw_mask |= REDRAW_ALL; - if (door_state & DOOR_ACTION_1) door1 = door_state & DOOR_ACTION_1; if (door_state & DOOR_ACTION_2)