X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Ftools.c;h=8610e5103476b976aa2731326f38226e22fb99a8;hp=6a1306e45e903f9238a6526b4a6a86f68bcc1ce2;hb=3466bff66861926f480a96e5b8923a4e044d50a4;hpb=bfe3ef29da6539dffdd8674a67c3144f6a3cdddc diff --git a/src/tools.c b/src/tools.c index 6a1306e4..8610e510 100644 --- a/src/tools.c +++ b/src/tools.c @@ -24,7 +24,8 @@ /* select level set with EMC X11 graphics before activating EM GFX debugging */ -#define DEBUG_EM_GFX 0 +#define DEBUG_EM_GFX FALSE +#define DEBUG_FRAME_TIME FALSE /* tool button identifiers */ #define TOOL_CTRL_ID_YES 0 @@ -288,96 +289,126 @@ void RedrawPlayfield() } static void DrawMaskedBorderExt_Rect(int x, int y, int width, int height, - boolean blit_to_screen) + int draw_target) { - Bitmap *bitmap = getGlobalBorderBitmapFromGameStatus(); + Bitmap *src_bitmap = getGlobalBorderBitmapFromStatus(global.border_status); + Bitmap *dst_bitmap = gfx.masked_border_bitmap_ptr; - if (blit_to_screen) - BlitToScreenMasked(bitmap, x, y, width, height, x, y); + if (x == -1 && y == -1) + return; + + if (draw_target == DRAW_BORDER_TO_SCREEN) + BlitToScreenMasked(src_bitmap, x, y, width, height, x, y); else - BlitBitmapMasked(bitmap, backbuffer, x, y, width, height, x, y); + BlitBitmapMasked(src_bitmap, dst_bitmap, x, y, width, height, x, y); } -static void DrawMaskedBorderExt_FIELD(boolean blit_to_screen) +static void DrawMaskedBorderExt_FIELD(int draw_target) { - if (global.border_status >= GAME_MODE_TITLE && + if (global.border_status >= GAME_MODE_MAIN && global.border_status <= GAME_MODE_PLAYING && border.draw_masked[global.border_status]) DrawMaskedBorderExt_Rect(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, - blit_to_screen); + draw_target); } -static void DrawMaskedBorderExt_DOOR_1(boolean blit_to_screen) +static void DrawMaskedBorderExt_DOOR_1(int draw_target) { - // only draw border over closed doors when drawing to backbuffer - if (!blit_to_screen && (GetDoorState() & DOOR_OPEN_1)) + // when drawing to backbuffer, never draw border over open doors + if (draw_target == DRAW_BORDER_TO_BACKBUFFER && + (GetDoorState() & DOOR_OPEN_1)) return; if (border.draw_masked[GFX_SPECIAL_ARG_DOOR] && (global.border_status != GAME_MODE_EDITOR || border.draw_masked[GFX_SPECIAL_ARG_EDITOR])) - DrawMaskedBorderExt_Rect(DX, DY, DXSIZE, DYSIZE, blit_to_screen); + DrawMaskedBorderExt_Rect(DX, DY, DXSIZE, DYSIZE, draw_target); } -static void DrawMaskedBorderExt_DOOR_2(boolean blit_to_screen) +static void DrawMaskedBorderExt_DOOR_2(int draw_target) { - // only draw border over closed doors when drawing to backbuffer - if (!blit_to_screen && (GetDoorState() & DOOR_OPEN_2)) + // when drawing to backbuffer, never draw border over open doors + if (draw_target == DRAW_BORDER_TO_BACKBUFFER && + (GetDoorState() & DOOR_OPEN_2)) return; if (border.draw_masked[GFX_SPECIAL_ARG_DOOR] && global.border_status != GAME_MODE_EDITOR) - DrawMaskedBorderExt_Rect(VX, VY, VXSIZE, VYSIZE, blit_to_screen); + DrawMaskedBorderExt_Rect(VX, VY, VXSIZE, VYSIZE, draw_target); } -static void DrawMaskedBorderExt_DOOR_3(boolean blit_to_screen) +static void DrawMaskedBorderExt_DOOR_3(int draw_target) { /* currently not available */ } -static void DrawMaskedBorderExt_ALL(boolean blit_to_screen) +static void DrawMaskedBorderExt_ALL(int draw_target) { - DrawMaskedBorderExt_FIELD(blit_to_screen); - DrawMaskedBorderExt_DOOR_1(blit_to_screen); - DrawMaskedBorderExt_DOOR_2(blit_to_screen); - DrawMaskedBorderExt_DOOR_3(blit_to_screen); + DrawMaskedBorderExt_FIELD(draw_target); + DrawMaskedBorderExt_DOOR_1(draw_target); + DrawMaskedBorderExt_DOOR_2(draw_target); + DrawMaskedBorderExt_DOOR_3(draw_target); } -static void DrawMaskedBorderExt(int redraw_mask, boolean blit_to_screen) +static void DrawMaskedBorderExt(int redraw_mask, int draw_target) { /* never draw masked screen borders on borderless screens */ - if (game_status == GAME_MODE_LOADING || - game_status == GAME_MODE_TITLE) + if (global.border_status == GAME_MODE_LOADING || + global.border_status == GAME_MODE_TITLE) return; if (redraw_mask & REDRAW_ALL) - DrawMaskedBorderExt_ALL(blit_to_screen); + DrawMaskedBorderExt_ALL(draw_target); else { if (redraw_mask & REDRAW_FIELD) - DrawMaskedBorderExt_FIELD(blit_to_screen); + DrawMaskedBorderExt_FIELD(draw_target); if (redraw_mask & REDRAW_DOOR_1) - DrawMaskedBorderExt_DOOR_1(blit_to_screen); + DrawMaskedBorderExt_DOOR_1(draw_target); if (redraw_mask & REDRAW_DOOR_2) - DrawMaskedBorderExt_DOOR_2(blit_to_screen); + DrawMaskedBorderExt_DOOR_2(draw_target); if (redraw_mask & REDRAW_DOOR_3) - DrawMaskedBorderExt_DOOR_3(blit_to_screen); + DrawMaskedBorderExt_DOOR_3(draw_target); } } void DrawMaskedBorder_FIELD() { - DrawMaskedBorderExt_FIELD(FALSE); + DrawMaskedBorderExt_FIELD(DRAW_BORDER_TO_BACKBUFFER); } void DrawMaskedBorder(int redraw_mask) { - DrawMaskedBorderExt(redraw_mask, FALSE); + DrawMaskedBorderExt(redraw_mask, DRAW_BORDER_TO_BACKBUFFER); } -void DrawMaskedBorderToScreen(int redraw_mask) +void DrawMaskedBorderToTarget(int draw_target) { - DrawMaskedBorderExt(redraw_mask, TRUE); + if (draw_target == DRAW_BORDER_TO_BACKBUFFER || + draw_target == DRAW_BORDER_TO_SCREEN) + { + DrawMaskedBorderExt(REDRAW_ALL, draw_target); + } + else + { + int last_border_status = global.border_status; + + if (draw_target == DRAW_BORDER_TO_FADE_SOURCE) + { + global.border_status = gfx.fade_border_source_status; + gfx.masked_border_bitmap_ptr = gfx.fade_bitmap_source; + } + else if (draw_target == DRAW_BORDER_TO_FADE_TARGET) + { + global.border_status = gfx.fade_border_target_status; + gfx.masked_border_bitmap_ptr = gfx.fade_bitmap_target; + } + + DrawMaskedBorderExt(REDRAW_ALL, draw_target); + + global.border_status = last_border_status; + gfx.masked_border_bitmap_ptr = backbuffer; + } } void BlitScreenToBitmap_RND(Bitmap *target_bitmap) @@ -462,10 +493,54 @@ void DrawFramesPerSecond() font_nr, BLIT_OPAQUE); } +#if DEBUG_FRAME_TIME +static void PrintFrameTimeDebugging() +{ + static unsigned int last_counter = 0; + unsigned int counter = Counter(); + int diff_1 = counter - last_counter; + int diff_2 = diff_1 - GAME_FRAME_DELAY; + int diff_2_max = 20; + int diff_2_cut = MIN(ABS(diff_2), diff_2_max); + char diff_bar[2 * diff_2_max + 5]; + int pos = 0; + int i; + + diff_bar[pos++] = (diff_2 < -diff_2_max ? '<' : ' '); + + for (i = 0; i < diff_2_max; i++) + diff_bar[pos++] = (diff_2 >= 0 ? ' ' : + i >= diff_2_max - diff_2_cut ? '-' : ' '); + + diff_bar[pos++] = '|'; + + for (i = 0; i < diff_2_max; i++) + diff_bar[pos++] = (diff_2 <= 0 ? ' ' : i < diff_2_cut ? '+' : ' '); + + diff_bar[pos++] = (diff_2 > diff_2_max ? '>' : ' '); + + diff_bar[pos++] = '\0'; + + Error(ERR_INFO, "%06d [%02d] [%c%02d] %s", + counter, + diff_1, + (diff_2 < 0 ? '-' : diff_2 > 0 ? '+' : ' '), ABS(diff_2), + diff_bar); + + last_counter = counter; +} +#endif + void BackToFront() { + static int last_redraw_mask = REDRAW_NONE; + + // force screen redraw in every frame to continue drawing global animations + // (but always use the last redraw mask to prevent unwanted side effects) if (redraw_mask == REDRAW_NONE) - return; + redraw_mask = last_redraw_mask; + + last_redraw_mask = redraw_mask; #if 1 // masked border now drawn immediately when blitting backbuffer to window @@ -509,6 +584,10 @@ void BackToFront() } redraw_mask = REDRAW_NONE; + +#if DEBUG_FRAME_TIME + PrintFrameTimeDebugging(); +#endif } static void FadeCrossSaveBackbuffer() @@ -628,8 +707,39 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type) redraw_mask &= ~fade_mask; } +static void SetScreenStates_BeforeFadingIn() +{ +} + +static void SetScreenStates_AfterFadingIn() +{ + // store new source screen (to use correct masked border for 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() +{ + // store new target screen (to use correct masked border for fading) + gfx.fade_border_target_status = game_status; + + global.anim_status = GAME_MODE_PSEUDO_FADING; +} + +static void SetScreenStates_AfterFadingOut() +{ + global.border_status = game_status; +} + void FadeIn(int fade_mask) { + SetScreenStates_BeforeFadingIn(); + #if 1 DrawMaskedBorder(REDRAW_ALL); #endif @@ -643,10 +753,14 @@ void FadeIn(int fade_mask) FADE_SY = REAL_SY; FADE_SXSIZE = FULL_SXSIZE; FADE_SYSIZE = FULL_SYSIZE; + + SetScreenStates_AfterFadingIn(); } void FadeOut(int fade_mask) { + SetScreenStates_BeforeFadingOut(); + #if 0 DrawMaskedBorder(REDRAW_ALL); #endif @@ -656,7 +770,7 @@ void FadeOut(int fade_mask) else FadeExt(fade_mask, FADE_MODE_FADE_OUT, FADE_TYPE_FADE_OUT); - global.border_status = game_status; + SetScreenStates_AfterFadingOut(); } static void FadeSetLeaveNext(struct TitleFadingInfo fading_leave, boolean set) @@ -750,14 +864,14 @@ Bitmap *getGlobalBorderBitmap(int graphic) return getBitmapFromGraphicOrDefault(graphic, IMG_GLOBAL_BORDER); } -Bitmap *getGlobalBorderBitmapFromGameStatus() +Bitmap *getGlobalBorderBitmapFromStatus(int status) { int graphic = - (game_status == GAME_MODE_MAIN || - game_status == GAME_MODE_PSEUDO_TYPENAME ? IMG_GLOBAL_BORDER_MAIN : - game_status == GAME_MODE_SCORES ? IMG_GLOBAL_BORDER_SCORES : - game_status == GAME_MODE_EDITOR ? IMG_GLOBAL_BORDER_EDITOR : - game_status == GAME_MODE_PLAYING ? IMG_GLOBAL_BORDER_PLAYING : + (status == GAME_MODE_MAIN || + status == GAME_MODE_PSEUDO_TYPENAME ? IMG_GLOBAL_BORDER_MAIN : + status == GAME_MODE_SCORES ? IMG_GLOBAL_BORDER_SCORES : + status == GAME_MODE_EDITOR ? IMG_GLOBAL_BORDER_EDITOR : + status == GAME_MODE_PLAYING ? IMG_GLOBAL_BORDER_PLAYING : IMG_GLOBAL_BORDER); return getGlobalBorderBitmap(graphic); @@ -858,7 +972,7 @@ boolean CheckIfGlobalBorderHasChanged() return FALSE; // determine and store new global border bitmap for current game status - global_border_bitmap = getGlobalBorderBitmapFromGameStatus(); + global_border_bitmap = getGlobalBorderBitmapFromStatus(game_status); return (global_border_bitmap_last != global_border_bitmap); } @@ -905,7 +1019,7 @@ void RedrawGlobalBorderFromBitmap(Bitmap *bitmap) void RedrawGlobalBorder() { - Bitmap *bitmap = getGlobalBorderBitmapFromGameStatus(); + Bitmap *bitmap = getGlobalBorderBitmapFromStatus(game_status); RedrawGlobalBorderFromBitmap(bitmap); @@ -2314,7 +2428,6 @@ static void setRequestPosition(int *x, int *y, boolean add_border_size) void DrawEnvelopeRequest(char *text) { - int last_game_status = game_status; /* save current game status */ char *text_final = text; char *text_door_style = NULL; int graphic = IMG_BACKGROUND_REQUEST; @@ -2382,13 +2495,13 @@ void DrawEnvelopeRequest(char *text) tile_size, tile_size); /* force DOOR font inside door area */ - game_status = GAME_MODE_PSEUDO_DOOR; + SetFontStatus(GAME_MODE_PSEUDO_DOOR); DrawTextBuffer(sx + sx_offset, sy + sy_offset, text_final, font_nr, line_length, -1, max_lines, line_spacing, mask_mode, request.autowrap, request.centered, FALSE); - game_status = last_game_status; /* restore current game status */ + ResetFontStatus(); for (i = 0; i < NUM_TOOL_BUTTONS; i++) RedrawGadget(tool_gadget[i]); @@ -2747,7 +2860,6 @@ static void DrawPreviewLevelExt(boolean restart) boolean show_level_border = (BorderElement != EL_EMPTY); int level_xsize = lev_fieldx + (show_level_border ? 2 : 0); int level_ysize = lev_fieldy + (show_level_border ? 2 : 0); - int last_game_status = game_status; /* save current game status */ if (restart) { @@ -2793,8 +2905,6 @@ static void DrawPreviewLevelExt(boolean restart) DrawTextSAligned(pos->x, pos->y, label_text, font_nr, pos->align); } - game_status = last_game_status; /* restore current game status */ - return; } @@ -2894,8 +3004,6 @@ static void DrawPreviewLevelExt(boolean restart) DrawPreviewLevelLabelExt(label_state); } - - game_status = last_game_status; /* restore current game status */ } void DrawPreviewLevelInitial() @@ -3623,7 +3731,6 @@ static int RequestHandleEvents(unsigned int req_state) static boolean RequestDoor(char *text, unsigned int req_state) { unsigned int old_door_state; - int last_game_status = game_status; /* save current game status */ int max_request_line_len = MAX_REQUEST_LINE_FONT1_LEN; int font_nr = FONT_TEXT_2; char *text_ptr; @@ -3680,7 +3787,7 @@ static boolean RequestDoor(char *text, unsigned int req_state) DrawBackground(DX, DY, DXSIZE, DYSIZE); /* force DOOR font inside door area */ - game_status = GAME_MODE_PSEUDO_DOOR; + SetFontStatus(GAME_MODE_PSEUDO_DOOR); /* write text for request */ for (text_ptr = text, ty = 0; ty < MAX_REQUEST_LINES; ty++) @@ -3720,7 +3827,7 @@ static boolean RequestDoor(char *text, unsigned int req_state) // text_ptr += tl + (tc == ' ' || tc == '?' || tc == '!' ? 1 : 0); } - game_status = last_game_status; /* restore current game status */ + ResetFontStatus(); if (req_state & REQ_ASK) { @@ -4164,7 +4271,7 @@ unsigned int MoveDoor(unsigned int door_state) { DX, DY, DXSIZE, DYSIZE }, { VX, VY, VXSIZE, VYSIZE } }; - static int door1 = DOOR_OPEN_1; + static int door1 = DOOR_CLOSE_1; static int door2 = DOOR_CLOSE_2; unsigned int door_delay = 0; unsigned int door_delay_value; @@ -8097,9 +8204,6 @@ void ToggleFullscreenOrChangeWindowScalingIfNeeded() { boolean change_fullscreen = (setup.fullscreen != video.fullscreen_enabled); - boolean change_fullscreen_mode = (video.fullscreen_enabled && - !strEqual(setup.fullscreen_mode, - video.fullscreen_mode_current)); boolean change_window_scaling_percent = (!video.fullscreen_enabled && setup.window_scaling_percent != video.window_scaling_percent); @@ -8129,7 +8233,6 @@ void ToggleFullscreenOrChangeWindowScalingIfNeeded() #endif if (change_fullscreen || - change_fullscreen_mode || change_window_scaling_percent) { Bitmap *tmp_backbuffer = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH); @@ -8137,12 +8240,6 @@ void ToggleFullscreenOrChangeWindowScalingIfNeeded() /* save backbuffer content which gets lost when toggling fullscreen mode */ BlitBitmap(backbuffer, tmp_backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); - if (change_fullscreen_mode) - { - /* keep fullscreen, but change fullscreen mode (screen resolution) */ - video.fullscreen_enabled = FALSE; /* force new fullscreen mode */ - } - if (change_window_scaling_percent) { /* keep window mode, but change window scaling */ @@ -8178,6 +8275,50 @@ void JoinRectangles(int *x, int *y, int *width, int *height, *height = MAX(*height, height2); } +void SetAnimStatus(int anim_status_new) +{ + if (anim_status_new == GAME_MODE_MAIN) + anim_status_new = GAME_MODE_PSEUDO_MAINONLY; + + global.anim_status_next = anim_status_new; + + // directly set screen modes that are entered without fading + if ((global.anim_status == GAME_MODE_PSEUDO_MAINONLY && + global.anim_status_next == GAME_MODE_PSEUDO_TYPENAME) || + (global.anim_status == GAME_MODE_PSEUDO_TYPENAME && + global.anim_status_next == GAME_MODE_PSEUDO_MAINONLY)) + global.anim_status = global.anim_status_next; +} + +void SetGameStatus(int game_status_new) +{ + game_status = game_status_new; + + SetAnimStatus(game_status_new); +} + +void SetFontStatus(int game_status_new) +{ + static int last_game_status = -1; + + if (game_status_new != -1) + { + // set game status for font use after storing last game status + last_game_status = game_status; + game_status = game_status_new; + } + else + { + // reset game status after font use from last stored game status + game_status = last_game_status; + } +} + +void ResetFontStatus() +{ + SetFontStatus(-1); +} + void ChangeViewportPropertiesIfNeeded() { int gfx_game_mode = game_status; @@ -8233,6 +8374,7 @@ void ChangeViewportPropertiesIfNeeded() init_video_buffer = TRUE; init_gfx_buffers = TRUE; + init_gadgets_and_toons = TRUE; // printf("::: video: init_video_buffer, init_gfx_buffers\n"); } @@ -8383,6 +8525,7 @@ void ChangeViewportPropertiesIfNeeded() InitGadgets(); InitToons(); + InitGlobalAnimations(); } if (init_em_graphics)