X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fscreens.c;h=9c02fc9e3a7f697a1792f00656d9e77d3de7b393;hp=264617545eca10292faeeebe26e54864e5dcefcb;hb=5c6c42f1;hpb=c3fa9fcf03db2a48bbd8fa343b79a94c42d4cac3 diff --git a/src/screens.c b/src/screens.c index 26461754..9c02fc9e 100644 --- a/src/screens.c +++ b/src/screens.c @@ -18,11 +18,15 @@ #include "editor.h" #include "files.h" #include "tape.h" -#include "cartoons.h" +#include "anim.h" #include "network.h" #include "init.h" #include "config.h" + +#define DEBUG_JOYSTICKS 0 + + /* screens on the info screen */ #define INFO_MODE_MAIN 0 #define INFO_MODE_TITLE 1 @@ -61,9 +65,9 @@ #define SETUP_MODE_CHOOSE_GAME_SPEED 16 #define SETUP_MODE_CHOOSE_SCROLL_DELAY 17 #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_WINDOW_SIZE 19 +#define SETUP_MODE_CHOOSE_SCALING_TYPE 20 +#define SETUP_MODE_CHOOSE_RENDERING 21 #define SETUP_MODE_CHOOSE_GRAPHICS 22 #define SETUP_MODE_CHOOSE_SOUNDS 23 #define SETUP_MODE_CHOOSE_MUSIC 24 @@ -84,6 +88,9 @@ #define SETUPINPUT_SCREEN_POS_EMPTY1 (SETUPINPUT_SCREEN_POS_START + 3) #define SETUPINPUT_SCREEN_POS_EMPTY2 (SETUPINPUT_SCREEN_POS_END - 1) +#define MENU_SETUP_FONT_TITLE FONT_TEXT_1 +#define MENU_SETUP_FONT_TEXT FONT_TITLE_2 + /* for various menu stuff */ #define MENU_SCREEN_START_XPOS 1 #define MENU_SCREEN_START_YPOS 2 @@ -91,9 +98,16 @@ #define MENU_SCREEN_MAX_XPOS (SCR_FIELDX - 1) #define MENU_TITLE1_YPOS 8 #define MENU_TITLE2_YPOS 46 +#define MENU_INFO_FONT_TITLE FONT_TEXT_1 +#define MENU_INFO_FONT_HEAD FONT_TEXT_2 +#define MENU_INFO_FONT_TEXT FONT_TEXT_3 +#define MENU_INFO_FONT_FOOT FONT_TEXT_4 +#define MENU_INFO_SPACE_HEAD (menu.headline2_spacing_info[info_mode]) #define MENU_SCREEN_INFO_XSTART 16 #define MENU_SCREEN_INFO_YSTART1 100 -#define MENU_SCREEN_INFO_YSTART2 128 +#define MENU_SCREEN_INFO_YSTART2 (MENU_SCREEN_INFO_YSTART1 + \ + getMenuTextStep(MENU_INFO_SPACE_HEAD, \ + MENU_INFO_FONT_TITLE)) #define MENU_SCREEN_INFO_YSTEP (TILEY + 4) #define MENU_SCREEN_INFO_YBOTTOM (SYSIZE - 20) #define MENU_SCREEN_INFO_YSIZE (MENU_SCREEN_INFO_YBOTTOM - \ @@ -163,7 +177,7 @@ static void HandleScreenGadgets(struct GadgetInfo *); static void HandleSetupScreen_Generic(int, int, int, int, int); static void HandleSetupScreen_Input(int, int, int, int, int); static void CustomizeKeyboard(int); -static void CalibrateJoystick(int); +static void ConfigureJoystick(int); static void execSetupGame(void); static void execSetupGraphics(void); static void execSetupSound(void); @@ -196,15 +210,15 @@ static struct GadgetInfo *screen_gadget[NUM_SCREEN_GADGETS]; static int info_mode = INFO_MODE_MAIN; static int setup_mode = SETUP_MODE_MAIN; -static TreeInfo *screen_modes = NULL; -static TreeInfo *screen_mode_current = NULL; - static TreeInfo *window_sizes = NULL; static TreeInfo *window_size_current = NULL; static TreeInfo *scaling_types = NULL; static TreeInfo *scaling_type_current = NULL; +static TreeInfo *rendering_modes = NULL; +static TreeInfo *rendering_mode_current = NULL; + static TreeInfo *scroll_delays = NULL; static TreeInfo *scroll_delay_current = NULL; @@ -270,6 +284,23 @@ static struct { NULL, NULL }, }; +static struct +{ + char *value; + char *text; +} rendering_modes_list[] = +{ + { STR_SPECIAL_RENDERING_OFF, "Off (May show artifacts, fast)" }, + { STR_SPECIAL_RENDERING_BITMAP, "Bitmap/Texture mode (slower)" }, +#if DEBUG + // this mode may work under certain conditions, but does not work on Windows + { STR_SPECIAL_RENDERING_TARGET, "Target Texture mode (slower)" }, +#endif + { STR_SPECIAL_RENDERING_DOUBLE, "Double Texture mode (slower)" }, + + { NULL, NULL }, +}; + static struct { int value; @@ -326,11 +357,12 @@ static struct char *text; } snapshot_modes_list[] = { - { STR_SNAPSHOT_MODE_OFF, "Off" }, - { STR_SNAPSHOT_MODE_EVERY_STEP, "Every Step" }, - { STR_SNAPSHOT_MODE_EVERY_MOVE, "Every Move" }, + { STR_SNAPSHOT_MODE_OFF, "Off" }, + { STR_SNAPSHOT_MODE_EVERY_STEP, "Every Step" }, + { STR_SNAPSHOT_MODE_EVERY_MOVE, "Every Move" }, + { STR_SNAPSHOT_MODE_EVERY_COLLECT, "Every Collect" }, - { NULL, NULL }, + { NULL, NULL }, }; static struct @@ -365,6 +397,7 @@ static struct { { TOUCH_CONTROL_VIRTUAL_BUTTONS, "Virtual Buttons" }, { TOUCH_CONTROL_WIPE_GESTURES, "Wipe Gestures" }, + { TOUCH_CONTROL_FOLLOW_FINGER, "Follow Finger" }, { NULL, NULL }, }; @@ -394,7 +427,7 @@ static struct GAME_MODE_MAIN : GAME_MODE_DEFAULT) /* (there are no draw offset definitions needed for INFO_MODE_TITLE) */ -#define DRAW_MODE_INFO(i) ((i) >= INFO_MODE_ELEMENTS && \ +#define DRAW_MODE_INFO(i) ((i) >= INFO_MODE_TITLE && \ (i) <= INFO_MODE_LEVELSET ? (i) : \ INFO_MODE_MAIN) @@ -411,6 +444,9 @@ static struct #define DRAW_YOFFSET_INFO(i) (DRAW_MODE_INFO(i) == INFO_MODE_MAIN ? \ menu.draw_yoffset[GAME_MODE_INFO] : \ menu.draw_yoffset_info[DRAW_MODE_INFO(i)]) +#define EXTRA_SPACING_INFO(i) (DRAW_MODE_INFO(i) == INFO_MODE_MAIN ? \ + menu.extra_spacing[GAME_MODE_INFO] : \ + menu.extra_spacing_info[DRAW_MODE_INFO(i)]) #define DRAW_XOFFSET_SETUP(i) (DRAW_MODE_SETUP(i) == SETUP_MODE_MAIN ? \ menu.draw_xoffset[GAME_MODE_SETUP] : \ @@ -418,6 +454,9 @@ static struct #define DRAW_YOFFSET_SETUP(i) (DRAW_MODE_SETUP(i) == SETUP_MODE_MAIN ? \ menu.draw_yoffset[GAME_MODE_SETUP] : \ menu.draw_yoffset_setup[DRAW_MODE_SETUP(i)]) +#define EXTRA_SPACING_SETUP(i) (DRAW_MODE_SETUP(i) == SETUP_MODE_MAIN ? \ + menu.extra_spacing[GAME_MODE_SETUP] : \ + menu.extra_spacing_setup[DRAW_MODE_SETUP(i)]) #define DRAW_XOFFSET(s) ((s) == GAME_MODE_INFO ? \ DRAW_XOFFSET_INFO(info_mode) : \ @@ -429,6 +468,11 @@ static struct (s) == GAME_MODE_SETUP ? \ DRAW_YOFFSET_SETUP(setup_mode) : \ menu.draw_yoffset[DRAW_MODE(s)]) +#define EXTRA_SPACING(s) ((s) == GAME_MODE_INFO ? \ + EXTRA_SPACING_INFO(info_mode) : \ + (s) == GAME_MODE_SETUP ? \ + EXTRA_SPACING_SETUP(setup_mode) : \ + menu.extra_spacing[DRAW_MODE(s)]) #define mSX (SX + DRAW_XOFFSET(game_status)) #define mSY (SY + DRAW_YOFFSET(game_status)) @@ -455,6 +499,7 @@ struct TitleControlInfo { boolean is_image; boolean initial; + boolean first; int local_nr; int sort_priority; }; @@ -706,6 +751,13 @@ static int getTitleMessageGameMode(boolean initial) return (initial ? GAME_MODE_TITLE_INITIAL : GAME_MODE_TITLE); } +static int getTitleAnimMode(struct TitleControlInfo *tci) +{ + int base = (tci->initial ? GAME_MODE_TITLE_INITIAL_1 : GAME_MODE_TITLE_1); + + return base + tci->local_nr; +} + #if 0 static int getTitleScreenBackground(boolean initial) { @@ -803,44 +855,29 @@ static int getTitleMusic(struct TitleControlInfo *tci) static struct TitleFadingInfo getTitleFading(struct TitleControlInfo *tci) { boolean is_image = tci->is_image; - int initial = tci->initial; + boolean initial = tci->initial; + boolean first = tci->first; int nr = tci->local_nr; + struct TitleMessageInfo tmi; struct TitleFadingInfo ti; - if (is_image) - { - int graphic = getTitleScreenGraphic(nr, initial); - - /* initialize fading control values to default title config settings */ - ti = (initial ? title_initial_default : title_default); - - /* override default settings with image config settings, if defined */ - if (graphic_info[graphic].fade_mode != FADE_MODE_DEFAULT) - ti.fade_mode = graphic_info[graphic].fade_mode; - if (graphic_info[graphic].fade_delay > -1) - ti.fade_delay = graphic_info[graphic].fade_delay; - if (graphic_info[graphic].post_delay > -1) - ti.post_delay = graphic_info[graphic].post_delay; - if (graphic_info[graphic].auto_delay > -1) - ti.auto_delay = graphic_info[graphic].auto_delay; - } - else - { - if (initial) - { - ti.fade_mode = titlemessage_initial[nr].fade_mode; - ti.fade_delay = titlemessage_initial[nr].fade_delay; - ti.post_delay = titlemessage_initial[nr].post_delay; - ti.auto_delay = titlemessage_initial[nr].auto_delay; - } - else - { - ti.fade_mode = titlemessage[nr].fade_mode; - ti.fade_delay = titlemessage[nr].fade_delay; - ti.post_delay = titlemessage[nr].post_delay; - ti.auto_delay = titlemessage[nr].auto_delay; - } - } + tmi = (is_image ? (initial ? (first ? + titlescreen_initial_first[nr] : + titlescreen_initial[nr]) + : (first ? + titlescreen_first[nr] : + titlescreen[nr])) + : (initial ? (first ? + titlemessage_initial_first[nr] : + titlemessage_initial[nr]) + : (first ? + titlemessage_first[nr] : + titlemessage[nr]))); + + ti.fade_mode = tmi.fade_mode; + ti.fade_delay = tmi.fade_delay; + ti.post_delay = tmi.post_delay; + ti.auto_delay = tmi.auto_delay; return ti; } @@ -872,6 +909,8 @@ static void InitializeTitleControlsExt_AddTitleInfo(boolean is_image, title_controls[num_title_screens].local_nr = nr; title_controls[num_title_screens].sort_priority = sort_priority; + title_controls[num_title_screens].first = FALSE; /* will be set later */ + num_title_screens++; } @@ -914,6 +953,9 @@ static void InitializeTitleControls(boolean show_title_initial) /* sort title screens according to sort_priority and title number */ qsort(title_controls, num_title_screens, sizeof(struct TitleControlInfo), compareTitleControlInfo); + + /* mark first title screen */ + title_controls[0].first = TRUE; } static boolean visibleMenuPos(struct MenuPosInfo *pos) @@ -1168,6 +1210,17 @@ static boolean insideTextPosRect(struct TextPosInfo *rect, int x, int y) y >= rect_y && y < rect_y + rect->height); } +static boolean insidePreviewRect(struct PreviewInfo *preview, int x, int y) +{ + int rect_width = preview->xsize * preview->tile_size; + int rect_height = preview->ysize * preview->tile_size; + int rect_x = ALIGNED_XPOS(preview->x, rect_width, preview->align); + int rect_y = ALIGNED_YPOS(preview->y, rect_height, preview->valign); + + return (x >= rect_x && x < rect_x + rect_width && + y >= rect_y && y < rect_y + rect_height); +} + static void AdjustScrollbar(int id, int items_max, int items_visible, int item_position) { @@ -1238,11 +1291,7 @@ static void drawCursorXY(int xpos, int ypos, int graphic) static void drawChooseTreeCursor(int ypos, boolean active) { - int last_game_status = game_status; /* save current game status */ - drawCursorExt(0, ypos, active, -1); - - game_status = last_game_status; /* restore current game status */ } void DrawHeadline() @@ -1252,14 +1301,6 @@ void DrawHeadline() setup.internal.program_copyright); } -int effectiveGameStatus() -{ - if (game_status == GAME_MODE_INFO && info_mode == INFO_MODE_TITLE) - return GAME_MODE_TITLE; - - return game_status; -} - void DrawTitleScreenImage(int nr, boolean initial) { int graphic = getTitleScreenGraphic(nr, initial); @@ -1308,13 +1349,20 @@ void DrawTitleScreenMessage(int nr, boolean initial) { char *filename = getLevelSetTitleMessageFilename(nr, initial); struct TitleMessageInfo *tmi = getTitleMessageInfo(nr, initial); - int last_game_status = game_status; /* save current game status */ if (filename == NULL) return; /* force TITLE font on title message screen */ - game_status = getTitleMessageGameMode(initial); + SetFontStatus(getTitleMessageGameMode(initial)); + + /* if chars *and* width set to "-1", automatically determine width */ + if (tmi->chars == -1 && tmi->width == -1) + tmi->width = viewport.window[game_status].width; + + /* if lines *and* height set to "-1", automatically determine height */ + if (tmi->lines == -1 && tmi->height == -1) + tmi->height = viewport.window[game_status].height; /* if chars set to "-1", automatically determine by text and font width */ if (tmi->chars == -1) @@ -1328,6 +1376,14 @@ void DrawTitleScreenMessage(int nr, boolean initial) else tmi->height = tmi->lines * getFontHeight(tmi->font); + /* if x set to "-1", automatically determine by width and alignment */ + if (tmi->x == -1) + tmi->x = -1 * ALIGNED_XPOS(0, tmi->width, tmi->align); + + /* if y set to "-1", automatically determine by height and alignment */ + if (tmi->y == -1) + tmi->y = -1 * ALIGNED_YPOS(0, tmi->height, tmi->valign); + SetDrawBackgroundMask(REDRAW_ALL); SetWindowBackgroundImage(getTitleBackground(nr, initial, FALSE)); @@ -1337,7 +1393,7 @@ void DrawTitleScreenMessage(int nr, boolean initial) filename, tmi->font, tmi->chars, -1, tmi->lines, 0, -1, tmi->autowrap, tmi->centered, tmi->parse_comments); - game_status = last_game_status; /* restore current game status */ + ResetFontStatus(); } void DrawTitleScreen() @@ -1345,8 +1401,6 @@ void DrawTitleScreen() KeyboardAutoRepeatOff(); HandleTitleScreen(0, 0, 0, 0, MB_MENU_INITIALIZE); - - StopAnimation(); } boolean CheckTitleScreen(boolean levelset_has_changed) @@ -1379,10 +1433,11 @@ void DrawMainMenu() /* do not fade out here -- function may continue and fade on editor screen */ UnmapAllGadgets(); - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); + + ExpireSoundLoops(FALSE); KeyboardAutoRepeatOn(); - ActivateJoystick(); audio.sound_deactivated = FALSE; @@ -1391,7 +1446,10 @@ void DrawMainMenu() /* needed if last screen was the playing screen, invoked from level editor */ if (level_editor_test_game) { - game_status = GAME_MODE_EDITOR; + CloseDoor(DOOR_CLOSE_ALL); + + SetGameStatus(GAME_MODE_EDITOR); + DrawLevelEd(); return; @@ -1416,30 +1474,27 @@ void DrawMainMenu() /* needed if last screen (level choice) changed graphics, sounds or music */ ReloadCustomArtwork(0); - /* needed if different viewport properties defined for menues */ - ChangeViewportPropertiesIfNeeded(); + if (CheckTitleScreen(levelset_has_changed)) + { + SetGameStatus(GAME_MODE_TITLE); + + DrawTitleScreen(); + + return; + } if (redraw_mask & REDRAW_ALL) fade_mask = REDRAW_ALL; - if (CheckIfGlobalBorderHasChanged()) + if (CheckIfGlobalBorderOrPlayfieldViewportHasChanged()) fade_mask = REDRAW_ALL; FadeOut(fade_mask); - /* needed if last screen was the editor screen */ - UndrawSpecialEditorDoor(); - - SetDrawtoField(DRAW_BACKBUFFER); - - if (CheckTitleScreen(levelset_has_changed)) - { - game_status = GAME_MODE_TITLE; - - DrawTitleScreen(); + /* needed if different viewport properties defined for menues */ + ChangeViewportPropertiesIfNeeded(); - return; - } + SetDrawtoField(DRAW_TO_BACKBUFFER); /* level_nr may have been set to value over handicap with level editor */ if (setup.handicap && level_nr > leveldir_current->handicap_level) @@ -1448,6 +1503,8 @@ void DrawMainMenu() LoadLevel(level_nr); LoadScore(level_nr); + SaveLevelSetup_SeriesInfo(); + // set this after "ChangeViewportPropertiesIfNeeded()" (which may reset it) SetDrawDeactivationMask(REDRAW_NONE); SetDrawBackgroundMask(REDRAW_FIELD); @@ -1473,8 +1530,7 @@ void DrawMainMenu() LoadTape(level_nr); DrawCompleteVideoDisplay(); - PlayMenuSound(); - PlayMenuMusic(); + PlayMenuSoundsAndMusic(); /* create gadgets for main menu screen */ FreeScreenGadgets(); @@ -1485,11 +1541,12 @@ void DrawMainMenu() MapScreenMenuGadgets(SCREEN_MASK_MAIN); /* copy actual game door content to door double buffer for OpenDoor() */ + BlitBitmap(drawto, bitmap_db_door_1, DX, DY, DXSIZE, DYSIZE, 0, 0); BlitBitmap(drawto, bitmap_db_door_2, VX, VY, VXSIZE, VYSIZE, 0, 0); OpenDoor(GetDoorState() | DOOR_NO_DELAY | DOOR_FORCE_REDRAW); - DrawMaskedBorder(REDRAW_ALL); + DrawMaskedBorder(fade_mask); FadeIn(fade_mask); FadeSetEnterMenu(); @@ -1500,8 +1557,6 @@ void DrawMainMenu() SetMouseCursor(CURSOR_DEFAULT); - InitAnimation(); - OpenDoor(DOOR_CLOSE_1 | DOOR_OPEN_2); } @@ -1542,9 +1597,6 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) static int last_sound = -1, last_music = -1; boolean return_to_main_menu = FALSE; struct TitleControlInfo *tci; - struct TitleFadingInfo fading_default; - struct TitleFadingInfo fading_last = fading; - struct TitleFadingInfo fading_next; int sound, music; if (button == MB_MENU_INITIALIZE) @@ -1553,40 +1605,50 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) title_screen_nr = 0; tci = &title_controls[title_screen_nr]; + SetAnimStatus(getTitleAnimMode(tci)); + last_sound = SND_UNDEFINED; last_music = MUS_UNDEFINED; - if (game_status == GAME_MODE_INFO) + if (num_title_screens != 0) + { + FadeSetEnterScreen(); + + /* use individual title fading instead of global "enter screen" fading */ + fading = getTitleFading(tci); + } + + if (game_status_last_screen == GAME_MODE_INFO) { if (num_title_screens == 0) { + /* switch game mode from title screen mode back to info screen mode */ + SetGameStatus(GAME_MODE_INFO); + + /* store that last screen was info screen, not main menu screen */ + game_status_last_screen = GAME_MODE_INFO; + DrawInfoScreen_NotAvailable("Title screen information:", "No title screen for this level set."); - return; } - FadeSoundsAndMusic(); - - FadeOut(REDRAW_ALL); + FadeMenuSoundsAndMusic(); } + FadeOut(REDRAW_ALL); + + /* title screens may have different window size */ + ChangeViewportPropertiesIfNeeded(); + + /* only required to update logic for redrawing global border */ + ClearField(); + if (tci->is_image) DrawTitleScreenImage(tci->local_nr, tci->initial); else DrawTitleScreenMessage(tci->local_nr, tci->initial); - fading_default = (tci->initial ? title_initial_default : title_default); - - fading = fading_next = getTitleFading(tci); - - if (!(fading_last.fade_mode & FADE_TYPE_TRANSFORM) && - fading_next.fade_mode & FADE_TYPE_TRANSFORM) - { - fading.fade_mode = FADE_MODE_FADE; - fading.fade_delay = fading_default.fade_delay; - } - sound = getTitleSound(tci); music = getTitleMusic(tci); @@ -1602,8 +1664,6 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) FadeIn(REDRAW_ALL); - fading = fading_next; - DelayReached(&title_delay, 0); /* reset delay counter */ return; @@ -1618,29 +1678,35 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) } else if (button == MB_MENU_CHOICE) { - if (game_status == GAME_MODE_INFO && num_title_screens == 0) + if (game_status_last_screen == GAME_MODE_INFO && num_title_screens == 0) { - FadeSetEnterScreen(); + SetGameStatus(GAME_MODE_INFO); info_mode = INFO_MODE_MAIN; + DrawInfoScreen(); return; } title_screen_nr++; - tci = &title_controls[title_screen_nr]; if (title_screen_nr < num_title_screens) { + tci = &title_controls[title_screen_nr]; + + SetAnimStatus(getTitleAnimMode(tci)); + sound = getTitleSound(tci); music = getTitleMusic(tci); - if (sound == SND_UNDEFINED || sound != last_sound) - FadeSounds(); - if (music == MUS_UNDEFINED || music != last_music) + if (last_sound != SND_UNDEFINED && sound != last_sound) + FadeSound(last_sound); + if (last_music != MUS_UNDEFINED && music != last_music) FadeMusic(); + fading = getTitleFading(tci); + FadeOut(REDRAW_ALL); if (tci->is_image) @@ -1648,8 +1714,6 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) else DrawTitleScreenMessage(tci->local_nr, tci->initial); - fading_next = getTitleFading(tci); - sound = getTitleSound(tci); music = getTitleMusic(tci); @@ -1661,20 +1725,13 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) last_sound = sound; last_music = music; - /* last screen already faded out, next screen has no animation */ - if (!(fading.fade_mode & FADE_TYPE_TRANSFORM) && - fading_next.fade_mode == FADE_MODE_NONE) - fading = fading_next; - FadeIn(REDRAW_ALL); - fading = fading_next; - DelayReached(&title_delay, 0); /* reset delay counter */ } else { - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); return_to_main_menu = TRUE; } @@ -1687,15 +1744,17 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) /* force full menu screen redraw after displaying title screens */ redraw_mask = REDRAW_ALL; - if (game_status == GAME_MODE_INFO) + if (game_status_last_screen == GAME_MODE_INFO) { + SetGameStatus(GAME_MODE_INFO); + info_mode = INFO_MODE_MAIN; DrawInfoScreen(); } else /* default: return to main menu */ { - game_status = GAME_MODE_MAIN; + SetGameStatus(GAME_MODE_MAIN); DrawMainMenu(); } @@ -1749,6 +1808,8 @@ void HandleMainMenu_SelectLevel(int step, int direction, int selected_level_nr) LoadTape(level_nr); DrawCompleteVideoDisplay(); + SaveLevelSetup_SeriesInfo(); + /* needed because DrawPreviewLevelInitial() takes some time */ BackToFront(); /* SyncDisplay(); */ @@ -1786,6 +1847,10 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) } } + /* check if level preview was clicked */ + if (insidePreviewRect(&preview, mx - SX, my - SY)) + pos = MAIN_CONTROL_GAME; + // handle pressed/unpressed state for active/inactive menu buttons // (if pos != -1, "i" contains index position corresponding to "pos") if (button && @@ -1812,11 +1877,7 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) pos = choice + dy; } - if (pos == MAIN_CONTROL_LEVELS && dx != 0 && button) - { - HandleMainMenu_SelectLevel(1, (dx < 0 ? -1 : +1), NO_DIRECT_LEVEL_SELECT); - } - else if (pos == MAIN_CONTROL_FIRST_LEVEL && !button) + if (pos == MAIN_CONTROL_FIRST_LEVEL && !button) { HandleMainMenu_SelectLevel(MAX_LEVELS, -1, NO_DIRECT_LEVEL_SELECT); } @@ -1826,9 +1887,9 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) } else if (pos == MAIN_CONTROL_LEVEL_NUMBER && !button) { - game_status = GAME_MODE_LEVELNR; + CloseDoor(DOOR_CLOSE_2); - ChangeViewportPropertiesIfNeeded(); + SetGameStatus(GAME_MODE_LEVELNR); DrawChooseLevelNr(); } @@ -1845,6 +1906,12 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) choice = pos; } + else if (dx != 0) + { + if (choice != MAIN_CONTROL_INFO && + choice != MAIN_CONTROL_SETUP) + HandleMainMenu_SelectLevel(1, dx, NO_DIRECT_LEVEL_SELECT); + } } else { @@ -1852,7 +1919,7 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) if (pos == MAIN_CONTROL_NAME) { - game_status = GAME_MODE_PSEUDO_TYPENAME; + SetGameStatus(GAME_MODE_PSEUDO_TYPENAME); HandleTypeName(strlen(setup.player_name), 0); } @@ -1860,7 +1927,9 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) { if (leveldir_first) { - game_status = GAME_MODE_LEVELS; + CloseDoor(DOOR_CLOSE_2); + + SetGameStatus(GAME_MODE_LEVELS); SaveLevelSetup_LastSeries(); SaveLevelSetup_SeriesInfo(); @@ -1868,14 +1937,14 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) if (setup.internal.choose_from_top_leveldir) gotoTopLevelDir(); - ChangeViewportPropertiesIfNeeded(); - DrawChooseLevelSet(); } } else if (pos == MAIN_CONTROL_SCORES) { - game_status = GAME_MODE_SCORES; + CloseDoor(DOOR_CLOSE_2); + + SetGameStatus(GAME_MODE_SCORES); DrawHallOfFame(-1); } @@ -1887,7 +1956,7 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) CloseDoor(DOOR_CLOSE_2); - game_status = GAME_MODE_EDITOR; + SetGameStatus(GAME_MODE_EDITOR); FadeSetEnterScreen(); @@ -1895,10 +1964,11 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) } else if (pos == MAIN_CONTROL_INFO) { - game_status = GAME_MODE_INFO; - info_mode = INFO_MODE_MAIN; + CloseDoor(DOOR_CLOSE_2); + + SetGameStatus(GAME_MODE_INFO); - ChangeViewportPropertiesIfNeeded(); + info_mode = INFO_MODE_MAIN; DrawInfoScreen(); } @@ -1908,10 +1978,11 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) } else if (pos == MAIN_CONTROL_SETUP) { - game_status = GAME_MODE_SETUP; - setup_mode = SETUP_MODE_MAIN; + CloseDoor(DOOR_CLOSE_2); + + SetGameStatus(GAME_MODE_SETUP); - ChangeViewportPropertiesIfNeeded(); + setup_mode = SETUP_MODE_MAIN; DrawSetupScreen(); } @@ -1921,7 +1992,7 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) SaveLevelSetup_SeriesInfo(); if (Request("Do you really want to quit?", REQ_ASK | REQ_STAY_CLOSED)) - game_status = GAME_MODE_QUIT; + SetGameStatus(GAME_MODE_QUIT); } } } @@ -1989,7 +2060,7 @@ static void execInfoLevelSet() static void execExitInfo() { - game_status = GAME_MODE_MAIN; + SetGameStatus(GAME_MODE_MAIN); DrawMainMenu(); } @@ -2062,7 +2133,6 @@ static void DrawCursorAndText_Setup(int screen_pos, int menu_info_pos_raw, DrawCursorAndText_Menu_Ext(setup_info, screen_pos, menu_info_pos_raw, active); } -static char *screen_mode_text; static char *window_size_text; static char *scaling_type_text; @@ -2089,7 +2159,6 @@ static void drawMenuInfoList(int first_entry, int num_page_entries, (value_ptr == &setup.sound_loops && !audio.loops_available) || (value_ptr == &setup.sound_music && !audio.music_available) || (value_ptr == &setup.fullscreen && !video.fullscreen_available) || - (value_ptr == &screen_mode_text && !video.fullscreen_available) || (value_ptr == &window_size_text && !video.window_scaling_available) || (value_ptr == &scaling_type_text && !video.window_scaling_available)) si->type |= TYPE_GHOSTED; @@ -2117,16 +2186,15 @@ static void DrawInfoScreen_Main() if (redraw_mask & REDRAW_ALL) fade_mask = REDRAW_ALL; - if (CheckIfGlobalBorderHasChanged()) + if (CheckIfGlobalBorderOrPlayfieldViewportHasChanged()) fade_mask = REDRAW_ALL; UnmapAllGadgets(); + FadeMenuSoundsAndMusic(); FreeScreenGadgets(); CreateScreenGadgets(); - CloseDoor(DOOR_CLOSE_2); - /* (needed after displaying title screens which disable auto repeat) */ KeyboardAutoRepeatOn(); @@ -2134,15 +2202,15 @@ static void DrawInfoScreen_Main() FadeOut(fade_mask); - if (fade_mask == REDRAW_ALL) - { - RedrawGlobalBorder(); + /* needed if different viewport properties defined for info screen */ + ChangeViewportPropertiesIfNeeded(); - OpenDoor(DOOR_CLOSE_1 | DOOR_CLOSE_2 | DOOR_NO_DELAY | DOOR_FORCE_REDRAW); - } + SetMainBackgroundImage(IMG_BACKGROUND_INFO); ClearField(); + OpenDoor(GetDoorState() | DOOR_NO_DELAY | DOOR_FORCE_REDRAW); + DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, "Info Screen"); info_info = info_info_main; @@ -2161,14 +2229,11 @@ static void DrawInfoScreen_Main() MapScreenGadgets(max_info_info); - PlayMenuSound(); - PlayMenuMusic(); + PlayMenuSoundsAndMusic(); DrawMaskedBorder(fade_mask); FadeIn(fade_mask); - - InitAnimation(); } static void changeSetupValue(int, int, int); @@ -2414,6 +2479,27 @@ void HandleMenuScreen(int mx, int my, int dx, int dy, int button, choice = choice_store[mode] = first_entry + y; } + else if (dx < 0) + { + PlaySound(SND_MENU_ITEM_SELECTING); + + for (i = 0; menu_info[i].type != 0; i++) + { + if (menu_info[i].type & TYPE_LEAVE_MENU) + { + void (*menu_callback_function)(void) = menu_info[i].value; + + FadeSetLeaveMenu(); + + menu_callback_function(); + + /* absolutely needed because function changes 'menu_info'! */ + break; + } + } + + return; + } } else if (!(menu_info[first_entry + y].type & TYPE_GHOSTED)) { @@ -2455,10 +2541,34 @@ void HandleInfoScreen_Main(int mx, int my, int dx, int dy, int button) info_mode, num_info_info, max_info_info); } +static int getMenuFontSpacing(int spacing_height, int font_nr) +{ + int font_spacing = getFontHeight(font_nr) + EXTRA_SPACING(game_status); + + return (spacing_height < 0 ? ABS(spacing_height) * font_spacing : + spacing_height); +} + +static int getMenuTextSpacing(int spacing_height, int font_nr) +{ + return (getMenuFontSpacing(spacing_height, font_nr) + + EXTRA_SPACING(game_status)); +} + +static int getMenuTextStep(int spacing_height, int font_nr) +{ + return getFontHeight(font_nr) + getMenuTextSpacing(spacing_height, font_nr); +} + void DrawInfoScreen_NotAvailable(char *text_title, char *text_error) { + int font_title = MENU_INFO_FONT_TITLE; + int font_error = FONT_TEXT_2; + int font_foot = MENU_INFO_FONT_FOOT; + int spacing_title = menu.headline1_spacing_info[info_mode]; + int ystep_title = getMenuTextStep(spacing_title, font_title); int ystart1 = mSY - SY + 100; - int ystart2 = mSY - SY + 150; + int ystart2 = ystart1 + ystep_title; int ybottom = mSY - SY + SYSIZE - 20; SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO); @@ -2468,10 +2578,10 @@ void DrawInfoScreen_NotAvailable(char *text_title, char *text_error) ClearField(); DrawHeadline(); - DrawTextSCentered(ystart1, FONT_TEXT_1, text_title); - DrawTextSCentered(ystart2, FONT_TEXT_2, text_error); + DrawTextSCentered(ystart1, font_title, text_title); + DrawTextSCentered(ystart2, font_error, text_error); - DrawTextSCentered(ybottom, FONT_TEXT_4, + DrawTextSCentered(ybottom, font_foot, "Press any key or button for info menu"); FadeIn(REDRAW_FIELD); @@ -2481,6 +2591,8 @@ void DrawInfoScreen_HelpAnim(int start, int max_anims, boolean init) { static int infoscreen_step[MAX_INFO_ELEMENTS_ON_SCREEN]; static int infoscreen_frame[MAX_INFO_ELEMENTS_ON_SCREEN]; + int font_title = MENU_INFO_FONT_TITLE; + int font_foot = MENU_INFO_FONT_FOOT; int xstart = mSX + MENU_SCREEN_INFO_XSTART; int ystart1 = mSY - SY + MENU_SCREEN_INFO_YSTART1; int ystart2 = mSY + MENU_SCREEN_INFO_YSTART2; @@ -2500,9 +2612,9 @@ void DrawInfoScreen_HelpAnim(int start, int max_anims, boolean init) ClearField(); DrawHeadline(); - DrawTextSCentered(ystart1, FONT_TEXT_1, "The Game Elements:"); + DrawTextSCentered(ystart1, font_title, "The Game Elements:"); - DrawTextSCentered(ybottom, FONT_TEXT_4, + DrawTextSCentered(ybottom, font_foot, "Press any key or button for next page"); FrameCounter = 0; @@ -2609,10 +2721,12 @@ void DrawInfoScreen_HelpText(int element, int action, int direction, int ypos) { int font_nr = FONT_INFO_ELEMENTS; int font_width = getFontWidth(font_nr); - int sx = mSX + MINI_TILEX + TILEX + MINI_TILEX; - int sy = mSY + 65 + 2 * 32 + 1; + int font_height = getFontHeight(font_nr); + int yoffset = (TILEX - 2 * font_height) / 2; + int xstart = mSX + MINI_TILEX + TILEX + MINI_TILEX; + int ystart = mSY + MENU_SCREEN_INFO_YSTART2 + yoffset; int ystep = TILEY + 4; - int pad_x = sx - SX; + int pad_x = xstart - SX; int max_chars_per_line = (SXSIZE - pad_x - MINI_TILEX) / font_width; int max_lines_per_text = 2; char *text = NULL; @@ -2633,15 +2747,17 @@ void DrawInfoScreen_HelpText(int element, int action, int direction, int ypos) text = "No description available"; if (strlen(text) <= max_chars_per_line) /* only one line of text */ - sy += getFontHeight(font_nr) / 2; + ystart += getFontHeight(font_nr) / 2; - DrawTextBuffer(sx, sy + ypos * ystep, text, font_nr, + DrawTextBuffer(xstart, ystart + ypos * ystep, text, font_nr, max_chars_per_line, -1, max_lines_per_text, 0, -1, TRUE, FALSE, FALSE); } void DrawInfoScreen_TitleScreen() { + SetGameStatus(GAME_MODE_TITLE); + DrawTitleScreen(); } @@ -2662,8 +2778,6 @@ void DrawInfoScreen_Elements() HandleInfoScreen_Elements(MB_MENU_INITIALIZE); FadeIn(REDRAW_FIELD); - - InitAnimation(); } void HandleInfoScreen_Elements(int button) @@ -2716,7 +2830,7 @@ void HandleInfoScreen_Elements(int button) if (page >= num_pages) { - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -2764,10 +2878,16 @@ void DrawInfoScreen_Music() void HandleInfoScreen_Music(int button) { static struct MusicFileInfo *list = NULL; - int ystart1 = mSY - SY + 100; - int ystart2 = mSY - SY + 150; + 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_info[info_mode]; + int spacing_head = menu.headline2_spacing_info[info_mode]; + int ystep_title = getMenuTextStep(spacing_title, font_title); + int ystep_head = getMenuTextStep(spacing_head, font_head); + int ystart = mSY - SY + 100; int ybottom = mSY - SY + SYSIZE - 20; - int dy = 30; if (button == MB_MENU_INITIALIZE) { @@ -2775,15 +2895,15 @@ void HandleInfoScreen_Music(int button) if (list == NULL) { - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); ClearField(); DrawHeadline(); - DrawTextSCentered(ystart1, FONT_TEXT_1, + DrawTextSCentered(ystart, font_title, "No music info for this level set."); - DrawTextSCentered(ybottom, FONT_TEXT_4, + DrawTextSCentered(ybottom, font_foot, "Press any key or button for info menu"); return; @@ -2794,7 +2914,7 @@ void HandleInfoScreen_Music(int button) { PlaySound(SND_MENU_ITEM_SELECTING); - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -2803,8 +2923,6 @@ void HandleInfoScreen_Music(int button) } else if (button == MB_MENU_CHOICE || button == MB_MENU_INITIALIZE) { - int y = 0; - if (button != MB_MENU_INITIALIZE) { PlaySound(SND_MENU_ITEM_SELECTING); @@ -2815,7 +2933,7 @@ void HandleInfoScreen_Music(int button) if (list == NULL) { - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -2823,7 +2941,7 @@ void HandleInfoScreen_Music(int button) return; } - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); if (list != music_file_info) FadeSetNextScreen(); @@ -2843,51 +2961,66 @@ void HandleInfoScreen_Music(int button) else PlaySound(sound); - DrawTextSCentered(ystart1, FONT_TEXT_1, "The Game Background Sounds:"); + DrawTextSCentered(ystart, font_title, "The Game Background Sounds:"); } else { PlayMusic(list->music); - DrawTextSCentered(ystart1, FONT_TEXT_1, "The Game Background Music:"); + DrawTextSCentered(ystart, font_title, "The Game Background Music:"); } + ystart += ystep_title; + if (!strEqual(list->title, UNKNOWN_NAME)) { if (!strEqual(list->title_header, UNKNOWN_NAME)) - DrawTextSCentered(ystart2 + y++ * dy, FONT_TEXT_2, list->title_header); + { + DrawTextSCentered(ystart, font_head, list->title_header); + ystart += ystep_head; + } - DrawTextFCentered(ystart2 + y++ * dy, FONT_TEXT_3, "\"%s\"", list->title); + DrawTextFCentered(ystart, font_text, "\"%s\"", list->title); + ystart += ystep_head; } if (!strEqual(list->artist, UNKNOWN_NAME)) { if (!strEqual(list->artist_header, UNKNOWN_NAME)) - DrawTextSCentered(ystart2 + y++ * dy, FONT_TEXT_2, list->artist_header); + DrawTextSCentered(ystart, font_head, list->artist_header); else - DrawTextSCentered(ystart2 + y++ * dy, FONT_TEXT_2, "by"); + DrawTextSCentered(ystart, font_head, "by"); + + ystart += ystep_head; - DrawTextFCentered(ystart2 + y++ * dy, FONT_TEXT_3, "%s", list->artist); + DrawTextFCentered(ystart, font_text, "%s", list->artist); + ystart += ystep_head; } if (!strEqual(list->album, UNKNOWN_NAME)) { if (!strEqual(list->album_header, UNKNOWN_NAME)) - DrawTextSCentered(ystart2 + y++ * dy, FONT_TEXT_2, list->album_header); + DrawTextSCentered(ystart, font_head, list->album_header); else - DrawTextSCentered(ystart2 + y++ * dy, FONT_TEXT_2, "from the album"); + DrawTextSCentered(ystart, font_head, "from the album"); - DrawTextFCentered(ystart2 + y++ * dy, FONT_TEXT_3, "\"%s\"", list->album); + ystart += ystep_head; + + DrawTextFCentered(ystart, font_text, "\"%s\"", list->album); + ystart += ystep_head; } if (!strEqual(list->year, UNKNOWN_NAME)) { if (!strEqual(list->year_header, UNKNOWN_NAME)) - DrawTextSCentered(ystart2 + y++ * dy, FONT_TEXT_2, list->year_header); + DrawTextSCentered(ystart, font_head, list->year_header); else - DrawTextSCentered(ystart2 + y++ * dy, FONT_TEXT_2, "from the year"); + DrawTextSCentered(ystart, font_head, "from the year"); + + ystart += ystep_head; - DrawTextFCentered(ystart2 + y++ * dy, FONT_TEXT_3, "%s", list->year); + DrawTextFCentered(ystart, font_text, "%s", list->year); + ystart += ystep_head; } DrawTextSCentered(ybottom, FONT_TEXT_4, @@ -2903,174 +3036,232 @@ void HandleInfoScreen_Music(int button) static void DrawInfoScreen_CreditsScreen(int screen_nr) { - int ystart1 = mSY - SY + 100; - int ystart2 = mSY - SY + 150; + 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_info[info_mode]; + int spacing_head = menu.headline2_spacing_info[info_mode]; + int spacing_para = menu.paragraph_spacing_info[info_mode]; + int spacing_line = menu.line_spacing_info[info_mode]; + int ystep_title = getMenuTextStep(spacing_title, font_title); + int ystep_head = getMenuTextStep(spacing_head, font_head); + int ystep_para = getMenuTextStep(spacing_para, font_text); + int ystep_line = getMenuTextStep(spacing_line, font_text); + int ystart = mSY - SY + 100; int ybottom = mSY - SY + SYSIZE - 20; - int ystep = 30; ClearField(); DrawHeadline(); - DrawTextSCentered(ystart1, FONT_TEXT_1, "Credits:"); + DrawTextSCentered(ystart, font_title, "Credits:"); + ystart += ystep_title; if (screen_nr == 0) { - DrawTextSCentered(ystart2 + 0 * ystep, FONT_TEXT_2, + DrawTextSCentered(ystart, font_head, "Special thanks to"); - DrawTextSCentered(ystart2 + 1 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "Peter Liepa"); - DrawTextSCentered(ystart2 + 2 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "for creating"); - DrawTextSCentered(ystart2 + 3 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "\"Boulder Dash\""); - DrawTextSCentered(ystart2 + 4 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "in the year"); - DrawTextSCentered(ystart2 + 5 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "1984"); - DrawTextSCentered(ystart2 + 6 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "published by"); - DrawTextSCentered(ystart2 + 7 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "First Star Software"); } else if (screen_nr == 1) { - DrawTextSCentered(ystart2 + 0 * ystep, FONT_TEXT_2, + DrawTextSCentered(ystart, font_head, "Special thanks to"); - DrawTextSCentered(ystart2 + 1 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "Klaus Heinz & Volker Wertich"); - DrawTextSCentered(ystart2 + 2 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "for creating"); - DrawTextSCentered(ystart2 + 3 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "\"Emerald Mine\""); - DrawTextSCentered(ystart2 + 4 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "in the year"); - DrawTextSCentered(ystart2 + 5 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "1987"); - DrawTextSCentered(ystart2 + 6 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "published by"); - DrawTextSCentered(ystart2 + 7 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "Kingsoft"); } else if (screen_nr == 2) { - DrawTextSCentered(ystart2 + 0 * ystep, FONT_TEXT_2, + DrawTextSCentered(ystart, font_head, "Special thanks to"); - DrawTextSCentered(ystart2 + 1 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "Michael Stopp & Philip Jespersen"); - DrawTextSCentered(ystart2 + 2 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "for creating"); - DrawTextSCentered(ystart2 + 3 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "\"Supaplex\""); - DrawTextSCentered(ystart2 + 4 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "in the year"); - DrawTextSCentered(ystart2 + 5 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "1991"); - DrawTextSCentered(ystart2 + 6 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "published by"); - DrawTextSCentered(ystart2 + 7 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "Digital Integration"); } else if (screen_nr == 3) { - DrawTextSCentered(ystart2 + 0 * ystep, FONT_TEXT_2, + DrawTextSCentered(ystart, font_head, "Special thanks to"); - DrawTextSCentered(ystart2 + 1 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "Hiroyuki Imabayashi"); - DrawTextSCentered(ystart2 + 2 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "for creating"); - DrawTextSCentered(ystart2 + 3 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "\"Sokoban\""); - DrawTextSCentered(ystart2 + 4 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "in the year"); - DrawTextSCentered(ystart2 + 5 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "1982"); - DrawTextSCentered(ystart2 + 6 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "published by"); - DrawTextSCentered(ystart2 + 7 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "Thinking Rabbit"); } else if (screen_nr == 4) { - DrawTextSCentered(ystart2 + 0 * ystep, FONT_TEXT_2, + DrawTextSCentered(ystart, font_head, "Special thanks to"); - DrawTextSCentered(ystart2 + 1 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "Alan Bond"); - DrawTextSCentered(ystart2 + 2 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "and"); - DrawTextSCentered(ystart2 + 3 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "J\xfcrgen Bonhagen"); - DrawTextSCentered(ystart2 + 4 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "for the continuous creation"); - DrawTextSCentered(ystart2 + 5 * ystep, FONT_TEXT_2, + ystart += ystep_line; + DrawTextSCentered(ystart, font_head, "of outstanding level sets"); } else if (screen_nr == 5) { - DrawTextSCentered(ystart2 + 0 * ystep, FONT_TEXT_2, + DrawTextSCentered(ystart, font_head, "Thanks to"); - DrawTextSCentered(ystart2 + 1 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "Peter Elzner"); - DrawTextSCentered(ystart2 + 2 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "for ideas and inspiration by"); - DrawTextSCentered(ystart2 + 3 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "Diamond Caves"); + ystart += ystep_para; - DrawTextSCentered(ystart2 + 5 * ystep, FONT_TEXT_2, + DrawTextSCentered(ystart, font_head, "Thanks to"); - DrawTextSCentered(ystart2 + 6 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "Steffest"); - DrawTextSCentered(ystart2 + 7 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "for ideas and inspiration by"); - DrawTextSCentered(ystart2 + 8 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "DX-Boulderdash"); } else if (screen_nr == 6) { - DrawTextSCentered(ystart2 + 0 * ystep, FONT_TEXT_2, + DrawTextSCentered(ystart, font_head, "Thanks to"); - DrawTextSCentered(ystart2 + 1 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "David Tritscher"); -#if 1 - DrawTextSCentered(ystart2 + 2 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "for the code base used for the"); - DrawTextSCentered(ystart2 + 3 * ystep, FONT_TEXT_2, + ystart += ystep_line; + DrawTextSCentered(ystart, font_head, "native Emerald Mine engine"); -#else - DrawTextSCentered(ystart2 + 2 * ystep, FONT_TEXT_2, - "for the new Emerald Mine engine"); -#endif } else if (screen_nr == 7) { - DrawTextSCentered(ystart2 + 0 * ystep, FONT_TEXT_2, + DrawTextSCentered(ystart, font_head, "Thanks to"); - DrawTextSCentered(ystart2 + 1 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "Guido Schulz"); - DrawTextSCentered(ystart2 + 2 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "for the initial DOS port"); + ystart += ystep_para; - DrawTextSCentered(ystart2 + 4 * ystep, FONT_TEXT_2, + DrawTextSCentered(ystart, font_head, "Thanks to"); - DrawTextSCentered(ystart2 + 5 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "Karl H\xf6rnell"); - DrawTextSCentered(ystart2 + 6 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "for some additional toons"); } else if (screen_nr == 8) { - DrawTextSCentered(ystart2 + 0 * ystep, FONT_TEXT_2, + DrawTextSCentered(ystart, font_head, "And not to forget:"); - DrawTextSCentered(ystart2 + 1 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "Many thanks to"); - DrawTextSCentered(ystart2 + 2 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, "All those who contributed"); - DrawTextSCentered(ystart2 + 3 * ystep, FONT_TEXT_3, + ystart += ystep_line; + DrawTextSCentered(ystart, font_text, "levels to this game"); - DrawTextSCentered(ystart2 + 4 * ystep, FONT_TEXT_3, + ystart += ystep_line; + DrawTextSCentered(ystart, font_text, "since 1995"); } - DrawTextSCentered(ybottom, FONT_TEXT_4, + DrawTextSCentered(ybottom, font_foot, "Press any key or button for next page"); } @@ -3078,7 +3269,7 @@ void DrawInfoScreen_Credits() { SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_CREDITS); - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); FadeOut(REDRAW_FIELD); @@ -3119,7 +3310,7 @@ void HandleInfoScreen_Credits(int button) if (screen_nr >= num_screens) { - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -3146,10 +3337,20 @@ void HandleInfoScreen_Credits(int button) void DrawInfoScreen_Program() { - int ystart1 = mSY - SY + 100; - int ystart2 = mSY - SY + 150; + 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_info[info_mode]; + int spacing_head = menu.headline2_spacing_info[info_mode]; + int spacing_para = menu.paragraph_spacing_info[info_mode]; + int spacing_line = menu.line_spacing_info[info_mode]; + int ystep_title = getMenuTextStep(spacing_title, font_title); + int ystep_head = getMenuTextStep(spacing_head, font_head); + int ystep_para = getMenuTextStep(spacing_para, font_text); + int ystep_line = getMenuTextStep(spacing_line, font_text); + int ystart = mSY - SY + 100; int ybottom = mSY - SY + SYSIZE - 20; - int ystep = 30; SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_PROGRAM); @@ -3158,26 +3359,36 @@ void DrawInfoScreen_Program() ClearField(); DrawHeadline(); - DrawTextSCentered(ystart1, FONT_TEXT_1, "Program Information:"); + DrawTextSCentered(ystart, font_title, "Program Information:"); + ystart += ystep_title; - DrawTextSCentered(ystart2 + 0 * ystep, FONT_TEXT_2, + DrawTextSCentered(ystart, font_head, "This game is Freeware!"); - DrawTextSCentered(ystart2 + 1 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, "If you like it, send e-mail to:"); - DrawTextSCentered(ystart2 + 2 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, setup.internal.program_email); - DrawTextSCentered(ystart2 + 4 * ystep, FONT_TEXT_2, + ystart += ystep_para; + + DrawTextSCentered(ystart, font_head, "More information and levels:"); - DrawTextSCentered(ystart2 + 5 * ystep, FONT_TEXT_3, + ystart += ystep_head; + DrawTextSCentered(ystart, font_text, setup.internal.program_website); - DrawTextSCentered(ystart2 + 7 * ystep, FONT_TEXT_2, + ystart += ystep_para; + + DrawTextSCentered(ystart, font_head, "If you have created new levels,"); - DrawTextSCentered(ystart2 + 8 * ystep, FONT_TEXT_2, + ystart += ystep_line; + DrawTextSCentered(ystart, font_head, "send them to me to include them!"); - DrawTextSCentered(ystart2 + 9 * ystep, FONT_TEXT_2, + ystart += ystep_head; + DrawTextSCentered(ystart, font_head, ":-)"); - DrawTextSCentered(ybottom, FONT_TEXT_4, + DrawTextSCentered(ybottom, font_foot, "Press any key or button for info menu"); FadeIn(REDRAW_FIELD); @@ -3198,7 +3409,7 @@ void HandleInfoScreen_Program(int button) { PlaySound(SND_MENU_ITEM_SELECTING); - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -3211,12 +3422,20 @@ void HandleInfoScreen_Program(int button) void DrawInfoScreen_Version() { - int font_header = FONT_TEXT_3; - int font_text = FONT_TEXT_2; + 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_info[info_mode]; + int spacing_head = menu.headline2_spacing_info[info_mode]; + int spacing_para = menu.paragraph_spacing_info[info_mode]; + int spacing_line = menu.line_spacing_info[info_mode]; int xstep = getFontWidth(font_text); - int ystep = getFontHeight(font_text); - int ystart1 = mSY - SY + 100; - int ystart2 = mSY - SY + 150; + int ystep_title = getMenuTextStep(spacing_title, font_title); + int ystep_head = getMenuTextStep(spacing_head, font_head); + int ystep_para = getMenuTextStep(spacing_para, font_text); + int ystep_line = getMenuTextStep(spacing_line, font_text); + int ystart = mSY - SY + 100; int ybottom = mSY - SY + SYSIZE - 20; int xstart1 = mSX - SX + 2 * xstep; int xstart2 = mSX - SX + 18 * xstep; @@ -3238,31 +3457,46 @@ void DrawInfoScreen_Version() ClearField(); DrawHeadline(); - DrawTextSCentered(ystart1, FONT_TEXT_1, "Version Information:"); + DrawTextSCentered(ystart, font_title, "Version Information:"); + ystart += ystep_title; + + DrawTextF(xstart1, ystart, font_head, "Name"); + DrawTextF(xstart2, ystart, font_text, getProgramTitleString()); + ystart += ystep_line; - DrawTextF(xstart1, ystart2, font_header, "Name"); - DrawTextF(xstart2, ystart2, font_text, getProgramTitleString()); + if (!strEqual(getProgramVersionString(), getProgramRealVersionString())) + { + DrawTextF(xstart1, ystart, font_head, "Version (fake)"); + DrawTextF(xstart2, ystart, font_text, getProgramVersionString()); + ystart += ystep_line; - ystart2 += ystep; - DrawTextF(xstart1, ystart2, font_header, "Version"); - DrawTextF(xstart2, ystart2, font_text, getProgramVersionString()); + DrawTextF(xstart1, ystart, font_head, "Version (real)"); + DrawTextF(xstart2, ystart, font_text, getProgramRealVersionString()); + ystart += ystep_line; + } + else + { + DrawTextF(xstart1, ystart, font_head, "Version"); + DrawTextF(xstart2, ystart, font_text, getProgramVersionString()); + ystart += ystep_line; + } - ystart2 += ystep; - DrawTextF(xstart1, ystart2, font_header, "Platform"); - DrawTextF(xstart2, ystart2, font_text, PLATFORM_STRING); + DrawTextF(xstart1, ystart, font_head, "Platform"); + DrawTextF(xstart2, ystart, font_text, PLATFORM_STRING); + ystart += ystep_line; - ystart2 += ystep; - DrawTextF(xstart1, ystart2, font_header, "Target"); - DrawTextF(xstart2, ystart2, font_text, TARGET_STRING); + DrawTextF(xstart1, ystart, font_head, "Target"); + DrawTextF(xstart2, ystart, font_text, TARGET_STRING); + ystart += ystep_line; - ystart2 += ystep; - DrawTextF(xstart1, ystart2, font_header, "Compile time"); - DrawTextF(xstart2, ystart2, font_text, getCompileDateString()); + DrawTextF(xstart1, ystart, font_head, "Source date"); + DrawTextF(xstart2, ystart, font_text, getSourceDateString()); + ystart += ystep_para; - ystart2 += 3 * ystep; - DrawTextF(xstart1, ystart2, font_header, "Library"); - DrawTextF(xstart2, ystart2, font_header, "compiled"); - DrawTextF(xstart3, ystart2, font_header, "linked"); + DrawTextF(xstart1, ystart, font_head, "Library"); + DrawTextF(xstart2, ystart, font_head, "compiled"); + DrawTextF(xstart3, ystart, font_head, "linked"); + ystart += ystep_head; SDL_VERSION(&sdl_version_compiled); #if defined(TARGET_SDL2) @@ -3272,63 +3506,63 @@ void DrawInfoScreen_Version() sdl_version_linked = SDL_Linked_Version(); #endif - ystart2 += 2 * ystep; - DrawTextF(xstart1, ystart2, font_text, "SDL"); - DrawTextF(xstart2, ystart2, font_text, "%d.%d.%d", + DrawTextF(xstart1, ystart, font_text, "SDL"); + DrawTextF(xstart2, ystart, font_text, "%d.%d.%d", sdl_version_compiled.major, sdl_version_compiled.minor, sdl_version_compiled.patch); - DrawTextF(xstart3, ystart2, font_text, "%d.%d.%d", + DrawTextF(xstart3, ystart, font_text, "%d.%d.%d", sdl_version_linked->major, sdl_version_linked->minor, sdl_version_linked->patch); + ystart += ystep_line; SDL_IMAGE_VERSION(&sdl_version_compiled); sdl_version_linked = IMG_Linked_Version(); - ystart2 += ystep; - DrawTextF(xstart1, ystart2, font_text, "SDL_image"); - DrawTextF(xstart2, ystart2, font_text, "%d.%d.%d", + DrawTextF(xstart1, ystart, font_text, "SDL_image"); + DrawTextF(xstart2, ystart, font_text, "%d.%d.%d", sdl_version_compiled.major, sdl_version_compiled.minor, sdl_version_compiled.patch); - DrawTextF(xstart3, ystart2, font_text, "%d.%d.%d", + DrawTextF(xstart3, ystart, font_text, "%d.%d.%d", sdl_version_linked->major, sdl_version_linked->minor, sdl_version_linked->patch); + ystart += ystep_line; SDL_MIXER_VERSION(&sdl_version_compiled); sdl_version_linked = Mix_Linked_Version(); - ystart2 += ystep; - DrawTextF(xstart1, ystart2, font_text, "SDL_mixer"); - DrawTextF(xstart2, ystart2, font_text, "%d.%d.%d", + DrawTextF(xstart1, ystart, font_text, "SDL_mixer"); + DrawTextF(xstart2, ystart, font_text, "%d.%d.%d", sdl_version_compiled.major, sdl_version_compiled.minor, sdl_version_compiled.patch); - DrawTextF(xstart3, ystart2, font_text, "%d.%d.%d", + DrawTextF(xstart3, ystart, font_text, "%d.%d.%d", sdl_version_linked->major, sdl_version_linked->minor, sdl_version_linked->patch); + ystart += ystep_line; SDL_NET_VERSION(&sdl_version_compiled); sdl_version_linked = SDLNet_Linked_Version(); - ystart2 += ystep; - DrawTextF(xstart1, ystart2, font_text, "SDL_net"); - DrawTextF(xstart2, ystart2, font_text, "%d.%d.%d", + DrawTextF(xstart1, ystart, font_text, "SDL_net"); + DrawTextF(xstart2, ystart, font_text, "%d.%d.%d", sdl_version_compiled.major, sdl_version_compiled.minor, sdl_version_compiled.patch); - DrawTextF(xstart3, ystart2, font_text, "%d.%d.%d", + DrawTextF(xstart3, ystart, font_text, "%d.%d.%d", sdl_version_linked->major, sdl_version_linked->minor, sdl_version_linked->patch); + ystart += ystep_para; - ystart2 += 3 * ystep; - DrawTextF(xstart1, ystart2, font_header, "Driver"); - DrawTextF(xstart2, ystart2, font_header, "Requested"); - DrawTextF(xstart3, ystart2, font_header, "Used"); + DrawTextF(xstart1, ystart, font_head, "Driver"); + DrawTextF(xstart2, ystart, font_head, "Requested"); + DrawTextF(xstart3, ystart, font_head, "Used"); + ystart += ystep_head; #if defined(TARGET_SDL2) driver_name = getStringCopyNStatic(SDL_GetVideoDriver(0), driver_name_len); @@ -3336,10 +3570,10 @@ void DrawInfoScreen_Version() SDL_VideoDriverName(driver_name, driver_name_len); #endif - ystart2 += 2 * ystep; - DrawTextF(xstart1, ystart2, font_text, "SDL_VideoDriver"); - DrawTextF(xstart2, ystart2, font_text, "%s", setup.system.sdl_videodriver); - DrawTextF(xstart3, ystart2, font_text, "%s", driver_name); + DrawTextF(xstart1, ystart, font_text, "SDL_VideoDriver"); + DrawTextF(xstart2, ystart, font_text, "%s", setup.system.sdl_videodriver); + DrawTextF(xstart3, ystart, font_text, "%s", driver_name); + ystart += ystep_line; #if defined(TARGET_SDL2) driver_name = getStringCopyNStatic(SDL_GetAudioDriver(0), driver_name_len); @@ -3347,12 +3581,11 @@ void DrawInfoScreen_Version() SDL_AudioDriverName(driver_name, driver_name_len); #endif - ystart2 += ystep; - DrawTextF(xstart1, ystart2, font_text, "SDL_AudioDriver"); - DrawTextF(xstart2, ystart2, font_text, "%s", setup.system.sdl_audiodriver); - DrawTextF(xstart3, ystart2, font_text, "%s", driver_name); + DrawTextF(xstart1, ystart, font_text, "SDL_AudioDriver"); + DrawTextF(xstart2, ystart, font_text, "%s", setup.system.sdl_audiodriver); + DrawTextF(xstart3, ystart, font_text, "%s", driver_name); - DrawTextSCentered(ybottom, FONT_TEXT_4, + DrawTextSCentered(ybottom, font_foot, "Press any key or button for info menu"); FadeIn(REDRAW_FIELD); @@ -3373,7 +3606,7 @@ void HandleInfoScreen_Version(int button) { PlaySound(SND_MENU_ITEM_SELECTING); - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -3389,7 +3622,7 @@ void DrawInfoScreen_LevelSet() struct TitleMessageInfo *tmi = &readme; char *filename = getLevelSetInfoFilename(); char *title = "Level Set Information:"; - int ystart1 = mSY - SY + 100; + int ystart = mSY - SY + 100; int ybottom = mSY - SY + SYSIZE - 20; if (filename == NULL) @@ -3406,7 +3639,7 @@ void DrawInfoScreen_LevelSet() ClearField(); DrawHeadline(); - DrawTextSCentered(ystart1, FONT_TEXT_1, title); + DrawTextSCentered(ystart, FONT_TEXT_1, title); /* if x position set to "-1", automatically determine by playfield width */ if (tmi->x == -1) @@ -3461,7 +3694,7 @@ void HandleInfoScreen_LevelSet(int button) { PlaySound(SND_MENU_ITEM_SELECTING); - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -3474,8 +3707,6 @@ void HandleInfoScreen_LevelSet(int button) static void DrawInfoScreen() { - SetMainBackgroundImage(IMG_BACKGROUND_INFO); - if (info_mode == INFO_MODE_TITLE) DrawInfoScreen_TitleScreen(); else if (info_mode == INFO_MODE_ELEMENTS) @@ -3496,10 +3727,7 @@ static void DrawInfoScreen() if (info_mode != INFO_MODE_MAIN && info_mode != INFO_MODE_TITLE && info_mode != INFO_MODE_MUSIC) - { - PlayMenuSound(); - PlayMenuMusic(); - } + PlayMenuSoundsAndMusic(); } void HandleInfoScreen(int mx, int my, int dx, int dy, int button) @@ -3550,9 +3778,7 @@ void HandleTypeName(int newxpos, Key key) xpos = newxpos; -#if defined(TARGET_SDL2) - SDL_StartTextInput(); -#endif + StartTextInput(startx, starty, pos->width, pos->height); } else if (is_valid_key_char && xpos < MAX_PLAYER_NAME_LEN) { @@ -3573,7 +3799,7 @@ void HandleTypeName(int newxpos, Key key) is_active = FALSE; - game_status = GAME_MODE_MAIN; + SetGameStatus(GAME_MODE_MAIN); } else if (key == KSYM_Escape) { @@ -3581,7 +3807,7 @@ void HandleTypeName(int newxpos, Key key) is_active = FALSE; - game_status = GAME_MODE_MAIN; + SetGameStatus(GAME_MODE_MAIN); } if (is_active) @@ -3599,9 +3825,7 @@ void HandleTypeName(int newxpos, Key key) DrawText(startx, starty, setup.player_name, font_nr); -#if defined(TARGET_SDL2) - SDL_StopTextInput(); -#endif + StopTextInput(); } } @@ -3614,12 +3838,12 @@ static void DrawChooseTree(TreeInfo **ti_ptr) { int fade_mask = REDRAW_FIELD; - if (CheckIfGlobalBorderHasChanged()) + if (CheckIfGlobalBorderOrPlayfieldViewportHasChanged()) fade_mask = REDRAW_ALL; if (strEqual((*ti_ptr)->subdir, STRING_TOP_DIRECTORY)) { - game_status = GAME_MODE_MAIN; + SetGameStatus(GAME_MODE_MAIN); DrawMainMenu(); @@ -3631,18 +3855,26 @@ static void DrawChooseTree(TreeInfo **ti_ptr) FreeScreenGadgets(); CreateScreenGadgets(); - CloseDoor(DOOR_CLOSE_2); - FadeOut(fade_mask); + /* needed if different viewport properties defined for choosing level (set) */ + ChangeViewportPropertiesIfNeeded(); + + if (game_status == GAME_MODE_LEVELNR) + SetMainBackgroundImage(IMG_BACKGROUND_LEVELNR); + else if (game_status == GAME_MODE_LEVELS) + SetMainBackgroundImage(IMG_BACKGROUND_LEVELS); + ClearField(); + OpenDoor(GetDoorState() | DOOR_NO_DELAY | DOOR_FORCE_REDRAW); + HandleChooseTree(0, 0, 0, 0, MB_MENU_INITIALIZE, ti_ptr); MapScreenTreeGadgets(*ti_ptr); - FadeIn(fade_mask); + DrawMaskedBorder(fade_mask); - InitAnimation(); + FadeIn(fade_mask); } static void drawChooseTreeList(int first_entry, int num_page_entries, @@ -3654,7 +3886,6 @@ static void drawChooseTreeList(int first_entry, int num_page_entries, int yoffset_setup = 16; int yoffset = (ti->type == TREE_TYPE_LEVEL_DIR || ti->type == TREE_TYPE_LEVEL_NR ? yoffset_sets : yoffset_setup); - int last_game_status = game_status; /* save current game status */ title_string = ti->infotext; @@ -3694,8 +3925,6 @@ static void drawChooseTreeList(int first_entry, int num_page_entries, initCursor(i, IMG_MENU_BUTTON); } - game_status = last_game_status; /* restore current game status */ - redraw_mask |= REDRAW_FIELD; } @@ -3743,7 +3972,6 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, int step = (button == 1 ? 1 : button == 2 ? 5 : 10); int num_entries = numTreeInfoInGroup(ti); int num_page_entries; - int last_game_status = game_status; /* save current game status */ boolean position_set_by_scrollbar = (dx == 999); if (num_entries <= NUM_MENU_ENTRIES_ON_SCREEN) @@ -3751,8 +3979,6 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, else num_page_entries = NUM_MENU_ENTRIES_ON_SCREEN; - game_status = last_game_status; /* restore current game status */ - if (button == MB_MENU_INITIALIZE) { int num_entries = numTreeInfoInGroup(ti); @@ -3802,9 +4028,9 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, 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 || - setup_mode == SETUP_MODE_CHOOSE_SCALING_TYPE) + else if (setup_mode == SETUP_MODE_CHOOSE_WINDOW_SIZE || + setup_mode == SETUP_MODE_CHOOSE_SCALING_TYPE || + setup_mode == SETUP_MODE_CHOOSE_RENDERING) execSetupGraphics(); else if (setup_mode == SETUP_MODE_CHOOSE_VOLUME_SIMPLE || setup_mode == SETUP_MODE_CHOOSE_VOLUME_LOOPS || @@ -3826,7 +4052,7 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, HandleMainMenu_SelectLevel(0, 0, new_level_nr); } - game_status = GAME_MODE_MAIN; + SetGameStatus(GAME_MODE_MAIN); DrawMainMenu(); } @@ -3836,12 +4062,8 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, if (mx || my) /* mouse input */ { - int last_game_status = game_status; /* save current game status */ - x = (mx - mSX) / 32; y = (my - mSY) / 32 - MENU_SCREEN_START_YPOS; - - game_status = last_game_status; /* restore current game status */ } else if (dx || dy) /* keyboard or scrollbar/scrollbutton input */ { @@ -3950,6 +4172,30 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, ti->cl_cursor = y; } + else if (dx < 0) + { + 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_SNAPSHOT_MODE) + execSetupGame(); + else if (setup_mode == SETUP_MODE_CHOOSE_WINDOW_SIZE || + setup_mode == SETUP_MODE_CHOOSE_SCALING_TYPE || + setup_mode == SETUP_MODE_CHOOSE_RENDERING) + execSetupGraphics(); + else if (setup_mode == SETUP_MODE_CHOOSE_VOLUME_SIMPLE || + setup_mode == SETUP_MODE_CHOOSE_VOLUME_LOOPS || + setup_mode == SETUP_MODE_CHOOSE_VOLUME_MUSIC) + execSetupSound(); + else if (setup_mode == SETUP_MODE_CHOOSE_TOUCH_CONTROL || + setup_mode == SETUP_MODE_CHOOSE_MOVE_DISTANCE || + setup_mode == SETUP_MODE_CHOOSE_DROP_DISTANCE) + execSetupTouch(); + else + execSetupArtwork(); + } + } } else { @@ -4000,9 +4246,9 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, 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 || - setup_mode == SETUP_MODE_CHOOSE_SCALING_TYPE) + else if (setup_mode == SETUP_MODE_CHOOSE_WINDOW_SIZE || + setup_mode == SETUP_MODE_CHOOSE_SCALING_TYPE || + setup_mode == SETUP_MODE_CHOOSE_RENDERING) execSetupGraphics(); else if (setup_mode == SETUP_MODE_CHOOSE_VOLUME_SIMPLE || setup_mode == SETUP_MODE_CHOOSE_VOLUME_LOOPS || @@ -4024,7 +4270,7 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, HandleMainMenu_SelectLevel(0, 0, new_level_nr); } - game_status = GAME_MODE_MAIN; + SetGameStatus(GAME_MODE_MAIN); DrawMainMenu(); } @@ -4035,12 +4281,11 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, void DrawChooseLevelSet() { - SetMainBackgroundImage(IMG_BACKGROUND_LEVELS); + FadeMenuSoundsAndMusic(); DrawChooseTree(&leveldir_current); - PlayMenuSound(); - PlayMenuMusic(); + PlayMenuSoundsAndMusic(); } void HandleChooseLevelSet(int mx, int my, int dx, int dy, int button) @@ -4052,6 +4297,8 @@ void DrawChooseLevelNr() { int i; + FadeMenuSoundsAndMusic(); + if (level_number != NULL) { freeTreeInfo(level_number); @@ -4070,13 +4317,13 @@ void DrawChooseLevelNr() ti->node_top = &level_number; ti->sort_priority = 10000 + value; - ti->color = (level.no_valid_file ? FC_BLUE : + ti->color = (level.no_level_file ? FC_BLUE : LevelStats_getSolved(i) ? FC_GREEN : LevelStats_getPlayed(i) ? FC_YELLOW : FC_RED); - sprintf(identifier, "%d", value); - sprintf(name, "%03d: %s", value, - (level.no_valid_file ? "(no file)" : level.name)); + snprintf(identifier, sizeof(identifier), "%d", value); + snprintf(name, sizeof(name), "%03d: %s", value, + (level.no_level_file ? "(no file)" : level.name)); setString(&ti->identifier, identifier); setString(&ti->name, name); @@ -4096,12 +4343,9 @@ void DrawChooseLevelNr() if (level_number_current == NULL) level_number_current = level_number; - SetMainBackgroundImage(IMG_BACKGROUND_LEVELNR); - DrawChooseTree(&level_number_current); - PlayMenuSound(); - PlayMenuMusic(); + PlayMenuSoundsAndMusic(); } void HandleChooseLevelNr(int mx, int my, int dx, int dy, int button) @@ -4113,21 +4357,14 @@ void DrawHallOfFame(int highlight_position) { int fade_mask = REDRAW_FIELD; - /* required before door position may be changed in next step */ - CloseDoor(DOOR_CLOSE_ALL); - - /* needed if different viewport properties defined for scores */ - ChangeViewportPropertiesIfNeeded(); - - if (CheckIfGlobalBorderHasChanged()) + if (CheckIfGlobalBorderOrPlayfieldViewportHasChanged()) fade_mask = REDRAW_ALL; UnmapAllGadgets(); - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); /* (this is needed when called from GameEnd() after winning a game) */ KeyboardAutoRepeatOn(); - ActivateJoystick(); /* (this is needed when called from GameEnd() after winning a game) */ SetDrawDeactivationMask(REDRAW_NONE); @@ -4135,18 +4372,24 @@ void DrawHallOfFame(int highlight_position) if (highlight_position < 0) LoadScore(level_nr); + else + SetAnimStatus(GAME_MODE_PSEUDO_SCORESNEW); FadeSetEnterScreen(); FadeOut(fade_mask); - InitAnimation(); + /* needed if different viewport properties defined for scores */ + ChangeViewportPropertiesIfNeeded(); - PlayMenuSound(); - PlayMenuMusic(); + PlayMenuSoundsAndMusic(); + + OpenDoor(GetDoorState() | DOOR_NO_DELAY | DOOR_FORCE_REDRAW); HandleHallOfFame(highlight_position, 0, 0, 0, MB_MENU_INITIALIZE); + DrawMaskedBorder(fade_mask); + FadeIn(fade_mask); } @@ -4169,9 +4412,10 @@ static void drawHallOfFameList(int first_entry, int highlight_position) int font_nr2 = (active ? FONT_TEXT_2_ACTIVE : FONT_TEXT_2); int font_nr3 = (active ? FONT_TEXT_3_ACTIVE : FONT_TEXT_3); int font_nr4 = (active ? FONT_TEXT_4_ACTIVE : FONT_TEXT_4); + int dxoff = getFontDrawOffsetX(font_nr1); int dx1 = 3 * getFontWidth(font_nr1); int dx2 = dx1 + getFontWidth(font_nr1); - int dx3 = SXSIZE - 2 * (mSX - SX) - 5 * getFontWidth(font_nr4); + int dx3 = SXSIZE - 2 * (mSX - SX + dxoff) - 5 * getFontWidth(font_nr4); int num_dots = (dx3 - dx2) / getFontWidth(font_nr3); int sy = mSY + 64 + i * 32; @@ -4236,7 +4480,7 @@ void HandleHallOfFame(int mx, int my, int dx, int dy, int button) FadeSound(SND_BACKGROUND_SCORES); - game_status = GAME_MODE_MAIN; + SetGameStatus(GAME_MODE_MAIN); DrawMainMenu(); } @@ -4246,7 +4490,7 @@ void HandleHallOfFame(int mx, int my, int dx, int dy, int button) FadeSound(SND_BACKGROUND_SCORES); - game_status = GAME_MODE_MAIN; + SetGameStatus(GAME_MODE_MAIN); DrawMainMenu(); } @@ -4264,9 +4508,9 @@ static struct TokenInfo *setup_info; static int num_setup_info; /* number of setup entries shown on screen */ static int max_setup_info; /* total number of setup entries in list */ -static char *screen_mode_text; static char *window_size_text; static char *scaling_type_text; +static char *rendering_mode_text; static char *scroll_delay_text; static char *snapshot_mode_text; static char *game_speed_text; @@ -4359,31 +4603,31 @@ static void execSetupGame_setScrollDelays() setString(&ti->identifier, identifier); setString(&ti->name, name); setString(&ti->name_sorting, name); - setString(&ti->infotext, "Scaling Type"); + setString(&ti->infotext, "Scroll Delay"); pushTreeInfo(&scroll_delays, ti); } - /* sort scaling type values to start with lowest scaling type value */ + /* sort scroll delay values to start with lowest scroll delay value */ sortTreeInfo(&scroll_delays); - /* set current scaling type value to configured scaling type value */ + /* set current scroll delay value to configured scroll delay value */ scroll_delay_current = getTreeInfoFromIdentifier(scroll_delays,i_to_a(setup.scroll_delay_value)); - /* if that fails, set current scaling type to reliable default value */ + /* if that fails, set current scroll delay to reliable default value */ if (scroll_delay_current == NULL) scroll_delay_current = getTreeInfoFromIdentifier(scroll_delays, i_to_a(STD_SCROLL_DELAY)); - /* if that also fails, set current scaling type to first available value */ + /* if that also fails, set current scroll delay to first available value */ if (scroll_delay_current == NULL) scroll_delay_current = scroll_delays; } setup.scroll_delay_value = atoi(scroll_delay_current->identifier); - /* needed for displaying scaling type text instead of identifier */ + /* needed for displaying scroll delay text instead of identifier */ scroll_delay_text = scroll_delay_current->name; } @@ -4611,82 +4855,70 @@ static void execSetupGraphics_setScalingTypes() scaling_type_text = scaling_type_current->name; } -static void execSetupGraphics_setScreenModes() +static void execSetupGraphics_setRenderingModes() { - // if (screen_modes == NULL && video.fullscreen_available) - if (screen_modes == NULL && video.fullscreen_modes != NULL) + if (rendering_modes == NULL) { int i; - for (i = 0; video.fullscreen_modes[i].width != -1; i++) + for (i = 0; rendering_modes_list[i].value != NULL; i++) { TreeInfo *ti = newTreeInfo_setDefaults(TREE_TYPE_UNDEFINED); char identifier[32], name[32]; - int x = video.fullscreen_modes[i].width; - int y = video.fullscreen_modes[i].height; - int xx, yy; - - get_aspect_ratio_from_screen_mode(&video.fullscreen_modes[i], &xx, &yy); + char *value = rendering_modes_list[i].value; + char *text = rendering_modes_list[i].text; - ti->node_top = &screen_modes; - ti->sort_priority = x * 10000 + y; + ti->node_top = &rendering_modes; + ti->sort_priority = i; - sprintf(identifier, "%dx%d", x, y); - sprintf(name, "%d x %d [%d:%d]", x, y, xx, yy); + sprintf(identifier, "%s", value); + sprintf(name, "%s", text); setString(&ti->identifier, identifier); setString(&ti->name, name); setString(&ti->name_sorting, name); - setString(&ti->infotext, "Fullscreen Mode"); + setString(&ti->infotext, "Special Rendering"); - pushTreeInfo(&screen_modes, ti); + pushTreeInfo(&rendering_modes, ti); } - /* sort fullscreen modes to start with lowest available screen resolution */ - sortTreeInfo(&screen_modes); - - /* set current screen mode for fullscreen mode to configured setup value */ - screen_mode_current = getTreeInfoFromIdentifier(screen_modes, - setup.fullscreen_mode); + /* sort rendering mode values to start with lowest rendering mode value */ + sortTreeInfo(&rendering_modes); - /* if that fails, set current screen mode to reliable default value */ - if (screen_mode_current == NULL) - screen_mode_current = getTreeInfoFromIdentifier(screen_modes, - DEFAULT_FULLSCREEN_MODE); + /* set current rendering mode value to configured rendering mode value */ + rendering_mode_current = + getTreeInfoFromIdentifier(rendering_modes, setup.screen_rendering_mode); - /* if that also fails, set current screen mode to first available mode */ - if (screen_mode_current == NULL) - screen_mode_current = screen_modes; + /* if that fails, set current rendering mode to reliable default value */ + if (rendering_mode_current == NULL) + rendering_mode_current = + getTreeInfoFromIdentifier(rendering_modes, + STR_SPECIAL_RENDERING_DEFAULT); - if (screen_mode_current == NULL) - video.fullscreen_available = FALSE; + /* if that also fails, set current rendering mode to first available one */ + if (rendering_mode_current == NULL) + rendering_mode_current = rendering_modes; } - // if (video.fullscreen_available) - if (screen_mode_current != NULL) - { - setup.fullscreen_mode = screen_mode_current->identifier; + setup.screen_rendering_mode = rendering_mode_current->identifier; - /* needed for displaying screen mode name instead of identifier */ - screen_mode_text = screen_mode_current->name; - } + /* needed for displaying rendering mode text instead of identifier */ + rendering_mode_text = rendering_mode_current->name; } static void execSetupGraphics() { + // update "setup.window_scaling_percent" from list selection + // (in this case, window scaling was changed on setup screen) if (setup_mode == SETUP_MODE_CHOOSE_WINDOW_SIZE) - { - // update "setup.window_scaling_percent" from list selection execSetupGraphics_setWindowSizes(FALSE); - } - else - { - // update list selection from "setup.window_scaling_percent" - execSetupGraphics_setWindowSizes(TRUE); - } + + // update list selection from "setup.window_scaling_percent" + // (window scaling may have changed by resizing the window) + execSetupGraphics_setWindowSizes(TRUE); execSetupGraphics_setScalingTypes(); - execSetupGraphics_setScreenModes(); + execSetupGraphics_setRenderingModes(); setup_mode = SETUP_MODE_GRAPHICS; @@ -4699,11 +4931,13 @@ static void execSetupGraphics() // window scaling quality may have changed at this point if (!strEqual(setup.window_scaling_quality, video.window_scaling_quality)) SDLSetWindowScalingQuality(setup.window_scaling_quality); + + // screen rendering mode may have changed at this point + SDLSetScreenRenderingMode(setup.screen_rendering_mode); #endif } -#if !defined(PLATFORM_ANDROID) -#if defined(TARGET_SDL2) +#if defined(TARGET_SDL2) && !defined(PLATFORM_ANDROID) static void execSetupChooseWindowSize() { setup_mode = SETUP_MODE_CHOOSE_WINDOW_SIZE; @@ -4717,18 +4951,14 @@ static void execSetupChooseScalingType() DrawSetupScreen(); } -#else -static void execSetupChooseScreenMode() -{ - if (!video.fullscreen_available) - return; - setup_mode = SETUP_MODE_CHOOSE_SCREEN_MODE; +static void execSetupChooseRenderingMode() +{ + setup_mode = SETUP_MODE_CHOOSE_RENDERING; DrawSetupScreen(); } #endif -#endif static void execSetupChooseVolumeSimple() { @@ -5183,14 +5413,12 @@ static void execSetupChooseMusic() DrawSetupScreen(); } -#if !defined(PLATFORM_ANDROID) static void execSetupInput() { setup_mode = SETUP_MODE_INPUT; DrawSetupScreen(); } -#endif static void execSetupShortcuts() { @@ -5236,7 +5464,7 @@ static void execSetupShortcuts5() static void execExitSetup() { - game_status = GAME_MODE_MAIN; + SetGameStatus(GAME_MODE_MAIN); DrawMainMenu(); } @@ -5254,12 +5482,8 @@ static struct TokenInfo setup_info_main[] = { TYPE_ENTER_MENU, execSetupGraphics, "Graphics" }, { TYPE_ENTER_MENU, execSetupSound, "Sound & Music" }, { TYPE_ENTER_MENU, execSetupArtwork, "Custom Artwork" }, -#if !defined(PLATFORM_ANDROID) { TYPE_ENTER_MENU, execSetupInput, "Input Devices" }, { TYPE_ENTER_MENU, execSetupTouch, "Touch Controls" }, -#else - { TYPE_ENTER_MENU, execSetupTouch, "Touch Controls" }, -#endif { TYPE_ENTER_MENU, execSetupShortcuts, "Key Shortcuts" }, { TYPE_EMPTY, NULL, "" }, { TYPE_LEAVE_MENU, execExitSetup, "Exit" }, @@ -5272,9 +5496,10 @@ static struct TokenInfo setup_info_game[] = { { TYPE_SWITCH, &setup.team_mode, "Team-Mode (Multi-Player):" }, { TYPE_YES_NO, &setup.input_on_focus, "Only Move Focussed Player:" }, + { TYPE_SWITCH, &setup.time_limit, "Time Limit:" }, { TYPE_SWITCH, &setup.handicap, "Handicap:" }, { TYPE_SWITCH, &setup.skip_levels, "Skip Unsolved Levels:" }, - { TYPE_SWITCH, &setup.time_limit, "Time Limit:" }, + { TYPE_SWITCH, &setup.increment_levels,"Increment Solved Levels:" }, { TYPE_SWITCH, &setup.autorecord, "Auto-Record Tapes:" }, { TYPE_ENTER_LIST, execSetupChooseGameSpeed, "Game Speed:" }, { TYPE_STRING, &game_speed_text, "" }, @@ -5302,9 +5527,10 @@ static struct TokenInfo setup_info_editor[] = { TYPE_SWITCH, &setup.editor.el_supaplex, "Supaplex:" }, { TYPE_SWITCH, &setup.editor.el_diamond_caves, "Diamond Caves II:" }, { TYPE_SWITCH, &setup.editor.el_dx_boulderdash,"DX-Boulderdash:" }, -#endif { TYPE_SWITCH, &setup.editor.el_chars, "Text Characters:" }, { TYPE_SWITCH, &setup.editor.el_steel_chars, "Text Characters (Steel):" }, +#endif + { TYPE_SWITCH, &setup.editor.el_classic, "Classic Elements:" }, { TYPE_SWITCH, &setup.editor.el_custom, "Custom & Group Elements:" }, #if 0 { TYPE_SWITCH, &setup.editor.el_headlines, "Headlines:" }, @@ -5326,17 +5552,14 @@ static struct TokenInfo setup_info_editor[] = static struct TokenInfo setup_info_graphics[] = { -#if !defined(PLATFORM_ANDROID) +#if defined(TARGET_SDL2) && !defined(PLATFORM_ANDROID) { TYPE_SWITCH, &setup.fullscreen, "Fullscreen:" }, -#if defined(TARGET_SDL2) { TYPE_ENTER_LIST, execSetupChooseWindowSize, "Window Scaling:" }, { TYPE_STRING, &window_size_text, "" }, { TYPE_ENTER_LIST, execSetupChooseScalingType, "Anti-Aliasing:" }, { TYPE_STRING, &scaling_type_text, "" }, -#else - { TYPE_ENTER_LIST, execSetupChooseScreenMode, "Fullscreen Mode:" }, - { TYPE_STRING, &screen_mode_text, "" }, -#endif + { TYPE_ENTER_LIST, execSetupChooseRenderingMode, "Special Rendering:" }, + { TYPE_STRING, &rendering_mode_text, "" }, #endif #if 0 { TYPE_ENTER_LIST, execSetupChooseScrollDelay, "Scroll Delay:" }, @@ -5346,7 +5569,7 @@ static struct TokenInfo setup_info_graphics[] = { TYPE_SWITCH, &setup.quick_switch, "Quick Player Focus Switch:" }, { TYPE_SWITCH, &setup.quick_doors, "Quick Menu Doors:" }, { TYPE_SWITCH, &setup.show_titlescreen,"Show Title Screens:" }, - { TYPE_SWITCH, &setup.toons, "Show Toons:" }, + { TYPE_SWITCH, &setup.toons, "Show Menu Animations:" }, { TYPE_ECS_AGA, &setup.prefer_aga_graphics,"EMC graphics preference:" }, { TYPE_SWITCH, &setup.sp_show_border_elements,"Supaplex Border Elements:" }, { TYPE_SWITCH, &setup.small_game_graphics, "Small Game Graphics:" }, @@ -5396,7 +5619,7 @@ static struct TokenInfo setup_info_input[] = { { TYPE_SWITCH, NULL, "Player:" }, { TYPE_SWITCH, NULL, "Device:" }, - { TYPE_ENTER_MENU, NULL, "" }, + { TYPE_SWITCH, NULL, "" }, { TYPE_EMPTY, NULL, "" }, { TYPE_EMPTY, NULL, "" }, { TYPE_EMPTY, NULL, "" }, @@ -5413,6 +5636,16 @@ static struct TokenInfo setup_info_input[] = }; static struct TokenInfo setup_info_touch[] = +{ + { TYPE_ENTER_LIST, execSetupChooseTouchControls, "Touch Control Type:" }, + { TYPE_STRING, &touch_controls_text, "" }, + { TYPE_EMPTY, NULL, "" }, + { TYPE_LEAVE_MENU, execSetupMain, "Back" }, + + { 0, NULL, NULL } +}; + +static struct TokenInfo setup_info_touch_wipe_gestures[] = { { TYPE_ENTER_LIST, execSetupChooseTouchControls, "Touch Control Type:" }, { TYPE_STRING, &touch_controls_text, "" }, @@ -5532,12 +5765,10 @@ static Key getSetupKey() while (!got_key_event) { - if (PendingEvent()) /* got event */ - { - Event event; - - NextEvent(&event); + Event event; + if (NextValidEvent(&event)) + { switch (event.type) { case EVENT_KEYPRESS: @@ -5562,11 +5793,7 @@ static Key getSetupKey() } } - DoAnimation(); BackToFront(); - - /* don't eat all CPU time */ - Delay(10); } return key; @@ -5574,7 +5801,9 @@ static Key getSetupKey() static int getSetupValueFont(int type, void *value) { - if (type & TYPE_KEY) + if (type & TYPE_GHOSTED) + return FONT_OPTION_OFF; + else if (type & TYPE_KEY) return (type & TYPE_QUERY ? FONT_INPUT_1_ACTIVE : FONT_VALUE_1); else if (type & TYPE_STRING) return FONT_VALUE_2; @@ -5589,20 +5818,29 @@ static int getSetupValueFont(int type, void *value) return FONT_VALUE_1; } +static int getSetupValueFontNarrow(int type, int font_nr) +{ + return (font_nr == FONT_VALUE_1 ? FONT_VALUE_NARROW : + font_nr == FONT_OPTION_ON ? FONT_OPTION_ON_NARROW : + font_nr == FONT_OPTION_OFF ? FONT_OPTION_OFF_NARROW : + font_nr); +} + static void drawSetupValue(int screen_pos, int setup_info_pos_raw) { int si_pos = (setup_info_pos_raw < 0 ? screen_pos : setup_info_pos_raw); struct TokenInfo *si = &setup_info[si_pos]; boolean font_draw_xoffset_modified = FALSE; + boolean scrollbar_needed = (num_setup_info < max_setup_info); int font_draw_xoffset_old = -1; - int xoffset = (num_setup_info < max_setup_info ? -1 : 0); + int xoffset = (scrollbar_needed ? -1 : 0); int menu_screen_value_xpos = MENU_SCREEN_VALUE_XPOS + xoffset; int menu_screen_max_xpos = MENU_SCREEN_MAX_XPOS + xoffset; int xpos = menu_screen_value_xpos; int ypos = MENU_SCREEN_START_YPOS + screen_pos; int startx = mSX + xpos * 32; int starty = mSY + ypos * 32; - int font_nr, font_width; + int font_nr, font_nr_default, font_width_default; int type = si->type; void *value = si->value; char *value_string = getSetupValue(type, value); @@ -5634,8 +5872,29 @@ static void drawSetupValue(int screen_pos, int setup_info_pos_raw) startx = mSX + xpos * 32; starty = mSY + ypos * 32; - font_nr = getSetupValueFont(type, value); - font_width = getFontWidth(font_nr); + font_nr_default = getSetupValueFont(type, value); + font_width_default = getFontWidth(font_nr_default); + + font_nr = font_nr_default; + + // special check if right-side setup values moved left due to scrollbar + if (scrollbar_needed && xpos > MENU_SCREEN_START_XPOS) + { + int max_menu_text_length = 26; // maximum text length for classic menu + int font_xoffset = getFontBitmapInfo(font_nr)->draw_xoffset; + int text_startx = mSX + MENU_SCREEN_START_XPOS * 32; + int text_font_nr = getMenuTextFont(FONT_MENU_2); + int text_font_xoffset = getFontBitmapInfo(text_font_nr)->draw_xoffset; + int text_width = max_menu_text_length * getFontWidth(text_font_nr); + + if (startx + font_xoffset < text_startx + text_width + text_font_xoffset) + { + xpos += 1; + startx = mSX + xpos * 32; + + font_nr = getSetupValueFontNarrow(type, font_nr); + } + } /* downward compatibility correction for Juergen Bonhagen's menu settings */ if (setup_mode != SETUP_MODE_INPUT) @@ -5676,7 +5935,7 @@ static void drawSetupValue(int screen_pos, int setup_info_pos_raw) } for (i = 0; i <= menu_screen_max_xpos - xpos; i++) - DrawText(startx + i * font_width, starty, " ", font_nr); + DrawText(startx + i * font_width_default, starty, " ", font_nr_default); DrawText(startx, starty, value_string, font_nr); @@ -5722,6 +5981,28 @@ static void changeSetupValue(int screen_pos, int setup_info_pos_raw, int dx) ToggleFullscreenOrChangeWindowScalingIfNeeded(); } +static struct TokenInfo *getSetupInfoFinal(struct TokenInfo *setup_info_orig) +{ + static struct TokenInfo *setup_info_hide = NULL; + int list_size = 0; + int list_pos = 0; + int i; + + /* determine maximum list size of target list */ + while (setup_info_orig[list_size++].type != 0); + + /* free, allocate and clear memory for target list */ + checked_free(setup_info_hide); + setup_info_hide = checked_calloc(list_size * sizeof(struct TokenInfo)); + + /* copy setup info list without setup entries marked as hidden */ + for (i = 0; setup_info_orig[i].type != 0; i++) + if (!hideSetupEntry(setup_info_orig[i].value)) + setup_info_hide[list_pos++] = setup_info_orig[i]; + + return setup_info_hide; +} + static void DrawSetupScreen_Generic() { int fade_mask = REDRAW_FIELD; @@ -5729,23 +6010,29 @@ static void DrawSetupScreen_Generic() char *title_string = NULL; int i; - if (CheckIfGlobalBorderHasChanged()) + if (CheckIfGlobalBorderOrPlayfieldViewportHasChanged()) fade_mask = REDRAW_ALL; UnmapAllGadgets(); + FadeMenuSoundsAndMusic(); FreeScreenGadgets(); CreateScreenGadgets(); - CloseDoor(DOOR_CLOSE_2); - if (redraw_mask & REDRAW_ALL) redraw_all = TRUE; FadeOut(fade_mask); + /* needed if different viewport properties defined for setup screen */ + ChangeViewportPropertiesIfNeeded(); + + SetMainBackgroundImage(IMG_BACKGROUND_SETUP); + ClearField(); + OpenDoor(GetDoorState() | DOOR_NO_DELAY | DOOR_FORCE_REDRAW); + if (setup_mode == SETUP_MODE_MAIN) { setup_info = setup_info_main; @@ -5780,6 +6067,9 @@ static void DrawSetupScreen_Generic() { setup_info = setup_info_touch; title_string = "Setup Touch Ctrls"; + + if (strEqual(setup.touch.control_type, TOUCH_CONTROL_WIPE_GESTURES)) + setup_info = setup_info_touch_wipe_gestures; } else if (setup_mode == SETUP_MODE_SHORTCUTS) { @@ -5812,6 +6102,9 @@ static void DrawSetupScreen_Generic() title_string = "Setup Shortcuts"; } + /* use modified setup info without setup entries marked as hidden */ + setup_info = getSetupInfoFinal(setup_info); + DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, title_string); // determine maximal number of setup entries that can be displayed on screen @@ -5831,9 +6124,9 @@ static void DrawSetupScreen_Generic() if (redraw_all) redraw_mask = fade_mask = REDRAW_ALL; - FadeIn(fade_mask); + DrawMaskedBorder(fade_mask); - InitAnimation(); + FadeIn(fade_mask); } void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button) @@ -5856,9 +6149,6 @@ void DrawSetupScreen_Input() DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, "Setup Input"); - DrawTextSCentered(SYSIZE - 20, FONT_TITLE_2, - "Joysticks deactivated on this screen"); - for (i = 0; setup_info[i].type != 0 && i < MAX_MENU_ENTRIES_ON_SCREEN; i++) { if (setup_info[i].type & (TYPE_ENTER_MENU|TYPE_ENTER_LIST)) @@ -5881,8 +6171,6 @@ void DrawSetupScreen_Input() HandleSetupScreen_Input(0, 0, 0, 0, MB_MENU_INITIALIZE); FadeIn(REDRAW_FIELD); - - InitAnimation(); } static void setJoystickDeviceToNr(char *device_name, int device_nr) @@ -5916,12 +6204,12 @@ static void drawPlayerSetupInputInfo(int player_nr, boolean active) char *text; } custom[] = { - { &custom_key.left, "Joystick Left" }, - { &custom_key.right, "Joystick Right" }, - { &custom_key.up, "Joystick Up" }, - { &custom_key.down, "Joystick Down" }, - { &custom_key.snap, "Button 1" }, - { &custom_key.drop, "Button 2" } + { &custom_key.left, "Axis/Pad Left" }, + { &custom_key.right, "Axis/Pad Right" }, + { &custom_key.up, "Axis/Pad Up" }, + { &custom_key.down, "Axis/Pad Down" }, + { &custom_key.snap, "Button 1/A/X" }, + { &custom_key.drop, "Button 2/B/Y" } }; static char *joystick_name[MAX_PLAYERS] = { @@ -5932,8 +6220,6 @@ static void drawPlayerSetupInputInfo(int player_nr, boolean active) }; int text_font_nr = (active ? FONT_MENU_1_ACTIVE : FONT_MENU_1); - InitJoysticks(); - custom_key = setup.input[player_nr].key; DrawText(mSX + 11 * 32, mSY + 2 * 32, int2str(player_nr + 1, 1), @@ -5947,11 +6233,13 @@ static void drawPlayerSetupInputInfo(int player_nr, boolean active) if (setup.input[player_nr].use_joystick) { char *device_name = setup.input[player_nr].joy.device_name; - char *text = joystick_name[getJoystickNrFromDeviceName(device_name)]; - int font_nr = (joystick.fd[player_nr] < 0 ? FONT_VALUE_OLD : FONT_VALUE_1); + int joystick_nr = getJoystickNrFromDeviceName(device_name); + boolean joystick_active = CheckJoystickOpened(joystick_nr); + char *text = joystick_name[joystick_nr]; + int font_nr = (joystick_active ? FONT_VALUE_1 : FONT_VALUE_OLD); DrawText(mSX + 8 * 32, mSY + 3 * 32, text, font_nr); - DrawText(mSX + 32, mSY + 4 * 32, "Calibrate", text_font_nr); + DrawText(mSX + 32, mSY + 4 * 32, "Configure", text_font_nr); } else { @@ -6044,7 +6332,6 @@ void HandleSetupScreen_Input(int mx, int my, int dx, int dy, int button) if (dx && choice == 0) x = (dx < 0 ? 10 : 12); else if ((dx && choice == 1) || - (dx == +1 && choice == 2) || (dx == -1 && choice == pos_end)) button = MB_MENU_CHOICE; else if (dy) @@ -6103,10 +6390,7 @@ void HandleSetupScreen_Input(int mx, int my, int dx, int dy, int button) else if (y == 2) { if (setup.input[input_player_nr].use_joystick) - { - InitJoysticks(); - CalibrateJoystick(input_player_nr); - } + ConfigureJoystick(input_player_nr); else CustomizeKeyboard(input_player_nr); } @@ -6163,16 +6447,12 @@ void CustomizeKeyboard(int player_nr) FadeIn(REDRAW_FIELD); - InitAnimation(); - while (!finished) { - if (PendingEvent()) /* got event */ - { - Event event; - - NextEvent(&event); + Event event; + if (NextValidEvent(&event)) + { switch (event.type) { case EVENT_KEYPRESS: @@ -6246,211 +6526,439 @@ void CustomizeKeyboard(int player_nr) } } - DoAnimation(); BackToFront(); - - /* don't eat all CPU time */ - Delay(10); } /* write new key bindings back to player setup */ setup.input[player_nr].key = custom_key; - StopAnimation(); DrawSetupScreen_Input(); } -static boolean CalibrateJoystickMain(int player_nr) -{ - int new_joystick_xleft = JOYSTICK_XMIDDLE; - int new_joystick_xright = JOYSTICK_XMIDDLE; - int new_joystick_yupper = JOYSTICK_YMIDDLE; - int new_joystick_ylower = JOYSTICK_YMIDDLE; - int new_joystick_xmiddle, new_joystick_ymiddle; +/* game controller mapping generator by Gabriel Jacobo */ - int joystick_fd = joystick.fd[player_nr]; - int x, y, last_x, last_y, xpos = 8, ypos = 3; - boolean check[3][3]; - int check_remaining = 3 * 3; - int joy_x, joy_y; - int joy_value; - int result = -1; +#define MARKER_BUTTON 1 +#define MARKER_AXIS_X 2 +#define MARKER_AXIS_Y 3 - if (joystick.status == JOYSTICK_NOT_AVAILABLE) - return FALSE; +static boolean ConfigureJoystickMapButtonsAndAxes(SDL_Joystick *joystick) +{ +#if defined(TARGET_SDL2) + static boolean bitmaps_initialized = FALSE; + boolean screen_initialized = FALSE; + static Bitmap *controller, *button, *axis_x, *axis_y; + char *name; + boolean success = TRUE; + boolean done = FALSE, next = FALSE; + Event event; + int alpha = 200, alpha_step = -1; + int alpha_ticks = 0; + char mapping[4096], temp[4096]; + int font_name = MENU_SETUP_FONT_TITLE; + int font_info = MENU_SETUP_FONT_TEXT; + int spacing_name = menu.line_spacing_setup[SETUP_MODE_INPUT]; + int spacing_line = menu.line_spacing_setup[SETUP_MODE_INPUT]; + int spacing_para = menu.paragraph_spacing_setup[SETUP_MODE_INPUT]; + int ystep_name = getMenuTextStep(spacing_name, font_name); + int ystep_line = getMenuTextStep(spacing_line, font_info); + int ystep_para = getMenuTextStep(spacing_para, font_info); + int i, j; - if (joystick_fd < 0 || !setup.input[player_nr].use_joystick) - return FALSE; + struct + { + int x, y; + int marker; + char *field; + int axis, button, hat, hat_value; + char mapping[4096]; + } + *step, *prev_step, steps[] = + { + { 356, 155, MARKER_BUTTON, "a", }, + { 396, 122, MARKER_BUTTON, "b", }, + { 320, 125, MARKER_BUTTON, "x", }, + { 358, 95, MARKER_BUTTON, "y", }, + { 162, 125, MARKER_BUTTON, "back", }, + { 216, 125, MARKER_BUTTON, "guide", }, + { 271, 125, MARKER_BUTTON, "start", }, + { 110, 200, MARKER_BUTTON, "dpleft", }, + { 146, 228, MARKER_BUTTON, "dpdown", }, + { 178, 200, MARKER_BUTTON, "dpright", }, + { 146, 172, MARKER_BUTTON, "dpup", }, + { 50, 40, MARKER_BUTTON, "leftshoulder", }, + { 88, -10, MARKER_AXIS_Y, "lefttrigger", }, + { 382, 40, MARKER_BUTTON, "rightshoulder", }, + { 346, -10, MARKER_AXIS_Y, "righttrigger", }, + { 73, 141, MARKER_BUTTON, "leftstick", }, + { 282, 210, MARKER_BUTTON, "rightstick", }, + { 73, 141, MARKER_AXIS_X, "leftx", }, + { 73, 141, MARKER_AXIS_Y, "lefty", }, + { 282, 210, MARKER_AXIS_X, "rightx", }, + { 282, 210, MARKER_AXIS_Y, "righty", }, + }; - FadeSetEnterMenu(); - FadeOut(REDRAW_FIELD); + unsigned int event_frame_delay = 0; + unsigned int event_frame_delay_value = GAME_FRAME_DELAY; - ClearField(); + ResetDelayCounter(&event_frame_delay); - for (y = 0; y < 3; y++) + if (!bitmaps_initialized) { - for (x = 0; x < 3; x++) - { - DrawFixedGraphic(xpos + x - 1, ypos + y - 1, IMG_MENU_CALIBRATE_BLUE, 0); - check[x][y] = FALSE; - } + controller = LoadCustomImage("joystick/controller.png"); + button = LoadCustomImage("joystick/button.png"); + axis_x = LoadCustomImage("joystick/axis_x.png"); + axis_y = LoadCustomImage("joystick/axis_y.png"); + + bitmaps_initialized = TRUE; } - DrawTextSCentered(mSY - SY + 6 * 32, FONT_TITLE_1, "Rotate joystick"); - DrawTextSCentered(mSY - SY + 7 * 32, FONT_TITLE_1, "in all directions"); - DrawTextSCentered(mSY - SY + 9 * 32, FONT_TITLE_1, "if all balls"); - DrawTextSCentered(mSY - SY + 10 * 32, FONT_TITLE_1, "are marked,"); - DrawTextSCentered(mSY - SY + 11 * 32, FONT_TITLE_1, "center joystick"); - DrawTextSCentered(mSY - SY + 12 * 32, FONT_TITLE_1, "and"); - DrawTextSCentered(mSY - SY + 13 * 32, FONT_TITLE_1, "press any button!"); + name = getFormattedJoystickName(SDL_JoystickName(joystick)); - joy_value = Joystick(player_nr); - last_x = (joy_value & JOY_LEFT ? -1 : joy_value & JOY_RIGHT ? +1 : 0); - last_y = (joy_value & JOY_UP ? -1 : joy_value & JOY_DOWN ? +1 : 0); +#if DEBUG_JOYSTICKS + /* print info about the joystick we are watching */ + Error(ERR_DEBUG, "watching joystick %d: (%s)\n", + SDL_JoystickInstanceID(joystick), name); + Error(ERR_DEBUG, "joystick has %d axes, %d hats, %d balls, and %d buttons\n", + SDL_JoystickNumAxes(joystick), SDL_JoystickNumHats(joystick), + SDL_JoystickNumBalls(joystick), SDL_JoystickNumButtons(joystick)); +#endif - /* eventually uncalibrated center position (joystick could be uncentered) */ - if (!ReadJoystick(joystick_fd, &joy_x, &joy_y, NULL, NULL)) - return FALSE; + /* initialize mapping with GUID and name */ + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), temp, sizeof(temp)); - new_joystick_xmiddle = joy_x; - new_joystick_ymiddle = joy_y; + snprintf(mapping, sizeof(mapping), "%s,%s,platform:%s,", + temp, name, SDL_GetPlatform()); - DrawFixedGraphic(xpos + last_x, ypos + last_y, IMG_MENU_CALIBRATE_RED, 0); + /* loop through all steps (buttons and axes), getting joystick events */ + for (i = 0; i < SDL_arraysize(steps) && !done;) + { + Bitmap *marker = button; /* initialize with reliable default value */ - FadeIn(REDRAW_FIELD); + step = &steps[i]; + strcpy(step->mapping, mapping); + step->axis = -1; + step->button = -1; + step->hat = -1; + step->hat_value = -1; - while (Joystick(player_nr) & JOY_BUTTON); /* wait for released button */ - InitAnimation(); + marker = (step->marker == MARKER_BUTTON ? button : + step->marker == MARKER_AXIS_X ? axis_x : + step->marker == MARKER_AXIS_Y ? axis_y : marker); - while (result < 0) - { - if (PendingEvent()) /* got event */ + next = FALSE; + + while (!done && !next) { - Event event; + alpha += alpha_step * (int)(SDL_GetTicks() - alpha_ticks) / 5; + alpha_ticks = SDL_GetTicks(); - NextEvent(&event); + if (alpha >= 255) + { + alpha = 255; + alpha_step = -1; + } + else if (alpha < 128) + { + alpha = 127; + alpha_step = 1; + } - switch (event.type) + int controller_x = SX + (SXSIZE - controller->width) / 2; + int controller_y = SY + ystep_line; + + int marker_x = controller_x + step->x; + int marker_y = controller_y + step->y; + + int ystart1 = mSY - 2 * SY + controller_y + controller->height; + int ystart2 = ystart1 + ystep_name + ystep_line; + + ClearField(); + + DrawTextSCentered(ystart1, font_name, name); + + DrawTextSCentered(ystart2, font_info, + "Press buttons and move axes on"); + ystart2 += ystep_line; + DrawTextSCentered(ystart2, font_info, + "your controller when indicated."); + ystart2 += ystep_line; + DrawTextSCentered(ystart2, font_info, + "(Your controller may look different.)"); + ystart2 += ystep_para; + +#if defined(PLATFORM_ANDROID) + DrawTextSCentered(ystart2, font_info, + "To correct a mistake,"); + ystart2 += ystep_line; + DrawTextSCentered(ystart2, font_info, + "press the 'back' button."); + ystart2 += ystep_line; + DrawTextSCentered(ystart2, font_info, + "To skip a button or axis,"); + ystart2 += ystep_line; + DrawTextSCentered(ystart2, font_info, + "press the 'menu' button."); +#else + DrawTextSCentered(ystart2, font_info, + "To correct a mistake,"); + ystart2 += ystep_line; + DrawTextSCentered(ystart2, font_info, + "press the 'backspace' key."); + ystart2 += ystep_line; + DrawTextSCentered(ystart2, font_info, + "To skip a button or axis,"); + ystart2 += ystep_line; + DrawTextSCentered(ystart2, font_info, + "press the 'return' key."); + ystart2 += ystep_line; + DrawTextSCentered(ystart2, font_info, + "To exit, press the 'escape' key."); +#endif + + BlitBitmapMasked(controller, drawto, 0, 0, + controller->width, controller->height, + controller_x, controller_y); + + SDL_SetSurfaceAlphaMod(marker->surface_masked, alpha); + + BlitBitmapMasked(marker, drawto, 0, 0, + marker->width, marker->height, + marker_x, marker_y); + + if (!screen_initialized) + FadeIn(REDRAW_FIELD); + else + BackToFront(); + + screen_initialized = TRUE; + + while (NextValidEvent(&event)) { - case EVENT_KEYPRESS: - switch (GetEventKey((KeyEvent *)&event, TRUE)) - { - case KSYM_Return: - if (check_remaining == 0) - result = 1; + switch (event.type) + { + case SDL_JOYAXISMOTION: + if (event.jaxis.value > 20000 || + event.jaxis.value < -20000) + { + for (j = 0; j < i; j++) + if (steps[j].axis == event.jaxis.axis) + break; + + if (j == i) + { + if (step->marker != MARKER_AXIS_X && + step->marker != MARKER_AXIS_Y) + break; + + step->axis = event.jaxis.axis; + strcat(mapping, step->field); + snprintf(temp, sizeof(temp), ":a%u,", event.jaxis.axis); + strcat(mapping, temp); + i++; + next = TRUE; + } + } + + break; + + case SDL_JOYHATMOTION: + /* ignore centering; we're probably just coming back + to the center from the previous item we set */ + if (event.jhat.value == SDL_HAT_CENTERED) break; - case KSYM_Escape: - FadeSkipNextFadeIn(); - result = 0; + for (j = 0; j < i; j++) + if (steps[j].hat == event.jhat.hat && + steps[j].hat_value == event.jhat.value) + break; + + if (j == i) + { + step->hat = event.jhat.hat; + step->hat_value = event.jhat.value; + strcat(mapping, step->field); + snprintf(temp, sizeof(temp), ":h%u.%u,", + event.jhat.hat, event.jhat.value ); + strcat(mapping, temp); + i++; + next = TRUE; + } + + break; + + case SDL_JOYBALLMOTION: + break; + + case SDL_JOYBUTTONUP: + for (j = 0; j < i; j++) + if (steps[j].button == event.jbutton.button) + break; + + if (j == i) + { + step->button = event.jbutton.button; + strcat(mapping, step->field); + snprintf(temp, sizeof(temp), ":b%u,", event.jbutton.button); + strcat(mapping, temp); + i++; + next = TRUE; + } + + break; + + case SDL_FINGERDOWN: + case SDL_MOUSEBUTTONDOWN: + /* skip this step */ + i++; + next = TRUE; + + break; + + case SDL_KEYDOWN: + if (event.key.keysym.sym == KSYM_BackSpace || + event.key.keysym.sym == KSYM_Back) + { + if (i == 0) + { + /* leave screen */ + success = FALSE; + done = TRUE; + } + + /* undo this step */ + prev_step = &steps[i - 1]; + strcpy(mapping, prev_step->mapping); + i--; + next = TRUE; + break; + } + + if (event.key.keysym.sym == KSYM_space || + event.key.keysym.sym == KSYM_Return || + event.key.keysym.sym == KSYM_Menu) + { + /* skip this step */ + i++; + next = TRUE; - default: break; - } - break; + } - case EVENT_KEYRELEASE: - key_joystick_mapping = 0; - break; + if (event.key.keysym.sym == KSYM_Escape) + { + /* leave screen */ + success = FALSE; + done = TRUE; + } - default: - HandleOtherEvents(&event); + break; + + case SDL_QUIT: + program.exit_function(0); + break; + + default: + break; + } + + // do not handle events for longer than standard frame delay period + if (DelayReached(&event_frame_delay, event_frame_delay_value)) break; } } + } - if (!ReadJoystick(joystick_fd, &joy_x, &joy_y, NULL, NULL)) - return FALSE; - - new_joystick_xleft = MIN(new_joystick_xleft, joy_x); - new_joystick_xright = MAX(new_joystick_xright, joy_x); - new_joystick_yupper = MIN(new_joystick_yupper, joy_y); - new_joystick_ylower = MAX(new_joystick_ylower, joy_y); + if (success) + { +#if DEBUG_JOYSTICKS + Error(ERR_DEBUG, "New game controller mapping:\n\n%s\n\n", mapping); +#endif - setup.input[player_nr].joy.xleft = new_joystick_xleft; - setup.input[player_nr].joy.yupper = new_joystick_yupper; - setup.input[player_nr].joy.xright = new_joystick_xright; - setup.input[player_nr].joy.ylower = new_joystick_ylower; - setup.input[player_nr].joy.xmiddle = new_joystick_xmiddle; - setup.input[player_nr].joy.ymiddle = new_joystick_ymiddle; + // activate mapping for this game + SDL_GameControllerAddMapping(mapping); - CheckJoystickData(); + // save mapping to personal mappings + SaveSetup_AddGameControllerMapping(mapping); + } - joy_value = Joystick(player_nr); + /* wait until the last pending event was removed from event queue */ + while (NextValidEvent(&event)); - if (joy_value & JOY_BUTTON && check_remaining == 0) - result = 1; + return success; +#else + return TRUE; +#endif +} - x = (joy_value & JOY_LEFT ? -1 : joy_value & JOY_RIGHT ? +1 : 0); - y = (joy_value & JOY_UP ? -1 : joy_value & JOY_DOWN ? +1 : 0); +static int ConfigureJoystickMain(int player_nr) +{ + char *device_name = setup.input[player_nr].joy.device_name; + int joystick_nr = getJoystickNrFromDeviceName(device_name); + boolean joystick_active = CheckJoystickOpened(joystick_nr); + int success = FALSE; + int i; - if (x != last_x || y != last_y) - { - DrawFixedGraphic(xpos + last_x, ypos + last_y, - IMG_MENU_CALIBRATE_YELLOW, 0); - DrawFixedGraphic(xpos + x, ypos + y, - IMG_MENU_CALIBRATE_RED, 0); + if (joystick.status == JOYSTICK_NOT_AVAILABLE) + return JOYSTICK_NOT_AVAILABLE; - last_x = x; - last_y = y; + if (!joystick_active || !setup.input[player_nr].use_joystick) + return JOYSTICK_NOT_AVAILABLE; - if (check_remaining > 0 && !check[x+1][y+1]) - { - check[x+1][y+1] = TRUE; - check_remaining--; - } - } + FadeSetEnterMenu(); + FadeOut(REDRAW_FIELD); - DoAnimation(); - BackToFront(); + // close all joystick devices (potentially opened as game controllers) + for (i = 0; i < SDL_NumJoysticks(); i++) + SDLCloseJoystick(i); - /* don't eat all CPU time */ - Delay(10); - } + // open joystick device as plain joystick to configure as game controller + SDL_Joystick *joystick = SDL_JoystickOpen(joystick_nr); - /* calibrated center position (joystick should now be centered) */ - if (!ReadJoystick(joystick_fd, &joy_x, &joy_y, NULL, NULL)) + // as the joystick was successfully opened before, this should not happen + if (joystick == NULL) return FALSE; - new_joystick_xmiddle = joy_x; - new_joystick_ymiddle = joy_y; + // create new game controller mapping (buttons and axes) for joystick device + success = ConfigureJoystickMapButtonsAndAxes(joystick); - StopAnimation(); + // close joystick (and maybe re-open as configured game controller later) + SDL_JoystickClose(joystick); - /* wait until the last pressed button was released */ - while (Joystick(player_nr) & JOY_BUTTON) - { - if (PendingEvent()) /* got event */ - { - Event event; + // re-open all joystick devices (potentially as game controllers) + for (i = 0; i < SDL_NumJoysticks(); i++) + SDLOpenJoystick(i); - NextEvent(&event); - HandleOtherEvents(&event); + // clear all joystick input actions for all joystick devices + SDLClearJoystickState(); - Delay(10); - } - } - - return TRUE; + return (success ? JOYSTICK_CONFIGURED : JOYSTICK_NOT_CONFIGURED); } -void CalibrateJoystick(int player_nr) +void ConfigureJoystick(int player_nr) { - if (!CalibrateJoystickMain(player_nr)) + boolean state = ConfigureJoystickMain(player_nr); + + if (state != JOYSTICK_NOT_CONFIGURED) { + boolean success = (state == JOYSTICK_CONFIGURED); + char *message = (success ? " IS CONFIGURED! " : " NOT AVAILABLE! "); char *device_name = setup.input[player_nr].joy.device_name; int nr = getJoystickNrFromDeviceName(device_name) + 1; int xpos = mSX - SX; int ypos = mSY - SY; + unsigned int wait_frame_delay = 0; + unsigned int wait_frame_delay_value = 2000; + + ResetDelayCounter(&wait_frame_delay); ClearField(); DrawTextF(xpos + 16, ypos + 6 * 32, FONT_TITLE_1, " JOYSTICK %d ", nr); - DrawTextF(xpos + 16, ypos + 7 * 32, FONT_TITLE_1, " NOT AVAILABLE! "); - BackToFront(); + DrawTextF(xpos + 16, ypos + 7 * 32, FONT_TITLE_1, message); - Delay(2000); /* show error message for a short time */ + while (!DelayReached(&wait_frame_delay, wait_frame_delay_value)) + BackToFront(); ClearEventQueue(); } @@ -6460,10 +6968,6 @@ void CalibrateJoystick(int player_nr) void DrawSetupScreen() { - DeactivateJoystick(); - - SetMainBackgroundImage(IMG_BACKGROUND_SETUP); - if (setup_mode == SETUP_MODE_INPUT) DrawSetupScreen_Input(); else if (setup_mode == SETUP_MODE_CHOOSE_GAME_SPEED) @@ -6472,12 +6976,12 @@ void DrawSetupScreen() 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) DrawChooseTree(&window_size_current); else if (setup_mode == SETUP_MODE_CHOOSE_SCALING_TYPE) DrawChooseTree(&scaling_type_current); + else if (setup_mode == SETUP_MODE_CHOOSE_RENDERING) + DrawChooseTree(&rendering_mode_current); else if (setup_mode == SETUP_MODE_CHOOSE_GRAPHICS) DrawChooseTree(&artwork.gfx_current); else if (setup_mode == SETUP_MODE_CHOOSE_SOUNDS) @@ -6499,8 +7003,7 @@ void DrawSetupScreen() else DrawSetupScreen_Generic(); - PlayMenuSound(); - PlayMenuMusic(); + PlayMenuSoundsAndMusic(); } void RedrawSetupScreenAfterFullscreenToggle() @@ -6525,12 +7028,12 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button) 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) HandleChooseTree(mx, my, dx, dy, button, &window_size_current); else if (setup_mode == SETUP_MODE_CHOOSE_SCALING_TYPE) HandleChooseTree(mx, my, dx, dy, button, &scaling_type_current); + else if (setup_mode == SETUP_MODE_CHOOSE_RENDERING) + HandleChooseTree(mx, my, dx, dy, button, &rendering_mode_current); else if (setup_mode == SETUP_MODE_CHOOSE_GRAPHICS) HandleChooseTree(mx, my, dx, dy, button, &artwork.gfx_current); else if (setup_mode == SETUP_MODE_CHOOSE_SOUNDS) @@ -6879,14 +7382,10 @@ static void CreateScreenScrollbars() void CreateScreenGadgets() { - int last_game_status = game_status; /* save current game status */ - CreateScreenMenubuttons(); CreateScreenScrollbuttons(); CreateScreenScrollbars(); - - game_status = last_game_status; /* restore current game status */ } void FreeScreenGadgets()