X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Ftools.c;h=e534cc29c3e79c465cd50d0ee79420ed0bd5bc17;hp=ec059e12146082ca1613378e6e11ce18e1491d92;hb=aecdc1103c5dff9ef3900c213931d526df0cb3a7;hpb=0c454763268d571be71d2c7a633f5bd855d0ad0b diff --git a/src/tools.c b/src/tools.c index ec059e12..e534cc29 100644 --- a/src/tools.c +++ b/src/tools.c @@ -528,6 +528,22 @@ static void PrintFrameTimeDebugging() } #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; @@ -550,6 +566,10 @@ void BackToFront() 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; @@ -570,14 +590,37 @@ void BackToFront() } 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; @@ -598,9 +641,10 @@ void BackToFront_WithFrameDelay(unsigned int frame_delay_value) SetVideoFrameDelay(frame_delay_value_old); } +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; int x, y, width, height; int fade_delay, post_delay; @@ -692,7 +736,8 @@ static void SetScreenStates_BeforeFadingIn() 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; @@ -704,10 +749,6 @@ static void SetScreenStates_AfterFadingIn() 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() @@ -719,7 +760,8 @@ 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() @@ -746,10 +788,18 @@ void FadeIn(int fade_mask) 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 @@ -1024,7 +1074,7 @@ static void RedrawGlobalBorderIfNeeded() // 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()) { @@ -1037,20 +1087,20 @@ static void RedrawGlobalBorderIfNeeded() 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; @@ -1169,52 +1219,64 @@ int getGraphicAnimationFrame(int graphic, int sync_frame) 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; - *bitmap = src_bitmap; - *x = src_x * tilesize / g->tile_size; - *y = src_y * tilesize / g->tile_size; + getGraphicSourceBitmap(graphic, tilesize, bitmap); + getGraphicSourceXY(graphic, frame, x, y, get_backside); + + *x = *x * tilesize / g->tile_size; + *y = *y * tilesize / g->tile_size; } void getFixedGraphicSourceExt(int graphic, int frame, Bitmap **bitmap, @@ -1244,40 +1306,8 @@ void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y) 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) @@ -2498,7 +2528,7 @@ void DrawEnvelopeRequest(char *text) 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); @@ -2559,7 +2589,7 @@ void AnimateEnvelopeRequest(int anim_mode, int action) 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++) { @@ -2573,10 +2603,10 @@ void AnimateEnvelopeRequest(int anim_mode, int action) 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); } } @@ -2609,7 +2639,7 @@ void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) 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) { @@ -2656,7 +2686,7 @@ void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) 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); @@ -3561,7 +3591,7 @@ static int RequestHandleEvents(unsigned int req_state) 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); } } @@ -3635,7 +3665,10 @@ static int RequestHandleEvents(unsigned int req_state) } case EVENT_KEYPRESS: - switch (GetEventKey((KeyEvent *)&event, TRUE)) + { + Key key = GetEventKey((KeyEvent *)&event, TRUE); + + switch (key) { case KSYM_space: if (req_state & REQ_CONFIRM) @@ -3657,12 +3690,15 @@ static int RequestHandleEvents(unsigned int req_state) break; default: + HandleKeysDebug(key); break; } if (req_state & REQ_PLAYER) result = 0; + break; + } case EVENT_KEYRELEASE: ClearPlayerAction(); @@ -3689,7 +3725,7 @@ static int RequestHandleEvents(unsigned int req_state) 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); } } @@ -4424,7 +4460,8 @@ unsigned int MoveDoor(unsigned int door_state) 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 @@ -7996,42 +8033,38 @@ void CheckSaveEngineSnapshot_EM(byte action[MAX_PLAYERS], int frame, 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; } }