X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fscreens.c;h=cb979767cbd2360bbeaddcefc1b4493bd668004b;hb=957e1f3bce8fd0bfa083e5932d27a2298478020e;hp=e8e4133f76551431deb3d3527b217fa03cdb78d1;hpb=509ca8448453d677028c6e690d267926e81730ac;p=rocksndiamonds.git diff --git a/src/screens.c b/src/screens.c index e8e4133f..cb979767 100644 --- a/src/screens.c +++ b/src/screens.c @@ -60,20 +60,21 @@ /* sub-screens on the setup screen (specific) */ #define SETUP_MODE_CHOOSE_GAME_SPEED 16 #define SETUP_MODE_CHOOSE_SCROLL_DELAY 17 -#define SETUP_MODE_CHOOSE_SCREEN_MODE 18 -#define SETUP_MODE_CHOOSE_WINDOW_SIZE 19 -#define SETUP_MODE_CHOOSE_SCALING_TYPE 20 -#define SETUP_MODE_CHOOSE_GRAPHICS 21 -#define SETUP_MODE_CHOOSE_SOUNDS 22 -#define SETUP_MODE_CHOOSE_MUSIC 23 -#define SETUP_MODE_CHOOSE_VOLUME_SIMPLE 24 -#define SETUP_MODE_CHOOSE_VOLUME_LOOPS 25 -#define SETUP_MODE_CHOOSE_VOLUME_MUSIC 26 -#define SETUP_MODE_CHOOSE_TOUCH_CONTROL 27 -#define SETUP_MODE_CHOOSE_MOVE_DISTANCE 28 -#define SETUP_MODE_CHOOSE_DROP_DISTANCE 29 - -#define MAX_SETUP_MODES 30 +#define SETUP_MODE_CHOOSE_SNAPSHOT_MODE 18 +#define SETUP_MODE_CHOOSE_SCREEN_MODE 19 +#define SETUP_MODE_CHOOSE_WINDOW_SIZE 20 +#define SETUP_MODE_CHOOSE_SCALING_TYPE 21 +#define SETUP_MODE_CHOOSE_GRAPHICS 22 +#define SETUP_MODE_CHOOSE_SOUNDS 23 +#define SETUP_MODE_CHOOSE_MUSIC 24 +#define SETUP_MODE_CHOOSE_VOLUME_SIMPLE 25 +#define SETUP_MODE_CHOOSE_VOLUME_LOOPS 26 +#define SETUP_MODE_CHOOSE_VOLUME_MUSIC 27 +#define SETUP_MODE_CHOOSE_TOUCH_CONTROL 28 +#define SETUP_MODE_CHOOSE_MOVE_DISTANCE 29 +#define SETUP_MODE_CHOOSE_DROP_DISTANCE 30 + +#define MAX_SETUP_MODES 31 /* for input setup functions */ #define SETUPINPUT_SCREEN_POS_START 0 @@ -97,9 +98,15 @@ MENU_SCREEN_INFO_YSTART2 - \ TILEY / 2) #define MAX_INFO_ELEMENTS_ON_SCREEN 128 -#define NUM_INFO_ELEMENTS_ON_SCREEN MIN(MENU_SCREEN_INFO_YSIZE / \ - MENU_SCREEN_INFO_YSTEP, \ - MAX_INFO_ELEMENTS_ON_SCREEN) +#define STD_INFO_ELEMENTS_ON_SCREEN (MENU_SCREEN_INFO_YSIZE / \ + MENU_SCREEN_INFO_YSTEP) +#define NUM_INFO_ELEMENTS_FROM_CONF \ + (menu.list_size_info[GFX_SPECIAL_ARG_INFO_ELEMENTS] > 0 ? \ + menu.list_size_info[GFX_SPECIAL_ARG_INFO_ELEMENTS] : \ + MAX_MENU_ENTRIES_ON_SCREEN) +#define NUM_INFO_ELEMENTS_ON_SCREEN MIN(MIN(STD_INFO_ELEMENTS_ON_SCREEN, \ + MAX_INFO_ELEMENTS_ON_SCREEN), \ + NUM_INFO_ELEMENTS_FROM_CONF) #define MAX_MENU_ENTRIES_ON_SCREEN (SCR_FIELDY - MENU_SCREEN_START_YPOS) #define MAX_MENU_TEXT_LENGTH_BIG 13 #define MAX_MENU_TEXT_LENGTH_MEDIUM (MAX_MENU_TEXT_LENGTH_BIG * 2) @@ -201,6 +208,9 @@ static TreeInfo *scaling_type_current = NULL; static TreeInfo *scroll_delays = NULL; static TreeInfo *scroll_delay_current = NULL; +static TreeInfo *snapshot_modes = NULL; +static TreeInfo *snapshot_mode_current = NULL; + static TreeInfo *game_speeds = NULL; static TreeInfo *game_speed_current = NULL; @@ -310,6 +320,19 @@ static struct { -1, NULL }, }; +static struct +{ + char *value; + char *text; +} snapshot_modes_list[] = +{ + { STR_SNAPSHOT_MODE_OFF, "Off" }, + { STR_SNAPSHOT_MODE_EVERY_STEP, "Every Step" }, + { STR_SNAPSHOT_MODE_EVERY_MOVE, "Every Move" }, + + { NULL, NULL }, +}; + static struct { int value; @@ -487,9 +510,6 @@ static char *main_text_level_year = NULL; static char *main_text_level_imported_from = NULL; static char *main_text_level_imported_by = NULL; static char *main_text_level_tested_by = NULL; -static char *main_text_title_1 = PROGRAM_TITLE_STRING; -static char *main_text_title_2 = PROGRAM_COPYRIGHT_STRING; -static char *main_text_title_3 = PROGRAM_GAME_BY_STRING; struct MainControlInfo { @@ -639,19 +659,19 @@ static struct MainControlInfo main_controls[] = { MAIN_CONTROL_TITLE_1, NULL, -1, - &menu.main.text.title_1, &main_text_title_1, + &menu.main.text.title_1, &setup.internal.program_title, NULL, NULL, }, { MAIN_CONTROL_TITLE_2, NULL, -1, - &menu.main.text.title_2, &main_text_title_2, + &menu.main.text.title_2, &setup.internal.program_copyright, NULL, NULL, }, { MAIN_CONTROL_TITLE_3, NULL, -1, - &menu.main.text.title_3, &main_text_title_3, + &menu.main.text.title_3, &setup.internal.program_company, NULL, NULL, }, @@ -1148,6 +1168,38 @@ static boolean insideTextPosRect(struct TextPosInfo *rect, int x, int y) y >= rect_y && y < rect_y + rect->height); } +static void AdjustScrollbar(int id, int items_max, int items_visible, + int item_position) +{ + struct GadgetInfo *gi = screen_gadget[id]; + + if (item_position > items_max - items_visible) + item_position = items_max - items_visible; + + ModifyGadget(gi, GDI_SCROLLBAR_ITEMS_MAX, items_max, + GDI_SCROLLBAR_ITEMS_VISIBLE, items_visible, + GDI_SCROLLBAR_ITEM_POSITION, item_position, GDI_END); +} + +static void AdjustChooseTreeScrollbar(int id, int first_entry, TreeInfo *ti) +{ + AdjustScrollbar(id, numTreeInfoInGroup(ti), NUM_MENU_ENTRIES_ON_SCREEN, + first_entry); +} + +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 > SX + SC_SCROLLBAR_XPOS) + scrollbar_xpos = SX + SC_SCROLLBAR_XPOS; + + /* clear menu list area, but not title or scrollbar */ + DrawBackground(mSX, mSY + MENU_SCREEN_START_YPOS * 32, + scrollbar_xpos - mSX, NUM_MENU_ENTRIES_ON_SCREEN * 32); +} + static void drawCursorExt(int xpos, int ypos, boolean active, int graphic) { static int cursor_array[MAX_LEV_FIELDY]; @@ -1195,8 +1247,9 @@ static void drawChooseTreeCursor(int ypos, boolean active) void DrawHeadline() { - DrawTextSCentered(MENU_TITLE1_YPOS, FONT_TITLE_1, PROGRAM_TITLE_STRING); - DrawTextSCentered(MENU_TITLE2_YPOS, FONT_TITLE_2, PROGRAM_COPYRIGHT_STRING); + DrawTextSCentered(MENU_TITLE1_YPOS, FONT_TITLE_1, getProgramTitleString()); + DrawTextSCentered(MENU_TITLE2_YPOS, FONT_TITLE_2, + setup.internal.program_copyright); } int effectiveGameStatus() @@ -1456,11 +1509,11 @@ void DrawMainMenu() DrawMainMenuExt(REDRAW_ALL, FALSE); } -#if defined(CREATE_SPECIAL_EDITION_RND_JUE) static void gotoTopLevelDir() { - /* move upwards to top level directory */ - while (leveldir_current->node_parent) + /* move upwards until inside (but not above) top level directory */ + while (leveldir_current->node_parent && + !strEqual(leveldir_current->node_parent->subdir, STRING_TOP_DIRECTORY)) { /* write a "path" into level tree for easy navigation to last level */ if (leveldir_current->node_parent->node_group->cl_first == -1) @@ -1485,7 +1538,6 @@ static void gotoTopLevelDir() leveldir_current = leveldir_current->node_parent; } } -#endif void HandleTitleScreen(int mx, int my, int dx, int dy, int button) { @@ -1747,7 +1799,14 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) button_pressed = TRUE; if (button_pressed != button_pressed_last) + { DrawCursorAndText_Main(choice, TRUE, button_pressed); + + if (button_pressed) + PlaySound(SND_MENU_BUTTON_PRESSING); + else + PlaySound(SND_MENU_BUTTON_RELEASING); + } } else if (dx || dy) /* keyboard input */ { @@ -1811,9 +1870,8 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) SaveLevelSetup_LastSeries(); SaveLevelSetup_SeriesInfo(); -#if defined(CREATE_SPECIAL_EDITION_RND_JUE) - gotoTopLevelDir(); -#endif + if (setup.internal.choose_from_top_leveldir) + gotoTopLevelDir(); ChangeViewportPropertiesIfNeeded(); @@ -1884,7 +1942,8 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) /* ========================================================================= */ static struct TokenInfo *info_info; -static int num_info_info; +static int num_info_info; /* number of info entries shown on screen */ +static int max_info_info; /* total number of info entries in list */ static void execInfoTitleScreen() { @@ -1957,19 +2016,54 @@ static struct TokenInfo info_info_main[] = { 0, NULL, NULL } }; -static void DrawCursorAndText_Info(int pos, boolean active) +static void DrawCursorAndText_Info(int screen_pos, int info_info_pos_raw, + boolean active) { + int ii_pos = (info_info_pos_raw < 0 ? screen_pos : info_info_pos_raw); + struct TokenInfo *ii = &info_info[ii_pos]; int xpos = MENU_SCREEN_START_XPOS; - int ypos = MENU_SCREEN_START_YPOS + pos; + int ypos = MENU_SCREEN_START_YPOS + screen_pos; int font_nr = FONT_MENU_1; if (active) font_nr = FONT_ACTIVE(font_nr); - DrawText(mSX + xpos * 32, mSY + ypos * 32, info_info[pos].text, font_nr); + DrawText(mSX + xpos * 32, mSY + ypos * 32, ii->text, font_nr); + + if (ii->type & ~TYPE_SKIP_ENTRY) + drawCursor(screen_pos, active); +} + +static void drawInfoInfoList(struct TokenInfo *info_info, + int first_entry, int num_page_entries) +{ + int i; + + if (num_page_entries > NUM_MENU_ENTRIES_ON_SCREEN) + num_page_entries = NUM_MENU_ENTRIES_ON_SCREEN; + + if (num_page_entries > max_info_info) + num_page_entries = max_info_info; + + if (first_entry + num_page_entries > max_info_info) + first_entry = 0; + + clearMenuListArea(); - if (info_info[pos].type & ~TYPE_SKIP_ENTRY) - drawCursor(pos, active); + for (i = 0; i < num_page_entries; i++) + { + int info_info_pos = first_entry + i; + struct TokenInfo *ii = &info_info[info_info_pos]; + + if (ii->type & (TYPE_ENTER_MENU|TYPE_ENTER_LIST)) + initCursor(i, IMG_MENU_BUTTON_ENTER_MENU); + else if (ii->type & (TYPE_LEAVE_MENU|TYPE_LEAVE_LIST)) + initCursor(i, IMG_MENU_BUTTON_LEAVE_MENU); + else if (ii->type & ~TYPE_SKIP_ENTRY) + initCursor(i, IMG_MENU_BUTTON); + + DrawCursorAndText_Info(i, info_info_pos, FALSE); + } } static void DrawInfoScreen_Main(int fade_mask, boolean do_fading) @@ -1977,6 +2071,10 @@ static void DrawInfoScreen_Main(int fade_mask, boolean do_fading) int i; UnmapAllGadgets(); + + FreeScreenGadgets(); + CreateScreenGadgets(); + CloseDoor(DOOR_CLOSE_2); /* (needed after displaying title screens which disable auto repeat) */ @@ -1998,24 +2096,21 @@ static void DrawInfoScreen_Main(int fade_mask, boolean do_fading) DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, "Info Screen"); info_info = info_info_main; - num_info_info = 0; + // determine maximal number of info entries that can be displayed on screen + num_info_info = 0; for (i = 0; info_info[i].type != 0 && i < MAX_MENU_ENTRIES_ON_SCREEN; i++) - { - if (info_info[i].type & (TYPE_ENTER_MENU|TYPE_ENTER_LIST)) - initCursor(i, IMG_MENU_BUTTON_ENTER_MENU); - else if (info_info[i].type & (TYPE_LEAVE_MENU|TYPE_LEAVE_LIST)) - initCursor(i, IMG_MENU_BUTTON_LEAVE_MENU); - else if (info_info[i].type & ~TYPE_SKIP_ENTRY) - initCursor(i, IMG_MENU_BUTTON); - - DrawCursorAndText_Info(i, FALSE); - num_info_info++; - } + + // determine maximal number of info entries available for menu of info screen + max_info_info = 0; + for (i = 0; info_info[i].type != 0; i++) + max_info_info++; HandleInfoScreen_Main(0, 0, 0, 0, MB_MENU_INITIALIZE); + MapScreenGadgets(max_info_info); + PlayMenuSound(); PlayMenuMusic(); @@ -2029,19 +2124,69 @@ static void DrawInfoScreen_Main(int fade_mask, boolean do_fading) 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 */ + static int first_entry_store[MAX_INFO_MODES]; + static int num_page_entries_last = 0; + int choice = choice_store[info_mode]; /* starts with 0 */ + int first_entry = first_entry_store[info_mode]; /* starts with 0 */ int x = 0; - int y = choice; + int y = choice - first_entry; + int y_old = y; + boolean position_set_by_scrollbar = (dx == 999); + int step = (button == 1 ? 1 : button == 2 ? 5 : 10); + int num_page_entries; + + num_page_entries = MIN(max_info_info, NUM_MENU_ENTRIES_ON_SCREEN); if (button == MB_MENU_INITIALIZE) { + // check if number of menu page entries has changed (may happen by change + // of custom artwork definition value for 'list_size' for this menu screen) + // (in this case, the last menu position most probably has to be corrected) + if (num_page_entries != num_page_entries_last) + { + int i; + + for (i = 0; i < MAX_INFO_MODES; i++) + choice_store[i] = first_entry_store[i] = 0; + + num_page_entries_last = num_page_entries; + + HandleInfoScreen_Main(mx, my, dx, dy, button); + + return; + } + /* advance to first valid menu entry */ while (choice < num_info_info && info_info[choice].type & TYPE_SKIP_ENTRY) choice++; + + if (position_set_by_scrollbar) + first_entry = first_entry_store[info_mode] = dy; + else + AdjustScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL, max_info_info, + NUM_MENU_ENTRIES_ON_SCREEN, first_entry); + + drawInfoInfoList(info_info, first_entry, NUM_MENU_ENTRIES_ON_SCREEN); + + if (choice < first_entry) + { + choice = first_entry; + + if (info_info[choice].type & TYPE_SKIP_ENTRY) + choice++; + } + else if (choice > first_entry + num_page_entries - 1) + { + choice = first_entry + num_page_entries - 1; + + if (info_info[choice].type & TYPE_SKIP_ENTRY) + choice--; + } + choice_store[info_mode] = choice; - DrawCursorAndText_Info(choice, TRUE); + DrawCursorAndText_Info(choice - first_entry, choice, TRUE); return; } @@ -2069,51 +2214,165 @@ void HandleInfoScreen_Main(int mx, int my, int dx, int dy, int button) x = (mx - mSX) / 32; y = (my - mSY) / 32 - MENU_SCREEN_START_YPOS; } - else if (dx || dy) /* keyboard input */ + else if (dx || dy) /* keyboard or scrollbar/scrollbutton input */ { + /* move cursor instead of scrolling when already at start/end of list */ + if (dy == -1 * SCROLL_LINE && first_entry == 0) + dy = -1; + else if (dy == +1 * SCROLL_LINE && + first_entry + num_page_entries == max_info_info) + dy = 1; + + /* handle scrolling screen one line or page */ + if (y + dy < 0 || + y + dy > num_page_entries - 1) + { + boolean redraw = FALSE; + + if (ABS(dy) == SCROLL_PAGE) + step = num_page_entries - 1; + + if (dy < 0 && first_entry > 0) + { + /* scroll page/line up */ + + first_entry -= step; + if (first_entry < 0) + first_entry = 0; + + redraw = TRUE; + } + else if (dy > 0 && first_entry + num_page_entries < max_info_info) + { + /* scroll page/line down */ + + first_entry += step; + if (first_entry + num_page_entries > max_info_info) + first_entry = MAX(0, max_info_info - num_page_entries); + + redraw = TRUE; + } + + if (redraw) + { + choice += first_entry - first_entry_store[info_mode]; + + if (choice < first_entry) + { + choice = first_entry; + + if (info_info[choice].type & TYPE_SKIP_ENTRY) + choice++; + } + else if (choice > first_entry + num_page_entries - 1) + { + choice = first_entry + num_page_entries - 1; + + if (info_info[choice].type & TYPE_SKIP_ENTRY) + choice--; + } + else if (info_info[choice].type & TYPE_SKIP_ENTRY) + { + choice += SIGN(dy); + + if (choice < first_entry || + choice > first_entry + num_page_entries - 1) + first_entry += SIGN(dy); + } + + first_entry_store[info_mode] = first_entry; + choice_store[info_mode] = choice; + + drawInfoInfoList(info_info, first_entry, NUM_MENU_ENTRIES_ON_SCREEN); + + DrawCursorAndText_Info(choice - first_entry, choice, TRUE); + + AdjustScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL, max_info_info, + NUM_MENU_ENTRIES_ON_SCREEN, first_entry); + } + + return; + } + if (dx) { int menu_navigation_type = (dx < 0 ? TYPE_LEAVE : TYPE_ENTER); if (info_info[choice].type & menu_navigation_type || - info_info[choice].type & TYPE_ENTER_SCREEN || info_info[choice].type & TYPE_BOOLEAN_STYLE || info_info[choice].type & TYPE_YES_NO_AUTO) button = MB_MENU_CHOICE; } else if (dy) - y = choice + dy; + y += 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) + while (first_entry + y > 0 && + first_entry + y < max_info_info - 1 && + info_info[first_entry + y].type & TYPE_SKIP_ENTRY) y += dy; + + if (!IN_VIS_MENU(x, y)) + { + choice += y - y_old; + + if (choice < first_entry) + first_entry = choice; + else if (choice > first_entry + num_page_entries - 1) + first_entry = choice - num_page_entries + 1; + + if (first_entry >= 0 && + first_entry + num_page_entries <= max_info_info) + { + first_entry_store[info_mode] = first_entry; + + if (choice < first_entry) + choice = first_entry; + else if (choice > first_entry + num_page_entries - 1) + choice = first_entry + num_page_entries - 1; + + choice_store[info_mode] = choice; + + drawInfoInfoList(info_info, first_entry, NUM_MENU_ENTRIES_ON_SCREEN); + + DrawCursorAndText_Info(choice - first_entry, choice, TRUE); + + AdjustScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL, max_info_info, + NUM_MENU_ENTRIES_ON_SCREEN, first_entry); + } + + return; + } } - if (IN_VIS_MENU(x, y) && - y >= 0 && y < num_info_info && info_info[y].type & ~TYPE_SKIP_ENTRY) + if (!anyScrollbarGadgetActive() && + IN_VIS_MENU(x, y) && + mx < screen_gadget[SCREEN_CTRL_ID_SCROLL_VERTICAL]->x && + y >= 0 && y < num_page_entries) { if (button) { - if (y != choice) + if (first_entry + y != choice && + info_info[first_entry + y].type & ~TYPE_SKIP_ENTRY) { PlaySound(SND_MENU_ITEM_ACTIVATING); - DrawCursorAndText_Info(choice, FALSE); - DrawCursorAndText_Info(y, TRUE); + DrawCursorAndText_Info(choice - first_entry, choice, FALSE); + DrawCursorAndText_Info(y, first_entry + y, TRUE); - choice = choice_store[info_mode] = y; + choice = choice_store[info_mode] = first_entry + y; } } - else if (!(info_info[y].type & TYPE_GHOSTED)) + else if (!(info_info[first_entry + y].type & TYPE_GHOSTED)) { PlaySound(SND_MENU_ITEM_SELECTING); - if (info_info[y].type & TYPE_ENTER_OR_LEAVE) + if (info_info[first_entry + y].type & TYPE_ENTER_OR_LEAVE) { - void (*menu_callback_function)(void) = info_info[choice].value; + void (*menu_callback_function)(void) = + info_info[first_entry + y].value; - FadeSetFromType(info_info[y].type); + FadeSetFromType(info_info[first_entry + y].type); menu_callback_function(); } @@ -2831,11 +3090,11 @@ void DrawInfoScreen_Program() DrawTextSCentered(ystart2 + 1 * ystep, FONT_TEXT_2, "If you like it, send e-mail to:"); DrawTextSCentered(ystart2 + 2 * ystep, FONT_TEXT_3, - PROGRAM_EMAIL_STRING); + setup.internal.program_email); DrawTextSCentered(ystart2 + 4 * ystep, FONT_TEXT_2, "More information and levels:"); DrawTextSCentered(ystart2 + 5 * ystep, FONT_TEXT_3, - PROGRAM_WEBSITE_STRING); + setup.internal.program_website); DrawTextSCentered(ystart2 + 7 * ystep, FONT_TEXT_2, "If you have created new levels,"); DrawTextSCentered(ystart2 + 8 * ystep, FONT_TEXT_2, @@ -2907,7 +3166,7 @@ void DrawInfoScreen_Version() DrawTextSCentered(ystart1, FONT_TEXT_1, "Version Information:"); DrawTextF(xstart1, ystart2, font_header, "Name"); - DrawTextF(xstart2, ystart2, font_text, PROGRAM_TITLE_STRING); + DrawTextF(xstart2, ystart2, font_text, getProgramTitleString()); ystart2 += ystep; DrawTextF(xstart1, ystart2, font_header, "Version"); @@ -3290,6 +3549,15 @@ static void DrawChooseTree(TreeInfo **ti_ptr) { int fade_mask = (DrawingAreaChanged() ? REDRAW_ALL : REDRAW_FIELD); + if (strEqual((*ti_ptr)->subdir, STRING_TOP_DIRECTORY)) + { + game_status = GAME_MODE_MAIN; + + DrawMainMenuExt(REDRAW_FIELD, FALSE); + + return; + } + UnmapAllGadgets(); FreeScreenGadgets(); @@ -3309,38 +3577,6 @@ static void DrawChooseTree(TreeInfo **ti_ptr) InitAnimation(); } -static void AdjustScrollbar(int id, int items_max, int items_visible, - int item_position) -{ - struct GadgetInfo *gi = screen_gadget[id]; - - if (item_position > items_max - items_visible) - item_position = items_max - items_visible; - - ModifyGadget(gi, GDI_SCROLLBAR_ITEMS_MAX, items_max, - GDI_SCROLLBAR_ITEMS_VISIBLE, items_visible, - GDI_SCROLLBAR_ITEM_POSITION, item_position, GDI_END); -} - -static void AdjustChooseTreeScrollbar(int id, int first_entry, TreeInfo *ti) -{ - AdjustScrollbar(id, numTreeInfoInGroup(ti), NUM_MENU_ENTRIES_ON_SCREEN, - first_entry); -} - -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 > SX + SC_SCROLLBAR_XPOS) - scrollbar_xpos = SX + SC_SCROLLBAR_XPOS; - - /* clear menu list area, but not title or scrollbar */ - DrawBackground(mSX, mSY + MENU_SCREEN_START_YPOS * 32, - scrollbar_xpos - mSX, NUM_MENU_ENTRIES_ON_SCREEN * 32); -} - static void drawChooseTreeList(int first_entry, int num_page_entries, TreeInfo *ti) { @@ -3425,7 +3661,7 @@ static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti) node->class_desc); /* let BackToFront() redraw only what is needed */ - redraw_mask = last_redraw_mask | REDRAW_TILES; + redraw_mask = last_redraw_mask; for (x = 0; x < SCR_FIELDX; x++) MarkTileDirty(x, 1); } @@ -3495,7 +3731,8 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, else if (game_status == GAME_MODE_SETUP) { if (setup_mode == SETUP_MODE_CHOOSE_GAME_SPEED || - setup_mode == SETUP_MODE_CHOOSE_SCROLL_DELAY) + setup_mode == SETUP_MODE_CHOOSE_SCROLL_DELAY || + setup_mode == SETUP_MODE_CHOOSE_SNAPSHOT_MODE) execSetupGame(); else if (setup_mode == SETUP_MODE_CHOOSE_SCREEN_MODE || setup_mode == SETUP_MODE_CHOOSE_WINDOW_SIZE || @@ -3587,7 +3824,6 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, ti->cl_first, ti); } - return; } @@ -3693,7 +3929,8 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, if (game_status == GAME_MODE_SETUP) { if (setup_mode == SETUP_MODE_CHOOSE_GAME_SPEED || - setup_mode == SETUP_MODE_CHOOSE_SCROLL_DELAY) + setup_mode == SETUP_MODE_CHOOSE_SCROLL_DELAY || + setup_mode == SETUP_MODE_CHOOSE_SNAPSHOT_MODE) execSetupGame(); else if (setup_mode == SETUP_MODE_CHOOSE_SCREEN_MODE || setup_mode == SETUP_MODE_CHOOSE_WINDOW_SIZE || @@ -3819,7 +4056,7 @@ void DrawHallOfFame(int highlight_position) SetDrawDeactivationMask(REDRAW_NONE); SetDrawBackgroundMask(REDRAW_FIELD); - CloseDoor(DOOR_CLOSE_2); + CloseDoor(DOOR_CLOSE_ALL); if (highlight_position < 0) LoadScore(level_nr); @@ -3956,6 +4193,7 @@ static char *screen_mode_text; static char *window_size_text; static char *scaling_type_text; static char *scroll_delay_text; +static char *snapshot_mode_text; static char *game_speed_text; static char *graphics_set_name; static char *sounds_set_name; @@ -4074,10 +4312,61 @@ static void execSetupGame_setScrollDelays() scroll_delay_text = scroll_delay_current->name; } +static void execSetupGame_setSnapshotModes() +{ + if (snapshot_modes == NULL) + { + int i; + + for (i = 0; snapshot_modes_list[i].value != NULL; i++) + { + TreeInfo *ti = newTreeInfo_setDefaults(TREE_TYPE_UNDEFINED); + char identifier[32], name[32]; + char *value = snapshot_modes_list[i].value; + char *text = snapshot_modes_list[i].text; + + ti->node_top = &snapshot_modes; + ti->sort_priority = i; + + sprintf(identifier, "%s", value); + sprintf(name, "%s", text); + + setString(&ti->identifier, identifier); + setString(&ti->name, name); + setString(&ti->name_sorting, name); + setString(&ti->infotext, "Snapshot Mode"); + + pushTreeInfo(&snapshot_modes, ti); + } + + /* sort snapshot mode values to start with lowest snapshot mode value */ + sortTreeInfo(&snapshot_modes); + + /* set current snapshot mode value to configured snapshot mode value */ + snapshot_mode_current = + getTreeInfoFromIdentifier(snapshot_modes, setup.engine_snapshot_mode); + + /* if that fails, set current snapshot mode to reliable default value */ + if (snapshot_mode_current == NULL) + snapshot_mode_current = + getTreeInfoFromIdentifier(snapshot_modes, STR_SNAPSHOT_MODE_DEFAULT); + + /* if that also fails, set current snapshot mode to first available value */ + if (snapshot_mode_current == NULL) + snapshot_mode_current = snapshot_modes; + } + + setup.engine_snapshot_mode = snapshot_mode_current->identifier; + + /* needed for displaying snapshot mode text instead of identifier */ + snapshot_mode_text = snapshot_mode_current->name; +} + static void execSetupGame() { execSetupGame_setGameSpeeds(); execSetupGame_setScrollDelays(); + execSetupGame_setSnapshotModes(); setup_mode = SETUP_MODE_GAME; @@ -4098,6 +4387,13 @@ static void execSetupChooseScrollDelay() DrawSetupScreen(); } +static void execSetupChooseSnapshotMode() +{ + setup_mode = SETUP_MODE_CHOOSE_SNAPSHOT_MODE; + + DrawSetupScreen(); +} + static void execSetupEditor() { setup_mode = SETUP_MODE_EDITOR; @@ -4911,6 +5207,8 @@ static struct TokenInfo setup_info_game[] = { TYPE_ENTER_LIST, execSetupChooseScrollDelay, "Scroll Delay:" }, { TYPE_STRING, &scroll_delay_text, "" }, #endif + { TYPE_ENTER_LIST, execSetupChooseSnapshotMode,"Game Engine Snapshot Mode:" }, + { TYPE_STRING, &snapshot_mode_text, "" }, { TYPE_EMPTY, NULL, "" }, { TYPE_LEAVE_MENU, execSetupMain, "Back" }, @@ -5544,6 +5842,7 @@ void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button) { static int choice_store[MAX_SETUP_MODES]; static int first_entry_store[MAX_SETUP_MODES]; + static int num_page_entries_last = 0; int choice = choice_store[setup_mode]; /* starts with 0 */ int first_entry = first_entry_store[setup_mode]; /* starts with 0 */ int x = 0; @@ -5557,6 +5856,23 @@ void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button) if (button == MB_MENU_INITIALIZE) { + // check if number of menu page entries has changed (may happen by change + // of custom artwork definition value for 'list_size' for this menu screen) + // (in this case, the last menu position most probably has to be corrected) + if (num_page_entries != num_page_entries_last) + { + int i; + + for (i = 0; i < MAX_INFO_MODES; i++) + choice_store[i] = first_entry_store[i] = 0; + + num_page_entries_last = num_page_entries; + + HandleSetupScreen_Generic(mx, my, dx, dy, button); + + return; + } + /* advance to first valid menu entry */ while (choice < num_setup_info && setup_info[choice].type & TYPE_SKIP_ENTRY) @@ -6426,6 +6742,8 @@ void DrawSetupScreen() DrawChooseTree(&game_speed_current); else if (setup_mode == SETUP_MODE_CHOOSE_SCROLL_DELAY) DrawChooseTree(&scroll_delay_current); + else if (setup_mode == SETUP_MODE_CHOOSE_SNAPSHOT_MODE) + DrawChooseTree(&snapshot_mode_current); else if (setup_mode == SETUP_MODE_CHOOSE_SCREEN_MODE) DrawChooseTree(&screen_mode_current); else if (setup_mode == SETUP_MODE_CHOOSE_WINDOW_SIZE) @@ -6477,6 +6795,8 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button) HandleChooseTree(mx, my, dx, dy, button, &game_speed_current); else if (setup_mode == SETUP_MODE_CHOOSE_SCROLL_DELAY) HandleChooseTree(mx, my, dx, dy, button, &scroll_delay_current); + else if (setup_mode == SETUP_MODE_CHOOSE_SNAPSHOT_MODE) + HandleChooseTree(mx, my, dx, dy, button, &snapshot_mode_current); else if (setup_mode == SETUP_MODE_CHOOSE_SCREEN_MODE) HandleChooseTree(mx, my, dx, dy, button, &screen_mode_current); else if (setup_mode == SETUP_MODE_CHOOSE_WINDOW_SIZE) @@ -6908,6 +7228,8 @@ static void HandleScreenGadgets(struct GadgetInfo *gi) HandleChooseLevelNr(0,0, 0, -1 * SCROLL_LINE, MB_MENU_MARK); else if (game_status == GAME_MODE_SETUP) HandleSetupScreen(0,0, 0, -1 * SCROLL_LINE, MB_MENU_MARK); + else if (game_status == GAME_MODE_INFO) + HandleInfoScreen(0,0, 0, -1 * SCROLL_LINE, MB_MENU_MARK); break; case SCREEN_CTRL_ID_SCROLL_DOWN: @@ -6917,6 +7239,8 @@ static void HandleScreenGadgets(struct GadgetInfo *gi) HandleChooseLevelNr(0,0, 0, +1 * SCROLL_LINE, MB_MENU_MARK); else if (game_status == GAME_MODE_SETUP) HandleSetupScreen(0,0, 0, +1 * SCROLL_LINE, MB_MENU_MARK); + else if (game_status == GAME_MODE_INFO) + HandleInfoScreen(0,0, 0, +1 * SCROLL_LINE, MB_MENU_MARK); break; case SCREEN_CTRL_ID_SCROLL_VERTICAL: @@ -6926,6 +7250,8 @@ static void HandleScreenGadgets(struct GadgetInfo *gi) HandleChooseLevelNr(0,0,999,gi->event.item_position,MB_MENU_INITIALIZE); else if (game_status == GAME_MODE_SETUP) HandleSetupScreen(0,0, 999,gi->event.item_position,MB_MENU_INITIALIZE); + else if (game_status == GAME_MODE_INFO) + HandleInfoScreen(0,0, 999,gi->event.item_position,MB_MENU_INITIALIZE); break; default: