}
#endif
+static int unifiedRedrawMask(int mask)
+{
+ if (mask & REDRAW_ALL)
+ return REDRAW_ALL;
+
+ if (mask & REDRAW_FIELD && mask & REDRAW_DOORS)
+ return REDRAW_ALL;
+
+ return mask;
+}
+
+static boolean equalRedrawMasks(int mask_1, int mask_2)
+{
+ return unifiedRedrawMask(mask_1) == unifiedRedrawMask(mask_2);
+}
+
void BackToFront()
{
static int last_redraw_mask = REDRAW_NONE;
if (redraw_mask & REDRAW_FPS)
DrawFramesPerSecond();
+ // remove playfield redraw before potentially merging with doors redraw
+ if (DrawingDeactivated(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE))
+ redraw_mask &= ~REDRAW_FIELD;
+
// redraw complete window if both playfield and (some) doors need redraw
if (redraw_mask & REDRAW_FIELD && redraw_mask & REDRAW_DOORS)
redraw_mask = REDRAW_ALL;
}
else if (redraw_mask & REDRAW_DOORS)
{
+ // merge door areas to prevent calling screen redraw more than once
+ int x1 = WIN_XSIZE;
+ int y1 = WIN_YSIZE;
+ int x2 = 0;
+ int y2 = 0;
+
if (redraw_mask & REDRAW_DOOR_1)
- BlitBitmap(backbuffer, window, DX, DY, DXSIZE, DYSIZE, DX, DY);
+ {
+ x1 = MIN(x1, DX);
+ y1 = MIN(y1, DY);
+ x2 = MAX(x2, DX + DXSIZE);
+ y2 = MAX(y2, DY + DYSIZE);
+ }
if (redraw_mask & REDRAW_DOOR_2)
- BlitBitmap(backbuffer, window, VX, VY, VXSIZE, VYSIZE, VX, VY);
+ {
+ x1 = MIN(x1, VX);
+ y1 = MIN(y1, VY);
+ x2 = MAX(x2, VX + VXSIZE);
+ y2 = MAX(y2, VY + VYSIZE);
+ }
if (redraw_mask & REDRAW_DOOR_3)
- BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
+ {
+ x1 = MIN(x1, EX);
+ y1 = MIN(y1, EY);
+ x2 = MAX(x2, EX + EXSIZE);
+ y2 = MAX(y2, EY + EYSIZE);
+ }
+
+ BlitBitmap(backbuffer, window, x1, y1, x2 - x1, y2 - y1, x1, y1);
}
redraw_mask = REDRAW_NONE;
SetVideoFrameDelay(frame_delay_value_old);
}
-static void FadeCrossSaveBackbuffer()
-{
- BlitBitmap(backbuffer, bitmap_db_cross, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
-}
-
-static void FadeCrossRestoreBackbuffer()
-{
- int redraw_mask_last = redraw_mask;
-
- BlitBitmap(bitmap_db_cross, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
-
- // do not change redraw mask when restoring backbuffer after cross-fading
- redraw_mask = redraw_mask_last;
-}
+static int fade_type_skip = FADE_TYPE_NONE;
static void FadeExt(int fade_mask, int fade_mode, int fade_type)
{
- static int fade_type_skip = FADE_TYPE_NONE;
void (*draw_border_function)(void) = NULL;
- Bitmap *bitmap = (fade_mode & FADE_TYPE_TRANSFORM ? bitmap_db_cross : NULL);
int x, y, width, height;
int fade_delay, post_delay;
return;
}
-#if 1
- FadeCrossSaveBackbuffer();
-#endif
-
if (fading.fade_mode & FADE_TYPE_TRANSFORM)
- {
-#if 0
- FadeCrossSaveBackbuffer();
-#endif
-
return;
- }
}
redraw_mask |= fade_mask;
return;
}
- FadeRectangle(bitmap, x, y, width, height, fade_mode, fade_delay, post_delay,
+ FadeRectangle(x, y, width, height, fade_mode, fade_delay, post_delay,
draw_border_function);
- if (fade_type == FADE_TYPE_FADE_OUT)
- FadeCrossRestoreBackbuffer();
-
redraw_mask &= ~fade_mask;
}
global.anim_status = global.anim_status_next;
// store backbuffer with all animations that will be started after fading in
- PrepareFadeBitmap(DRAW_TO_FADE_TARGET);
+ if (fade_type_skip != FADE_MODE_SKIP_FADE_IN)
+ PrepareFadeBitmap(DRAW_TO_FADE_TARGET);
// set screen mode for animations back to fading
global.anim_status = GAME_MODE_PSEUDO_FADING;
gfx.fade_border_source_status = global.border_status;
global.anim_status = global.anim_status_next;
-
- // force update of global animation status in case of rapid screen changes
- redraw_mask = REDRAW_ALL;
- BackToFront();
}
static void SetScreenStates_BeforeFadingOut()
global.anim_status = GAME_MODE_PSEUDO_FADING;
// store backbuffer with all animations that will be stopped for fading out
- PrepareFadeBitmap(DRAW_TO_FADE_SOURCE);
+ if (fade_type_skip != FADE_MODE_SKIP_FADE_OUT)
+ PrepareFadeBitmap(DRAW_TO_FADE_SOURCE);
}
static void SetScreenStates_AfterFadingOut()
FADE_SYSIZE = FULL_SYSIZE;
SetScreenStates_AfterFadingIn();
+
+ // force update of global animation status in case of rapid screen changes
+ redraw_mask = REDRAW_ALL;
+ BackToFront();
}
void FadeOut(int fade_mask)
{
+ // update screen if areas covered by "fade_mask" and "redraw_mask" differ
+ if (!equalRedrawMasks(fade_mask, redraw_mask))
+ BackToFront();
+
SetScreenStates_BeforeFadingOut();
#if 0
// copy current draw buffer to later copy back areas that have not changed
if (game_status_last != GAME_MODE_TITLE)
- BlitBitmap(backbuffer, bitmap_db_store, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+ BlitBitmap(backbuffer, bitmap_db_store_1, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
if (CheckIfGlobalBorderRedrawIsNeeded())
{
if (real_sx_last != -1 && real_sy_last != -1 &&
REAL_SX != -1 && REAL_SY != -1 &&
full_sxsize_last == FULL_SXSIZE && full_sysize_last == FULL_SYSIZE)
- BlitBitmap(bitmap_db_store, backbuffer,
+ BlitBitmap(bitmap_db_store_1, backbuffer,
real_sx_last, real_sy_last, FULL_SXSIZE, FULL_SYSIZE,
REAL_SX, REAL_SY);
if (dx_last != -1 && dy_last != -1 &&
DX != -1 && DY != -1 &&
dxsize_last == DXSIZE && dysize_last == DYSIZE)
- BlitBitmap(bitmap_db_store, backbuffer,
+ BlitBitmap(bitmap_db_store_1, backbuffer,
dx_last, dy_last, DXSIZE, DYSIZE, DX, DY);
if (vx_last != -1 && vy_last != -1 &&
VX != -1 && VY != -1 &&
vxsize_last == VXSIZE && vysize_last == VYSIZE)
- BlitBitmap(bitmap_db_store, backbuffer,
+ BlitBitmap(bitmap_db_store_1, backbuffer,
vx_last, vy_last, VXSIZE, VYSIZE, VX, VY);
redraw_mask = REDRAW_ALL;
sync_frame);
}
-void getSizedGraphicSourceExt(int graphic, int frame, int tilesize,
- Bitmap **bitmap, int *x, int *y,
- boolean get_backside)
+void getGraphicSourceBitmap(int graphic, int tilesize, Bitmap **bitmap)
{
struct GraphicInfo *g = &graphic_info[graphic];
- Bitmap *src_bitmap = g->bitmap;
- int src_x = g->src_x + (get_backside ? g->offset2_x : 0);
- int src_y = g->src_y + (get_backside ? g->offset2_y : 0);
int tilesize_capped = MIN(MAX(1, tilesize), TILESIZE);
- // if no in-game graphics defined, always use standard graphic size
- if (g->bitmaps[IMG_BITMAP_GAME] == NULL)
- tilesize = TILESIZE;
-
if (tilesize == gfx.standard_tile_size)
- src_bitmap = g->bitmaps[IMG_BITMAP_STANDARD];
+ *bitmap = g->bitmaps[IMG_BITMAP_STANDARD];
else if (tilesize == game.tile_size)
- src_bitmap = g->bitmaps[IMG_BITMAP_GAME];
+ *bitmap = g->bitmaps[IMG_BITMAP_GAME];
else
- src_bitmap = g->bitmaps[IMG_BITMAP_1x1 - log_2(tilesize_capped)];
+ *bitmap = g->bitmaps[IMG_BITMAP_1x1 - log_2(tilesize_capped)];
+}
+
+void getGraphicSourceXY(int graphic, int frame, int *x, int *y,
+ boolean get_backside)
+{
+ struct GraphicInfo *g = &graphic_info[graphic];
+ int src_x = g->src_x + (get_backside ? g->offset2_x : 0);
+ int src_y = g->src_y + (get_backside ? g->offset2_y : 0);
if (g->offset_y == 0) /* frames are ordered horizontally */
{
int max_width = g->anim_frames_per_line * g->width;
int pos = (src_y / g->height) * max_width + src_x + frame * g->offset_x;
- src_x = pos % max_width;
- src_y = src_y % g->height + pos / max_width * g->height;
+ *x = pos % max_width;
+ *y = src_y % g->height + pos / max_width * g->height;
}
else if (g->offset_x == 0) /* frames are ordered vertically */
{
int max_height = g->anim_frames_per_line * g->height;
int pos = (src_x / g->width) * max_height + src_y + frame * g->offset_y;
- src_x = src_x % g->width + pos / max_height * g->width;
- src_y = pos % max_height;
+ *x = src_x % g->width + pos / max_height * g->width;
+ *y = pos % max_height;
}
else /* frames are ordered diagonally */
{
- src_x = src_x + frame * g->offset_x;
- src_y = src_y + frame * g->offset_y;
+ *x = src_x + frame * g->offset_x;
+ *y = src_y + frame * g->offset_y;
}
+}
+
+void getSizedGraphicSourceExt(int graphic, int frame, int tilesize,
+ Bitmap **bitmap, int *x, int *y,
+ boolean get_backside)
+{
+ struct GraphicInfo *g = &graphic_info[graphic];
+
+ // if no in-game graphics defined, always use standard graphic size
+ if (g->bitmaps[IMG_BITMAP_GAME] == NULL)
+ tilesize = TILESIZE;
+
+ getGraphicSourceBitmap(graphic, tilesize, bitmap);
+ getGraphicSourceXY(graphic, frame, x, y, get_backside);
- *bitmap = src_bitmap;
- *x = src_x * tilesize / g->tile_size;
- *y = src_y * tilesize / g->tile_size;
+ *x = *x * tilesize / g->tile_size;
+ *y = *y * tilesize / g->tile_size;
}
void getFixedGraphicSourceExt(int graphic, int frame, Bitmap **bitmap,
inline static void getGraphicSourceExt(int graphic, int frame, Bitmap **bitmap,
int *x, int *y, boolean get_backside)
{
- struct GraphicInfo *g = &graphic_info[graphic];
- int src_x = g->src_x + (get_backside ? g->offset2_x : 0);
- int src_y = g->src_y + (get_backside ? g->offset2_y : 0);
-
- if (TILESIZE_VAR != TILESIZE)
- return getSizedGraphicSourceExt(graphic, frame, TILESIZE_VAR, bitmap, x, y,
- get_backside);
-
- *bitmap = g->bitmap;
-
- if (g->offset_y == 0) /* frames are ordered horizontally */
- {
- int max_width = g->anim_frames_per_line * g->width;
- int pos = (src_y / g->height) * max_width + src_x + frame * g->offset_x;
-
- *x = pos % max_width;
- *y = src_y % g->height + pos / max_width * g->height;
- }
- else if (g->offset_x == 0) /* frames are ordered vertically */
- {
- int max_height = g->anim_frames_per_line * g->height;
- int pos = (src_x / g->width) * max_height + src_y + frame * g->offset_y;
-
- *x = src_x % g->width + pos / max_height * g->width;
- *y = pos % max_height;
- }
- else /* frames are ordered diagonally */
- {
- *x = src_x + frame * g->offset_x;
- *y = src_y + frame * g->offset_y;
- }
-
- *x = *x * TILESIZE_VAR / g->tile_size;
- *y = *y * TILESIZE_VAR / g->tile_size;
+ getSizedGraphicSourceExt(graphic, frame, TILESIZE_VAR, bitmap, x, y,
+ get_backside);
}
void getGraphicSource(int graphic, int frame, Bitmap **bitmap, int *x, int *y)
RedrawGadget(tool_gadget[i]);
// store readily prepared envelope request for later use when animating
- BlitBitmap(backbuffer, bitmap_db_cross, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+ BlitBitmap(backbuffer, bitmap_db_store_2, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
if (text_door_style)
free(text_door_style);
setRequestPosition(&src_x, &src_y, FALSE);
setRequestPositionExt(&dst_x, &dst_y, width, height, FALSE);
- BlitBitmap(bitmap_db_store, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+ BlitBitmap(bitmap_db_store_1, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
for (yy = 0; yy < 2; yy++)
{
int yy_size = (yy ? tile_size : ysize_size_top);
if (draw_masked)
- BlitBitmapMasked(bitmap_db_cross, backbuffer,
+ BlitBitmapMasked(bitmap_db_store_2, backbuffer,
src_xx, src_yy, xx_size, yy_size, dst_xx, dst_yy);
else
- BlitBitmap(bitmap_db_cross, backbuffer,
+ BlitBitmap(bitmap_db_store_2, backbuffer,
src_xx, src_yy, xx_size, yy_size, dst_xx, dst_yy);
}
}
if (action == ACTION_OPENING)
{
- BlitBitmap(backbuffer, bitmap_db_store, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+ BlitBitmap(backbuffer, bitmap_db_store_1, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
if (req_state & REQ_ASK)
{
game.envelope_active = FALSE;
if (action == ACTION_CLOSING)
- BlitBitmap(bitmap_db_store, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+ BlitBitmap(bitmap_db_store_1, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
// SetDrawBackgroundMask(last_draw_background_mask);
if (global.use_envelope_request)
{
/* copy current state of request area to middle of playfield area */
- BlitBitmap(bitmap_db_cross, drawto, sx, sy, width, height, sx, sy);
+ BlitBitmap(bitmap_db_store_2, drawto, sx, sy, width, height, sx, sy);
}
}
}
case EVENT_KEYPRESS:
- switch (GetEventKey((KeyEvent *)&event, TRUE))
+ {
+ Key key = GetEventKey((KeyEvent *)&event, TRUE);
+
+ switch (key)
{
case KSYM_space:
if (req_state & REQ_CONFIRM)
break;
default:
+ HandleKeysDebug(key);
break;
}
if (req_state & REQ_PLAYER)
result = 0;
+
break;
+ }
case EVENT_KEYRELEASE:
ClearPlayerAction();
if (global.use_envelope_request)
{
/* copy back current state of pressed buttons inside request area */
- BlitBitmap(drawto, bitmap_db_cross, sx, sy, width, height, sx, sy);
+ BlitBitmap(drawto, bitmap_db_store_2, sx, sy, width, height, sx, sy);
}
}
int sync_frame = kk_door * door_delay_value;
int frame = getGraphicAnimationFrame(dpc->graphic, sync_frame);
- getGraphicSource(dpc->graphic, frame, &bitmap, &g_src_x, &g_src_y);
+ getFixedGraphicSource(dpc->graphic, frame, &bitmap,
+ &g_src_x, &g_src_y);
}
// draw door panel
boolean any_player_snapping,
boolean any_player_dropping)
{
- static boolean player_was_waiting = TRUE;
-
if (frame == 0 && !any_player_dropping)
{
- if (!player_was_waiting)
+ if (!local_player->was_waiting)
{
- if (!SaveEngineSnapshotToList())
+ if (!CheckSaveEngineSnapshotToList())
return;
- player_was_waiting = TRUE;
+ local_player->was_waiting = TRUE;
}
}
else if (any_player_moving || any_player_snapping || any_player_dropping)
{
- player_was_waiting = FALSE;
+ local_player->was_waiting = FALSE;
}
}
void CheckSaveEngineSnapshot_SP(boolean murphy_is_waiting,
boolean murphy_is_dropping)
{
- static boolean player_was_waiting = TRUE;
-
if (murphy_is_waiting)
{
- if (!player_was_waiting)
+ if (!local_player->was_waiting)
{
- if (!SaveEngineSnapshotToList())
+ if (!CheckSaveEngineSnapshotToList())
return;
- player_was_waiting = TRUE;
+ local_player->was_waiting = TRUE;
}
}
else
{
- player_was_waiting = FALSE;
+ local_player->was_waiting = FALSE;
}
}