// screen gadget identifiers
#define SCREEN_CTRL_ID_PREV_LEVEL 0
#define SCREEN_CTRL_ID_NEXT_LEVEL 1
-#define SCREEN_CTRL_ID_FIRST_LEVEL 2
-#define SCREEN_CTRL_ID_LAST_LEVEL 3
-#define SCREEN_CTRL_ID_LEVEL_NUMBER 4
-#define SCREEN_CTRL_ID_PREV_PLAYER 5
-#define SCREEN_CTRL_ID_NEXT_PLAYER 6
-#define SCREEN_CTRL_ID_INSERT_SOLUTION 7
-#define SCREEN_CTRL_ID_PLAY_SOLUTION 8
-#define SCREEN_CTRL_ID_SWITCH_ECS_AGA 9
-#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE 10
-#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE 11
-#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE2 12
-#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2 13
-#define SCREEN_CTRL_ID_SCROLL_UP 14
-#define SCREEN_CTRL_ID_SCROLL_DOWN 15
-#define SCREEN_CTRL_ID_SCROLL_VERTICAL 16
-#define SCREEN_CTRL_ID_NETWORK_SERVER 17
-
-#define NUM_SCREEN_GADGETS 18
-
-#define NUM_SCREEN_MENUBUTTONS 14
+#define SCREEN_CTRL_ID_PREV_LEVEL2 2
+#define SCREEN_CTRL_ID_NEXT_LEVEL2 3
+#define SCREEN_CTRL_ID_FIRST_LEVEL 4
+#define SCREEN_CTRL_ID_LAST_LEVEL 5
+#define SCREEN_CTRL_ID_LEVEL_NUMBER 6
+#define SCREEN_CTRL_ID_PREV_PLAYER 7
+#define SCREEN_CTRL_ID_NEXT_PLAYER 8
+#define SCREEN_CTRL_ID_INSERT_SOLUTION 9
+#define SCREEN_CTRL_ID_PLAY_SOLUTION 10
+#define SCREEN_CTRL_ID_SWITCH_ECS_AGA 11
+#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE 12
+#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE 13
+#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE2 14
+#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2 15
+#define SCREEN_CTRL_ID_SCROLL_UP 16
+#define SCREEN_CTRL_ID_SCROLL_DOWN 17
+#define SCREEN_CTRL_ID_SCROLL_VERTICAL 18
+#define SCREEN_CTRL_ID_NETWORK_SERVER 19
+
+#define NUM_SCREEN_GADGETS 20
+
+#define NUM_SCREEN_MENUBUTTONS 16
#define NUM_SCREEN_SCROLLBUTTONS 2
#define NUM_SCREEN_SCROLLBARS 1
#define NUM_SCREEN_TEXTINPUT 1
#define SCREEN_MASK_INPUT (1 << 2)
#define SCREEN_MASK_TOUCH (1 << 3)
#define SCREEN_MASK_TOUCH2 (1 << 4)
+#define SCREEN_MASK_SCORES (1 << 5)
// graphic position and size values for buttons and scrollbars
#define SC_MENUBUTTON_XSIZE TILEX
static void DrawChoosePlayerName(void);
static void DrawChooseLevelSet(void);
static void DrawChooseLevelNr(void);
+static void DrawScoreInfo(int);
static void DrawInfoScreen(void);
static void DrawSetupScreen(void);
static void DrawTypeName(void);
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 void execOfferUploadTapes(void);
static void DrawHallOfFame_setScoreEntries(void);
+static void HandleHallOfFame_SelectLevel(int, int);
static char *getHallOfFameScoreText(int);
static struct GadgetInfo *screen_gadget[NUM_SCREEN_GADGETS];
#define EXTRA_SPACING_SCORES(i) (EXTRA_SPACING_INFO(i))
+#define EXTRA_SPACING_SCOREINFO(i) (menu.extra_spacing[GAME_MODE_SCOREINFO])
+
#define DRAW_XOFFSET(s) ((s) == GAME_MODE_INFO ? \
DRAW_XOFFSET_INFO(info_mode) : \
(s) == GAME_MODE_SETUP ? \
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)
OpenDoor(GetDoorState() | DOOR_NO_DELAY | DOOR_FORCE_REDRAW);
+ // map gadgets for high score screen
+ if (game_status == GAME_MODE_SCORES)
+ MapScreenMenuGadgets(SCREEN_MASK_SCORES);
+
MapScreenTreeGadgets(*ti_ptr);
+
HandleChooseTree(0, 0, 0, 0, MB_MENU_INITIALIZE, ti_ptr);
DrawMaskedBorder(fade_mask);
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);
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();
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);
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);
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);
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(SCREEN_CTRL_ID_SCROLL_VERTICAL, ti->cl_first, ti);
+ 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)
DrawHallOfFame_setScoreEntries();
- ti = setHallOfFameActiveEntry(ti_ptr);
+ if (score_entries != NULL)
+ {
+ ti = setHallOfFameActiveEntry(ti_ptr);
- if (button != MB_MENU_INITIALIZE)
- drawChooseTreeScreen(ti);
+ if (button != MB_MENU_INITIALIZE)
+ drawChooseTreeScreen(ti);
+ }
}
if (score_entries == NULL)
y = ti->cl_cursor + dy;
}
- if (dx == 1)
+ if (game_status == GAME_MODE_SCORES && ABS(dx) == 1)
+ {
+ HandleHallOfFame_SelectLevel(1, dx);
+
+ return;
+ }
+ else if (dx == 1)
{
TreeInfo *node_first, *node_cursor;
int entry_pos = ti->cl_first + y;
{
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)
{
level.random_seed);
return;
}
+ else
+ {
+ SetGameStatus(GAME_MODE_SCOREINFO);
+
+ DrawScoreInfo(node_cursor->pos);
+
+ return;
+ }
}
SetGameStatus(GAME_MODE_MAIN);
DrawChooseTree(&score_entry_current);
}
-static char *getHallOfFameScoreText(int nr)
+static char *getHallOfFameTimeText(int nr)
{
- if (!level.rate_time_over_score)
- return int2str(scores.entry[nr].score, 5); // show normal score
-
- if (level.use_step_counter)
- return int2str(scores.entry[nr].time, 5); // show number of steps
-
static char score_text[10];
int time_seconds = scores.entry[nr].time / FRAMES_PER_SECOND;
int mm = (time_seconds / 60) % 60;
return score_text;
}
+static char *getHallOfFameScoreText(int nr)
+{
+ if (!level.rate_time_over_score)
+ return int2str(scores.entry[nr].score, 5); // show normal score
+ else if (level.use_step_counter)
+ return int2str(scores.entry[nr].time, 5); // show number of steps
+ else
+ return getHallOfFameTimeText(nr); // show playing time
+}
+
+static void HandleHallOfFame_SelectLevel(int step, int direction)
+{
+ int old_level_nr = level_nr;
+ int 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)
+ new_level_nr = leveldir_current->last_level;
+
+ if (setup.handicap && new_level_nr > leveldir_current->handicap_level)
+ new_level_nr = leveldir_current->handicap_level;
+
+ if (new_level_nr != old_level_nr)
+ {
+ PlaySound(SND_MENU_ITEM_SELECTING);
+
+ scores.last_level_nr = level_nr = new_level_nr;
+
+ LoadLocalAndServerScore(level_nr, TRUE);
+
+ DrawHallOfFame_setScoreEntries();
+
+ // force remapping optional gadgets (especially scroll bar)
+ UnmapScreenTreeGadgets();
+
+ // redraw complete high score screen, as sub-title has changed
+ ClearField();
+
+ // redraw level selection buttons (which have just been erased)
+ RedrawScreenMenuGadgets(SCREEN_MASK_SCORES);
+
+ HandleChooseTree(0, 0, 0, 0, MB_MENU_INITIALIZE, &score_entry_current);
+
+ SaveLevelSetup_SeriesInfo();
+ }
+}
+
void HandleHallOfFame(int mx, int my, int dx, int dy, int button)
{
HandleChooseTree(mx, my, dx, dy, button, &score_entry_current);
}
+static void DrawScoreInfo(int pos)
+{
+ struct ScoreEntry *entry = &scores.entry[pos];
+ int font_title = MENU_INFO_FONT_TITLE;
+ int font_head = MENU_INFO_FONT_HEAD;
+ int font_text = MENU_INFO_FONT_TEXT;
+ int font_foot = MENU_INFO_FONT_FOOT;
+ int spacing_title = menu.headline1_spacing[GAME_MODE_SCOREINFO];
+ int spacing_para = menu.paragraph_spacing[GAME_MODE_SCOREINFO];
+ int spacing_line = menu.line_spacing[GAME_MODE_SCOREINFO];
+ int xstep = getFontWidth(font_text);
+ int ystep_title = getMenuTextStep(spacing_title, font_title);
+ int ystep_para = getMenuTextStep(spacing_para, font_text);
+ int ystep_line = getMenuTextStep(spacing_line, font_text);
+ int ystart = mSY - SY + menu.top_spacing[GAME_MODE_SCOREINFO];
+ int ybottom = mSY - SY + SYSIZE - menu.bottom_spacing[GAME_MODE_SCOREINFO];
+ int xstart1 = mSX - SX + 2 * xstep;
+ int xstart2 = mSX - SX + 14 * xstep;
+
+ SetMainBackgroundImageIfDefined(IMG_BACKGROUND_SCOREINFO);
+
+ FadeOut(REDRAW_FIELD);
+
+ ClearField();
+
+ drawChooseTreeHead(score_entries);
+ drawChooseTreeInfo(score_entries);
+
+ DrawTextSCentered(ystart, font_title, "Score Information:");
+ ystart += ystep_title;
+
+ DrawTextF(xstart1, ystart, font_head, "Level Set");
+ DrawTextF(xstart2, ystart, font_text, leveldir_current->name);
+ ystart += ystep_line;
+
+ DrawTextF(xstart1, ystart, font_head, "Level Name");
+ DrawTextF(xstart2, ystart, font_text, level.name);
+ ystart += ystep_para;
+
+ DrawTextF(xstart1, ystart, font_head, "Player");
+ DrawTextF(xstart2, ystart, font_text, entry->name);
+ ystart += ystep_line;
+
+ if (level.use_step_counter)
+ {
+ DrawTextF(xstart1, ystart, font_head, "Steps");
+ DrawTextF(xstart2, ystart, font_text, int2str(entry->time, 5));
+ ystart += ystep_line;
+ }
+ else
+ {
+ DrawTextF(xstart1, ystart, font_head, "Time");
+ DrawTextF(xstart2, ystart, font_text, getHallOfFameTimeText(pos));
+ ystart += ystep_line;
+ }
+
+ if (!level.rate_time_over_score || entry->score > 0)
+ {
+ DrawTextF(xstart1, ystart, font_head, "Score");
+ DrawTextF(xstart2, ystart, font_text, int2str(entry->score, 5));
+ ystart += ystep_line;
+ }
+
+ DrawTextSCentered(ybottom, font_foot, "Press any key or button to go back");
+
+ FadeIn(REDRAW_FIELD);
+}
+
+void HandleScoreInfo(int mx, int my, int dx, int dy, int button)
+{
+ if (button == MB_MENU_LEAVE || button == MB_MENU_CHOICE)
+ {
+ PlaySound(SND_MENU_ITEM_SELECTING);
+
+ SetGameStatus(GAME_MODE_SCORES);
+
+ DrawHallOfFame(level_nr);
+ }
+}
+
// ============================================================================
// setup screen functions
GD_EVENT_PRESSED | GD_EVENT_REPEATED,
FALSE, "next level"
},
+ {
+ IMG_MENU_BUTTON_PREV_LEVEL2, IMG_MENU_BUTTON_PREV_LEVEL2_ACTIVE,
+ &menu.scores.button.prev_level, NULL,
+ SCREEN_CTRL_ID_PREV_LEVEL2,
+ SCREEN_MASK_SCORES,
+ GD_EVENT_PRESSED | GD_EVENT_REPEATED,
+ FALSE, "previous level"
+ },
+ {
+ IMG_MENU_BUTTON_NEXT_LEVEL2, IMG_MENU_BUTTON_NEXT_LEVEL2_ACTIVE,
+ &menu.scores.button.next_level, NULL,
+ SCREEN_CTRL_ID_NEXT_LEVEL2,
+ SCREEN_MASK_SCORES,
+ GD_EVENT_PRESSED | GD_EVENT_REPEATED,
+ FALSE, "next level"
+ },
{
IMG_MENU_BUTTON_FIRST_LEVEL, IMG_MENU_BUTTON_FIRST_LEVEL_ACTIVE,
&menu.main.button.first_level, NULL,
for (i = 0; i < NUM_SCREEN_MENUBUTTONS; i++)
{
struct MenuPosInfo *pos = menubutton_info[i].pos;
+ int screen_mask = menubutton_info[i].screen_mask;
boolean is_touch_button = menubutton_info[i].is_touch_button;
boolean is_check_button = menubutton_info[i].check_value != NULL;
+ boolean is_score_button = (screen_mask == SCREEN_MASK_SCORES);
Bitmap *gd_bitmap_unpressed, *gd_bitmap_pressed;
int gfx_unpressed, gfx_pressed;
int x, y, width, height;
checked = *menubutton_info[i].check_value;
}
+ if (is_score_button)
+ {
+ // if x/y set to -1, dynamically place buttons next to title text
+ int title_width = getTextWidth(INFOTEXT_SCORE_ENTRY, FONT_TITLE_1);
+
+ if (pos->x == -1)
+ x = (id == SCREEN_CTRL_ID_PREV_LEVEL2 ?
+ SX + (SXSIZE - title_width) / 2 - width * 3 / 2 :
+ id == SCREEN_CTRL_ID_NEXT_LEVEL2 ?
+ SX + (SXSIZE + title_width) / 2 + width / 2 : 0);
+
+ if (pos->y == -1)
+ y = mSY + MENU_TITLE1_YPOS;
+ }
+
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
GDI_IMAGE_ID, gfx_unpressed,
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;
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;
HandleMainMenu_SelectLevel(step, +1, NO_DIRECT_LEVEL_SELECT);
break;
+ case SCREEN_CTRL_ID_PREV_LEVEL2:
+ HandleHallOfFame_SelectLevel(step, -1);
+ break;
+
+ case SCREEN_CTRL_ID_NEXT_LEVEL2:
+ HandleHallOfFame_SelectLevel(step, +1);
+ break;
+
case SCREEN_CTRL_ID_FIRST_LEVEL:
HandleMainMenu_SelectLevel(MAX_LEVELS, -1, NO_DIRECT_LEVEL_SELECT);
break;