added functions to redraw and unmap screen gadgets
[rocksndiamonds.git] / src / screens.c
index de1c498f3535df62e0317d2965ddc8d1503985e4..62eb2979cd59bbc752c5ff95d8e1e8f206ab9c63 100644 (file)
@@ -277,16 +277,20 @@ static void HandleInfoScreen_Version(int);
 static void ModifyGameSpeedIfNeeded(void);
 static void DisableVsyncIfNeeded(void);
 
+static void RedrawScreenMenuGadgets(int);
 static void MapScreenMenuGadgets(int);
 static void UnmapScreenMenuGadgets(int);
 static void MapScreenGadgets(int);
+static void UnmapScreenGadgets(void);
 static void MapScreenTreeGadgets(TreeInfo *);
+static void UnmapScreenTreeGadgets(void);
 
 static void UpdateScreenMenuGadgets(int, boolean);
 
 static boolean OfferUploadTapes(void);
 static void execOfferUploadTapes(void);
 
+static void DrawHallOfFame_setScoreEntries(void);
 static char *getHallOfFameScoreText(int);
 
 static struct GadgetInfo *screen_gadget[NUM_SCREEN_GADGETS];
@@ -609,6 +613,8 @@ static int align_yoffset = 0;
                                 menu.extra_spacing[GAME_MODE_SETUP] :  \
                                 menu.extra_spacing_setup[DRAW_MODE_SETUP(i)])
 
+#define EXTRA_SPACING_SCORES(i)        (EXTRA_SPACING_INFO(i))
+
 #define DRAW_XOFFSET(s)                ((s) == GAME_MODE_INFO ?                \
                                 DRAW_XOFFSET_INFO(info_mode) :         \
                                 (s) == GAME_MODE_SETUP ?               \
@@ -623,6 +629,8 @@ static int align_yoffset = 0;
                                 EXTRA_SPACING_INFO(info_mode) :        \
                                 (s) == GAME_MODE_SETUP ?               \
                                 EXTRA_SPACING_SETUP(setup_mode) :      \
+                                (s) == GAME_MODE_SCORES ?              \
+                                EXTRA_SPACING_SCORES(info_mode) :      \
                                 menu.extra_spacing[DRAW_MODE(s)])
 
 #define mSX                    (SX + DRAW_XOFFSET(game_status))
@@ -1398,10 +1406,10 @@ static void AdjustScrollbar(int id, int items_max, int items_visible,
               GDI_SCROLLBAR_ITEM_POSITION, item_position, GDI_END);
 }
 
-static void AdjustChooseTreeScrollbar(int id, int first_entry, TreeInfo *ti)
+static void AdjustChooseTreeScrollbar(TreeInfo *ti, int id)
 {
   AdjustScrollbar(id, numTreeInfoInGroup(ti), NUM_MENU_ENTRIES_ON_SCREEN,
-                 first_entry);
+                 ti->cl_first);
 }
 
 static void clearMenuListArea(void)
@@ -4877,7 +4885,7 @@ static int getChooseTreeFont(TreeInfo *node, boolean active)
     return MENU_CHOOSE_TREE_FONT(MENU_CHOOSE_TREE_COLOR(node, active));
 }
 
-static void drawChooseTreeText(int y, boolean active, TreeInfo *ti)
+static void drawChooseTreeText(TreeInfo *ti, int y, boolean active)
 {
   int num_entries = numTreeInfoInGroup(ti);
   boolean scrollbar_needed = (num_entries > NUM_MENU_ENTRIES_ON_SCREEN);
@@ -4964,9 +4972,11 @@ static void drawChooseTreeHead(TreeInfo *ti)
   drawChooseTreeHeadExt(ti->type, ti->infotext);
 }
 
-static void drawChooseTreeList(int first_entry, int num_page_entries,
-                              TreeInfo *ti)
+static void drawChooseTreeList(TreeInfo *ti)
 {
+  int first_entry = ti->cl_first;
+  int num_entries = numTreeInfoInGroup(ti);
+  int num_page_entries = MIN(num_entries, NUM_MENU_ENTRIES_ON_SCREEN);
   int i;
 
   clearMenuListArea();
@@ -4979,7 +4989,7 @@ static void drawChooseTreeList(int first_entry, int num_page_entries,
     node_first = getTreeInfoFirstGroupEntry(ti);
     node = getTreeInfoFromPos(node_first, entry_pos);
 
-    drawChooseTreeText(i, FALSE, ti);
+    drawChooseTreeText(ti, i, FALSE);
 
     if (node->parent_link)
       initCursor(i, IMG_MENU_BUTTON_LEAVE_MENU);
@@ -4998,12 +5008,13 @@ static void drawChooseTreeList(int first_entry, int num_page_entries,
   redraw_mask |= REDRAW_FIELD;
 }
 
-static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti)
+static void drawChooseTreeInfo(TreeInfo *ti)
 {
-  TreeInfo *node, *node_first;
-  int x, last_redraw_mask = redraw_mask;
+  int entry_pos = ti->cl_first + ti->cl_cursor;
+  int last_redraw_mask = redraw_mask;
   int ypos = MENU_TITLE2_YPOS;
   int font_nr = FONT_TITLE_2;
+  int x;
 
   if (ti->type == TREE_TYPE_LEVEL_NR)
     DrawTextFCentered(ypos, font_nr, leveldir_current->name);
@@ -5015,8 +5026,8 @@ static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti)
   if (ti->type != TREE_TYPE_LEVEL_DIR)
     return;
 
-  node_first = getTreeInfoFirstGroupEntry(ti);
-  node = getTreeInfoFromPos(node_first, entry_pos);
+  TreeInfo *node_first = getTreeInfoFirstGroupEntry(ti);
+  TreeInfo *node = getTreeInfoFromPos(node_first, entry_pos);
 
   DrawBackgroundForFont(SX, SY + ypos, SXSIZE, getFontHeight(font_nr), font_nr);
 
@@ -5037,23 +5048,53 @@ static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti)
     MarkTileDirty(x, 1);
 }
 
-static void drawChooseTreeCursorAndText(int y, boolean active, TreeInfo *ti)
+static void drawChooseTreeCursorAndText(TreeInfo *ti, boolean active)
 {
-  drawChooseTreeCursor(y, active);
-  drawChooseTreeText(y, active, ti);
+  drawChooseTreeCursor(ti->cl_cursor, active);
+  drawChooseTreeText(ti, ti->cl_cursor, active);
 }
 
 static void drawChooseTreeScreen(TreeInfo *ti)
 {
-  int num_entries = numTreeInfoInGroup(ti);
-  int num_page_entries = MIN(num_entries, NUM_MENU_ENTRIES_ON_SCREEN);
-
   drawChooseTreeHead(ti);
-  drawChooseTreeList(ti->cl_first, num_page_entries, ti);
-  drawChooseTreeInfo(ti->cl_first + ti->cl_cursor, ti);
-  drawChooseTreeCursorAndText(ti->cl_cursor, TRUE, ti);
+  drawChooseTreeList(ti);
+  drawChooseTreeInfo(ti);
+  drawChooseTreeCursorAndText(ti, TRUE);
+
+  AdjustChooseTreeScrollbar(ti, SCREEN_CTRL_ID_SCROLL_VERTICAL);
+
+  // scroll bar and buttons may just have been added after reloading scores
+  if (game_status == GAME_MODE_SCORES)
+    MapScreenTreeGadgets(ti);
+}
+
+static void drawChooseTreeScreen_Scores_NotAvailable(void)
+{
+  // dirty workaround to use spacing definitions from info screen
+  info_mode = INFO_MODE_TITLE;
+
+  char *text_info = "HighScores of Level %d";
+  char *text_title = "Score information:";
+  char *text_error = "No scores for this level.";
+  char *text_foot = "Press any key or button for main menu";
+  int font_info = FONT_TITLE_2;
+  int font_title = FONT_INITIAL_3;
+  int font_error = FONT_INITIAL_4;
+  int font_foot  = FONT_INITIAL_2;
+  int spacing_title = menu.headline1_spacing_info[INFO_MODE_TITLE];
+  int ystep_title = getMenuTextStep(spacing_title, font_title);
+  int ystart1 = mSY - SY + MENU_SCREEN_INFO_YSTART1;
+  int ystart2 = ystart1 + ystep_title;
+  int ybottom = mSY - SY + MENU_SCREEN_INFO_YBOTTOM;
+  int ystart0 = MENU_TITLE2_YPOS;
 
-  AdjustChooseTreeScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL, ti->cl_first, ti);
+  drawChooseTreeHeadExt(TREE_TYPE_SCORE_ENTRY, INFOTEXT_SCORE_ENTRY);
+  DrawTextFCentered(ystart0, font_info, text_info, scores.last_level_nr);
+
+  DrawTextSCentered(ystart1, font_title, text_title);
+  DrawTextSCentered(ystart2, font_error, text_error);
+
+  DrawTextSCentered(ybottom, font_foot, text_foot);
 }
 
 static TreeInfo *setHallOfFameActiveEntry(TreeInfo **ti_ptr)
@@ -5093,6 +5134,42 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
   int num_page_entries = MIN(num_entries, NUM_MENU_ENTRIES_ON_SCREEN);
   boolean position_set_by_scrollbar = (dx == 999);
 
+  if (game_status == GAME_MODE_SCORES)
+  {
+    if (server_scores.updated)
+    {
+      // reload scores, using updated server score cache file
+      LoadLocalAndServerScore(scores.last_level_nr, FALSE);
+
+      server_scores.updated = FALSE;
+
+      DrawHallOfFame_setScoreEntries();
+
+      ti = setHallOfFameActiveEntry(ti_ptr);
+
+      if (button != MB_MENU_INITIALIZE)
+       drawChooseTreeScreen(ti);
+    }
+
+    if (score_entries == NULL)
+    {
+      if (button == MB_MENU_INITIALIZE)
+      {
+       drawChooseTreeScreen_Scores_NotAvailable();
+      }
+      else if (button == MB_MENU_LEAVE || button == MB_MENU_CHOICE)
+      {
+       PlaySound(SND_MENU_ITEM_SELECTING);
+
+       SetGameStatus(GAME_MODE_MAIN);
+
+       DrawMainMenu();
+      }
+
+      return;
+    }
+  }
+
   if (button == MB_MENU_INITIALIZE)
   {
     int num_entries = numTreeInfoInGroup(ti);
@@ -5103,14 +5180,6 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
 
     if (game_status == GAME_MODE_SCORES)
     {
-      if (server_scores.updated)
-      {
-       // reload scores, using updated server score cache file
-       LoadLocalAndServerScore(scores.last_level_nr, FALSE);
-
-       server_scores.updated = FALSE;
-      }
-
       ti = setHallOfFameActiveEntry(ti_ptr);
     }
     else if (ti->cl_first == -1)
@@ -5301,11 +5370,13 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
       {
        PlaySound(SND_MENU_ITEM_ACTIVATING);
 
-       drawChooseTreeCursorAndText(ti->cl_cursor, FALSE, ti);
-       drawChooseTreeCursorAndText(y, TRUE, ti);
-       drawChooseTreeInfo(ti->cl_first + y, ti);
+       drawChooseTreeCursorAndText(ti, FALSE);
 
        ti->cl_cursor = y;
+
+       drawChooseTreeCursorAndText(ti, TRUE);
+
+       drawChooseTreeInfo(ti);
       }
       else if (dx < 0)
       {
@@ -5482,18 +5553,6 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
     }
   }
 
-  if (game_status == GAME_MODE_SCORES && server_scores.updated)
-  {
-    // reload scores, using updated server score cache file
-    LoadLocalAndServerScore(scores.last_level_nr, FALSE);
-
-    server_scores.updated = FALSE;
-
-    ti = setHallOfFameActiveEntry(ti_ptr);
-
-    drawChooseTreeScreen(ti);
-  }
-
   if (game_status == GAME_MODE_SCORES)
     PlayMenuSoundIfLoop();
 }
@@ -5628,6 +5687,11 @@ static void DrawHallOfFame_setScoreEntries(void)
 
   for (i = 0; i < MAX_SCORE_ENTRIES; i++)
   {
+    // do not add empty score entries
+    if (scores.entry[i].score == 0 &&
+       scores.entry[i].time == 0)
+      break;
+
     TreeInfo *ti = newTreeInfo_setDefaults(TREE_TYPE_SCORE_ENTRY);
     char identifier[32], name[64];
     int value = i;
@@ -5660,6 +5724,8 @@ static void DrawHallOfFame_setScoreEntries(void)
   // if that fails, set current score entry to first valid score entry
   if (score_entry_current == NULL)
     score_entry_current = getFirstValidTreeInfoEntry(score_entries);
+
+  // ("score_entries" and "score_entry_current" may be NULL here)
 }
 
 void DrawHallOfFame(int level_nr)
@@ -9998,6 +10064,15 @@ void FreeScreenGadgets(void)
     FreeGadget(screen_gadget[i]);
 }
 
+static void RedrawScreenMenuGadgets(int screen_mask)
+{
+  int i;
+
+  for (i = 0; i < NUM_SCREEN_MENUBUTTONS; i++)
+    if (screen_mask & menubutton_info[i].screen_mask)
+      RedrawGadget(screen_gadget[menubutton_info[i].gadget_id]);
+}
+
 static void MapScreenMenuGadgets(int screen_mask)
 {
   int i;
@@ -10048,11 +10123,27 @@ static void MapScreenGadgets(int num_entries)
     MapGadget(screen_gadget[scrollbar_info[i].gadget_id]);
 }
 
+static void UnmapScreenGadgets()
+{
+  int i;
+
+  for (i = 0; i < NUM_SCREEN_SCROLLBUTTONS; i++)
+    UnmapGadget(screen_gadget[scrollbutton_info[i].gadget_id]);
+
+  for (i = 0; i < NUM_SCREEN_SCROLLBARS; i++)
+    UnmapGadget(screen_gadget[scrollbar_info[i].gadget_id]);
+}
+
 static void MapScreenTreeGadgets(TreeInfo *ti)
 {
   MapScreenGadgets(numTreeInfoInGroup(ti));
 }
 
+static void UnmapScreenTreeGadgets(void)
+{
+  UnmapScreenGadgets();
+}
+
 static void HandleScreenGadgets(struct GadgetInfo *gi)
 {
   int id = gi->custom_id;