+
+/* ========================================================================= */
+/* info screen functions */
+/* ========================================================================= */
+
+static struct TokenInfo *info_info;
+static int num_info_info;
+
+static void execInfoElements()
+{
+ info_mode = INFO_MODE_ELEMENTS;
+ DrawInfoScreen();
+}
+
+static void execInfoMusic()
+{
+ info_mode = INFO_MODE_MUSIC;
+ DrawInfoScreen();
+}
+
+static void execInfoCredits()
+{
+ info_mode = INFO_MODE_CREDITS;
+ DrawInfoScreen();
+}
+
+static void execInfoProgram()
+{
+ info_mode = INFO_MODE_PROGRAM;
+ DrawInfoScreen();
+}
+
+static void execInfoLevelSet()
+{
+ info_mode = INFO_MODE_LEVELSET;
+ DrawInfoScreen();
+}
+
+static void execExitInfo()
+{
+ game_status = GAME_MODE_MAIN;
+ DrawMainMenu();
+}
+
+static struct TokenInfo info_info_main[] =
+{
+ { TYPE_ENTER_SCREEN, execInfoElements, "Elements Info" },
+ { TYPE_ENTER_SCREEN, execInfoMusic, "Music Info" },
+ { TYPE_ENTER_SCREEN, execInfoCredits, "Credits" },
+ { TYPE_ENTER_SCREEN, execInfoProgram, "Program Info" },
+ { TYPE_ENTER_SCREEN, execInfoLevelSet, "Level Set Info" },
+ { TYPE_EMPTY, NULL, "" },
+ { TYPE_LEAVE_MENU, execExitInfo, "Exit" },
+
+ { 0, NULL, NULL }
+};
+
+static void DrawInfoScreen_Main()
+{
+ int i;
+
+ UnmapAllGadgets();
+ CloseDoor(DOOR_CLOSE_2);
+
+ ClearWindow();
+
+ DrawText(mSX + 16, mSY + 16, "Info Screen", FONT_TITLE_1);
+
+ info_info = info_info_main;
+ num_info_info = 0;
+
+ for (i = 0; info_info[i].type != 0 && i < NUM_MENU_ENTRIES_ON_SCREEN; i++)
+ {
+ int ypos = MENU_SCREEN_START_YPOS + i;
+ int font_nr = FONT_MENU_1;
+
+ DrawText(mSX + 32, mSY + ypos * 32, info_info[i].text, font_nr);
+
+ if (info_info[i].type & TYPE_ENTER_MENU)
+ initCursor(i, IMG_MENU_BUTTON_RIGHT);
+ else if (info_info[i].type & TYPE_LEAVE_MENU)
+ initCursor(i, IMG_MENU_BUTTON_LEFT);
+ else if (info_info[i].type & ~TYPE_SKIP_ENTRY)
+ initCursor(i, IMG_MENU_BUTTON);
+
+ num_info_info++;
+ }
+
+ FadeToFront();
+ InitAnimation();
+
+ PlayMenuSound();
+ PlayMenuMusic();
+
+ HandleInfoScreen_Main(0, 0, 0, 0, MB_MENU_INITIALIZE);
+}
+
+void HandleInfoScreen_Main(int mx, int my, int dx, int dy, int button)
+{
+ static int choice_store[MAX_INFO_MODES];
+ int choice = choice_store[info_mode]; /* always starts with 0 */
+ int x = 0;
+ int y = choice;
+
+ if (button == MB_MENU_INITIALIZE)
+ {
+ /* advance to first valid menu entry */
+ while (choice < num_info_info &&
+ info_info[choice].type & TYPE_SKIP_ENTRY)
+ choice++;
+ choice_store[info_mode] = choice;
+
+ drawCursor(choice, FC_RED);
+ return;
+ }
+ else if (button == MB_MENU_LEAVE)
+ {
+ for (y = 0; y < num_info_info; y++)
+ {
+ if (info_info[y].type & TYPE_LEAVE_MENU)
+ {
+ void (*menu_callback_function)(void) = info_info[y].value;
+
+ menu_callback_function();
+ break; /* absolutely needed because function changes 'info_info'! */
+ }
+ }
+
+ return;
+ }
+
+ if (mx || my) /* mouse input */
+ {
+ x = (mx - mSX) / 32;
+ y = (my - mSY) / 32 - MENU_SCREEN_START_YPOS;
+ }
+ else if (dx || dy) /* keyboard input */
+ {
+ if (dx)
+ {
+ int menu_navigation_type = (dx < 0 ? TYPE_LEAVE_MENU : TYPE_ENTER_MENU);
+
+ if (info_info[choice].type & menu_navigation_type ||
+ info_info[choice].type & TYPE_ENTER_SCREEN ||
+ info_info[choice].type & TYPE_BOOLEAN_STYLE)
+ button = MB_MENU_CHOICE;
+ }
+ else if (dy)
+ y = choice + dy;
+
+ /* jump to next non-empty menu entry (up or down) */
+ while (y > 0 && y < num_info_info - 1 &&
+ info_info[y].type & TYPE_SKIP_ENTRY)
+ y += dy;
+ }
+
+ if (IN_VIS_FIELD(x, y) &&
+ y >= 0 && y < num_info_info && info_info[y].type & ~TYPE_SKIP_ENTRY)
+ {
+ if (button)
+ {
+ if (y != choice)
+ {
+ drawCursor(y, FC_RED);
+ drawCursor(choice, FC_BLUE);
+ choice = choice_store[info_mode] = y;
+ }
+ }
+ else if (!(info_info[y].type & TYPE_GHOSTED))
+ {
+ if (info_info[y].type & TYPE_ENTER_OR_LEAVE_MENU)
+ {
+ void (*menu_callback_function)(void) = info_info[choice].value;
+
+ menu_callback_function();
+ }
+ }
+ }