X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Ftools.c;h=cff76238c3b2f2c6db6fd6e6460aa885010e6951;hp=e2352d185703d22585a66931c5e3a5ab07b199ac;hb=4e98e5e4aebea5b783f574bd8662b51bdc34ead6;hpb=78731da5bda94be8ad5633fc5ef615c35db318a7 diff --git a/src/tools.c b/src/tools.c index e2352d18..cff76238 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 @@ -287,50 +288,68 @@ void RedrawPlayfield() gfx.sx, gfx.sy); } -void DrawMaskedBorder_Rect(int x, int y, int width, int height) +static void DrawMaskedBorderExt_Rect(int x, int y, int width, int height, + int draw_target) { Bitmap *bitmap = getGlobalBorderBitmapFromGameStatus(); - BlitBitmapMasked(bitmap, backbuffer, x, y, width, height, x, y); + if (x == -1 && y == -1) + return; + + if (draw_target == DRAW_BORDER_TO_SCREEN) + BlitToScreenMasked(bitmap, x, y, width, height, x, y); + else + BlitBitmapMasked(bitmap, backbuffer, x, y, width, height, x, y); } -void DrawMaskedBorder_FIELD() +static void DrawMaskedBorderExt_FIELD(int draw_target) { if (global.border_status >= GAME_MODE_TITLE && global.border_status <= GAME_MODE_PLAYING && border.draw_masked[global.border_status]) - DrawMaskedBorder_Rect(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE); + DrawMaskedBorderExt_Rect(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, + draw_target); } -void DrawMaskedBorder_DOOR_1() +static void DrawMaskedBorderExt_DOOR_1(int draw_target) { + // 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])) - DrawMaskedBorder_Rect(DX, DY, DXSIZE, DYSIZE); + DrawMaskedBorderExt_Rect(DX, DY, DXSIZE, DYSIZE, draw_target); } -void DrawMaskedBorder_DOOR_2() +static void DrawMaskedBorderExt_DOOR_2(int draw_target) { + // 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) - DrawMaskedBorder_Rect(VX, VY, VXSIZE, VYSIZE); + DrawMaskedBorderExt_Rect(VX, VY, VXSIZE, VYSIZE, draw_target); } -void DrawMaskedBorder_DOOR_3() +static void DrawMaskedBorderExt_DOOR_3(int draw_target) { /* currently not available */ } -void DrawMaskedBorder_ALL() +static void DrawMaskedBorderExt_ALL(int draw_target) { - DrawMaskedBorder_FIELD(); - DrawMaskedBorder_DOOR_1(); - DrawMaskedBorder_DOOR_2(); - DrawMaskedBorder_DOOR_3(); + DrawMaskedBorderExt_FIELD(draw_target); + DrawMaskedBorderExt_DOOR_1(draw_target); + DrawMaskedBorderExt_DOOR_2(draw_target); + DrawMaskedBorderExt_DOOR_3(draw_target); } -void DrawMaskedBorder(int redraw_mask) +static void DrawMaskedBorderExt(int redraw_mask, int draw_target) { /* never draw masked screen borders on borderless screens */ if (game_status == GAME_MODE_LOADING || @@ -338,20 +357,35 @@ void DrawMaskedBorder(int redraw_mask) return; if (redraw_mask & REDRAW_ALL) - DrawMaskedBorder_ALL(); + DrawMaskedBorderExt_ALL(draw_target); else { if (redraw_mask & REDRAW_FIELD) - DrawMaskedBorder_FIELD(); + DrawMaskedBorderExt_FIELD(draw_target); if (redraw_mask & REDRAW_DOOR_1) - DrawMaskedBorder_DOOR_1(); + DrawMaskedBorderExt_DOOR_1(draw_target); if (redraw_mask & REDRAW_DOOR_2) - DrawMaskedBorder_DOOR_2(); + DrawMaskedBorderExt_DOOR_2(draw_target); if (redraw_mask & REDRAW_DOOR_3) - DrawMaskedBorder_DOOR_3(); + DrawMaskedBorderExt_DOOR_3(draw_target); } } +void DrawMaskedBorder_FIELD() +{ + DrawMaskedBorderExt_FIELD(DRAW_BORDER_TO_BACKBUFFER); +} + +void DrawMaskedBorder(int redraw_mask) +{ + DrawMaskedBorderExt(redraw_mask, DRAW_BORDER_TO_BACKBUFFER); +} + +void DrawMaskedBorderToScreen(int draw_target) +{ + DrawMaskedBorderExt(REDRAW_ALL, draw_target); +} + void BlitScreenToBitmap_RND(Bitmap *target_bitmap) { int fx = FX, fy = FY; @@ -434,13 +468,61 @@ 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 +#else // draw masked border to all viewports, if defined DrawMaskedBorder(redraw_mask); +#endif // draw frames per second (only if debug mode is enabled) if (redraw_mask & REDRAW_FPS) @@ -477,6 +559,10 @@ void BackToFront() } redraw_mask = REDRAW_NONE; + +#if DEBUG_FRAME_TIME + PrintFrameTimeDebugging(); +#endif } static void FadeCrossSaveBackbuffer() @@ -596,8 +682,37 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type) redraw_mask &= ~fade_mask; } +static void SetScreenStates_BeforeFadingIn() +{ +} + +static void SetScreenStates_AfterFadingIn() +{ + 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; +} + +static void SetScreenStates_AfterFadingOut() +{ + global.border_status = game_status; +} + void FadeIn(int fade_mask) { + SetScreenStates_BeforeFadingIn(); + +#if 1 + DrawMaskedBorder(REDRAW_ALL); +#endif + if (fading.fade_mode & FADE_TYPE_TRANSFORM) FadeExt(fade_mask, fading.fade_mode, FADE_TYPE_FADE_IN); else @@ -607,16 +722,24 @@ 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 + if (fading.fade_mode & FADE_TYPE_TRANSFORM) FadeExt(fade_mask, fading.fade_mode, FADE_TYPE_FADE_OUT); 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) @@ -2342,13 +2465,13 @@ void DrawEnvelopeRequest(char *text) tile_size, tile_size); /* force DOOR font inside door area */ - game_status = GAME_MODE_PSEUDO_DOOR; + SetGameStatus(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 */ + SetGameStatus(last_game_status); /* restore current game status */ for (i = 0; i < NUM_TOOL_BUTTONS; i++) RedrawGadget(tool_gadget[i]); @@ -2753,7 +2876,7 @@ 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 */ + SetGameStatus(last_game_status); /* restore current game status */ return; } @@ -2855,7 +2978,7 @@ static void DrawPreviewLevelExt(boolean restart) DrawPreviewLevelLabelExt(label_state); } - game_status = last_game_status; /* restore current game status */ + SetGameStatus(last_game_status); /* restore current game status */ } void DrawPreviewLevelInitial() @@ -3640,7 +3763,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; + SetGameStatus(GAME_MODE_PSEUDO_DOOR); /* write text for request */ for (text_ptr = text, ty = 0; ty < MAX_REQUEST_LINES; ty++) @@ -3680,7 +3803,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 */ + SetGameStatus(last_game_status); /* restore current game status */ if (req_state & REQ_ASK) { @@ -4124,7 +4247,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; @@ -4438,6 +4561,10 @@ unsigned int MoveDoor(unsigned int door_state) if (door_state & DOOR_ACTION_2) door2 = door_state & DOOR_ACTION_2; + // draw masked border over door area + DrawMaskedBorder(REDRAW_DOOR_1); + DrawMaskedBorder(REDRAW_DOOR_2); + return (door1 | door2); } @@ -8134,6 +8261,13 @@ void JoinRectangles(int *x, int *y, int *width, int *height, *height = MAX(*height, height2); } +void SetGameStatus(int game_status_new) +{ + game_status = game_status_new; + + global.anim_status_next = game_status; +} + void ChangeViewportPropertiesIfNeeded() { int gfx_game_mode = game_status; @@ -8189,6 +8323,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"); } @@ -8330,6 +8465,7 @@ void ChangeViewportPropertiesIfNeeded() // printf("::: init_video_buffer\n"); InitVideoBuffer(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, setup.fullscreen); + InitImageTextures(); } if (init_gadgets_and_toons) @@ -8338,6 +8474,7 @@ void ChangeViewportPropertiesIfNeeded() InitGadgets(); InitToons(); + InitGlobalAnimations(); } if (init_em_graphics)