X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fscreens.c;h=9c02fc9e3a7f697a1792f00656d9e77d3de7b393;hp=c69b78fb4fcd4e22bd1f2e12a742ba23b4756479;hb=5c6c42f1;hpb=fd7a17027bb5c580b5d007fa33109f8a914d605b diff --git a/src/screens.c b/src/screens.c index c69b78fb..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 @@ -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); @@ -278,7 +292,10 @@ static struct { { 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 }, @@ -380,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 }, }; @@ -409,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) @@ -426,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] : \ @@ -433,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) : \ @@ -444,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)) @@ -1181,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) { @@ -1361,8 +1401,6 @@ void DrawTitleScreen() KeyboardAutoRepeatOff(); HandleTitleScreen(0, 0, 0, 0, MB_MENU_INITIALIZE); - - StopAnimation(); } boolean CheckTitleScreen(boolean levelset_has_changed) @@ -1395,12 +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; @@ -1439,8 +1476,6 @@ void DrawMainMenu() if (CheckTitleScreen(levelset_has_changed)) { - game_status_last_screen = GAME_MODE_MAIN; - SetGameStatus(GAME_MODE_TITLE); DrawTitleScreen(); @@ -1448,18 +1483,18 @@ void DrawMainMenu() return; } - /* needed if different viewport properties defined for menues */ - ChangeViewportPropertiesIfNeeded(); - if (redraw_mask & REDRAW_ALL) fade_mask = REDRAW_ALL; - if (CheckIfGlobalBorderHasChanged()) + if (CheckIfGlobalBorderOrPlayfieldViewportHasChanged()) fade_mask = REDRAW_ALL; FadeOut(fade_mask); - SetDrawtoField(DRAW_BACKBUFFER); + /* needed if different viewport properties defined for menues */ + ChangeViewportPropertiesIfNeeded(); + + 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) @@ -1468,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); @@ -1493,8 +1530,7 @@ void DrawMainMenu() LoadTape(level_nr); DrawCompleteVideoDisplay(); - PlayMenuSound(); - PlayMenuMusic(); + PlayMenuSoundsAndMusic(); /* create gadgets for main menu screen */ FreeScreenGadgets(); @@ -1521,8 +1557,6 @@ void DrawMainMenu() SetMouseCursor(CURSOR_DEFAULT); - InitAnimation(); - OpenDoor(DOOR_CLOSE_1 | DOOR_OPEN_2); } @@ -1591,22 +1625,25 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) /* 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(); + FadeMenuSoundsAndMusic(); } FadeOut(REDRAW_ALL); - /* only required to update logic for redrawing global border */ - ClearField(); - /* 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 @@ -1694,7 +1731,7 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) } else { - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); return_to_main_menu = TRUE; } @@ -1771,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(); */ @@ -1808,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 && @@ -1834,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); } @@ -1848,14 +1887,10 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) } else if (pos == MAIN_CONTROL_LEVEL_NUMBER && !button) { - StopAnimation(); - CloseDoor(DOOR_CLOSE_2); SetGameStatus(GAME_MODE_LEVELNR); - ChangeViewportPropertiesIfNeeded(); - DrawChooseLevelNr(); } else if (pos >= MAIN_CONTROL_NAME && pos <= MAIN_CONTROL_QUIT) @@ -1871,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 { @@ -1886,8 +1927,6 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) { if (leveldir_first) { - StopAnimation(); - CloseDoor(DOOR_CLOSE_2); SetGameStatus(GAME_MODE_LEVELS); @@ -1898,15 +1937,11 @@ 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) { - StopAnimation(); - CloseDoor(DOOR_CLOSE_2); SetGameStatus(GAME_MODE_SCORES); @@ -1919,8 +1954,6 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) !strEqual(setup.player_name, "Artsoft")) Request("This level is read only!", REQ_CONFIRM); - StopAnimation(); - CloseDoor(DOOR_CLOSE_2); SetGameStatus(GAME_MODE_EDITOR); @@ -1931,36 +1964,26 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) } else if (pos == MAIN_CONTROL_INFO) { - StopAnimation(); - CloseDoor(DOOR_CLOSE_2); SetGameStatus(GAME_MODE_INFO); info_mode = INFO_MODE_MAIN; - ChangeViewportPropertiesIfNeeded(); - DrawInfoScreen(); } else if (pos == MAIN_CONTROL_GAME) { - StopAnimation(); - StartGameActions(options.network, setup.autorecord, level.random_seed); } else if (pos == MAIN_CONTROL_SETUP) { - StopAnimation(); - CloseDoor(DOOR_CLOSE_2); SetGameStatus(GAME_MODE_SETUP); setup_mode = SETUP_MODE_MAIN; - ChangeViewportPropertiesIfNeeded(); - DrawSetupScreen(); } else if (pos == MAIN_CONTROL_QUIT) @@ -2163,11 +2186,11 @@ static void DrawInfoScreen_Main() if (redraw_mask & REDRAW_ALL) fade_mask = REDRAW_ALL; - if (CheckIfGlobalBorderHasChanged()) + if (CheckIfGlobalBorderOrPlayfieldViewportHasChanged()) fade_mask = REDRAW_ALL; UnmapAllGadgets(); - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); FreeScreenGadgets(); CreateScreenGadgets(); @@ -2179,8 +2202,11 @@ static void DrawInfoScreen_Main() FadeOut(fade_mask); + /* needed if different viewport properties defined for info screen */ ChangeViewportPropertiesIfNeeded(); + SetMainBackgroundImage(IMG_BACKGROUND_INFO); + ClearField(); OpenDoor(GetDoorState() | DOOR_NO_DELAY | DOOR_FORCE_REDRAW); @@ -2203,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); @@ -2456,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)) { @@ -2497,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); @@ -2510,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); @@ -2523,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; @@ -2542,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; @@ -2651,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; @@ -2675,17 +2747,15 @@ 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() { - game_status_last_screen = GAME_MODE_INFO; - SetGameStatus(GAME_MODE_TITLE); DrawTitleScreen(); @@ -2708,8 +2778,6 @@ void DrawInfoScreen_Elements() HandleInfoScreen_Elements(MB_MENU_INITIALIZE); FadeIn(REDRAW_FIELD); - - InitAnimation(); } void HandleInfoScreen_Elements(int button) @@ -2762,7 +2830,7 @@ void HandleInfoScreen_Elements(int button) if (page >= num_pages) { - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -2810,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) { @@ -2821,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; @@ -2840,7 +2914,7 @@ void HandleInfoScreen_Music(int button) { PlaySound(SND_MENU_ITEM_SELECTING); - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -2849,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); @@ -2861,7 +2933,7 @@ void HandleInfoScreen_Music(int button) if (list == NULL) { - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -2869,7 +2941,7 @@ void HandleInfoScreen_Music(int button) return; } - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); if (list != music_file_info) FadeSetNextScreen(); @@ -2889,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, @@ -2949,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"); } @@ -3124,7 +3269,7 @@ void DrawInfoScreen_Credits() { SetMainBackgroundImageIfDefined(IMG_BACKGROUND_INFO_CREDITS); - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); FadeOut(REDRAW_FIELD); @@ -3165,7 +3310,7 @@ void HandleInfoScreen_Credits(int button) if (screen_nr >= num_screens) { - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -3192,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); @@ -3204,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); @@ -3244,7 +3409,7 @@ void HandleInfoScreen_Program(int button) { PlaySound(SND_MENU_ITEM_SELECTING); - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -3257,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; @@ -3284,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, ystart2, font_header, "Name"); - DrawTextF(xstart2, ystart2, font_text, getProgramTitleString()); + DrawTextF(xstart1, ystart, font_head, "Name"); + DrawTextF(xstart2, ystart, font_text, getProgramTitleString()); + ystart += ystep_line; - ystart2 += ystep; - DrawTextF(xstart1, ystart2, font_header, "Version"); - DrawTextF(xstart2, ystart2, font_text, getProgramVersionString()); + if (!strEqual(getProgramVersionString(), getProgramRealVersionString())) + { + DrawTextF(xstart1, ystart, font_head, "Version (fake)"); + DrawTextF(xstart2, ystart, font_text, getProgramVersionString()); + ystart += ystep_line; + + 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) @@ -3318,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); @@ -3382,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); @@ -3393,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); @@ -3419,7 +3606,7 @@ void HandleInfoScreen_Version(int button) { PlaySound(SND_MENU_ITEM_SELECTING); - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -3435,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) @@ -3452,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) @@ -3507,7 +3694,7 @@ void HandleInfoScreen_LevelSet(int button) { PlaySound(SND_MENU_ITEM_SELECTING); - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); info_mode = INFO_MODE_MAIN; DrawInfoScreen(); @@ -3520,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) @@ -3542,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) @@ -3596,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) { @@ -3645,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(); } } @@ -3660,7 +3838,7 @@ 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)) @@ -3679,6 +3857,14 @@ static void DrawChooseTree(TreeInfo **ti_ptr) 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); @@ -3689,8 +3875,6 @@ static void DrawChooseTree(TreeInfo **ti_ptr) DrawMaskedBorder(fade_mask); FadeIn(fade_mask); - - InitAnimation(); } static void drawChooseTreeList(int first_entry, int num_page_entries, @@ -3988,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 { @@ -4073,14 +4281,11 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, void DrawChooseLevelSet() { - FadeSoundsAndMusic(); - - SetMainBackgroundImage(IMG_BACKGROUND_LEVELS); + FadeMenuSoundsAndMusic(); DrawChooseTree(&leveldir_current); - PlayMenuSound(); - PlayMenuMusic(); + PlayMenuSoundsAndMusic(); } void HandleChooseLevelSet(int mx, int my, int dx, int dy, int button) @@ -4092,7 +4297,7 @@ void DrawChooseLevelNr() { int i; - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); if (level_number != NULL) { @@ -4112,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); @@ -4138,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) @@ -4155,18 +4357,14 @@ void DrawHallOfFame(int highlight_position) { int fade_mask = REDRAW_FIELD; - /* 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); @@ -4174,15 +4372,17 @@ 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); @@ -4212,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; @@ -4707,16 +4908,14 @@ static void execSetupGraphics_setRenderingModes() 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_setRenderingModes(); @@ -5214,14 +5413,12 @@ static void execSetupChooseMusic() DrawSetupScreen(); } -#if !defined(PLATFORM_ANDROID) static void execSetupInput() { setup_mode = SETUP_MODE_INPUT; DrawSetupScreen(); } -#endif static void execSetupShortcuts() { @@ -5285,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" }, @@ -5303,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, "" }, @@ -5333,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:" }, @@ -5424,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, "" }, @@ -5441,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, "" }, @@ -5560,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: @@ -5590,7 +5793,6 @@ static Key getSetupKey() } } - DoAnimation(); BackToFront(); } @@ -5599,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; @@ -5777,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; @@ -5784,11 +6010,11 @@ static void DrawSetupScreen_Generic() char *title_string = NULL; int i; - if (CheckIfGlobalBorderHasChanged()) + if (CheckIfGlobalBorderOrPlayfieldViewportHasChanged()) fade_mask = REDRAW_ALL; UnmapAllGadgets(); - FadeSoundsAndMusic(); + FadeMenuSoundsAndMusic(); FreeScreenGadgets(); CreateScreenGadgets(); @@ -5798,6 +6024,11 @@ static void DrawSetupScreen_Generic() 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); @@ -5836,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) { @@ -5868,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 @@ -5890,8 +6127,6 @@ static void DrawSetupScreen_Generic() DrawMaskedBorder(fade_mask); FadeIn(fade_mask); - - InitAnimation(); } void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button) @@ -5914,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)) @@ -5939,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) @@ -5974,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] = { @@ -5990,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), @@ -6005,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 { @@ -6102,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) @@ -6161,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); } @@ -6221,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: @@ -6304,205 +6526,439 @@ void CustomizeKeyboard(int player_nr) } } - DoAnimation(); BackToFront(); } /* 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)); + +#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 - 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); + /* initialize mapping with GUID and name */ + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), temp, sizeof(temp)); - /* eventually uncalibrated center position (joystick could be uncentered) */ - if (!ReadJoystick(joystick_fd, &joy_x, &joy_y, NULL, NULL)) - return FALSE; + snprintf(mapping, sizeof(mapping), "%s,%s,platform:%s,", + temp, name, SDL_GetPlatform()); - new_joystick_xmiddle = joy_x; - new_joystick_ymiddle = joy_y; + /* 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 */ - DrawFixedGraphic(xpos + last_x, ypos + last_y, IMG_MENU_CALIBRATE_RED, 0); + step = &steps[i]; + strcpy(step->mapping, mapping); + step->axis = -1; + step->button = -1; + step->hat = -1; + step->hat_value = -1; - FadeIn(REDRAW_FIELD); + marker = (step->marker == MARKER_BUTTON ? button : + step->marker == MARKER_AXIS_X ? axis_x : + step->marker == MARKER_AXIS_Y ? axis_y : marker); - while (Joystick(player_nr) & JOY_BUTTON); /* wait for released button */ - InitAnimation(); + next = FALSE; - while (result < 0) - { - if (PendingEvent()) /* got event */ + 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; + if (success) + { +#if DEBUG_JOYSTICKS + Error(ERR_DEBUG, "New game controller mapping:\n\n%s\n\n", mapping); +#endif - 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); + // activate mapping for this game + SDL_GameControllerAddMapping(mapping); - 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; + // save mapping to personal mappings + SaveSetup_AddGameControllerMapping(mapping); + } - CheckJoystickData(); + /* wait until the last pending event was removed from event queue */ + while (NextValidEvent(&event)); - joy_value = Joystick(player_nr); + return success; +#else + return TRUE; +#endif +} - if (joy_value & JOY_BUTTON && check_remaining == 0) - result = 1; +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; - x = (joy_value & JOY_LEFT ? -1 : joy_value & JOY_RIGHT ? +1 : 0); - y = (joy_value & JOY_UP ? -1 : joy_value & JOY_DOWN ? +1 : 0); + if (joystick.status == JOYSTICK_NOT_AVAILABLE) + return JOYSTICK_NOT_AVAILABLE; - 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_active || !setup.input[player_nr].use_joystick) + return JOYSTICK_NOT_AVAILABLE; - last_x = x; - last_y = y; + FadeSetEnterMenu(); + FadeOut(REDRAW_FIELD); - if (check_remaining > 0 && !check[x+1][y+1]) - { - check[x+1][y+1] = TRUE; - check_remaining--; - } - } + // close all joystick devices (potentially opened as game controllers) + for (i = 0; i < SDL_NumJoysticks(); i++) + SDLCloseJoystick(i); - DoAnimation(); - BackToFront(); - } + // 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(); - BackToFront(); - } - } - - 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(); } @@ -6512,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) @@ -6551,8 +7003,7 @@ void DrawSetupScreen() else DrawSetupScreen_Generic(); - PlayMenuSound(); - PlayMenuMusic(); + PlayMenuSoundsAndMusic(); } void RedrawSetupScreenAfterFullscreenToggle()