/* constants for number of doors and door parts */
#define NUM_DOORS 2
+#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)
+#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
IMG_DOOR_1_GFX_PART_8,
&door_1.part_8
},
+
{
DOOR_2,
IMG_DOOR_2_GFX_PART_1,
&door_2.part_8
},
+ {
+ DOOR_1,
+ IMG_BACKGROUND_PANEL,
+ &door_1.panel
+ },
+ {
+ DOOR_2,
+ IMG_BACKGROUND_TAPE,
+ &door_2.panel
+ },
+
{
-1,
-1,
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;
};
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
boolean door_panel_drawn[NUM_DOORS];
boolean door_part_done[MAX_DOOR_PARTS];
boolean door_part_done_all;
- int num_xsteps[MAX_DOOR_PARTS];
- int num_ysteps[MAX_DOOR_PARTS];
+ 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
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);
}
+#if 0
for (i = 0; i < MAX_DOOR_PARTS; i++)
{
struct DoorPartControlInfo *dpc = &door_part_controls[i];
- struct GraphicInfo *g = &graphic_info[dpc->graphic];
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++)
+ {
+ 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_nr;
+ boolean is_panel = DOOR_PART_IS_PANEL(nr);
int step_xoffset = ABS(pos->step_xoffset);
int step_yoffset = ABS(pos->step_yoffset);
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_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 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[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[nr] = move_steps;
- num_xsteps[i] = move_xsteps;
- num_ysteps[i] = move_ysteps;
+#if 0
+#if 0
+ 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
}
num_move_steps = max_move_delay / max_step_delay;
#endif
#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);
-#endif
-
-#if 0
- for (i = 0; i < MAX_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++)
{
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_nr;
int door_index = DOOR_INDEX_FROM_TOKEN(door_token);
- struct GraphicInfo *g = &graphic_info[dpc->graphic];
- struct DoorPartPosInfo *pos = dpc->pos;
+ boolean is_panel = DOOR_PART_IS_PANEL(nr);
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 part_opening = (is_panel ? door_closing : door_opening);
+ int start_step = (part_opening ? pos->start_step_opening :
+ pos->start_step_closing);
int step_delay = pos->step_delay;
- int src_xx, src_yy;
- int dst_xx, dst_yy;
+ int step_factor = step_delay / max_step_delay;
+ int k1 = (step_factor ? k / step_factor + 1 : k);
+ 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;
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 != 0 && nr != 8)
+ if (nr != 16 && nr != 0)
continue;
#endif
+#if 0
if (door_part_done[nr])
continue;
+#endif
if (!(door_state & door_token))
continue;
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 ((door_state & door_token) & DOOR_OPEN)
+ // draw opening or closing door parts
+
+ if (pos->step_xoffset < 0) // door part on right side
{
- int step_factor = step_delay / max_step_delay;
- int kx = k / step_factor + 1;
- int ky = k / step_factor + 1;
+ src_xx = 0;
+ dst_xx = pos->x + ABS(kk * pos->step_xoffset);
+ width = g->width;
-#if 0
- // if (k == 0)
- printf("::: kx == %d, ky == %d\n", kx, ky);
-#endif
+ 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;
- if (pos->step_xoffset < 0)
+ if (dst_xx < 0)
{
- src_xx = 0;
- dst_xx = pos->x + ABS(kx * pos->step_xoffset);
- width = g->width;
-
- if (dst_xx + width > door_rect->width)
- width = door_rect->width - dst_xx;
+ src_xx = ABS(dst_xx);
+ dst_xx = 0;
}
- else
- {
- src_xx = 0;
- dst_xx = pos->x - kx * pos->step_xoffset;
- if (dst_xx < 0)
- {
- src_xx = ABS(dst_xx);
- dst_xx = 0;
- }
+ width = g->width - src_xx;
- width = g->width - src_xx;
- }
-
- if (pos->step_yoffset < 0)
- {
- src_yy = 0;
- dst_yy = pos->y + ABS(ky * pos->step_yoffset);
- height = g->height;
-
- if (dst_yy + height > door_rect->height)
- height = door_rect->height - dst_yy;
- }
- else
- {
- src_yy = 0;
- dst_yy = pos->y - ky * pos->step_yoffset;
-
- 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 0
- if (width < 0 || height < 0)
- door_part_done[nr] = TRUE;
-#endif
+ if (dst_yy + height > door_rect->height)
+ height = door_rect->height - dst_yy;
}
- else // DOOR_CLOSE
+ else // door part on top side
{
- int step_factor = step_delay / max_step_delay;
- int num_steps = (num_xsteps[nr] && num_ysteps[nr] ?
- MIN(num_xsteps[nr], num_ysteps[nr]) :
- num_xsteps[nr] ? num_xsteps[nr] :
- num_ysteps[nr]);
-#if 1
- int kx = num_steps - k / step_factor - 1;
- int ky = num_steps - k / step_factor - 1;
-#else
- int kx = num_xsteps[nr] - k;
- int ky = num_ysteps[nr] - k;
-#endif
-
-#if 0
- // !!! TEST !!!
- if (nr != 0)
- continue;
-#endif
-
-#if 0
- // if (k == 0)
- printf("::: kx == %d, ky == %d\n", kx, ky);
-#endif
-
-#if 0
- if (k == 0)
- printf("::: step_xoffset == %d, step_yoffset == %d\n",
- pos->step_xoffset, pos->step_yoffset);
-#endif
+ src_yy = 0;
+ dst_yy = pos->y - kk * pos->step_yoffset;
- if (pos->step_xoffset < 0)
+ if (dst_yy < 0)
{
- src_xx = 0;
- dst_xx = pos->x + ABS(kx * pos->step_xoffset);
- width = g->width;
-
- if (dst_xx + width > door_rect->width)
- width = door_rect->width - dst_xx;
+ src_yy = ABS(dst_yy);
+ dst_yy = 0;
}
- else
- {
- src_xx = 0;
- dst_xx = pos->x - kx * pos->step_xoffset;
-
- if (dst_xx < 0)
- {
- src_xx = ABS(dst_xx);
- dst_xx = 0;
- }
-
- width = g->width - src_xx;
- }
-
- if (pos->step_yoffset < 0)
- {
- src_yy = 0;
- dst_yy = pos->y + ABS(ky * pos->step_yoffset);
- height = g->height;
-
- if (dst_yy + height > door_rect->height)
- height = door_rect->height - dst_yy;
- }
- else
- {
- src_yy = 0;
- dst_yy = pos->y - ky * pos->step_yoffset;
-
- if (dst_yy < 0)
- {
- src_yy = ABS(dst_yy);
- dst_yy = 0;
- }
-
- height = g->height - src_yy;
- }
-
-#if 0
- printf("::: src_xx, src_yy ; dst_xx, dst_yy ; width, height == %d, %d ; %d, %d ; %d, %d\n", src_xx, src_yy, dst_xx, dst_yy, width, height);
-#endif
-
-#if 0
- if ((pos->step_xoffset != 0 && width >= g->width) ||
- (pos->step_yoffset != 0 && height >= g->height))
- door_part_done[nr] = TRUE;
-#endif
-
-#if 0
-#if 1
- // !!! TEST !!!
- door_part_done[nr] = TRUE;
-
- BlitBitmapMasked(g->bitmap, drawto, g->src_x, g->src_y,
- g->width, g->height,
- door_rect->x + pos->x, door_rect->y + pos->y);
-
- 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
-#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
if (width >= 0 && width <= g->width &&
height >= 0 && height <= g->height)
- 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
- // printf("::: %d: width == %d, height == %d\n", nr, width, 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);
+ }
+
+#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);
-#if 1
- if ((((door_state & door_token) & DOOR_OPEN) &&
- (width < 0 || height < 0)) ||
- (((door_state & door_token) & DOOR_CLOSE) &&
- (width >= g->width && height >= g->height)))
+ if ((door_opening && (width < 0 || height < 0)) ||
+ (door_closing && (width >= g->width && height >= g->height)))
door_part_done[nr] = TRUE;
-#else
- if ((((door_state & door_token) & DOOR_OPEN) &&
- (width < 0 || height < 0)) ||
- (((door_state & door_token) & DOOR_CLOSE) &&
- ((pos->step_xoffset != 0 && width >= g->width) ||
- (pos->step_yoffset != 0 && height >= g->height))))
- door_part_done[nr] = TRUE;
-#endif
}
if (!(door_state & DOOR_NO_DELAY))
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)