fixed redraw/fade bugs when redefining the playfield size or position
[rocksndiamonds.git] / src / screens.c
index 9113105623bb2c561b841b6445cba65e6266b5d0..ca4e669ac05707cb747a48ee70fbec41b331d5a8 100644 (file)
@@ -420,6 +420,9 @@ static struct
 #define MAX_NUM_TITLE_SCREENS  (2 * MAX_NUM_TITLE_IMAGES +             \
                                 2 * MAX_NUM_TITLE_MESSAGES)
 
+#define NO_DIRECT_LEVEL_SELECT (-1)
+
+
 static int num_title_screens = 0;
 
 struct TitleControlInfo
@@ -958,10 +961,8 @@ static void InitializeMainControls()
 
     if (pos_button != NULL)            /* (x/y may be -1/-1 here) */
     {
-      if (pos_button->width == 0)
-       pos_button->width = button_width;
-      if (pos_button->height == 0)
-       pos_button->height = button_height;
+      pos_button->width  = button_width;
+      pos_button->height = button_height;
     }
 
     if (pos_text != NULL)              /* (x/y may be -1/-1 here) */
@@ -969,18 +970,19 @@ static void InitializeMainControls()
       /* calculate size for non-clickable text -- needed for text alignment */
       boolean calculate_text_size = (pos_button == NULL && text != NULL);
 
+      if (pos_text->width == -1 || calculate_text_size)
+       pos_text->width = text_width;
+      if (pos_text->height == -1 || calculate_text_size)
+       pos_text->height = text_height;
+
       if (visibleMenuPos(pos_button))
       {
        if (pos_text->x == -1)
          pos_text->x = pos_button->x + pos_button->width;
        if (pos_text->y == -1)
-         pos_text->y = pos_button->y;
+         pos_text->y =
+           pos_button->y + (pos_button->height - pos_text->height) / 2;
       }
-
-      if (pos_text->width == -1 || calculate_text_size)
-       pos_text->width = text_width;
-      if (pos_text->height == -1 || calculate_text_size)
-       pos_text->height = text_height;
     }
 
     if (pos_input != NULL)             /* (x/y may be -1/-1 here) */
@@ -1221,10 +1223,7 @@ void DrawTitleScreenImage(int nr, boolean initial)
   ClearRectangleOnBackground(drawto, 0, 0, WIN_XSIZE, WIN_YSIZE);
 
   if (DrawingOnBackground(dst_x, dst_y))
-  {
-    SetClipOrigin(bitmap, bitmap->stored_clip_gc, dst_x - src_x, dst_y - src_y);
     BlitBitmapMasked(bitmap, drawto, src_x, src_y, width, height, dst_x, dst_y);
-  }
   else
     BlitBitmap(bitmap, drawto, src_x, src_y, width, height, dst_x, dst_y);
 
@@ -1310,9 +1309,6 @@ void DrawMainMenuExt(int fade_mask, boolean do_fading)
   KeyboardAutoRepeatOn();
   ActivateJoystick();
 
-  SetDrawDeactivationMask(REDRAW_NONE);
-  SetDrawBackgroundMask(REDRAW_FIELD);
-
   audio.sound_deactivated = FALSE;
 
   GetPlayerConfig();
@@ -1374,6 +1370,10 @@ void DrawMainMenuExt(int fade_mask, boolean do_fading)
   LoadLevel(level_nr);
   LoadScore(level_nr);
 
+  // set this after "ChangeViewportPropertiesIfNeeded()" (which may reset it)
+  SetDrawDeactivationMask(REDRAW_NONE);
+  SetDrawBackgroundMask(REDRAW_FIELD);
+
   SetMainBackgroundImage(IMG_BACKGROUND_MAIN);
 
   if (fade_mask == REDRAW_ALL)
@@ -1632,12 +1632,16 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button)
   }
 }
 
-void HandleMainMenu_SelectLevel(int step, int direction)
+void HandleMainMenu_SelectLevel(int step, int direction, int selected_level_nr)
 {
   int old_level_nr = level_nr;
   int new_level_nr;
 
-  new_level_nr = old_level_nr + step * direction;
+  if (selected_level_nr != NO_DIRECT_LEVEL_SELECT)
+    new_level_nr = selected_level_nr;
+  else
+    new_level_nr = old_level_nr + step * direction;
+
   if (new_level_nr < leveldir_current->first_level)
     new_level_nr = leveldir_current->first_level;
   if (new_level_nr > leveldir_current->last_level)
@@ -1646,7 +1650,7 @@ void HandleMainMenu_SelectLevel(int step, int direction)
   if (setup.handicap && new_level_nr > leveldir_current->handicap_level)
   {
     /* skipping levels is only allowed when trying to skip single level */
-    if (setup.skip_levels && step == 1 &&
+    if (setup.skip_levels && new_level_nr == old_level_nr + 1 &&
        Request("Level still unsolved! Skip despite handicap?", REQ_ASK))
     {
       leveldir_current->handicap_level++;
@@ -1677,7 +1681,7 @@ void HandleMainMenu_SelectLevel(int step, int direction)
 
     /* needed because DrawPreviewLevelInitial() takes some time */
     BackToFront();
-    SyncDisplay();
+    /* SyncDisplay(); */
   }
 }
 
@@ -1721,15 +1725,15 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
 
   if (pos == MAIN_CONTROL_LEVELS && dx != 0 && button)
   {
-    HandleMainMenu_SelectLevel(1, dx < 0 ? -1 : +1);
+    HandleMainMenu_SelectLevel(1, (dx < 0 ? -1 : +1), NO_DIRECT_LEVEL_SELECT);
   }
   else if (pos == MAIN_CONTROL_FIRST_LEVEL && !button)
   {
-    HandleMainMenu_SelectLevel(MAX_LEVELS, -1);
+    HandleMainMenu_SelectLevel(MAX_LEVELS, -1, NO_DIRECT_LEVEL_SELECT);
   }
   else if (pos == MAIN_CONTROL_LAST_LEVEL && !button)
   {
-    HandleMainMenu_SelectLevel(MAX_LEVELS, +1);
+    HandleMainMenu_SelectLevel(MAX_LEVELS, +1, NO_DIRECT_LEVEL_SELECT);
   }
   else if (pos == MAIN_CONTROL_LEVEL_NUMBER && !button)
   {
@@ -3225,6 +3229,8 @@ void HandleTypeName(int newxpos, Key key)
 
 static void DrawChooseTree(TreeInfo **ti_ptr)
 {
+  int fade_mask = (DrawingAreaChanged() ? REDRAW_ALL : REDRAW_FIELD);
+
   UnmapAllGadgets();
 
   FreeScreenGadgets();
@@ -3232,14 +3238,14 @@ static void DrawChooseTree(TreeInfo **ti_ptr)
 
   CloseDoor(DOOR_CLOSE_2);
 
-  FadeOut(REDRAW_FIELD);
+  FadeOut(fade_mask);
 
   ClearField();
 
   HandleChooseTree(0, 0, 0, 0, MB_MENU_INITIALIZE, ti_ptr);
   MapScreenTreeGadgets(*ti_ptr);
 
-  FadeIn(REDRAW_FIELD);
+  FadeIn(fade_mask);
 
   InitAnimation();
 }
@@ -3268,8 +3274,8 @@ static void clearMenuListArea()
   int scrollbar_xpos = mSX + SC_SCROLLBAR_XPOS + menu.scrollbar_xoffset;
 
   /* correct scrollbar position if placed outside menu (playfield) area */
-  if (scrollbar_xpos > SC_SCROLLBAR_XPOS)
-    scrollbar_xpos = SC_SCROLLBAR_XPOS;
+  if (scrollbar_xpos > mSX + SC_SCROLLBAR_XPOS)
+    scrollbar_xpos = mSX + SC_SCROLLBAR_XPOS;
 
   /* clear menu list area, but not title or scrollbar */
   DrawBackground(mSX, mSY + MENU_SCREEN_START_YPOS * 32,
@@ -3450,7 +3456,11 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
     else
     {
       if (game_status == GAME_MODE_LEVELNR)
-       level_nr = atoi(level_number_current->identifier);
+      {
+       int new_level_nr = atoi(level_number_current->identifier);
+
+       HandleMainMenu_SelectLevel(0, 0, new_level_nr);
+      }
 
       game_status = GAME_MODE_MAIN;
 
@@ -3644,7 +3654,11 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
        else
        {
          if (game_status == GAME_MODE_LEVELNR)
-           level_nr = atoi(level_number_current->identifier);
+         {
+           int new_level_nr = atoi(level_number_current->identifier);
+
+           HandleMainMenu_SelectLevel(0, 0, new_level_nr);
+         }
 
          game_status = GAME_MODE_MAIN;
 
@@ -3733,6 +3747,8 @@ void HandleChooseLevelNr(int mx, int my, int dx, int dy, int button)
 
 void DrawHallOfFame(int highlight_position)
 {
+  int fade_mask = (DrawingAreaChanged() ? REDRAW_ALL : REDRAW_FIELD);
+
   UnmapAllGadgets();
   FadeSoundsAndMusic();
 
@@ -3751,7 +3767,7 @@ void DrawHallOfFame(int highlight_position)
 
   FadeSetEnterScreen();
 
-  FadeOut(REDRAW_FIELD);
+  FadeOut(fade_mask);
 
   InitAnimation();
 
@@ -3760,7 +3776,7 @@ void DrawHallOfFame(int highlight_position)
 
   HandleHallOfFame(highlight_position, 0, 0, 0, MB_MENU_INITIALIZE);
 
-  FadeIn(REDRAW_FIELD);
+  FadeIn(fade_mask);
 }
 
 static void drawHallOfFameList(int first_entry, int highlight_position)
@@ -5278,6 +5294,7 @@ static void drawSetupInfoList(struct TokenInfo *setup_info,
 
 static void DrawSetupScreen_Generic()
 {
+  int fade_mask = (DrawingAreaChanged() ? REDRAW_ALL : REDRAW_FIELD);
   boolean redraw_all = FALSE;
   char *title_string = NULL;
   int i;
@@ -5292,7 +5309,7 @@ static void DrawSetupScreen_Generic()
   if (redraw_mask & REDRAW_ALL)
     redraw_all = TRUE;
 
-  FadeOut(REDRAW_FIELD);
+  FadeOut(fade_mask);
 
   ClearField();
 
@@ -5379,9 +5396,9 @@ static void DrawSetupScreen_Generic()
   MapScreenGadgets(max_setup_info);
 
   if (redraw_all)
-    redraw_mask = REDRAW_ALL;
+    redraw_mask = fade_mask = REDRAW_ALL;
 
-  FadeIn(redraw_mask);
+  FadeIn(fade_mask);
 
   InitAnimation();
 }
@@ -6556,8 +6573,8 @@ static void CreateScreenScrollbuttons()
     height = SC_SCROLLBUTTON_YSIZE;
 
     /* correct scrollbar position if placed outside menu (playfield) area */
-    if (x > SC_SCROLL_UP_XPOS)
-      x = SC_SCROLL_UP_XPOS;
+    if (x > SX + SC_SCROLL_UP_XPOS)
+      x = SX + SC_SCROLL_UP_XPOS;
 
     if (id == SCREEN_CTRL_ID_SCROLL_DOWN)
       y = mSY + (SC_SCROLL_VERTICAL_YPOS +
@@ -6625,8 +6642,8 @@ static void CreateScreenScrollbars()
     height = scrollbar_info[i].height;
 
     /* correct scrollbar position if placed outside menu (playfield) area */
-    if (x > SC_SCROLL_VERTICAL_XPOS)
-      x = SC_SCROLL_VERTICAL_XPOS;
+    if (x > SX + SC_SCROLL_VERTICAL_XPOS)
+      x = SX + SC_SCROLL_VERTICAL_XPOS;
 
     if (id == SCREEN_CTRL_ID_SCROLL_VERTICAL)
       height = (NUM_MENU_ENTRIES_ON_SCREEN - 2) * SC_SCROLLBUTTON_YSIZE;
@@ -6732,11 +6749,11 @@ static void HandleScreenGadgets(struct GadgetInfo *gi)
   switch (id)
   {
     case SCREEN_CTRL_ID_PREV_LEVEL:
-      HandleMainMenu_SelectLevel(step, -1);
+      HandleMainMenu_SelectLevel(step, -1, NO_DIRECT_LEVEL_SELECT);
       break;
 
     case SCREEN_CTRL_ID_NEXT_LEVEL:
-      HandleMainMenu_SelectLevel(step, +1);
+      HandleMainMenu_SelectLevel(step, +1, NO_DIRECT_LEVEL_SELECT);
       break;
 
     case SCREEN_CTRL_ID_PREV_PLAYER: