struct GraphicInfo graphic_info;
struct GraphicInfo control_info;
- boolean class_playfield;
+ boolean class_playfield_or_door;
int viewport_x;
int viewport_y;
return compare_result;
}
-static boolean isPausedOnPlayfield(struct GlobalAnimPartControlInfo *part)
+static boolean isPausedOnPlayfieldOrDoor(struct GlobalAnimPartControlInfo *part)
{
- // only pause playfield animations when playing
+ // only pause playfield and door animations when playing
if (game_status != GAME_MODE_PLAYING)
return FALSE;
if (checkGameEnded())
return FALSE;
- // only pause animations on playfield
- if (!part->class_playfield)
+ // only pause animations on playfield and doors
+ if (!part->class_playfield_or_door)
return FALSE;
// only pause animations when engine is paused or request dialog is open(ing)
if (part->drawing_stage != drawing_stage)
continue;
- // if game is paused, also pause playfield animations
- if (isPausedOnPlayfield(part))
+ // if game is paused, also pause playfield and door animations
+ if (isPausedOnPlayfieldOrDoor(part))
part->initial_anim_sync_frame++;
sync_frame = anim_sync_frame - part->initial_anim_sync_frame;
part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_1;
- part->class_playfield = FALSE;
+ part->class_playfield_or_door = FALSE;
if (part->control_info.class == get_hash_from_key("window") ||
part->control_info.class == get_hash_from_key("border"))
viewport_y = DY;
viewport_width = DXSIZE;
viewport_height = DYSIZE;
+
+ part->class_playfield_or_door = TRUE;
}
else if (part->control_info.class == get_hash_from_key("door_2"))
{
viewport_width = VXSIZE;
viewport_height = VYSIZE;
}
+
+ part->class_playfield_or_door = TRUE;
}
else // default: "playfield"
{
viewport_width = FULL_SXSIZE;
viewport_height = FULL_SYSIZE;
- part->class_playfield = TRUE;
+ part->class_playfield_or_door = TRUE;
}
if (viewport_x != part->viewport_x ||
return ((part->control_info.style & STYLE_PASSTHROUGH) ? FALSE : TRUE);
}
+static void SetGlobalAnimPartTileXY(struct GlobalAnimPartControlInfo *part)
+{
+ // calculate playfield position (with scrolling) for related CE tile
+ // (do not use FX/FY, which are incorrect during envelope requests)
+ int FX0 = 2 * TILEX_VAR; // same as FX during DRAW_TO_FIELDBUFFER
+ int FY0 = 2 * TILEY_VAR; // same as FY during DRAW_TO_FIELDBUFFER
+ int fx = getFieldbufferOffsetX_RND(ScreenMovDir, ScreenGfxPos);
+ int fy = getFieldbufferOffsetY_RND(ScreenMovDir, ScreenGfxPos);
+ int sx = FX0 + SCREENX(part->tile_x) * TILEX_VAR;
+ int sy = FY0 + SCREENY(part->tile_y) * TILEY_VAR;
+ int cx = SX - REAL_SX;
+ int cy = SY - REAL_SY;
+ int x = sx - fx + cx;
+ int y = sy - fy + cy;
+
+ part->tile_xoffset += part->step_xoffset;
+ part->tile_yoffset += part->step_yoffset;
+
+ part->x = x + part->tile_xoffset;
+ part->y = y + part->tile_yoffset;
+}
+
static void InitGlobalAnim_Triggered(struct GlobalAnimPartControlInfo *part,
boolean *click_consumed,
boolean *any_event_action,
}
static void InitGlobalAnim_Triggered_ByCustomElement(int nr, int page,
- int x, int y)
+ int x, int y,
+ int trigger_x,
+ int trigger_y)
{
struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[GAME_MODE_PLAYING];
{
struct GraphicInfo *c = &part2->control_info;
- if (c->position == POS_CE)
+ if (c->position == POS_CE ||
+ c->position == POS_CE_TRIGGER)
{
- // may contain negative tile offset that is treated as "off-screen"
- part2->x = 0;
- part2->y = 0;
-
// store CE tile and offset position to handle scrolling
- part2->tile_x = x;
- part2->tile_y = y;
+ part2->tile_x = (c->position == POS_CE_TRIGGER ? trigger_x : x);
+ part2->tile_y = (c->position == POS_CE_TRIGGER ? trigger_y : y);
part2->tile_xoffset = c->x;
part2->tile_yoffset = c->y;
+ // set resulting animation position relative to CE tile position
+ // (but only for ".init_event", not ".anim_event" type events)
+ if (part2->init_event_state)
+ SetGlobalAnimPartTileXY(part2);
+
// restart animation (by using current sync frame)
part2->initial_anim_sync_frame = anim_sync_frame;
}
struct GraphicInfo *c = &part->control_info;
boolean viewport_changed = SetGlobalAnimPart_Viewport(part);
- // if game is paused, also pause playfield animations
- if (isPausedOnPlayfield(part))
+ // if game is paused, also pause playfield and door animations
+ if (isPausedOnPlayfieldOrDoor(part))
return state;
if (viewport_changed)
}
#endif
- if (c->position == POS_CE)
+ if (c->position == POS_CE ||
+ c->position == POS_CE_TRIGGER)
{
- // calculate playfield position (with scrolling) for related CE tile
- // (do not use FX/FY, which are incorrect during envelope requests)
- int FX0 = 2 * TILEX_VAR; // same as FX during DRAW_TO_FIELDBUFFER
- int FY0 = 2 * TILEY_VAR; // same as FY during DRAW_TO_FIELDBUFFER
- int fx = getFieldbufferOffsetX_RND(ScreenMovDir, ScreenGfxPos);
- int fy = getFieldbufferOffsetY_RND(ScreenMovDir, ScreenGfxPos);
- int sx = FX0 + SCREENX(part->tile_x) * TILEX_VAR;
- int sy = FY0 + SCREENY(part->tile_y) * TILEY_VAR;
- int cx = SX - REAL_SX;
- int cy = SY - REAL_SY;
- int x = sx - fx + cx;
- int y = sy - fy + cy;
-
- part->tile_xoffset += part->step_xoffset;
- part->tile_yoffset += part->step_yoffset;
-
- part->x = x + part->tile_xoffset;
- part->y = y + part->tile_yoffset;
+ SetGlobalAnimPartTileXY(part);
}
else
{
return anim_sync_frame;
}
-void HandleGlobalAnimEventByElementChange(int element, int page, int x, int y)
+void HandleGlobalAnimEventByElementChange(int element, int page, int x, int y,
+ int trigger_x, int trigger_y)
{
if (!IS_CUSTOM_ELEMENT(element))
return;
// custom element stored as 0 to 255, change page stored as 1 to 32
InitGlobalAnim_Triggered_ByCustomElement(element - EL_CUSTOM_START, page + 1,
- x, y);
+ x, y, trigger_x, trigger_y);
}