X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=be29c2000989a595b14eef85601b43d28dc07e82;hb=38b4bf3fec7d93aa252f57270246b3e4ff41cf8d;hp=a7867f87965b5b953e405fa9d0dab83e6cf641f6;hpb=cc1d6b89872ea3d6ae3e53023653ab86dd76c2ea;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index a7867f87..be29c200 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 @@ -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; @@ -8085,7 +8170,6 @@ void ChangeViewportPropertiesIfNeeded() boolean init_video_buffer = FALSE; boolean init_gadgets_and_toons = FALSE; boolean init_em_graphics = FALSE; - boolean drawing_area_changed = FALSE; if (viewport.window.width != WIN_XSIZE || viewport.window.height != WIN_YSIZE) @@ -8133,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"); @@ -8144,19 +8270,6 @@ void ChangeViewportPropertiesIfNeeded() init_em_graphics = TRUE; } - if (new_sx != SX || - new_sy != SY || - new_sxsize != SXSIZE || - new_sysize != SYSIZE || - new_real_sx != REAL_SX || - new_real_sy != REAL_SY || - new_full_sxsize != FULL_SXSIZE || - new_full_sysize != FULL_SYSIZE) - { - if (!init_video_buffer) - drawing_area_changed = TRUE; - } - SX = new_sx; SY = new_sy; DX = new_dx; @@ -8198,8 +8311,6 @@ void ChangeViewportPropertiesIfNeeded() SCR_FIELDX = new_scr_fieldx; SCR_FIELDY = new_scr_fieldy; - gfx.drawing_area_changed = drawing_area_changed; - SetDrawDeactivationMask(REDRAW_NONE); SetDrawBackgroundMask(REDRAW_FIELD); }