+/* title display and control definitions */
+
+#define MAX_NUM_TITLE_SCREENS (2 * MAX_NUM_TITLE_IMAGES + \
+ 2 * MAX_NUM_TITLE_MESSAGES)
+
+static int num_title_screens = 0;
+
+struct TitleControlInfo
+{
+ boolean is_image;
+ boolean initial;
+ int local_nr;
+ int sort_priority;
+};
+
+struct TitleControlInfo title_controls[MAX_NUM_TITLE_SCREENS];
+
+
+/* main menu display and control definitions */
+
+#define MAIN_CONTROL_NAME 0
+#define MAIN_CONTROL_LEVELS 1
+#define MAIN_CONTROL_SCORES 2
+#define MAIN_CONTROL_EDITOR 3
+#define MAIN_CONTROL_INFO 4
+#define MAIN_CONTROL_GAME 5
+#define MAIN_CONTROL_SETUP 6
+#define MAIN_CONTROL_QUIT 7
+#define MAIN_CONTROL_PREV_LEVEL 8
+#define MAIN_CONTROL_NEXT_LEVEL 9
+#define MAIN_CONTROL_CURRENT_LEVEL 10
+#define MAIN_CONTROL_FIRST_LEVEL 11
+#define MAIN_CONTROL_LAST_LEVEL 12
+#define MAIN_CONTROL_LEVEL_INFO_1 13
+#define MAIN_CONTROL_LEVEL_INFO_2 14
+#define MAIN_CONTROL_TITLE_1 15
+#define MAIN_CONTROL_TITLE_2 16
+#define MAIN_CONTROL_TITLE_3 17
+
+static char main_text_name[10];
+static char main_text_current_level[10];
+static char main_text_first_level[10];
+static char main_text_last_level[10];
+static char main_input_name[MAX_PLAYER_NAME_LEN + 1];
+
+struct MainControlInfo
+{
+ int nr;
+
+ struct MenuPosInfo *pos_button;
+ int button_graphic;
+
+ struct TextPosInfo *pos_text;
+ char *text;
+ int font_text;
+
+ struct MenuPosInfo *pos_input;
+ char *input;
+ int font_input;
+};
+
+static struct MainControlInfo main_controls[] =
+{
+ {
+ MAIN_CONTROL_NAME,
+ &menu.main.button.name, IMG_MENU_BUTTON,
+ &menu.main.text.name, main_text_name, FONT_MENU_1,
+ &menu.main.input.name, main_input_name, FONT_INPUT_1,
+ },
+ {
+ MAIN_CONTROL_LEVELS,
+ &menu.main.button.levels, IMG_MENU_BUTTON_ENTER_MENU,
+ &menu.main.text.levels, "Levelset", FONT_MENU_1,
+ NULL, NULL, -1,
+ },
+ {
+ MAIN_CONTROL_SCORES,
+ &menu.main.button.scores, IMG_MENU_BUTTON,
+ &menu.main.text.scores, "Hall Of Fame", FONT_MENU_1,
+ NULL, NULL, -1,
+ },
+ {
+ MAIN_CONTROL_EDITOR,
+ &menu.main.button.editor, IMG_MENU_BUTTON,
+ &menu.main.text.editor, "Level Creator", FONT_MENU_1,
+ NULL, NULL, -1,
+ },
+ {
+ MAIN_CONTROL_INFO,
+ &menu.main.button.info, IMG_MENU_BUTTON_ENTER_MENU,
+ &menu.main.text.info, "Info Screen", FONT_MENU_1,
+ NULL, NULL, -1,
+ },
+ {
+ MAIN_CONTROL_GAME,
+ &menu.main.button.game, IMG_MENU_BUTTON,
+ &menu.main.text.game, "Start Game", FONT_MENU_1,
+ NULL, NULL, -1,
+ },
+ {
+ MAIN_CONTROL_SETUP,
+ &menu.main.button.setup, IMG_MENU_BUTTON_ENTER_MENU,
+ &menu.main.text.setup, "Setup", FONT_MENU_1,
+ NULL, NULL, -1,
+ },
+ {
+ MAIN_CONTROL_QUIT,
+ &menu.main.button.quit, IMG_MENU_BUTTON,
+ &menu.main.text.quit, "Quit", FONT_MENU_1,
+ NULL, NULL, -1,
+ },
+#if 0
+ /* (these two buttons are real gadgets) */
+ {
+ MAIN_CONTROL_PREV_LEVEL,
+ &menu.main.button.prev_level, IMG_MENU_BUTTON_PREV_LEVEL,
+ NULL, NULL, -1,
+ NULL, NULL, -1,
+ },
+ {
+ MAIN_CONTROL_NEXT_LEVEL,
+ &menu.main.button.next_level, IMG_MENU_BUTTON_NEXT_LEVEL,
+ NULL, NULL, -1,
+ NULL, NULL, -1,
+ },
+#endif
+ {
+ MAIN_CONTROL_CURRENT_LEVEL,
+ NULL, -1,
+ &menu.main.text.current_level, main_text_current_level,FONT_VALUE_1,
+ NULL, NULL, -1,
+ },
+ {
+ MAIN_CONTROL_FIRST_LEVEL,
+ NULL, -1,
+ &menu.main.text.first_level, main_text_first_level, FONT_TEXT_3,
+ NULL, NULL, -1,
+ },
+ {
+ MAIN_CONTROL_LAST_LEVEL,
+ NULL, -1,
+ &menu.main.text.last_level, main_text_last_level, FONT_TEXT_3,
+ NULL, NULL, -1,
+ },
+ {
+ MAIN_CONTROL_LEVEL_INFO_1,
+ NULL, -1,
+ &menu.main.text.level_info_1, NULL, -1,
+ NULL, NULL, -1,
+ },
+ {
+ MAIN_CONTROL_LEVEL_INFO_2,
+ NULL, -1,
+ &menu.main.text.level_info_2, NULL, -1,
+ NULL, NULL, -1,
+ },
+ {
+ MAIN_CONTROL_TITLE_1,
+ NULL, -1,
+ &menu.main.text.title_1, PROGRAM_TITLE_STRING, FONT_TITLE_1,
+ NULL, NULL, -1,
+ },
+ {
+ MAIN_CONTROL_TITLE_2,
+ NULL, -1,
+ &menu.main.text.title_2, PROGRAM_COPYRIGHT_STRING, FONT_TITLE_2,
+ NULL, NULL, -1,
+ },
+ {
+ MAIN_CONTROL_TITLE_3,
+ NULL, -1,
+ &menu.main.text.title_3, PROGRAM_GAME_BY_STRING, FONT_TITLE_2,
+ NULL, NULL, -1,
+ },
+
+ {
+ -1,
+ NULL, -1,
+ NULL, NULL, -1,
+ NULL, NULL, -1,
+ }
+};
+
+
+static int getTitleScreenGraphic(int nr, boolean initial)
+{
+ return (initial ? IMG_TITLESCREEN_INITIAL_1 : IMG_TITLESCREEN_1) + nr;
+}
+
+static struct TitleMessageInfo *getTitleMessageInfo(int nr, boolean initial)
+{
+ return (initial ? &titlemessage_initial[nr] : &titlemessage[nr]);
+}
+
+static int compareTitleControlInfo(const void *object1, const void *object2)
+{
+ const struct TitleControlInfo *tci1 = (struct TitleControlInfo *)object1;
+ const struct TitleControlInfo *tci2 = (struct TitleControlInfo *)object2;
+ int compare_result;
+
+ if (tci1->initial != tci2->initial)
+ compare_result = (tci1->initial ? -1 : +1);
+ else if (tci1->sort_priority != tci2->sort_priority)
+ compare_result = tci1->sort_priority - tci2->sort_priority;
+ else
+ compare_result = tci1->local_nr - tci2->local_nr;
+
+ return compare_result;
+}
+
+static void InitializeTitleControlsExt_AddTitleInfo(boolean is_image,
+ boolean initial,
+ int nr, int sort_priority)
+{
+ title_controls[num_title_screens].is_image = is_image;
+ title_controls[num_title_screens].initial = initial;
+ title_controls[num_title_screens].local_nr = nr;
+ title_controls[num_title_screens].sort_priority = sort_priority;
+
+ num_title_screens++;
+}
+
+static void InitializeTitleControls_CheckTitleInfo(boolean initial)
+{
+ int i;
+
+ for (i = 0; i < MAX_NUM_TITLE_IMAGES; i++)
+ {
+ int graphic = getTitleScreenGraphic(i, initial);
+ Bitmap *bitmap = graphic_info[graphic].bitmap;
+ int sort_priority = graphic_info[graphic].sort_priority;
+
+ if (bitmap != NULL)
+ InitializeTitleControlsExt_AddTitleInfo(TRUE, initial, i, sort_priority);
+ }
+
+ for (i = 0; i < MAX_NUM_TITLE_MESSAGES; i++)
+ {
+ struct TitleMessageInfo *tmi = getTitleMessageInfo(i, initial);
+ char *filename = getLevelSetTitleMessageFilename(i, initial);
+ int sort_priority = tmi->sort_priority;
+
+ if (filename != NULL)
+ InitializeTitleControlsExt_AddTitleInfo(FALSE, initial, i, sort_priority);
+ }
+}
+
+static void InitializeTitleControls(boolean show_title_initial)
+{
+ num_title_screens = 0;
+
+ if (show_title_initial)
+ InitializeTitleControls_CheckTitleInfo(TRUE);
+
+ InitializeTitleControls_CheckTitleInfo(FALSE);
+
+ /* sort title screens according to sort_priority and title number */
+ qsort(title_controls, num_title_screens, sizeof(struct TitleControlInfo),
+ compareTitleControlInfo);
+}
+
+static void InitializeMainControls()
+{
+ boolean local_team_mode = (!options.network && setup.team_mode);
+ int i;
+
+ /* set main control text values to dynamically determined values */
+ sprintf(main_text_name, "%s", local_team_mode ? "Team:" : "Name:");
+ sprintf(main_text_current_level, "%s", int2str(level_nr, 3));
+ sprintf(main_text_first_level, "%03d", leveldir_current->first_level);
+ sprintf(main_text_last_level, "%03d", leveldir_current->last_level);
+ sprintf(main_input_name, "%s", setup.player_name);
+
+ /* set main control screen positions to dynamically determined values */
+ for (i = 0; main_controls[i].nr != -1; i++)
+ {
+ struct MainControlInfo *mci = &main_controls[i];
+ int nr = mci->nr;
+ struct MenuPosInfo *pos_button = mci->pos_button;
+ struct TextPosInfo *pos_text = mci->pos_text;
+ struct MenuPosInfo *pos_input = mci->pos_input;
+ char *text = mci->text;
+ char *input = mci->input;
+ int button_graphic = mci->button_graphic;
+ int font_text = mci->font_text;
+ int font_input = mci->font_input;
+
+ int font_text_width = (font_text != -1 ? getFontWidth(font_text) : 0);
+ int font_text_height = (font_text != -1 ? getFontHeight(font_text) : 0);
+ int font_input_width = (font_input != -1 ? getFontWidth(font_input) : 0);
+ int font_input_height = (font_input != -1 ? getFontHeight(font_input) : 0);
+ int text_chars = (text != NULL ? strlen(text) : 0);
+ int input_chars = (input != NULL ? strlen(input) : 0);
+
+ int button_width =
+ (button_graphic != -1 ? graphic_info[button_graphic].width : 0);
+ int button_height =
+ (button_graphic != -1 ? graphic_info[button_graphic].height : 0);
+ int text_width = font_text_width * text_chars;
+ int text_height = font_text_height;
+ int input_width = font_input_width * input_chars;
+ int input_height = font_input_height;
+
+ if (nr == MAIN_CONTROL_NAME)
+ {
+#if 0
+ if (menu.main.input.name.x == -1)
+ menu.main.input.name.x = menu.main.text.name.x + text_width;
+ if (menu.main.input.name.y == -1)
+ menu.main.input.name.y = menu.main.text.name.y;
+#endif
+
+#if 1
+ menu.main.input.name.width = input_width;
+ menu.main.input.name.height = input_height;
+#else
+ menu.main.input.name.width = font_input_width * MAX_PLAYER_NAME_LEN;
+ menu.main.input.name.height = font_input_height;
+#endif
+ }
+
+ if (pos_button != NULL)
+ {
+ if (pos_button->width == 0)
+ pos_button->width = button_width;
+ if (pos_button->height == 0)
+ pos_button->height = button_height;
+ }
+
+ if (pos_text != NULL)
+ {
+ /* calculate width for non-clickable text -- needed for text alignment */
+ boolean calculate_text_width = (pos_button == NULL && text != NULL);
+
+ if (pos_text->x == -1 && pos_button != NULL)
+ pos_text->x = pos_button->x + pos_button->width;
+ if (pos_text->y == -1 && pos_button != NULL)
+ pos_text->y = pos_button->y;
+
+ if (pos_text->width == -1 || calculate_text_width)
+ pos_text->width = text_width;
+ if (pos_text->height == -1)
+ pos_text->height = text_height;
+ }
+
+ if (pos_input != NULL)
+ {
+ if (pos_input->x == -1 && pos_text != NULL)
+ pos_input->x = pos_text->x + pos_text->width;
+ if (pos_input->y == -1 && pos_text != NULL)
+ pos_input->y = pos_text->y;
+
+ if (pos_input->width == -1)
+ pos_input->width = input_width;
+ if (pos_input->height == -1)
+ pos_input->height = input_height;
+ }
+ }
+}
+
+static void DrawCursorAndText_Main_Ext(int nr, boolean active_text,
+ boolean active_input)
+{
+ int i;
+
+ for (i = 0; main_controls[i].nr != -1; i++)
+ {
+ struct MainControlInfo *mci = &main_controls[i];
+
+ if (mci->nr == nr || nr == -1)
+ {
+ struct MenuPosInfo *pos_button = mci->pos_button;
+ struct TextPosInfo *pos_text = mci->pos_text;
+ struct MenuPosInfo *pos_input = mci->pos_input;
+ char *text = mci->text;
+ char *input = mci->input;
+ int button_graphic = mci->button_graphic;
+ int font_text = mci->font_text;
+ int font_input = mci->font_input;
+
+ if (active_text)
+ {
+ button_graphic = BUTTON_GRAPHIC_ACTIVE(button_graphic);
+ font_text = FONT_ACTIVE(font_text);
+ }
+
+ if (active_input)
+ {
+ font_input = FONT_ACTIVE(font_input);
+ }
+
+ if (pos_button != NULL)
+ {
+ struct MenuPosInfo *pos = pos_button;
+ int x = mSX + pos->x;
+ int y = mSY + pos->y;
+
+ DrawBackgroundForGraphic(x, y, pos->width, pos->height, button_graphic);
+ DrawGraphicThruMaskExt(drawto, x, y, button_graphic, 0);
+ }
+
+ if (pos_text != NULL && text != NULL)
+ {
+ struct TextPosInfo *pos = pos_text;
+ int x = mSX + ALIGNED_MENU_XPOS(pos);
+ int y = mSY + ALIGNED_MENU_YPOS(pos);
+
+ DrawBackgroundForFont(x, y, pos->width, pos->height, font_text);
+ DrawText(x, y, text, font_text);
+ }
+
+ if (pos_input != NULL && input != NULL)
+ {
+ struct MenuPosInfo *pos = pos_input;
+ int x = mSX + ALIGNED_MENU_XPOS(pos);
+ int y = mSY + ALIGNED_MENU_YPOS(pos);
+
+ DrawBackgroundForFont(x, y, pos->width, pos->height, font_input);
+ DrawText(x, y, input, font_input);
+ }
+ }
+ }
+}
+
+static void DrawCursorAndText_Main(int nr, boolean active_text)
+{
+ DrawCursorAndText_Main_Ext(nr, active_text, FALSE);
+}
+
+#if 0
+static void DrawCursorAndText_Main_Input(int nr, boolean active_text)
+{
+ DrawCursorAndText_Main_Ext(nr, active_text, TRUE);
+}
+#endif
+
+static struct MainControlInfo *getMainControlInfo(int nr)
+{
+ int i;
+
+ for (i = 0; main_controls[i].nr != -1; i++)
+ if (main_controls[i].nr == nr)
+ return &main_controls[i];
+
+ return NULL;
+}
+
+static boolean insideMenuPosRect(struct MenuPosInfo *rect, int x, int y)
+{
+ if (rect == NULL)
+ return FALSE;
+
+ int rect_x = ALIGNED_MENU_XPOS(rect);
+ int rect_y = ALIGNED_MENU_YPOS(rect);
+
+ return (x >= rect_x && x < rect_x + rect->width &&
+ y >= rect_y && y < rect_y + rect->height);
+}
+
+static boolean insideTextPosRect(struct TextPosInfo *rect, int x, int y)
+{
+ if (rect == NULL)
+ return FALSE;
+
+ int rect_x = ALIGNED_MENU_XPOS(rect);
+ int rect_y = ALIGNED_MENU_YPOS(rect);
+
+ return (x >= rect_x && x < rect_x + rect->width &&
+ y >= rect_y && y < rect_y + rect->height);
+}
+
+static void drawCursorExt(int xpos, int ypos, boolean active, int graphic)