X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=95bc7a45ac7bbdc8a83c1e6267b8314f43c446b4;hb=cff0c254d160d92dbd6151f6110b1ed9dfec6296;hp=d5dc6909490e514acd3bed4cf2d814ac2926420d;hpb=3282aa616432ea42399d4dc4ffe637c4406a71c4;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index d5dc6909..95bc7a45 100644 --- a/src/tools.c +++ b/src/tools.c @@ -233,7 +233,7 @@ void DumpTile(int x, int y) void SetDrawtoField(int mode) { - if (mode == DRAW_BUFFERED && setup.soft_scrolling) + if (mode == DRAW_FIELDBUFFER) { FX = 2 * TILEX_VAR; FY = 2 * TILEY_VAR; @@ -241,8 +241,6 @@ void SetDrawtoField(int mode) BY1 = -2; BX2 = SCR_FIELDX + 1; BY2 = SCR_FIELDY + 1; - redraw_x1 = 2; - redraw_y1 = 2; drawto_field = fieldbuffer; } @@ -254,8 +252,6 @@ void SetDrawtoField(int mode) BY1 = 0; BX2 = SCR_FIELDX - 1; BY2 = SCR_FIELDY - 1; - redraw_x1 = 0; - redraw_y1 = 0; drawto_field = backbuffer; } @@ -338,11 +334,6 @@ void DrawMaskedBorder(int redraw_mask) effectiveGameStatus() == GAME_MODE_TITLE) return; - /* never draw masked screen borders when displaying request outside door */ - if (effectiveGameStatus() == GAME_MODE_PSEUDO_DOOR && - global.use_envelope_request) - return; - if (redraw_mask & REDRAW_ALL) DrawMaskedBorder_ALL(); else @@ -358,9 +349,8 @@ void DrawMaskedBorder(int redraw_mask) } } -static void BlitScreenToBitmap_RND(Bitmap *target_bitmap) +void BlitScreenToBitmap_RND(Bitmap *target_bitmap) { - DrawBuffer *buffer = (drawto_field == window ? backbuffer : drawto_field); int fx = FX, fy = FY; int full_lev_fieldx = lev_fieldx + (BorderElement != EL_EMPTY ? 2 : 0); int full_lev_fieldy = lev_fieldy + (BorderElement != EL_EMPTY ? 2 : 0); @@ -414,23 +404,7 @@ static void BlitScreenToBitmap_RND(Bitmap *target_bitmap) fy = 2 * TILEY_VAR - (EVEN(lev_fieldy) ? TILEY_VAR / 2 : 0); } - if (border.draw_masked[GAME_MODE_PLAYING]) - { - if (buffer != backbuffer) - { - /* copy playfield buffer to backbuffer to add masked border */ - BlitBitmap(buffer, backbuffer, fx, fy, SXSIZE, SYSIZE, SX, SY); - DrawMaskedBorder(REDRAW_FIELD); - } - - BlitBitmap(backbuffer, target_bitmap, - REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, - REAL_SX, REAL_SY); - } - else - { - BlitBitmap(buffer, target_bitmap, fx, fy, SXSIZE, SYSIZE, SX, SY); - } + BlitBitmap(drawto_field, target_bitmap, fx, fy, SXSIZE, SYSIZE, SX, SY); } void BlitScreenToBitmap(Bitmap *target_bitmap) @@ -443,23 +417,10 @@ void BlitScreenToBitmap(Bitmap *target_bitmap) BlitScreenToBitmap_RND(target_bitmap); } -void BackToFront() +void BackToFront_OLD() { - int x, y; DrawBuffer *buffer = (drawto_field == window ? backbuffer : drawto_field); - if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD) - redraw_mask |= REDRAW_FIELD; - -#if 0 - // never redraw single tiles, always redraw the whole field - // (redrawing single tiles up to a certain threshold was faster on old, - // now legacy graphics, but slows things down on modern graphics now) - // UPDATE: this is now globally defined by value of REDRAWTILES_THRESHOLD - if (redraw_mask & REDRAW_TILES) - redraw_mask |= REDRAW_FIELD; -#endif - #if 0 /* !!! TEST ONLY !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ /* (force full redraw) */ @@ -467,9 +428,6 @@ void BackToFront() redraw_mask |= REDRAW_FIELD; #endif - if (redraw_mask & REDRAW_FIELD) - redraw_mask &= ~REDRAW_TILES; - if (redraw_mask == REDRAW_NONE) return; @@ -479,8 +437,6 @@ void BackToFront() printf("[REDRAW_ALL]"); if (redraw_mask & REDRAW_FIELD) printf("[REDRAW_FIELD]"); - if (redraw_mask & REDRAW_TILES) - printf("[REDRAW_TILES]"); if (redraw_mask & REDRAW_DOOR_1) printf("[REDRAW_DOOR_1]"); if (redraw_mask & REDRAW_DOOR_2) @@ -490,11 +446,6 @@ void BackToFront() printf(" [%d]\n", FrameCounter); #endif - if (redraw_mask & REDRAW_TILES && - game_status == GAME_MODE_PLAYING && - border.draw_masked[GAME_MODE_PLAYING]) - redraw_mask |= REDRAW_FIELD; - if (global.fps_slowdown && game_status == GAME_MODE_PLAYING) { static boolean last_frame_skipped = FALSE; @@ -585,70 +536,6 @@ void BackToFront() redraw_mask &= ~REDRAW_MICROLEVEL; } - if (redraw_mask & REDRAW_TILES) - { - int sx = SX; - int sy = SY; - - int dx = 0, dy = 0; - int dx_var = dx * TILESIZE_VAR / TILESIZE; - int dy_var = dy * TILESIZE_VAR / TILESIZE; - int ffx, ffy; - int fx = FX, fy = FY; - - int scr_fieldx = SCR_FIELDX + (EVEN(SCR_FIELDX) ? 2 : 0); - int scr_fieldy = SCR_FIELDY + (EVEN(SCR_FIELDY) ? 2 : 0); - - InitGfxClipRegion(TRUE, SX, SY, SXSIZE, SYSIZE); - - ffx = (scroll_x - SBX_Left) * TILEX_VAR + dx_var; - ffy = (scroll_y - SBY_Upper) * TILEY_VAR + dy_var; - - if (EVEN(SCR_FIELDX)) - { - if (ffx < SBX_Right * TILEX_VAR + TILEX_VAR / 2 + TILEX_VAR) - { - fx += dx_var - MIN(ffx, TILEX_VAR / 2) + TILEX_VAR; - - if (fx % TILEX_VAR) - sx -= TILEX_VAR / 2; - else - sx -= TILEX_VAR; - } - else - { - fx += (dx_var > 0 ? TILEX_VAR : 0); - } - } - - if (EVEN(SCR_FIELDY)) - { - if (ffy < SBY_Lower * TILEY_VAR + TILEY_VAR / 2 + TILEY_VAR) - { - fy += dy_var - MIN(ffy, TILEY_VAR / 2) + TILEY_VAR; - - if (fy % TILEY_VAR) - sy -= TILEY_VAR / 2; - else - sy -= TILEY_VAR; - } - else - { - fy += (dy_var > 0 ? TILEY_VAR : 0); - } - } - - for (x = 0; x < scr_fieldx; x++) - for (y = 0 ; y < scr_fieldy; y++) - if (redraw[redraw_x1 + x][redraw_y1 + y]) - BlitBitmap(buffer, window, - FX + x * TILEX_VAR, FY + y * TILEY_VAR, - TILEX_VAR, TILEY_VAR, - sx + x * TILEX_VAR, sy + y * TILEY_VAR); - - InitGfxClipRegion(FALSE, -1, -1, -1, -1); - } - if (redraw_mask & REDRAW_FPS) /* display frames per second */ { char text[100]; @@ -663,10 +550,20 @@ void BackToFront() DrawTextExt(window, SX + SXSIZE + SX, 0, text, FONT_TEXT_2, BLIT_OPAQUE); } - for (x = 0; x < MAX_BUF_XSIZE; x++) - for (y = 0; y < MAX_BUF_YSIZE; y++) - redraw[x][y] = 0; - redraw_tiles = 0; + redraw_mask = REDRAW_NONE; +} + +void BackToFront() +{ + if (redraw_mask == REDRAW_NONE) + return; + + // draw masked border to all viewports, if defined + DrawMaskedBorder(redraw_mask); + + // blit backbuffer to visible screen + BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); + redraw_mask = REDRAW_NONE; } @@ -951,25 +848,20 @@ void ClearField() DrawBackground(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); /* !!! maybe this should be done before clearing the background !!! */ - if (setup.soft_scrolling && game_status == GAME_MODE_PLAYING) + if (game_status == GAME_MODE_PLAYING) { ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE); - SetDrawtoField(DRAW_BUFFERED); + SetDrawtoField(DRAW_FIELDBUFFER); } else + { SetDrawtoField(DRAW_BACKBUFFER); + } } void MarkTileDirty(int x, int y) { - int xx = redraw_x1 + x; - int yy = redraw_y1 + y; - - if (!redraw[xx][yy]) - redraw_tiles++; - - redraw[xx][yy] = TRUE; - redraw_mask |= REDRAW_TILES; + redraw_mask |= REDRAW_FIELD; } void SetBorderElement() @@ -2028,6 +1920,14 @@ void DrawLevelField(int x, int y) } } +void DrawSizedElement(int x, int y, int element, int tilesize) +{ + int graphic; + + graphic = el2edimg(element); + DrawSizedGraphic(x, y, graphic, 0, tilesize); +} + void DrawMiniElement(int x, int y, int element) { int graphic; @@ -2036,6 +1936,19 @@ void DrawMiniElement(int x, int y, int element) DrawMiniGraphic(x, y, graphic); } +void DrawSizedElementOrWall(int sx, int sy, int scroll_x, int scroll_y, + int tilesize) +{ + int x = sx + scroll_x, y = sy + scroll_y; + + if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy) + DrawSizedElement(sx, sy, EL_EMPTY, tilesize); + else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy) + DrawSizedElement(sx, sy, Feld[x][y], tilesize); + else + DrawSizedGraphic(sx, sy, el2edimg(getBorderElement(x, y)), 0, tilesize); +} + void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y) { int x = sx + scroll_x, y = sy + scroll_y; @@ -2106,7 +2019,7 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action) boolean no_delay = (tape.warp_forward); unsigned int anim_delay = 0; int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay); - int anim_delay_value = (no_delay ? 0 : frame_delay_value); + int anim_delay_value = (no_delay ? 0 : frame_delay_value) / 2; int font_nr = FONT_ENVELOPE_1 + envelope_nr; int font_width = getFontWidth(font_nr); int font_height = getFontHeight(font_nr); @@ -2118,17 +2031,22 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action) int yend = (anim_mode != ANIM_DEFAULT ? max_ysize : 0); int xstep = (xstart < xend ? 1 : 0); int ystep = (ystart < yend || xstep == 0 ? 1 : 0); - int x, y; + int start = 0; + int end = MAX(xend - xstart, yend - ystart); + int i; - for (x = xstart, y = ystart; x <= xend && y <= yend; x += xstep, y += ystep) + for (i = start; i <= end; i++) { + int last_frame = end; // last frame of this "for" loop + int x = xstart + i * xstep; + int y = ystart + i * ystep; int xsize = (action == ACTION_CLOSING ? xend - (x - xstart) : x) + 2; int ysize = (action == ACTION_CLOSING ? yend - (y - ystart) : y) + 2; int sx = SX + (SXSIZE - xsize * font_width) / 2; int sy = SY + (SYSIZE - ysize * font_height) / 2; int xx, yy; - SetDrawtoField(DRAW_BUFFERED); + SetDrawtoField(DRAW_FIELDBUFFER); BlitScreenToBitmap(backbuffer); @@ -2147,7 +2065,7 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action) redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER; BackToFront(); - WaitUntilDelayReached(&anim_delay, anim_delay_value / 2); + SkipUntilDelayReached(&anim_delay, anim_delay_value, &i, last_frame); } } @@ -2189,19 +2107,31 @@ void ShowEnvelope(int envelope_nr) game.envelope_active = FALSE; - SetDrawtoField(DRAW_BUFFERED); + SetDrawtoField(DRAW_FIELDBUFFER); redraw_mask |= REDRAW_FIELD; BackToFront(); } -static void setRequestPosition(int *x, int *y, boolean add_border_size) +static void setRequestCenterPosition(int *x, int *y) { - int border_size = request.border_size; int sx_center = (request.x != -1 ? request.x : SX + SXSIZE / 2); int sy_center = (request.y != -1 ? request.y : SY + SYSIZE / 2); - int sx = sx_center - request.width / 2; - int sy = sy_center - request.height / 2; + + *x = sx_center; + *y = sy_center; +} + +static void setRequestPosition(int *x, int *y, boolean add_border_size) +{ + int border_size = request.border_size; + int sx_center, sy_center; + int sx, sy; + + setRequestCenterPosition(&sx_center, &sy_center); + + sx = sx_center - request.width / 2; + sy = sy_center - request.height / 2; if (add_border_size) { @@ -2298,7 +2228,7 @@ void AnimateEnvelopeRequest(int anim_mode, int action) boolean ffwd_delay = (tape.playing && tape.fast_forward); boolean no_delay = (tape.warp_forward); int delay_value = (ffwd_delay ? delay_value_fast : delay_value_normal); - int anim_delay_value = (no_delay ? 0 : delay_value + 500 * 0); + int anim_delay_value = (no_delay ? 0 : delay_value + 500 * 0) / 2; unsigned int anim_delay = 0; int width = request.width; @@ -2315,12 +2245,15 @@ void AnimateEnvelopeRequest(int anim_mode, int action) int yend = (anim_mode != ANIM_DEFAULT ? max_ysize_inner : 0); int xstep = (xstart < xend ? 1 : 0); int ystep = (ystart < yend || xstep == 0 ? 1 : 0); - int x, y; + int start = 0; + int end = MAX(xend - xstart, yend - ystart); + int i; if (setup.quick_doors) { xstart = xend; ystart = yend; + end = 0; } else { @@ -2330,22 +2263,29 @@ void AnimateEnvelopeRequest(int anim_mode, int action) PlayMenuSoundStereo(SND_DOOR_CLOSING, SOUND_MIDDLE); } - for (x = xstart, y = ystart; x <= xend && y <= yend; x += xstep, y += ystep) + for (i = start; i <= end; i++) { + int last_frame = end; // last frame of this "for" loop + int x = xstart + i * xstep; + int y = ystart + i * ystep; int xsize = (action == ACTION_CLOSING ? xend - (x - xstart) : x) + 2; int ysize = (action == ACTION_CLOSING ? yend - (y - ystart) : y) + 2; - int sx_center = (request.x != -1 ? request.x : SX + SXSIZE / 2); - int sy_center = (request.y != -1 ? request.y : SY + SYSIZE / 2); - int src_x = sx_center - width / 2; - int src_y = sy_center - height / 2; - int dst_x = sx_center - xsize * tile_size / 2; - int dst_y = sy_center - ysize * tile_size / 2; int xsize_size_left = (xsize - 1) * tile_size; int ysize_size_top = (ysize - 1) * tile_size; int max_xsize_pos = (max_xsize - 1) * tile_size; int max_ysize_pos = (max_ysize - 1) * tile_size; + int sx_center, sy_center; + int src_x, src_y; + int dst_x, dst_y; int xx, yy; + setRequestCenterPosition(&sx_center, &sy_center); + + src_x = sx_center - width / 2; + src_y = sy_center - height / 2; + dst_x = sx_center - xsize * tile_size / 2; + dst_y = sy_center - ysize * tile_size / 2; + BlitBitmap(bitmap_db_store, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); for (yy = 0; yy < 2; yy++) @@ -2373,11 +2313,10 @@ void AnimateEnvelopeRequest(int anim_mode, int action) DoAnimation(); BackToFront(); - WaitUntilDelayReached(&anim_delay, anim_delay_value / 2); + SkipUntilDelayReached(&anim_delay, anim_delay_value, &i, last_frame); } } - void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) { int last_game_status = game_status; /* save current game status */ @@ -2435,7 +2374,6 @@ void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) AnimateEnvelopeRequest(ANIM_DEFAULT, ACTION_OPENING); AnimateEnvelopeRequest(main_anim_mode, ACTION_OPENING); - } else { @@ -2472,7 +2410,7 @@ void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) if (action == ACTION_CLOSING && game_status == GAME_MODE_PLAYING && level.game_engine_type == GAME_ENGINE_TYPE_RND) - SetDrawtoField(DRAW_BUFFERED); + SetDrawtoField(DRAW_FIELDBUFFER); } void DrawPreviewElement(int dst_x, int dst_y, int element, int tilesize) @@ -2501,6 +2439,18 @@ void DrawLevel(int draw_background_mask) redraw_mask |= REDRAW_FIELD; } +void DrawSizedLevel(int size_x, int size_y, int scroll_x, int scroll_y, + int tilesize) +{ + int x,y; + + for (x = 0; x < size_x; x++) + for (y = 0; y < size_y; y++) + DrawSizedElementOrWall(x, y, scroll_x, scroll_y, tilesize); + + redraw_mask |= REDRAW_FIELD; +} + void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y) { int x,y; @@ -3105,9 +3055,6 @@ void DrawPlayer(struct PlayerInfo *player) syy = player->GfxPos; } - if (!setup.soft_scrolling && ScreenMovPos) - sxx = syy = 0; - if (player_is_opaque) DrawGraphicShifted(sx, sy, sxx, syy, graphic, frame,NO_CUTTING,NO_MASKING); else @@ -3213,9 +3160,6 @@ void DrawPlayer(struct PlayerInfo *player) syy = player->GfxPos; } - if (!setup.soft_scrolling && ScreenMovPos) - sxx = syy = 0; - if (player_is_opaque) DrawGraphicShifted(sx, sy, sxx, syy, graphic, frame,NO_CUTTING,NO_MASKING); else @@ -3341,9 +3285,15 @@ void WaitForEventToContinue() static int RequestHandleEvents(unsigned int req_state) { + boolean level_solved = (game_status == GAME_MODE_PLAYING && + local_player->LevelSolved_GameEnd); int last_game_status = game_status; /* save current game status */ + int width = request.width; + int height = request.height; + int sx, sy; int result; - int mx, my; + + setRequestPosition(&sx, &sy, FALSE); button_status = MB_RELEASED; @@ -3352,113 +3302,128 @@ static int RequestHandleEvents(unsigned int req_state) while (result < 0) { + if (level_solved) + { + SetDrawtoField(DRAW_FIELDBUFFER); + + HandleGameActions(); + + SetDrawtoField(DRAW_BACKBUFFER); + + 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); + } + } + if (PendingEvent()) { Event event; - NextEvent(&event); - - switch (event.type) + while (NextValidEvent(&event)) { - case EVENT_BUTTONPRESS: - case EVENT_BUTTONRELEASE: - case EVENT_MOTIONNOTIFY: + switch (event.type) { - if (event.type == EVENT_MOTIONNOTIFY) + case EVENT_BUTTONPRESS: + case EVENT_BUTTONRELEASE: + case EVENT_MOTIONNOTIFY: { - if (!PointerInWindow(window)) - continue; /* window and pointer are on different screens */ + int mx, my; - if (!button_status) - continue; + if (event.type == EVENT_MOTIONNOTIFY) + { + if (!button_status) + continue; - motion_status = TRUE; - mx = ((MotionEvent *) &event)->x; - my = ((MotionEvent *) &event)->y; - } - else - { - motion_status = FALSE; - mx = ((ButtonEvent *) &event)->x; - my = ((ButtonEvent *) &event)->y; - if (event.type == EVENT_BUTTONPRESS) - button_status = ((ButtonEvent *) &event)->button; + motion_status = TRUE; + mx = ((MotionEvent *) &event)->x; + my = ((MotionEvent *) &event)->y; + } else - button_status = MB_RELEASED; - } - - /* this sets 'request_gadget_id' */ - HandleGadgets(mx, my, button_status); - - switch (request_gadget_id) - { - case TOOL_CTRL_ID_YES: - result = TRUE; - break; - case TOOL_CTRL_ID_NO: - result = FALSE; - break; - case TOOL_CTRL_ID_CONFIRM: - result = TRUE | FALSE; - break; - - case TOOL_CTRL_ID_PLAYER_1: - result = 1; - break; - case TOOL_CTRL_ID_PLAYER_2: - result = 2; - break; - case TOOL_CTRL_ID_PLAYER_3: - result = 3; - break; - case TOOL_CTRL_ID_PLAYER_4: - result = 4; - break; - - default: - break; + { + motion_status = FALSE; + mx = ((ButtonEvent *) &event)->x; + my = ((ButtonEvent *) &event)->y; + if (event.type == EVENT_BUTTONPRESS) + button_status = ((ButtonEvent *) &event)->button; + else + button_status = MB_RELEASED; + } + + /* this sets 'request_gadget_id' */ + HandleGadgets(mx, my, button_status); + + switch (request_gadget_id) + { + case TOOL_CTRL_ID_YES: + result = TRUE; + break; + case TOOL_CTRL_ID_NO: + result = FALSE; + break; + case TOOL_CTRL_ID_CONFIRM: + result = TRUE | FALSE; + break; + + case TOOL_CTRL_ID_PLAYER_1: + result = 1; + break; + case TOOL_CTRL_ID_PLAYER_2: + result = 2; + break; + case TOOL_CTRL_ID_PLAYER_3: + result = 3; + break; + case TOOL_CTRL_ID_PLAYER_4: + result = 4; + break; + + default: + break; + } + + break; } - break; - } + case EVENT_KEYPRESS: + switch (GetEventKey((KeyEvent *)&event, TRUE)) + { + case KSYM_space: + if (req_state & REQ_CONFIRM) + result = 1; + break; - case EVENT_KEYPRESS: - switch (GetEventKey((KeyEvent *)&event, TRUE)) - { - case KSYM_space: - if (req_state & REQ_CONFIRM) - result = 1; - break; - - case KSYM_Return: + case KSYM_Return: #if defined(TARGET_SDL2) - case KSYM_Menu: + case KSYM_Menu: #endif - result = 1; - break; + result = 1; + break; - case KSYM_Escape: + case KSYM_Escape: #if defined(TARGET_SDL2) - case KSYM_Back: + case KSYM_Back: #endif - result = 0; - break; + result = 0; + break; - default: - break; - } + default: + break; + } - if (req_state & REQ_PLAYER) - result = 0; - break; + if (req_state & REQ_PLAYER) + result = 0; + break; - case EVENT_KEYRELEASE: - ClearPlayerAction(); - break; + case EVENT_KEYRELEASE: + ClearPlayerAction(); + break; - default: - HandleOtherEvents(&event); - break; + default: + HandleOtherEvents(&event); + break; + } } } else if (AnyJoystickButton() == JOY_BUTTON_NEW_PRESSED) @@ -3471,9 +3436,13 @@ static int RequestHandleEvents(unsigned int req_state) result = 0; } - if (game_status == GAME_MODE_PLAYING && local_player->LevelSolved_GameEnd) + if (level_solved) { - HandleGameActions(); + 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); + } } else { @@ -4151,6 +4120,8 @@ unsigned int MoveDoor(unsigned int door_state) } } + max_step_delay = MAX(1, max_step_delay); // prevent division by zero + num_move_steps = max_move_delay / max_step_delay; num_move_steps_doors_only = max_move_delay_doors_only / max_step_delay; @@ -4171,6 +4142,8 @@ unsigned int MoveDoor(unsigned int door_state) for (k = start; k < num_move_steps; k++) { + int last_frame = num_move_steps - 1; // last frame of this "for" loop + door_part_done_all = TRUE; for (i = 0; i < NUM_DOORS; i++) @@ -4329,7 +4302,7 @@ unsigned int MoveDoor(unsigned int door_state) if (game_status == GAME_MODE_MAIN) DoAnimation(); - WaitUntilDelayReached(&door_delay, door_delay_value); + SkipUntilDelayReached(&door_delay, door_delay_value, &k, last_frame); current_move_delay += max_step_delay; } @@ -7758,13 +7731,61 @@ void InitGraphicInfo_EM(void) #endif } +void CheckSaveEngineSnapshot_EM(byte action[MAX_PLAYERS], int frame, + boolean any_player_moving, + 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 (!SaveEngineSnapshotToList()) + return; + + player_was_waiting = TRUE; + } + } + else if (any_player_moving || any_player_snapping || any_player_dropping) + { + 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 (!SaveEngineSnapshotToList()) + return; + + player_was_waiting = TRUE; + } + } + else + { + player_was_waiting = FALSE; + } +} + void CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame, boolean any_player_moving, - boolean player_is_dropping) + boolean any_player_snapping, + boolean any_player_dropping) { if (tape.single_step && tape.recording && !tape.pausing) - if (frame == 0 && !player_is_dropping) + if (frame == 0 && !any_player_dropping) TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); + + CheckSaveEngineSnapshot_EM(action, frame, any_player_moving, + any_player_snapping, any_player_dropping); } void CheckSingleStepMode_SP(boolean murphy_is_waiting, @@ -7773,6 +7794,8 @@ void CheckSingleStepMode_SP(boolean murphy_is_waiting, if (tape.single_step && tape.recording && !tape.pausing) if (murphy_is_waiting) TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); + + CheckSaveEngineSnapshot_SP(murphy_is_waiting, murphy_is_dropping); } void getGraphicSource_SP(struct GraphicInfo_SP *g_sp, @@ -8044,7 +8067,7 @@ void ChangeViewportPropertiesIfNeeded() // printf("::: new_tilesize_var != TILESIZE_VAR\n"); // changing tile size invalidates scroll values of engine snapshots - FreeEngineSnapshot(); + FreeEngineSnapshotSingle(); // changing tile size requires update of graphic mapping for EM engine init_em_graphics = TRUE;