X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=6597768de6f08e6a9451eef6c81a62b46659ff92;hb=d0d2411a139b4ff6c5f9d2ba1df723ffbb0beeb8;hp=da879fa684a8fdc6db2179cc52523c596d86d5f3;hpb=f89a490028c36509216b97a96b779b779c2065c9;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index da879fa6..6597768d 100644 --- a/src/tools.c +++ b/src/tools.c @@ -286,7 +286,7 @@ void RedrawPlayfield() void DrawMaskedBorder_Rect(int x, int y, int width, int height) { - Bitmap *bitmap = graphic_info[IMG_GLOBAL_BORDER].bitmap; + Bitmap *bitmap = getGlobalBorderBitmapFromGameStatus(); BlitBitmapMasked(bitmap, backbuffer, x, y, width, height, x, y); } @@ -483,7 +483,12 @@ static void FadeCrossSaveBackbuffer() 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 void FadeExt(int fade_mask, int fade_mode, int fade_type) @@ -547,10 +552,10 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type) if (fade_mask == REDRAW_FIELD) { - x = REAL_SX; - y = REAL_SY; - width = FULL_SXSIZE; - height = FULL_SYSIZE; + x = FADE_SX; + y = FADE_SY; + width = FADE_SXSIZE; + height = FADE_SYSIZE; if (border.draw_masked_when_fading) draw_border_function = DrawMaskedBorder_FIELD; /* update when fading */ @@ -594,6 +599,11 @@ void FadeIn(int fade_mask) FadeExt(fade_mask, fading.fade_mode, FADE_TYPE_FADE_IN); else FadeExt(fade_mask, FADE_MODE_FADE_IN, FADE_TYPE_FADE_IN); + + FADE_SX = REAL_SX; + FADE_SY = REAL_SY; + FADE_SXSIZE = FULL_SXSIZE; + FADE_SYSIZE = FULL_SYSIZE; } void FadeOut(int fade_mask) @@ -677,6 +687,39 @@ void FadeSkipNextFadeOut() FadeExt(0, FADE_MODE_SKIP_FADE_OUT, FADE_TYPE_SKIP); } +Bitmap *getBitmapFromGraphicOrDefault(int graphic, int default_graphic) +{ + boolean redefined = getImageListEntryFromImageID(graphic)->redefined; + + return (graphic == IMG_UNDEFINED ? NULL : + graphic_info[graphic].bitmap != NULL || redefined ? + graphic_info[graphic].bitmap : + graphic_info[default_graphic].bitmap); +} + +Bitmap *getBackgroundBitmap(int graphic) +{ + return getBitmapFromGraphicOrDefault(graphic, IMG_BACKGROUND); +} + +Bitmap *getGlobalBorderBitmap(int graphic) +{ + return getBitmapFromGraphicOrDefault(graphic, IMG_GLOBAL_BORDER); +} + +Bitmap *getGlobalBorderBitmapFromGameStatus() +{ + 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 : + IMG_GLOBAL_BORDER); + + return getGlobalBorderBitmap(graphic); +} + void SetWindowBackgroundImageIfDefined(int graphic) { if (graphic_info[graphic].bitmap) @@ -697,26 +740,17 @@ void SetDoorBackgroundImageIfDefined(int graphic) void SetWindowBackgroundImage(int graphic) { - SetWindowBackgroundBitmap(graphic == IMG_UNDEFINED ? NULL : - graphic_info[graphic].bitmap ? - graphic_info[graphic].bitmap : - graphic_info[IMG_BACKGROUND].bitmap); + SetWindowBackgroundBitmap(getBackgroundBitmap(graphic)); } void SetMainBackgroundImage(int graphic) { - SetMainBackgroundBitmap(graphic == IMG_UNDEFINED ? NULL : - graphic_info[graphic].bitmap ? - graphic_info[graphic].bitmap : - graphic_info[IMG_BACKGROUND].bitmap); + SetMainBackgroundBitmap(getBackgroundBitmap(graphic)); } void SetDoorBackgroundImage(int graphic) { - SetDoorBackgroundBitmap(graphic == IMG_UNDEFINED ? NULL : - graphic_info[graphic].bitmap ? - graphic_info[graphic].bitmap : - graphic_info[IMG_BACKGROUND].bitmap); + SetDoorBackgroundBitmap(getBackgroundBitmap(graphic)); } void SetPanelBackground() @@ -774,27 +808,26 @@ static int dxsize_last = -1, dysize_last = -1; static int vx_last = -1, vy_last = -1; static int vxsize_last = -1, vysize_last = -1; -boolean CheckIfRedrawGlobalBorderIsNeeded() +boolean CheckIfGlobalBorderHasChanged() { - int global_border_graphic; - + // if game status has not changed, global border has not changed either if (game_status == game_status_last) return FALSE; - global_border_graphic = - (game_status == GAME_MODE_MAIN ? 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 : - IMG_GLOBAL_BORDER); + // determine and store new global border bitmap for current game status + global_border_bitmap = getGlobalBorderBitmapFromGameStatus(); + + return (global_border_bitmap_last != global_border_bitmap); +} - global_border_bitmap = - (graphic_info[global_border_graphic].bitmap ? - graphic_info[global_border_graphic].bitmap : - graphic_info[IMG_GLOBAL_BORDER].bitmap); +boolean CheckIfGlobalBorderRedrawIsNeeded() +{ + // if game status has not changed, nothing has to be redrawn + if (game_status == game_status_last) + return FALSE; // redraw if global screen border has changed - if (global_border_bitmap_last != global_border_bitmap) + if (CheckIfGlobalBorderHasChanged()) return TRUE; // redraw if position or size of playfield area has changed @@ -815,6 +848,23 @@ boolean CheckIfRedrawGlobalBorderIsNeeded() return FALSE; } +void RedrawGlobalBorderFromBitmap(Bitmap *bitmap) +{ + if (bitmap) + BlitBitmap(bitmap, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); + else + ClearRectangle(backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE); +} + +void RedrawGlobalBorder() +{ + Bitmap *bitmap = getGlobalBorderBitmapFromGameStatus(); + + RedrawGlobalBorderFromBitmap(bitmap); + + redraw_mask = REDRAW_ALL; +} + static void RedrawGlobalBorderIfNeeded() { if (game_status == game_status_last) @@ -823,15 +873,10 @@ static void RedrawGlobalBorderIfNeeded() // copy current draw buffer to later copy back areas that have not changed BlitBitmap(backbuffer, bitmap_db_store, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); - if (CheckIfRedrawGlobalBorderIsNeeded()) + if (CheckIfGlobalBorderRedrawIsNeeded()) { // redraw global screen border (or clear, if defined to be empty) - - if (global_border_bitmap) - BlitBitmap(global_border_bitmap, backbuffer, - 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0); - else - ClearRectangle(backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE); + RedrawGlobalBorderFromBitmap(global_border_bitmap); // copy previous playfield and door areas, if they are defined on both // previous and current screen and if they still have the same size @@ -958,7 +1003,7 @@ void SetRandomAnimationValue(int x, int y) gfx.anim_random_frame = GfxRandom[x][y]; } -inline int getGraphicAnimationFrame(int graphic, int sync_frame) +int getGraphicAnimationFrame(int graphic, int sync_frame) { /* animation synchronized with global frame counter, not move position */ if (graphic_info[graphic].anim_global_sync || sync_frame < 0) @@ -1043,8 +1088,8 @@ void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y) getSizedGraphicSource(graphic, 0, MINI_TILESIZE, bitmap, x, y); } -inline void getGraphicSourceExt(int graphic, int frame, Bitmap **bitmap, - int *x, int *y, boolean get_backside) +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); @@ -2219,6 +2264,7 @@ 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; @@ -2279,10 +2325,15 @@ void DrawEnvelopeRequest(char *text) x, y, x_steps, y_steps, tile_size, tile_size); + /* force DOOR font inside door area */ + game_status = GAME_MODE_PSEUDO_DOOR; + DrawTextBuffer(sx + border_size, sy + border_size, 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 */ + for (i = 0; i < NUM_TOOL_BUTTONS; i++) RedrawGadget(tool_gadget[i]); @@ -2388,7 +2439,6 @@ void AnimateEnvelopeRequest(int anim_mode, int action) void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) { - int last_game_status = game_status; /* save current game status */ int graphic = IMG_BACKGROUND_REQUEST; int sound_opening = SND_REQUEST_OPENING; int sound_closing = SND_REQUEST_CLOSING; @@ -2432,9 +2482,6 @@ void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) InitAnimation(); } - /* force DOOR font inside door area */ - game_status = GAME_MODE_PSEUDO_DOOR; - game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */ if (action == ACTION_OPENING) @@ -2459,8 +2506,6 @@ void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) game.envelope_active = FALSE; - game_status = last_game_status; /* restore current game status */ - if (action == ACTION_CLOSING) { if (game_status != GAME_MODE_MAIN) @@ -2814,8 +2859,9 @@ void DrawPreviewLevelAnimation() DrawPreviewLevelExt(FALSE); } -inline void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y, - int graphic, int sync_frame, int mask_mode) +inline static void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y, + int graphic, int sync_frame, + int mask_mode) { int frame = getGraphicAnimationFrame(graphic, sync_frame); @@ -2825,9 +2871,8 @@ inline void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y, DrawGraphicExt(dst_bitmap, x, y, graphic, frame); } -inline void DrawFixedGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y, - int graphic, int sync_frame, - int mask_mode) +void DrawFixedGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y, + int graphic, int sync_frame, int mask_mode) { int frame = getGraphicAnimationFrame(graphic, sync_frame); @@ -2837,7 +2882,7 @@ inline void DrawFixedGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y, DrawFixedGraphicExt(dst_bitmap, x, y, graphic, frame); } -inline void DrawGraphicAnimation(int x, int y, int graphic) +inline static void DrawGraphicAnimation(int x, int y, int graphic) { int lx = LEVELX(x), ly = LEVELY(y); @@ -2850,7 +2895,7 @@ inline void DrawGraphicAnimation(int x, int y, int graphic) MarkTileDirty(x, y); } -inline void DrawFixedGraphicAnimation(int x, int y, int graphic) +void DrawFixedGraphicAnimation(int x, int y, int graphic) { int lx = LEVELX(x), ly = LEVELY(y); @@ -2874,7 +2919,7 @@ void DrawLevelElementAnimation(int x, int y, int element) DrawGraphicAnimation(SCREENX(x), SCREENY(y), graphic); } -inline void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic) +void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic) { int sx = SCREENX(x), sy = SCREENY(y); @@ -3358,7 +3403,6 @@ 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; @@ -3523,11 +3567,7 @@ static int RequestHandleEvents(unsigned int req_state) Delay(10); } - game_status = GAME_MODE_PSEUDO_DOOR; - BackToFront(); - - game_status = last_game_status; /* restore current game status */ } return result; @@ -4305,6 +4345,9 @@ unsigned int MoveDoor(unsigned int door_state) width = g->width - src_xx; + if (width > door_rect->width) + width = door_rect->width; + // printf("::: k == %d [%d] \n", k, start_step); } @@ -4391,6 +4434,29 @@ unsigned int MoveDoor(unsigned int door_state) return (door1 | door2); } +static boolean useSpecialEditorDoor() +{ + int graphic = IMG_GLOBAL_BORDER_EDITOR; + boolean redefined = getImageListEntryFromImageID(graphic)->redefined; + + // do not draw special editor door if editor border defined or redefined + if (graphic_info[graphic].bitmap != NULL || redefined) + return FALSE; + + // do not draw special editor door if global border defined to be empty + if (graphic_info[IMG_GLOBAL_BORDER].bitmap == NULL) + return FALSE; + + // do not draw special editor door if viewport definitions do not match + if (EX != VX || + EY >= VY || + EXSIZE != VXSIZE || + EY + EYSIZE != VY + VYSIZE) + return FALSE; + + return TRUE; +} + void DrawSpecialEditorDoor() { struct GraphicInfo *gfx1 = &graphic_info[IMG_DOOR_2_TOP_BORDER_CORRECTION]; @@ -4402,6 +4468,9 @@ void DrawSpecialEditorDoor() int vy = VY - outer_border; int exsize = EXSIZE + 2 * outer_border; + if (!useSpecialEditorDoor()) + return; + /* draw bigger level editor toolbox window */ BlitBitmap(gfx1->bitmap, drawto, gfx1->src_x, gfx1->src_y, top_border_width, top_border_height, ex, ey - top_border_height); @@ -4423,6 +4492,9 @@ void UndrawSpecialEditorDoor() int exsize = EXSIZE + 2 * outer_border; int eysize = EYSIZE + 2 * outer_border; + if (!useSpecialEditorDoor()) + return; + /* draw normal tape recorder window */ if (graphic_info[IMG_GLOBAL_BORDER].bitmap) { @@ -8042,6 +8114,19 @@ void ToggleFullscreenOrChangeWindowScalingIfNeeded() } } +void JoinRectangles(int *x, int *y, int *width, int *height, + int x2, int y2, int width2, int height2) +{ + // do not join with "off-screen" rectangle + if (x2 == -1 || y2 == -1) + return; + + *x = MIN(*x, x2); + *y = MIN(*y, y2); + *width = MAX(*width, width2); + *height = MAX(*height, height2); +} + void ChangeViewportPropertiesIfNeeded() { int gfx_game_mode = game_status; @@ -8132,6 +8217,48 @@ void ChangeViewportPropertiesIfNeeded() new_tilesize_var != TILESIZE_VAR ) { + // ------------------------------------------------------------------------ + // determine next fading area for changed viewport definitions + // ------------------------------------------------------------------------ + + // start with current playfield area (default fading area) + FADE_SX = REAL_SX; + FADE_SY = REAL_SY; + FADE_SXSIZE = FULL_SXSIZE; + FADE_SYSIZE = FULL_SYSIZE; + + // add new playfield area if position or size has changed + if (new_real_sx != REAL_SX || new_real_sy != REAL_SY || + new_full_sxsize != FULL_SXSIZE || new_full_sysize != FULL_SYSIZE) + { + JoinRectangles(&FADE_SX, &FADE_SY, &FADE_SXSIZE, &FADE_SYSIZE, + new_real_sx, new_real_sy, new_full_sxsize,new_full_sysize); + } + + // add current and new door 1 area if position or size has changed + if (new_dx != DX || new_dy != DY || + new_dxsize != DXSIZE || new_dysize != DYSIZE) + { + JoinRectangles(&FADE_SX, &FADE_SY, &FADE_SXSIZE, &FADE_SYSIZE, + DX, DY, DXSIZE, DYSIZE); + JoinRectangles(&FADE_SX, &FADE_SY, &FADE_SXSIZE, &FADE_SYSIZE, + new_dx, new_dy, new_dxsize, new_dysize); + } + + // add current and new door 2 area if position or size has changed + if (new_dx != VX || new_dy != VY || + new_dxsize != VXSIZE || new_dysize != VYSIZE) + { + JoinRectangles(&FADE_SX, &FADE_SY, &FADE_SXSIZE, &FADE_SYSIZE, + VX, VY, VXSIZE, VYSIZE); + JoinRectangles(&FADE_SX, &FADE_SY, &FADE_SXSIZE, &FADE_SYSIZE, + new_vx, new_vy, new_vxsize, new_vysize); + } + + // ------------------------------------------------------------------------ + // handle changed tile size + // ------------------------------------------------------------------------ + if (new_tilesize_var != TILESIZE_VAR) { // printf("::: new_tilesize_var != TILESIZE_VAR\n");