fixed and enhanced screen fading and global border handling
authorHolger Schemel <info@artsoft.org>
Tue, 9 Jun 2015 20:37:20 +0000 (22:37 +0200)
committerHolger Schemel <info@artsoft.org>
Tue, 9 Jun 2015 20:37:20 +0000 (22:37 +0200)
src/conf_gfx.c
src/editor.c
src/game.c
src/init.c
src/screens.c
src/tools.c
src/tools.h

index 3bf86692669a6b71d04c64cf7efd096d73e6a729..28d85cf1bb4d6d8f0c2a30263b7e7b9028ac81f1 100644 (file)
@@ -5664,6 +5664,11 @@ struct ConfigInfo image_config[] =
   { "editor.input.gfx.level_number.border_size","1"                    },
 
   { "global.border",                           "RocksScreen.png"       },
+  { "global.border.MAIN",                      UNDEFINED_FILENAME      },
+  { "global.border.SCORES",                    UNDEFINED_FILENAME      },
+  { "global.border.EDITOR",                    UNDEFINED_FILENAME      },
+  { "global.border.PLAYING",                   UNDEFINED_FILENAME      },
+
   { "global.door",                             "RocksDoor.png"         },
 
   { "global.busy",                             "RocksBusy.png"         },
@@ -7709,16 +7714,21 @@ struct ConfigInfo image_config[] =
   { "viewport.playfield.MAIN.width",           ARG_DEFAULT             },
   { "viewport.playfield.MAIN.height",          ARG_DEFAULT             },
   { "viewport.playfield.MAIN.border_size",     ARG_DEFAULT             },
-  { "viewport.playfield.PLAYING.x",            ARG_DEFAULT             },
-  { "viewport.playfield.PLAYING.y",            ARG_DEFAULT             },
-  { "viewport.playfield.PLAYING.width",                ARG_DEFAULT             },
-  { "viewport.playfield.PLAYING.height",       ARG_DEFAULT             },
-  { "viewport.playfield.PLAYING.border_size",  ARG_DEFAULT             },
+  { "viewport.playfield.SCORES.x",             ARG_DEFAULT             },
+  { "viewport.playfield.SCORES.y",             ARG_DEFAULT             },
+  { "viewport.playfield.SCORES.width",         ARG_DEFAULT             },
+  { "viewport.playfield.SCORES.height",                ARG_DEFAULT             },
+  { "viewport.playfield.SCORES.border_size",   ARG_DEFAULT             },
   { "viewport.playfield.EDITOR.x",             ARG_DEFAULT             },
   { "viewport.playfield.EDITOR.y",             ARG_DEFAULT             },
   { "viewport.playfield.EDITOR.width",         ARG_DEFAULT             },
   { "viewport.playfield.EDITOR.height",                ARG_DEFAULT             },
   { "viewport.playfield.EDITOR.border_size",   ARG_DEFAULT             },
+  { "viewport.playfield.PLAYING.x",            ARG_DEFAULT             },
+  { "viewport.playfield.PLAYING.y",            ARG_DEFAULT             },
+  { "viewport.playfield.PLAYING.width",                ARG_DEFAULT             },
+  { "viewport.playfield.PLAYING.height",       ARG_DEFAULT             },
+  { "viewport.playfield.PLAYING.border_size",  ARG_DEFAULT             },
   { "viewport.door_1.x",                       "566"                   },
   { "viewport.door_1.y",                       "60"                    },
   { "viewport.door_1.width",                   "100"                   },
@@ -7729,16 +7739,21 @@ struct ConfigInfo image_config[] =
   { "viewport.door_1.MAIN.width",              ARG_DEFAULT             },
   { "viewport.door_1.MAIN.height",             ARG_DEFAULT             },
   { "viewport.door_1.MAIN.border_size",                ARG_DEFAULT             },
-  { "viewport.door_1.PLAYING.x",               ARG_DEFAULT             },
-  { "viewport.door_1.PLAYING.y",               ARG_DEFAULT             },
-  { "viewport.door_1.PLAYING.width",           ARG_DEFAULT             },
-  { "viewport.door_1.PLAYING.height",          ARG_DEFAULT             },
-  { "viewport.door_1.PLAYING.border_size",     ARG_DEFAULT             },
+  { "viewport.door_1.SCORES.x",                        ARG_DEFAULT             },
+  { "viewport.door_1.SCORES.y",                        ARG_DEFAULT             },
+  { "viewport.door_1.SCORES.width",            ARG_DEFAULT             },
+  { "viewport.door_1.SCORES.height",           ARG_DEFAULT             },
+  { "viewport.door_1.SCORES.border_size",      ARG_DEFAULT             },
   { "viewport.door_1.EDITOR.x",                        ARG_DEFAULT             },
   { "viewport.door_1.EDITOR.y",                        ARG_DEFAULT             },
   { "viewport.door_1.EDITOR.width",            ARG_DEFAULT             },
   { "viewport.door_1.EDITOR.height",           ARG_DEFAULT             },
   { "viewport.door_1.EDITOR.border_size",      ARG_DEFAULT             },
+  { "viewport.door_1.PLAYING.x",               ARG_DEFAULT             },
+  { "viewport.door_1.PLAYING.y",               ARG_DEFAULT             },
+  { "viewport.door_1.PLAYING.width",           ARG_DEFAULT             },
+  { "viewport.door_1.PLAYING.height",          ARG_DEFAULT             },
+  { "viewport.door_1.PLAYING.border_size",     ARG_DEFAULT             },
   { "viewport.door_2.x",                       "566"                   },
   { "viewport.door_2.y",                       "400"                   },
   { "viewport.door_2.width",                   "100"                   },
@@ -7749,16 +7764,21 @@ struct ConfigInfo image_config[] =
   { "viewport.door_2.MAIN.width",              ARG_DEFAULT             },
   { "viewport.door_2.MAIN.height",             ARG_DEFAULT             },
   { "viewport.door_2.MAIN.border_size",                ARG_DEFAULT             },
-  { "viewport.door_2.PLAYING.x",               ARG_DEFAULT             },
-  { "viewport.door_2.PLAYING.y",               ARG_DEFAULT             },
-  { "viewport.door_2.PLAYING.width",           ARG_DEFAULT             },
-  { "viewport.door_2.PLAYING.height",          ARG_DEFAULT             },
-  { "viewport.door_2.PLAYING.border_size",     ARG_DEFAULT             },
+  { "viewport.door_2.SCORES.x",                        ARG_DEFAULT             },
+  { "viewport.door_2.SCORES.y",                        ARG_DEFAULT             },
+  { "viewport.door_2.SCORES.width",            ARG_DEFAULT             },
+  { "viewport.door_2.SCORES.height",           ARG_DEFAULT             },
+  { "viewport.door_2.SCORES.border_size",      ARG_DEFAULT             },
   { "viewport.door_2.EDITOR.x",                        "566"                   },
   { "viewport.door_2.EDITOR.y",                        "356"                   },
   { "viewport.door_2.EDITOR.width",            "100"                   },
   { "viewport.door_2.EDITOR.height",           "144"                   },
   { "viewport.door_2.EDITOR.border_size",      "4"                     },
+  { "viewport.door_2.PLAYING.x",               ARG_DEFAULT             },
+  { "viewport.door_2.PLAYING.y",               ARG_DEFAULT             },
+  { "viewport.door_2.PLAYING.width",           ARG_DEFAULT             },
+  { "viewport.door_2.PLAYING.height",          ARG_DEFAULT             },
+  { "viewport.door_2.PLAYING.border_size",     ARG_DEFAULT             },
 
   { NULL,                                      NULL                    }
 };
index 3512218ee6bbb0fd3c4d1372c5b3d5fa53810bab..6414dbd4b5619682cb9771fe62c231819d7d9597 100644 (file)
@@ -7616,17 +7616,39 @@ static boolean playfield_area_changed = FALSE;
 
 void DrawLevelEd()
 {
+  int fade_mask = REDRAW_FIELD;
+
   StopAnimation();
 
   CloseDoor(DOOR_CLOSE_ALL);
 
-  FadeOut(REDRAW_FIELD);
+#if 1
+  /* needed if different viewport properties defined for editor */
+  ChangeViewportPropertiesIfNeeded();
+#endif
+
+  if (CheckIfRedrawGlobalBorderIsNeeded())
+    fade_mask = REDRAW_ALL;
+
+#if 0
+  printf("::: %d\n", (fade_mask == REDRAW_ALL ? 1 : 0));
+#endif
+
+  FadeOut(fade_mask);
 
+#if 0
   /* needed after playing if editor playfield area has different size */
   ClearRectangle(drawto, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
+#endif
 
+#if 0
   /* needed if different viewport properties defined for editor */
   ChangeViewportPropertiesIfNeeded();
+#endif
+
+#if 1
+  ClearField();
+#endif
 
   InitZoomLevelSettings();
 
@@ -7690,7 +7712,12 @@ void DrawLevelEd()
 
   DrawEditModeWindow();
 
-  FadeIn(playfield_area_changed ? REDRAW_ALL : REDRAW_FIELD);
+  fade_mask = (playfield_area_changed ? REDRAW_ALL : REDRAW_FIELD);
+
+  if (CheckIfRedrawGlobalBorderIsNeeded())
+    fade_mask = REDRAW_ALL;
+
+  FadeIn(fade_mask);
 
   /* copy actual editor door content to door double buffer for OpenDoor() */
   BlitBitmap(drawto, bitmap_db_door_1, DX, DY, DXSIZE, DYSIZE, 0, 0);
index 1f9289e8f7c8241df44992ecceb5fafee49f984f..1f0270d9051fbd850bbae2b27fd1deb94b8b82d8 100644 (file)
@@ -3083,6 +3083,7 @@ void InitGame()
 {
   int full_lev_fieldx = lev_fieldx + (BorderElement != EL_EMPTY ? 2 : 0);
   int full_lev_fieldy = lev_fieldy + (BorderElement != EL_EMPTY ? 2 : 0);
+  int fade_mask = REDRAW_FIELD;
 
   boolean emulate_bd = TRUE;   /* unless non-BOULDERDASH elements found */
   boolean emulate_sb = TRUE;   /* unless non-SOKOBAN     elements found */
@@ -3097,15 +3098,33 @@ void InitGame()
   if (!game.restart_level)
     CloseDoor(DOOR_CLOSE_1);
 
+#if 1
+  /* needed if different viewport properties defined for playing */
+  ChangeViewportPropertiesIfNeeded();
+#endif
+
   if (level_editor_test_game)
     FadeSkipNextFadeIn();
   else
     FadeSetEnterScreen();
 
-  FadeOut(REDRAW_FIELD);
+  if (CheckIfRedrawGlobalBorderIsNeeded())
+    fade_mask = REDRAW_ALL;
+
+#if 0
+  printf("::: %d\n", (fade_mask == REDRAW_ALL ? 1 : 0));
+#endif
+
+  FadeOut(fade_mask);
 
+#if 0
   /* needed if different viewport properties defined for playing */
   ChangeViewportPropertiesIfNeeded();
+#endif
+
+#if 1
+  ClearField();
+#endif
 
   DrawCompleteVideoDisplay();
 
@@ -3919,7 +3938,7 @@ void InitGame()
   BlitScreenToBitmap(backbuffer);
   /* !!! FIX THIS (END) !!! */
 
-  FadeIn(REDRAW_FIELD);
+  FadeIn(fade_mask);
 
 #if 1
   // full screen redraw is required at this point in the following cases:
index ad0af02d4ff70b3ea1d85a47ece745fed0dabcf9..58ebc1a3bb21d909979afd893191ba5a54dfcd8d 100644 (file)
@@ -1369,6 +1369,10 @@ static void InitGraphicInfo()
   static int full_size_graphics[] =
   {
     IMG_GLOBAL_BORDER,
+    IMG_GLOBAL_BORDER_MAIN,
+    IMG_GLOBAL_BORDER_SCORES,
+    IMG_GLOBAL_BORDER_EDITOR,
+    IMG_GLOBAL_BORDER_PLAYING,
     IMG_GLOBAL_DOOR,
 
     IMG_BACKGROUND_ENVELOPE_1,
@@ -4998,9 +5002,21 @@ static void InitMixer()
 
 void InitGfxBuffers()
 {
+  static int win_xsize_last = -1;
+  static int win_ysize_last = -1;
+
   /* create additional image buffers for double-buffering and cross-fading */
-  ReCreateBitmap(&bitmap_db_store, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
-  ReCreateBitmap(&bitmap_db_cross, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
+
+  if (WIN_XSIZE != win_xsize_last || WIN_YSIZE != win_ysize_last)
+  {
+    /* may contain content for cross-fading -- only re-create if changed */
+    ReCreateBitmap(&bitmap_db_store, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
+    ReCreateBitmap(&bitmap_db_cross, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
+
+    win_xsize_last = WIN_XSIZE;
+    win_ysize_last = WIN_YSIZE;
+  }
+
   ReCreateBitmap(&bitmap_db_field, FXSIZE, FYSIZE, DEFAULT_DEPTH);
   ReCreateBitmap(&bitmap_db_panel, DXSIZE, DYSIZE, DEFAULT_DEPTH);
   ReCreateBitmap(&bitmap_db_door_1, 3 * DXSIZE, DYSIZE, DEFAULT_DEPTH);
@@ -5188,7 +5204,16 @@ void InitGfx()
 
 void RedrawGlobalBorder()
 {
-  BlitBitmap(graphic_info[IMG_GLOBAL_BORDER].bitmap, backbuffer,
+  int global_border_graphic;
+
+  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);
+
+  BlitBitmap(graphic_info[global_border_graphic].bitmap, backbuffer,
             0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
 
   redraw_mask = REDRAW_ALL;
index d1b80e26eddf43d8ec759c59adbeba7eaffc38ec..99dedcefa3c9d446f5538bf5e8b5aa5b73700da4 100644 (file)
@@ -1417,19 +1417,32 @@ void DrawMainMenuExt(int fade_mask, boolean do_fading)
   /* needed if last screen (level choice) changed graphics, sounds or music */
   ReloadCustomArtwork(0);
 
+#if 1
+  /* needed if different viewport properties defined for menues */
+  ChangeViewportPropertiesIfNeeded();
+#endif
+
   if (redraw_mask & REDRAW_ALL)
     fade_mask = REDRAW_ALL;
 
+  if (CheckIfRedrawGlobalBorderIsNeeded())
+    fade_mask = REDRAW_ALL;
+
   FadeOut(fade_mask);
 
+#if 0
   /* needed if different viewport properties defined for menues */
   ChangeViewportPropertiesIfNeeded();
+#endif
 
   /* needed if last screen was the editor screen */
   UndrawSpecialEditorDoor();
 
   SetDrawtoField(DRAW_BACKBUFFER);
 
+  /* reset drawing area change flag */
+  DrawingAreaChanged();
+
   if (CheckTitleScreen(levelset_has_changed))
   {
     game_status = GAME_MODE_TITLE;
@@ -1452,8 +1465,10 @@ void DrawMainMenuExt(int fade_mask, boolean do_fading)
 
   SetMainBackgroundImage(IMG_BACKGROUND_MAIN);
 
+#if 1
   if (fade_mask == REDRAW_ALL)
     RedrawGlobalBorder();
+#endif
 
   ClearField();
 
@@ -1487,6 +1502,11 @@ void DrawMainMenuExt(int fade_mask, boolean do_fading)
 
   DrawMaskedBorder(REDRAW_ALL);
 
+#if 0
+  if (redraw_mask & REDRAW_ALL)
+    fade_mask = REDRAW_ALL;
+#endif
+
   FadeIn(fade_mask);
   FadeSetEnterMenu();
 
@@ -1884,6 +1904,11 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
       {
        game_status = GAME_MODE_SCORES;
 
+#if 1
+       /* required before door position may be changed in next step */
+       CloseDoor(DOOR_CLOSE_ALL);
+#endif
+
        ChangeViewportPropertiesIfNeeded();
 
        DrawHallOfFame(-1);
@@ -2122,6 +2147,9 @@ static void DrawInfoScreen_Main(int fade_mask, boolean do_fading)
 {
   int i;
 
+  if (CheckIfRedrawGlobalBorderIsNeeded())
+    fade_mask = REDRAW_ALL;
+
   UnmapAllGadgets();
 
   FreeScreenGadgets();
@@ -5731,6 +5759,9 @@ static void DrawSetupScreen_Generic()
   char *title_string = NULL;
   int i;
 
+  if (CheckIfRedrawGlobalBorderIsNeeded())
+    fade_mask = REDRAW_ALL;
+
   UnmapAllGadgets();
 
   FreeScreenGadgets();
index 10bbe6912a7628454f770afb93d4055f0ac01bf6..a7867f87965b5b953e405fa9d0dab83e6cf641f6 100644 (file)
@@ -481,6 +481,11 @@ static void FadeCrossSaveBackbuffer()
   BlitBitmap(backbuffer, bitmap_db_cross, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
 }
 
+static void FadeCrossRestoreBackbuffer()
+{
+  BlitBitmap(bitmap_db_cross, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+}
+
 static void FadeExt(int fade_mask, int fade_mode, int fade_type)
 {
   static int fade_type_skip = FADE_TYPE_NONE;
@@ -500,9 +505,15 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type)
       return;
     }
 
+#if 1
+    FadeCrossSaveBackbuffer();
+#endif
+
     if (fading.fade_mode & FADE_TYPE_TRANSFORM)
     {
+#if 0
       FadeCrossSaveBackbuffer();
+#endif
 
       return;
     }
@@ -571,6 +582,9 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type)
   FadeRectangle(bitmap, x, y, width, height, fade_mode, fade_delay, post_delay,
                draw_border_function);
 
+  if (fade_type == FADE_TYPE_FADE_OUT)
+    FadeCrossRestoreBackbuffer();
+
   redraw_mask &= ~fade_mask;
 }
 
@@ -750,8 +764,122 @@ void DrawBackgroundForGraphic(int x, int y, int width, int height, int graphic)
   DrawBackground(x, y, width, height);
 }
 
+static int game_status_last = -1;
+static Bitmap *global_border_bitmap_last = NULL;
+static Bitmap *global_border_bitmap = NULL;
+static int real_sx_last = -1, real_sy_last = -1;
+static int full_sxsize_last = -1, full_sysize_last = -1;
+static int dx_last = -1, dy_last = -1;
+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()
+{
+  int global_border_graphic;
+
+  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);
+
+  global_border_bitmap =
+    (graphic_info[global_border_graphic].bitmap ?
+     graphic_info[global_border_graphic].bitmap :
+     graphic_info[IMG_GLOBAL_BORDER].bitmap);
+
+  // redraw if global screen border has changed
+  if (global_border_bitmap_last != global_border_bitmap)
+    return TRUE;
+
+  // redraw if position or size of playfield area has changed
+  if (real_sx_last != REAL_SX || real_sy_last != REAL_SY ||
+      full_sxsize_last != FULL_SXSIZE || full_sysize_last != FULL_SYSIZE)
+    return TRUE;
+
+  // redraw if position or size of door area has changed
+  if (dx_last != DX || dy_last != DY ||
+      dxsize_last != DXSIZE || dysize_last != DYSIZE)
+    return TRUE;
+
+  // redraw if position or size of tape area has changed
+  if (vx_last != VX || vy_last != VY ||
+      vxsize_last != VXSIZE || vysize_last != VYSIZE)
+    return TRUE;
+
+  return FALSE;
+}
+
+static void RedrawGlobalBorderIfNeeded()
+{
+  if (game_status == game_status_last)
+    return;
+
+  // 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())
+  {
+    // 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);
+
+    // copy previous playfield and door areas, if they are defined on both
+    // previous and current screen and if they still have the same size
+
+    if (real_sx_last != -1 && real_sy_last != -1 &&
+       REAL_SX != -1 && REAL_SY != -1 &&
+       full_sxsize_last == FULL_SXSIZE && full_sysize_last == FULL_SYSIZE)
+      BlitBitmap(bitmap_db_store, backbuffer,
+                real_sx_last, real_sy_last, FULL_SXSIZE, FULL_SYSIZE,
+                REAL_SX, REAL_SY);
+
+    if (dx_last != -1 && dy_last != -1 &&
+       DX != -1 && DY != -1 &&
+       dxsize_last == DXSIZE && dysize_last == DYSIZE)
+      BlitBitmap(bitmap_db_store, backbuffer,
+                dx_last, dy_last, DXSIZE, DYSIZE, DX, DY);
+
+    if (vx_last != -1 && vy_last != -1 &&
+       VX != -1 && VY != -1 &&
+       vxsize_last == VXSIZE && vysize_last == VYSIZE)
+      BlitBitmap(bitmap_db_store, backbuffer,
+                vx_last, vy_last, VXSIZE, VYSIZE, VX, VY);
+
+    redraw_mask = REDRAW_ALL;
+  }
+
+  game_status_last = game_status;
+
+  global_border_bitmap_last = global_border_bitmap;
+
+  real_sx_last = REAL_SX;
+  real_sy_last = REAL_SY;
+  full_sxsize_last = FULL_SXSIZE;
+  full_sysize_last = FULL_SYSIZE;
+  dx_last = DX;
+  dy_last = DY;
+  dxsize_last = DXSIZE;
+  dysize_last = DYSIZE;
+  vx_last = VX;
+  vy_last = VY;
+  vxsize_last = VXSIZE;
+  vysize_last = VYSIZE;
+}
+
 void ClearField()
 {
+  RedrawGlobalBorderIfNeeded();
+
   /* !!! "drawto" might still point to playfield buffer here (see above) !!! */
   /* (when entering hall of fame after playing) */
   DrawBackground(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
index af450a90cdb3983139799a0c412f102d16117f35..b8edb85e41d8ffa47edf74ab7d8e42bceca6c04c 100644 (file)
@@ -106,6 +106,7 @@ void SetPanelBackground();
 void DrawBackground(int, int, int, int);
 void DrawBackgroundForFont(int, int, int, int, int);
 void DrawBackgroundForGraphic(int, int, int, int, int);
+boolean CheckIfRedrawGlobalBorderIsNeeded();
 
 void MarkTileDirty(int, int);
 void SetBorderElement();