added support for separate animations for 'main only' and 'type name' screen
[rocksndiamonds.git] / src / tools.c
index cff76238c3b2f2c6db6fd6e6460aa885010e6951..8610e5103476b976aa2731326f38226e22fb99a8 100644 (file)
@@ -291,20 +291,21 @@ void RedrawPlayfield()
 static void DrawMaskedBorderExt_Rect(int x, int y, int width, int height,
                                     int draw_target)
 {
-  Bitmap *bitmap = getGlobalBorderBitmapFromGameStatus();
+  Bitmap *src_bitmap = getGlobalBorderBitmapFromStatus(global.border_status);
+  Bitmap *dst_bitmap = gfx.masked_border_bitmap_ptr;
 
   if (x == -1 && y == -1)
     return;
 
   if (draw_target == DRAW_BORDER_TO_SCREEN)
-    BlitToScreenMasked(bitmap, x, y, width, height, x, y);
+    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(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,
@@ -352,8 +353,8 @@ static void DrawMaskedBorderExt_ALL(int draw_target)
 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)
@@ -381,9 +382,33 @@ void DrawMaskedBorder(int redraw_mask)
   DrawMaskedBorderExt(redraw_mask, DRAW_BORDER_TO_BACKBUFFER);
 }
 
-void DrawMaskedBorderToScreen(int draw_target)
+void DrawMaskedBorderToTarget(int draw_target)
 {
-  DrawMaskedBorderExt(REDRAW_ALL, draw_target);
+  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)
@@ -688,6 +713,9 @@ 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
@@ -697,6 +725,9 @@ static void SetScreenStates_AfterFadingIn()
 
 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;
 }
 
@@ -833,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);
@@ -941,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);
 }
@@ -988,7 +1019,7 @@ void RedrawGlobalBorderFromBitmap(Bitmap *bitmap)
 
 void RedrawGlobalBorder()
 {
-  Bitmap *bitmap = getGlobalBorderBitmapFromGameStatus();
+  Bitmap *bitmap = getGlobalBorderBitmapFromStatus(game_status);
 
   RedrawGlobalBorderFromBitmap(bitmap);
 
@@ -2397,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;
@@ -2465,13 +2495,13 @@ void DrawEnvelopeRequest(char *text)
                                  tile_size, tile_size);
 
   /* force DOOR font inside door area */
-  SetGameStatus(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);
 
-  SetGameStatus(last_game_status);     /* restore current game status */
+  ResetFontStatus();
 
   for (i = 0; i < NUM_TOOL_BUTTONS; i++)
     RedrawGadget(tool_gadget[i]);
@@ -2830,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)
   {
@@ -2876,8 +2905,6 @@ static void DrawPreviewLevelExt(boolean restart)
        DrawTextSAligned(pos->x, pos->y, label_text, font_nr, pos->align);
     }
 
-    SetGameStatus(last_game_status);   /* restore current game status */
-
     return;
   }
 
@@ -2977,8 +3004,6 @@ static void DrawPreviewLevelExt(boolean restart)
 
     DrawPreviewLevelLabelExt(label_state);
   }
-
-  SetGameStatus(last_game_status);     /* restore current game status */
 }
 
 void DrawPreviewLevelInitial()
@@ -3706,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;
@@ -3763,7 +3787,7 @@ static boolean RequestDoor(char *text, unsigned int req_state)
   DrawBackground(DX, DY, DXSIZE, DYSIZE);
 
   /* force DOOR font inside door area */
-  SetGameStatus(GAME_MODE_PSEUDO_DOOR);
+  SetFontStatus(GAME_MODE_PSEUDO_DOOR);
 
   /* write text for request */
   for (text_ptr = text, ty = 0; ty < MAX_REQUEST_LINES; ty++)
@@ -3803,7 +3827,7 @@ static boolean RequestDoor(char *text, unsigned int req_state)
     // text_ptr += tl + (tc == ' ' || tc == '?' || tc == '!' ? 1 : 0);
   }
 
-  SetGameStatus(last_game_status);     /* restore current game status */
+  ResetFontStatus();
 
   if (req_state & REQ_ASK)
   {
@@ -8180,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);
@@ -8212,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);
@@ -8220,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 */
@@ -8261,11 +8275,48 @@ 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;
 
-  global.anim_status_next = game_status;
+  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()