From b473adcf80226e22e2e9e9dec10ea8d2187f9a05 Mon Sep 17 00:00:00 2001 From: erorcun Date: Sun, 6 Dec 2020 17:29:48 +0300 Subject: [PATCH] Frontend cleanup, .INI, CFO, scrollable pages --- src/core/Frontend.cpp | 640 ++++++++++++++++++++-------- src/core/Frontend.h | 143 +++++-- src/core/MenuScreens.cpp | 73 +--- src/core/MenuScreensCustom.cpp | 734 +++++++++++++++++++++++++++++++++ src/core/config.h | 34 +- src/core/main.cpp | 8 + src/core/main.h | 5 + src/core/re3.cpp | 172 +++++++- src/extras/frontendoption.cpp | 167 ++++++++ src/extras/frontendoption.h | 86 ++++ src/peds/Ped.cpp | 33 +- src/peds/PedAI.cpp | 2 +- 12 files changed, 1780 insertions(+), 317 deletions(-) create mode 100644 src/core/MenuScreensCustom.cpp create mode 100644 src/extras/frontendoption.cpp create mode 100644 src/extras/frontendoption.h diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 2b458828..7c37308a 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -39,29 +39,60 @@ #include "User.h" #include "sampman.h" -#define MAP_MIN_SIZE 162.f -#define MAP_SIZE_TO_ALLOW_X_MOVE 297.f +// --MIAMI: file done // Similar story to Hud.cpp: // Game has colors inlined in code. // For easier modification we collect them here: -CRGBA LABEL_COLOR(255, 150, 225, 255); -CRGBA SELECTIONBORDER_COLOR(25, 130, 70, 255); -CRGBA MENUOPTION_COLOR(255, 150, 225, 255); -CRGBA SELECTEDMENUOPTION_COLOR(255, 150, 225, 255); -CRGBA HEADER_COLOR(255, 150, 255, 255); -CRGBA DARKMENUOPTION_COLOR(195, 90, 165, 255); -CRGBA SLIDERON_COLOR(97, 194, 247, 255); -CRGBA SLIDEROFF_COLOR(27, 89, 130, 255); -CRGBA LIST_BACKGROUND_COLOR(49, 101, 148, 130); -CRGBA RADIO_SELECTOR_COLOR(27, 89, 130, 255); -CRGBA INACTIVE_RADIO_COLOR(100, 100, 255, 100); +const CRGBA LABEL_COLOR(255, 150, 225, 255); +const CRGBA SELECTIONBORDER_COLOR(25, 130, 70, 255); +const CRGBA MENUOPTION_COLOR = LABEL_COLOR; +const CRGBA SELECTEDMENUOPTION_COLOR = LABEL_COLOR; +const CRGBA HEADER_COLOR = LABEL_COLOR; +const CRGBA DARKMENUOPTION_COLOR(195, 90, 165, 255); +const CRGBA SLIDERON_COLOR(97, 194, 247, 255); +const CRGBA SLIDEROFF_COLOR(27, 89, 130, 255); +const CRGBA LIST_BACKGROUND_COLOR(49, 101, 148, 130); +const CRGBA RADIO_SELECTOR_COLOR = SLIDEROFF_COLOR; +const CRGBA INACTIVE_RADIO_COLOR(100, 100, 255, 100); +const CRGBA SCROLLBAR_COLOR = LABEL_COLOR; + +#define MAP_MIN_SIZE 162.f +#define MAP_SIZE_TO_ALLOW_X_MOVE 297.f #define MAX_VISIBLE_LIST_ROW 30 #define SCROLLBAR_MAX_HEIGHT 263.0f // not in end result +#define SCROLLABLE_PAGES -#ifdef MAP_ENHANCEMENTS -CVector2D mapCrosshair; +#define hasNativeList(screen) (screen == MENUPAGE_SKIN_SELECT || screen == MENUPAGE_KEYBOARD_CONTROLS) + +#ifdef SCROLLABLE_PAGES +#define MAX_VISIBLE_OPTION 12 +#define MAX_VISIBLE_OPTION_ON_SCREEN (hasNativeList(m_nCurrScreen) ? MAX_VISIBLE_LIST_ROW : MAX_VISIBLE_OPTION) +#define SCREEN_HAS_AUTO_SCROLLBAR (m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen)) + +int GetOptionCount(int screen) +{ + int i = 0; + for (; i < NUM_MENUROWS && aScreens[screen].m_aEntries[i].m_Action != MENUACTION_NOTHING; i++); + return i; +} + +#define SETUP_SCROLLING(screen) \ + if (!hasNativeList(screen)) { \ + m_nTotalListRow = GetOptionCount(screen); \ + if (m_nTotalListRow > MAX_VISIBLE_OPTION) { \ + m_nSelectedListRow = 0; \ + m_nFirstVisibleRowOnList = 0; \ + m_nScrollbarTopMargin = 0; \ + } \ + } + +#define MINUS_SCROLL_OFFSET - scrollOffset +#else +#define MAX_VISIBLE_OPTION_ON_SCREEN MAX_VISIBLE_LIST_ROW +#define SETUP_SCROLLING(screen) +#define MINUS_SCROLL_OFFSET #endif #ifdef TRIANGLE_BACK_BUTTON @@ -75,6 +106,10 @@ CVector2D mapCrosshair; #define GetBackJustDown GetSquareJustDown #endif +#ifdef MAP_ENHANCEMENTS +CVector2D mapCrosshair; +#endif + #ifdef CUTSCENE_BORDERS_SWITCH bool CMenuManager::m_PrefsCutsceneBorders = true; #endif @@ -94,7 +129,6 @@ bool CMenuManager::m_PrefsMarketing = false; bool CMenuManager::m_PrefsDisableTutorials = false; #endif // !MASTER -// 0x68C144 const char* FrontendFilenames[][2] = { {"background", ""}, {"vc_logo", "vc_logom"}, @@ -151,6 +185,11 @@ wchar* CMenuManager::m_pDialogText = nil; CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \ CFont::SetDropShadowPosition(0); +#define SET_FONT_FOR_LIST_ITEM \ + CFont::SetRightJustifyOff(); \ + CFont::SetScale(MENU_X(LISTITEM_X_SCALE), MENU_Y(LISTITEM_Y_SCALE)); \ + CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + #define RESET_FONT_FOR_NEW_PAGE \ CFont::SetBackgroundOff(); \ CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); \ @@ -159,11 +198,12 @@ wchar* CMenuManager::m_pDialogText = nil; CFont::SetJustifyOn(); \ CFont::SetRightJustifyOff(); \ CFont::SetBackGroundOnlyTextOn(); \ - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); \ - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); \ + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN)); -#define ProcessSlider(value, y, increaseAction, decreaseAction, hoverEndX, onlyWhenHoveringRow) \ +#define ProcessSlider(value, origY, increaseAction, decreaseAction, hoverEndX, onlyWhenHoveringRow) \ do { \ + float y = origY MINUS_SCROLL_OFFSET; \ lastActiveBarX = DisplaySlider(MENU_X_LEFT_ALIGNED(MENUSLIDER_X), MENU_Y(y), MENU_Y(MENUSLIDER_SMALLEST_BAR), MENU_Y(MENUSLIDER_BIGGEST_BAR), MENU_X(MENUSLIDER_UNK), value, MENU_X(3.0f)); \ if (i != m_nCurrOption || !itemsAreSelectable) \ break; \ @@ -203,8 +243,8 @@ CMenuManager::ScrollUpListByOne() inline void CMenuManager::ScrollDownListByOne() { - if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1) { - if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { + if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN - 1) { + if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN) { m_nSelectedListRow++; m_nFirstVisibleRowOnList++; m_nScrollbarTopMargin += SCROLLBAR_MAX_HEIGHT / m_nTotalListRow; @@ -219,13 +259,13 @@ CMenuManager::ScrollDownListByOne() inline void CMenuManager::PageUpList(bool playSoundOnSuccess) { - if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { + if (m_nTotalListRow > MAX_VISIBLE_OPTION_ON_SCREEN) { if (m_nFirstVisibleRowOnList > 0) { if(playSoundOnSuccess) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0); - m_nFirstVisibleRowOnList = Max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_LIST_ROW); - m_nSelectedListRow = Min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1); + m_nFirstVisibleRowOnList = Max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_OPTION_ON_SCREEN); + m_nSelectedListRow = Min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN - 1); } else { m_nFirstVisibleRowOnList = 0; m_nSelectedListRow = 0; @@ -237,21 +277,100 @@ CMenuManager::PageUpList(bool playSoundOnSuccess) inline void CMenuManager::PageDownList(bool playSoundOnSuccess) { - if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) { - if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) { + if (m_nTotalListRow > MAX_VISIBLE_OPTION_ON_SCREEN) { + if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN) { if(playSoundOnSuccess) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0); - m_nFirstVisibleRowOnList = Min(m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW, m_nTotalListRow - MAX_VISIBLE_LIST_ROW); + m_nFirstVisibleRowOnList = Min(m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN, m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN); m_nSelectedListRow = Max(m_nSelectedListRow, m_nFirstVisibleRowOnList); } else { - m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW; + m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN; m_nSelectedListRow = m_nTotalListRow - 1; } m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; } } +#ifdef CUSTOM_FRONTEND_OPTIONS +#define PLUS_LINE_HEIGHT_ON_SCREEN + (aScreens[m_nCurrScreen].layout ? aScreens[m_nCurrScreen].layout->lineHeight : MENU_DEFAULT_LINE_HEIGHT) +bool ScreenHasOption(int screen, const char* gxtKey) +{ + for (int i = 0; i < NUM_MENUROWS; i++) { + if (strcmp(gxtKey, aScreens[screen].m_aEntries[i].m_EntryName) == 0) + return true; + } + return false; +} + +inline void +CMenuManager::ThingsToDoBeforeLeavingPage() +{ + if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) { + CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile); + + } else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) { + if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) + m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex(); + + DMAudio.StopFrontEndTrack(); + OutputDebugString("FRONTEND AUDIO TRACK STOPPED"); + + } else if (ScreenHasOption(m_nCurrScreen, "FED_RES")) { + m_nDisplayVideoMode = m_nPrefsVideoMode; + } + + if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) { + CPlayerSkin::EndFrontendSkinEdit(); + } + +#ifdef SCROLLABLE_PAGES + if (SCREEN_HAS_AUTO_SCROLLBAR) { + m_nSelectedListRow = 0; + m_nFirstVisibleRowOnList = 0; + m_nScrollbarTopMargin = 0; + } +#endif + + CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption]; + + if (option.m_Action == MENUACTION_CFO_DYNAMIC) + if(option.m_CFODynamic->buttonPressFunc) + option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); + + if (option.m_Action == MENUACTION_CFO_SELECT && option.m_CFOSelect->onlyApplyOnEnter && option.m_CFOSelect->lastSavedValue != option.m_CFOSelect->displayedValue) + option.m_CFOSelect->displayedValue = *option.m_CFO->value = option.m_CFOSelect->lastSavedValue; + + if (aScreens[m_nCurrScreen].returnPrevPageFunc) { + aScreens[m_nCurrScreen].returnPrevPageFunc(); + } +} + +inline int8 +CMenuManager::GetPreviousPageOption() +{ + int8 prevPage = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage : + (m_nCurrScreen == MENUPAGE_NEW_GAME || m_nCurrScreen == MENUPAGE_OPTIONS || m_nCurrScreen == MENUPAGE_EXIT ? MENUPAGE_START_MENU : aScreens[m_nCurrScreen].m_PreviousPage); + + if (prevPage == -1) // Game also does same + return 0; + + prevPage = prevPage == MENUPAGE_NONE ? (!m_bGameNotLoaded ? MENUPAGE_PAUSE_MENU : MENUPAGE_START_MENU) : prevPage; + + for (int i = 0; i < NUM_MENUROWS; i++) { + if (aScreens[prevPage].m_aEntries[i].m_Action >= MENUACTION_NOTHING) { // CFO check + if (aScreens[prevPage].m_aEntries[i].m_TargetMenu == m_nCurrScreen) { + return i; + } + } + } + + // This shouldn't happen + return 0; +} + +#else +#define PLUS_LINE_HEIGHT_ON_SCREEN + MENU_DEFAULT_LINE_HEIGHT inline void CMenuManager::ThingsToDoBeforeLeavingPage() { @@ -265,9 +384,6 @@ CMenuManager::ThingsToDoBeforeLeavingPage() break; case MENUPAGE_DISPLAY_SETTINGS: m_nDisplayVideoMode = m_nPrefsVideoMode; -#ifdef IMPROVED_VIDEOMODE - m_nSelectedScreenMode = m_nPrefsWindowed; -#endif break; case MENUPAGE_SKIN_SELECT: if (strcmp(m_aSkinName, m_PrefsSkinFile) != 0) @@ -276,6 +392,14 @@ CMenuManager::ThingsToDoBeforeLeavingPage() CPlayerSkin::EndFrontendSkinEdit(); break; } + +#ifdef SCROLLABLE_PAGES + if (SCREEN_HAS_AUTO_SCROLLBAR) { + m_nSelectedListRow = 0; + m_nFirstVisibleRowOnList = 0; + m_nScrollbarTopMargin = 0; + } +#endif } inline int8 @@ -284,13 +408,13 @@ CMenuManager::GetPreviousPageOption() return (!m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry : (m_nCurrScreen == MENUPAGE_NEW_GAME ? 0 : (m_nCurrScreen == MENUPAGE_OPTIONS ? 1 : (m_nCurrScreen == MENUPAGE_EXIT ? 2 : aScreens[m_nCurrScreen].m_ParentEntry)))); } +#endif // ------ Functions not in the game/inlined ends bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha); void DoRWStuffEndOfFrame(void); -// --MIAMI: Done void CMenuManager::SwitchToNewScreen(int8 screen) { @@ -320,8 +444,9 @@ CMenuManager::SwitchToNewScreen(int8 screen) m_nCurrOption = 0; m_nCurrScreen = screen; } - - if (m_nPrevScreen == MENUPAGE_SKIN_SELECT || m_nPrevScreen == MENUPAGE_KEYBOARD_CONTROLS) + SETUP_SCROLLING(m_nCurrScreen) + + if (hasNativeList(m_nPrevScreen)) m_nTotalListRow = 0; if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT) @@ -463,7 +588,6 @@ CMenuManager::CentreMousePointer() } } -// --MIAMI: Done void CMenuManager::CheckCodesForControls(int typeOfControl) { @@ -532,7 +656,6 @@ CMenuManager::CheckHover(int x1, int x2, int y1, int y2) m_nMousePosY > y1 && m_nMousePosY < y2; } -// --MIAMI: Done void CMenuManager::CheckSliderMovement(int value) { @@ -582,7 +705,6 @@ CMenuManager::CheckSliderMovement(int value) SaveSettings(); } -// --MIAMI: Done void CMenuManager::DisplayHelperText(char *text) { @@ -598,9 +720,10 @@ CMenuManager::DisplayHelperText(char *text) CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); CFont::SetDropShadowPosition(0); + // We're using SCREEN_STRETCH_FROM_RIGHT, because we also stretch black borders if (text) { CFont::SetColor(CRGBA(255, 255, 255, 255)); - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get(text)); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get(text)); return; } @@ -620,19 +743,19 @@ CMenuManager::DisplayHelperText(char *text) // TODO: name this cases? switch (m_nHelperTextMsgId) { case 1: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_APP")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_APP")); break; case 2: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_HRD")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_HRD")); break; case 3: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_RSO")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_RSO")); break; case 4: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_STS")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_STS")); break; case 5: - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_RSC")); + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get("FET_RSC")); break; default: if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_NO) @@ -641,7 +764,7 @@ CMenuManager::DisplayHelperText(char *text) if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_MUSICVOLUME || aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SFXVOLUME) { - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG")); return; } @@ -650,7 +773,7 @@ CMenuManager::DisplayHelperText(char *text) return; if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SCREENRES) { - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_bGameNotLoaded ? TheText.Get("FET_MIG") : TheText.Get("FEH_NA")); return; } @@ -658,7 +781,7 @@ CMenuManager::DisplayHelperText(char *text) if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_AUDIOHW || aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SPEAKERCONF) { - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG")); return; } @@ -667,19 +790,18 @@ CMenuManager::DisplayHelperText(char *text) return; if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_MP3VOLUMEBOOST) { - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER ? TheText.Get("FEH_NA") : TheText.Get("FET_MIG")); return; } - CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), + CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), m_nCurrScreen != MENUPAGE_STATS ? TheText.Get("FET_MIG") : TheText.Get("FEH_SSA")); break; } } -// --MIAMI: Done int CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostRightBarSize, float rectSize, float progress, float spacing) { @@ -731,7 +853,6 @@ CMenuManager::DoSettingsBeforeStartingAGame() DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds()); } -// --MIAMI: Done void CMenuManager::DrawStandardMenus(bool activeScreen) { @@ -743,8 +864,14 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetJustifyOn(); CFont::SetBackGroundOnlyTextOff(); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); +#ifdef CUSTOM_FRONTEND_OPTIONS + const int xMargin = aScreens[m_nCurrScreen].layout && aScreens[m_nCurrScreen].layout->xMargin != 0 ? aScreens[m_nCurrScreen].layout->xMargin : MENU_X_MARGIN; +#else + const int xMargin = MENU_X_MARGIN; +#endif + + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(xMargin)); + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(xMargin)); #ifdef ASPECT_RATIO_SCALE CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH)); #else @@ -790,7 +917,6 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); CFont::SetScale(MENU_X(BIGTEXT2_X_SCALE), MENU_Y(BIGTEXT2_Y_SCALE)); CFont::SetRightJustifyOff(); - CFont::SetDropShadowPosition(2); CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255))); @@ -825,8 +951,8 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } CFont::PrintString(MENU_X_LEFT_ALIGNED(100.0f), MENU_Y(97.0f), str); - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(xMargin)); + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(xMargin)); } if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { @@ -836,7 +962,6 @@ CMenuManager::DrawStandardMenus(bool activeScreen) DrawControllerScreenExtraText(-8.0f, MENU_X_LEFT_ALIGNED(350), MENU_DEFAULT_LINE_HEIGHT); } - bool foundTheHoveringItem = false; wchar unicodeTemp[64]; char asciiTemp[32]; @@ -845,7 +970,13 @@ CMenuManager::DrawStandardMenus(bool activeScreen) while (section < 2) { +#ifdef SCROLLABLE_PAGES + int firstOption = SCREEN_HAS_AUTO_SCROLLBAR ? m_nFirstVisibleRowOnList : 0; + int scrollOffset = aScreens[m_nCurrScreen].m_aEntries[firstOption].m_Y - aScreens[m_nCurrScreen].m_aEntries[0].m_Y; + for (int i = firstOption; i < firstOption + MAX_VISIBLE_OPTION && i < NUM_MENUROWS; ++i) { +#else for (int i = 0; i < NUM_MENUROWS; ++i) { +#endif wchar* rightText = nil; wchar* leftText; if (aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot >= SAVESLOT_1 && aScreens[m_nCurrScreen].m_aEntries[i].m_SaveSlot <= SAVESLOT_8) { @@ -870,16 +1001,26 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetRightJustifyOff(); CFont::SetCentreOn(); } - if (!aScreens[m_nCurrScreen].m_aEntries[i].m_X && !aScreens[m_nCurrScreen].m_aEntries[i].m_Y) { + if (aScreens[m_nCurrScreen].m_aEntries[i].m_X == 0 && aScreens[m_nCurrScreen].m_aEntries[i].m_Y == 0) { if (i == 0 || (i == 1 && weHaveLabel)) { +#ifdef CUSTOM_FRONTEND_OPTIONS + aScreens[m_nCurrScreen].m_aEntries[i].m_X = (aScreens[m_nCurrScreen].layout ? aScreens[m_nCurrScreen].layout->startX : MENU_DEFAULT_CONTENT_X); + aScreens[m_nCurrScreen].m_aEntries[i].m_Y = (aScreens[m_nCurrScreen].layout ? aScreens[m_nCurrScreen].layout->startY : MENU_DEFAULT_CONTENT_Y); +#else aScreens[m_nCurrScreen].m_aEntries[i].m_X = MENU_DEFAULT_CONTENT_X; aScreens[m_nCurrScreen].m_aEntries[i].m_Y = MENU_DEFAULT_CONTENT_Y; +#endif } else { aScreens[m_nCurrScreen].m_aEntries[i].m_X = aScreens[m_nCurrScreen].m_aEntries[i-1].m_X; - aScreens[m_nCurrScreen].m_aEntries[i].m_Y = aScreens[m_nCurrScreen].m_aEntries[i-1].m_Y + MENU_DEFAULT_LINE_HEIGHT; + aScreens[m_nCurrScreen].m_aEntries[i].m_Y = aScreens[m_nCurrScreen].m_aEntries[i-1].m_Y PLUS_LINE_HEIGHT_ON_SCREEN; } } +#ifdef CUSTOM_FRONTEND_OPTIONS + else if (aScreens[m_nCurrScreen].m_aEntries[i].m_Y == 0) { + aScreens[m_nCurrScreen].m_aEntries[i].m_Y = aScreens[m_nCurrScreen].m_aEntries[i-1].m_Y PLUS_LINE_HEIGHT_ON_SCREEN; + } +#endif if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action != MENUACTION_LABEL && aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName[0] != '\0') { @@ -1055,17 +1196,6 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); } break; -#ifdef IMPROVED_VIDEOMODE - case MENUACTION_SCREENFORMAT: - if (m_nSelectedScreenMode == 0) - sprintf(asciiTemp, "FULLSCREEN"); - else - sprintf(asciiTemp, "WINDOWED"); - - AsciiToUnicode(asciiTemp, unicodeTemp); - rightText = unicodeTemp; - break; -#endif case MENUACTION_AUDIOHW: if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER) rightText = TheText.Get("FEA_NAH"); @@ -1128,6 +1258,30 @@ CMenuManager::DrawStandardMenus(bool activeScreen) rightText = TheText.Get("FEA_NM3"); } break; +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_CFO_DYNAMIC: + case MENUACTION_CFO_SELECT: + CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[i]; + if (option.m_Action == MENUACTION_CFO_SELECT) { + // To whom manipulate option.m_CFO->value of static options externally (like RestoreDef functions) + if (*option.m_CFO->value != option.m_CFOSelect->lastSavedValue) + option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value; + + if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0) + option.m_CFOSelect->displayedValue = 0; + + rightText = TheText.Get(option.m_CFOSelect->rightTexts[option.m_CFOSelect->displayedValue]); + + } else if (option.m_Action == MENUACTION_CFO_DYNAMIC) { + if (option.m_CFODynamic->drawFunc) { + bool isOptionDisabled = false; + rightText = option.m_CFODynamic->drawFunc(&isOptionDisabled, m_nCurrOption == i); + if (isOptionDisabled) + CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255))); + } + } + break; +#endif } // Highlight trapezoid @@ -1135,7 +1289,8 @@ CMenuManager::DrawStandardMenus(bool activeScreen) int leftXMax, rightXMin; - // FIX: Let's don't scale those so GetStringWidth will give unscaled width, which will be handy to other calculations below that's done without scaling in mind. + // FIX: Let's don't scale those so GetStringWidth can give us unscaled width, which will be handy to other calculations below that's done without scaling in mind, + // and scaling will be done eventually. // CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); CFont::SetScale(BIGTEXT_X_SCALE, BIGTEXT_Y_SCALE); @@ -1165,9 +1320,9 @@ CMenuManager::DrawStandardMenus(bool activeScreen) leftXMax = 40; } - int y = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Y; + int y = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Y MINUS_SCROLL_OFFSET; int topYMax = y; - uint32 bottomYMin = y + 22; + uint32 bottomYMin = y + MENU_DEFAULT_LINE_HEIGHT - 7; // Decreasing is not recommended. Because this actually is dependent to font scale, not line height. // Actually bottomRight and bottomLeft should be exchanged here(although this is original code). // So this shows us either R* didn't use same struct for menu BG and highlight, or they just kept fields as x1,y1 etc. Yikes. @@ -1228,7 +1383,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen) if (section == 1) { if (leftText) { - CFont::PrintString(MENU_X_LEFT_ALIGNED(aScreens[m_nCurrScreen].m_aEntries[i].m_X), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y), leftText); + CFont::PrintString(MENU_X_LEFT_ALIGNED(aScreens[m_nCurrScreen].m_aEntries[i].m_X), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y MINUS_SCROLL_OFFSET), leftText); } if (rightText) { @@ -1241,7 +1396,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen) CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE)); } - CFont::PrintString(MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y), rightText); + CFont::PrintString(MENU_X_LEFT_ALIGNED(DEFAULT_SCREEN_WIDTH - RIGHT_ALIGNED_TEXT_RIGHT_MARGIN(xMargin)), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y MINUS_SCROLL_OFFSET), rightText); } if (m_nPrefsAudio3DProviderIndex == DMAudio.GetCurrent3DProviderIndex()) { @@ -1262,7 +1417,12 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) { if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") != 0 - && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS && m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { +#ifdef CUSTOM_FRONTEND_OPTIONS + && ScreenHasOption(m_nCurrScreen, "FEA_3DH") +#else + && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS +#endif + && m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex(); SetHelperText(3); @@ -1270,19 +1430,15 @@ CMenuManager::DrawStandardMenus(bool activeScreen) } if (m_nDisplayVideoMode != m_nPrefsVideoMode) { if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_RES") != 0 +#ifdef CUSTOM_FRONTEND_OPTIONS + && ScreenHasOption(m_nCurrScreen, "FED_RES")) { +#else && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) { +#endif m_nDisplayVideoMode = m_nPrefsVideoMode; SetHelperText(3); } } -#ifdef IMPROVED_VIDEOMODE - if (m_nSelectedScreenMode != m_nPrefsWindowed) { - if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_POS") != 0 - && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) { - m_nSelectedScreenMode = m_nPrefsWindowed; - } - } -#endif // Sliders int lastActiveBarX; @@ -1324,6 +1480,35 @@ CMenuManager::DrawStandardMenus(bool activeScreen) section++; } +#ifdef SCROLLABLE_PAGES + #define SCROLLBAR_BOTTOM_Y 105.0f // only for background, scrollbar's itself is calculated + #define SCROLLBAR_RIGHT_X 26.0f + #define SCROLLBAR_WIDTH 9.5f + #define SCROLLBAR_TOP_Y 84 + + if (activeScreen && SCREEN_HAS_AUTO_SCROLLBAR) { + // Scrollbar background + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2), MENU_Y(SCROLLBAR_TOP_Y), + MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 2 - SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(SCROLLBAR_BOTTOM_Y)), CRGBA(30, 30, 30, FadeIn(150))); + + float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / (m_nTotalListRow / (float) MAX_VISIBLE_OPTION); + float scrollbarBottom, scrollbarTop; + + scrollbarBottom = MENU_Y(SCROLLBAR_TOP_Y - 6 + m_nScrollbarTopMargin + scrollbarHeight); + scrollbarTop = MENU_Y(SCROLLBAR_TOP_Y + 2 + m_nScrollbarTopMargin); + // Scrollbar shadow + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 4), scrollbarTop, + MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 1 - SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)), + CRGBA(50, 50, 50, FadeIn(255))); + + // Scrollbar + CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 4), scrollbarTop, + MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - SCROLLBAR_WIDTH), scrollbarBottom), + CRGBA(SCROLLBAR_COLOR.r, SCROLLBAR_COLOR.g, SCROLLBAR_COLOR.b, FadeIn(255))); + + } +#endif + switch (m_nCurrScreen) { case MENUPAGE_STATS: case MENUPAGE_CONTROLLER_PC: @@ -1336,6 +1521,15 @@ CMenuManager::DrawStandardMenus(bool activeScreen) if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER && aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_LOADRADIO) DisplayHelperText("FEA_NAH"); break; +#ifdef CUSTOM_FRONTEND_OPTIONS + default: + if (aScreens[m_nCurrScreen].layout) { + if (aScreens[m_nCurrScreen].layout->showLeftRightHelper) { + DisplayHelperText(nil); + } + } + break; +#endif } if (m_nCurrScreen == MENUPAGE_DELETING_IN_PROGRESS) { @@ -1348,7 +1542,6 @@ CMenuManager::DrawStandardMenus(bool activeScreen) #endif } -// --MIAMI: Done int CMenuManager::GetNumOptionsCntrlConfigScreens(void) { @@ -1376,7 +1569,6 @@ CMenuManager::GetNumOptionsCntrlConfigScreens(void) return number; } -// --MIAMI: Done void CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 column) { @@ -1607,7 +1799,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 } // Print bindings, including seperator (-) between them - CFont::SetScale(MENU_X(0.25f), MENU_Y(0.6f)); + CFont::SetScale(MENU_X(0.25f), MENU_Y(LISTITEM_Y_SCALE)); for (; contSetOrder < MAX_SETORDERS && controllerAction != -1; contSetOrder++) { wchar *settingText = ControlsManager.GetControllerSettingTextWithOrderNumber((e_ControllerAction)controllerAction, (eContSetOrder)contSetOrder); if (settingText) { @@ -1680,31 +1872,24 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8 else DisplayHelperText("FET_RIG"); - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + SET_FONT_FOR_LIST_ITEM m_bKeyIsOK = true; } else { DisplayHelperText("FET_CIG"); - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + SET_FONT_FOR_LIST_ITEM m_bKeyIsOK = false; m_bKeyChangeNotProcessed = false; } } else if (optionIdx == m_nSelectedListRow) { DisplayHelperText("FET_EIG"); - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + SET_FONT_FOR_LIST_ITEM } } } } -// --MIAMI: Done void CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeight) { @@ -1761,7 +1946,6 @@ CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeig } } -// --MIAMI: Done void CMenuManager::DrawControllerSetupScreen() { @@ -1860,9 +2044,7 @@ CMenuManager::DrawControllerSetupScreen() CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_2_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CFT")); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X), MENU_Y(CONTSETUP_LIST_TOP), TheText.Get("FET_CCR")); CFont::SetDropShadowPosition(0); - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + SET_FONT_FOR_LIST_ITEM int yStart; if (m_ControlMethod == CONTROL_CLASSIC) @@ -1921,9 +2103,9 @@ CMenuManager::DrawControllerSetupScreen() CFont::SetRightJustifyOff(); if (m_PrefsLanguage == LANGUAGE_GERMAN && (i == 20 || i == 21 || i == 22 || i == 23)) - CFont::SetScale(MENU_X(0.32f), MENU_Y(0.6f)); + CFont::SetScale(MENU_X(0.32f), MENU_Y(LISTITEM_Y_SCALE)); else - CFont::SetScale(MENU_X(0.4f), MENU_Y(0.6f)); + CFont::SetScale(MENU_X(LISTITEM_X_SCALE), MENU_Y(LISTITEM_Y_SCALE)); CFont::PrintString(MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_1_X), MENU_Y(i * rowHeight + yStart), actionText); } @@ -1954,11 +2136,9 @@ CMenuManager::DrawControllerSetupScreen() CFont::SetDropShadowPosition(2); CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255))); - CFont::PrintString(MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT - 2.0f), SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - 4.0f), TheText.Get("FEDS_TB")); } -// --MIAMI: Done void CMenuManager::DrawFrontEnd() { @@ -1974,6 +2154,7 @@ CMenuManager::DrawFrontEnd() } else { m_nCurrScreen = MENUPAGE_PAUSE_MENU; } + SETUP_SCROLLING(m_nCurrScreen) } if (m_nCurrOption == 0 && aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL) @@ -1985,7 +2166,6 @@ CMenuManager::DrawFrontEnd() DrawBackground(false); } -// --MIAMI: Done void CMenuManager::DrawBackground(bool transitionCall) { @@ -2097,6 +2277,20 @@ CMenuManager::DrawBackground(bool transitionCall) menuBg.bottomRight_y = 398.0f; break; default: +#ifdef CUSTOM_FRONTEND_OPTIONS + if (aScreens[m_nCurrScreen].layout && aScreens[m_nCurrScreen].layout->noInvasiveBorders) { + // Taken from the case above + menuBg.topLeft_x = 26.0f; + menuBg.topLeft_y = 59.0f; + menuBg.topRight_x = 629.0f; + menuBg.topRight_y = 29.0f; + menuBg.bottomLeft_x = 15.0f; + menuBg.bottomLeft_y = 426.0f; + menuBg.bottomRight_x = 610.0f; + menuBg.bottomRight_y = 398.0f; + break; + } +#endif menuBg.topLeft_x = CGeneral::GetRandomNumber() % 40 + 65; menuBg.topLeft_y = CGeneral::GetRandomNumber() % 40 + 21; menuBg.topRight_x = CGeneral::GetRandomNumber() % 40 + 568; @@ -2209,7 +2403,6 @@ CMenuManager::DrawBackground(bool transitionCall) } } -// --MIAMI: Done void CMenuManager::DrawPlayerSetupScreen(bool activeScreen) { @@ -2332,9 +2525,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) CFont::SetDropShadowPosition(0); // Skin list - CFont::SetRightJustifyOff(); - CFont::SetScale(MENU_X(PLAYERSETUP_ROW_TEXT_X_SCALE), MENU_Y(PLAYERSETUP_ROW_TEXT_Y_SCALE)); - CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); + SET_FONT_FOR_LIST_ITEM if (m_nSkinsTotal > 0) { for (m_pSelectedSkin = m_pSkinListHead.nextSkin; m_pSelectedSkin->skinId != m_nFirstVisibleRowOnList; m_pSelectedSkin = m_pSelectedSkin->nextSkin); @@ -2403,7 +2594,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) ++rowIdx; m_pSelectedSkin = m_pSelectedSkin->nextSkin; } - // Scrollbar background + // Scrollbar background - it's unchanged since III and still yellowish... CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2), MENU_Y(PLAYERSETUP_LIST_TOP), MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 2 - PLAYERSETUP_SCROLLBAR_WIDTH), SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM)), CRGBA(100, 100, 66, FadeIn(205))); @@ -2433,7 +2624,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) } CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop, MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom), - CRGBA(255, 150, 225, FadeIn(255))); + CRGBA(SCROLLBAR_COLOR.r, SCROLLBAR_COLOR.g, SCROLLBAR_COLOR.b, FadeIn(255))); // FIX: Scroll button dimensions are buggy, because: // 1 - stretches the original image @@ -2601,14 +2792,12 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen) CFont::SetDropShadowPosition(0); } -// --MIAMI: Done int CMenuManager::FadeIn(int alpha) { return Min(m_nMenuFadeAlpha, alpha); } -// --MIAMI: Done int CMenuManager::GetStartOptionsCntrlConfigScreens() { @@ -2743,7 +2932,6 @@ CMenuManager::LoadAllTextures() CTimer::Update(); } -// --MIAMI: Done void CMenuManager::LoadSettings() { @@ -2792,12 +2980,7 @@ CMenuManager::LoadSettings() CFileMgr::Read(fileHandle, gString, 20); CFileMgr::Read(fileHandle, gString, 4); CFileMgr::Read(fileHandle, gString, 4); -#ifdef FREE_CAM - CFileMgr::Read(fileHandle, (char*)&TheCamera.bFreeCam, 1); -#else CFileMgr::Read(fileHandle, gString, 1); -#endif - #ifdef LEGACY_MENU_OPTIONS CFileMgr::Read(fileHandle, (char*)&m_PrefsVsyncDisp, 1); CFileMgr::Read(fileHandle, (char*)&CMBlur::BlurOn, 1); @@ -2828,9 +3011,6 @@ CMenuManager::LoadSettings() CFileMgr::Read(fileHandle, (char*)&m_PrefsShowHud, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsRadarMode, 1); CFileMgr::Read(fileHandle, (char*)&m_PrefsShowLegends, 1); -#ifdef CUTSCENE_BORDERS_SWITCH - CFileMgr::Read(fileHandle, (char *)&CMenuManager::m_PrefsCutsceneBorders, 1); -#endif } } @@ -2877,9 +3057,11 @@ CMenuManager::LoadSettings() strcpy(m_PrefsSkinFile, DEFAULT_SKIN_NAME); strcpy(m_aSkinName, DEFAULT_SKIN_NAME); } +#ifdef LOAD_INI_SETTINGS + LoadINISettings(); // needs frontend options to be loaded +#endif } -// --MIAMI: Done void CMenuManager::SaveSettings() { @@ -2904,12 +3086,7 @@ CMenuManager::SaveSettings() CFileMgr::Write(fileHandle, RubbishString, 20); CFileMgr::Write(fileHandle, RubbishString, 4); CFileMgr::Write(fileHandle, RubbishString, 4); -#ifdef FREE_CAM - CFileMgr::Write(fileHandle, (char*)&TheCamera.bFreeCam, 1); -#else CFileMgr::Write(fileHandle, RubbishString, 1); -#endif - #ifdef LEGACY_MENU_OPTIONS CFileMgr::Write(fileHandle, (char*)&m_PrefsVsyncDisp, 1); CFileMgr::Write(fileHandle, (char*)&CMBlur::BlurOn, 1); @@ -2940,14 +3117,15 @@ CMenuManager::SaveSettings() CFileMgr::Write(fileHandle, (char*)&m_PrefsShowHud, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsRadarMode, 1); CFileMgr::Write(fileHandle, (char*)&m_PrefsShowLegends, 1); -#ifdef CUTSCENE_BORDERS_SWITCH - CFileMgr::Write(fileHandle, (char *)&CMenuManager::m_PrefsCutsceneBorders, 1); -#endif } m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex; CFileMgr::CloseFile(fileHandle); CFileMgr::SetDir(""); + +#ifdef LOAD_INI_SETTINGS + SaveINISettings(); +#endif } void @@ -2972,7 +3150,6 @@ CMenuManager::MessageScreen(const char *text, bool blackBg) DoRWStuffEndOfFrame(); } -// --MIAMI: Done void CMenuManager::SmallMessageScreen(const char* text) { @@ -2999,7 +3176,6 @@ CMenuManager::SmallMessageScreen(const char* text) CFont::PrintString(SCREEN_WIDTH / 2.f, y, TheText.Get(text)); } -// --MIAMI: Done void CMenuManager::PrintBriefs() { @@ -3031,7 +3207,6 @@ CMenuManager::PrintBriefs() } } -// --MIAMI: Done void CMenuManager::PrintStats() { @@ -3137,14 +3312,17 @@ CMenuManager::PrintStats() UnicodeStrcat(gUString2, gUString); CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD)); +#ifndef FIX_BUGS CFont::SetScale(MENU_X(0.5f), MENU_Y(0.9f)); +#else + CFont::SetScale(MENU_X(SMALLTEXT_X_SCALE), MENU_Y(SMALLTEXT_Y_SCALE)); +#endif CFont::SetColor(CRGBA(0, 0, 0, FadeIn(255))); CFont::SetDropShadowPosition(0); CFont::PrintString(MENU_X_LEFT_ALIGNED(STATS_RATING_X) - CFont::GetStringWidth(gUString2, true) / 2.f, MENU_Y(STATS_RATING_Y_2), gUString2); } -// --MIAMI: Done void CMenuManager::Process(void) { @@ -3683,10 +3861,10 @@ CMenuManager::PrintRadioSelector(void) CRGBA(RADIO_SELECTOR_COLOR.r, RADIO_SELECTOR_COLOR.g, RADIO_SELECTOR_COLOR.b, FadeIn(255))); // Arrows and their shadows - CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(216.f), MENU_Y(333.f), MENU_X_LEFT_ALIGNED(196.f), MENU_Y(321.f), MENU_X_LEFT_ALIGNED(216.f), MENU_Y(307.f), MENU_X_LEFT_ALIGNED(196.f), MENU_Y(321.f), CRGBA(0, 0, 0, FadeIn(255))); - CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(213.f), MENU_Y(330.f), MENU_X_LEFT_ALIGNED(193.f), MENU_Y(318.f), MENU_X_LEFT_ALIGNED(213.f), MENU_Y(304.f), MENU_X_LEFT_ALIGNED(193.f), MENU_Y(318.f), CRGBA(97, 194, 247, FadeIn(255))); - CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(440.f), MENU_Y(333.f), MENU_X_LEFT_ALIGNED(460.f), MENU_Y(321.f), MENU_X_LEFT_ALIGNED(440.f), MENU_Y(307.f), MENU_X_LEFT_ALIGNED(460.f), MENU_Y(321.f), CRGBA(0, 0, 0, FadeIn(255))); - CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(443.f), MENU_Y(330.f), MENU_X_LEFT_ALIGNED(463.f), MENU_Y(318.f), MENU_X_LEFT_ALIGNED(443.f), MENU_Y(304.f), MENU_X_LEFT_ALIGNED(463.f), MENU_Y(318.f), CRGBA(97, 194, 247, FadeIn(255))); + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(216.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 48.f), MENU_X_LEFT_ALIGNED(196.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), MENU_X_LEFT_ALIGNED(216.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 22.f), MENU_X_LEFT_ALIGNED(196.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), CRGBA(0, 0, 0, FadeIn(255))); + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(213.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 45.f), MENU_X_LEFT_ALIGNED(193.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), MENU_X_LEFT_ALIGNED(213.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 19.f), MENU_X_LEFT_ALIGNED(193.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), CRGBA(97, 194, 247, FadeIn(255))); + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(440.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 48.f), MENU_X_LEFT_ALIGNED(460.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), MENU_X_LEFT_ALIGNED(440.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 22.f), MENU_X_LEFT_ALIGNED(460.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 36.f), CRGBA(0, 0, 0, FadeIn(255))); + CSprite2d::Draw2DPolygon(MENU_X_LEFT_ALIGNED(443.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 45.f), MENU_X_LEFT_ALIGNED(463.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), MENU_X_LEFT_ALIGNED(443.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 19.f), MENU_X_LEFT_ALIGNED(463.f), MENU_Y(MENURADIO_SELECTOR_START_Y + 33.f), CRGBA(97, 194, 247, FadeIn(255))); if (radioChangeRequested) { if (CTimer::GetTimeInMillisecondsPauseMode() - lastRadioChange > 50) { DMAudio.SetRadioInCar(m_PrefsRadioStation); @@ -3837,7 +4015,7 @@ CMenuManager::ProcessList(bool &optionSelected, bool &goBack) m_nCurrExLayer = HOVEROPTION_LIST; m_bShowMouse = false; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0); - if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) { + if (m_nTotalListRow >= MAX_VISIBLE_OPTION_ON_SCREEN) { m_nFirstVisibleRowOnList = 0; } m_nSelectedListRow = 0; @@ -3847,8 +4025,8 @@ CMenuManager::ProcessList(bool &optionSelected, bool &goBack) m_nCurrExLayer = HOVEROPTION_LIST; m_bShowMouse = false; DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0); - if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) { - m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW; + if (m_nTotalListRow >= MAX_VISIBLE_OPTION_ON_SCREEN) { + m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN; } m_nSelectedListRow = m_nTotalListRow - 1; m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList; @@ -3946,13 +4124,22 @@ CMenuManager::UserInput(void) static int oldOption = -99; oldOption = m_nCurrOption; +#ifdef SCROLLABLE_PAGES + int firstOption = SCREEN_HAS_AUTO_SCROLLBAR ? m_nFirstVisibleRowOnList : 0; + int scrollOffset = aScreens[m_nCurrScreen].m_aEntries[firstOption].m_Y - aScreens[m_nCurrScreen].m_aEntries[0].m_Y; + for (int rowToCheck = firstOption; rowToCheck < firstOption + MAX_VISIBLE_OPTION && rowToCheck < NUM_MENUROWS; ++rowToCheck) { +#else for (int rowToCheck = 0; rowToCheck < NUM_MENUROWS; ++rowToCheck) { +#endif if (aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_NOTHING || aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_LABEL) continue; - if (m_nMousePosY > MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y) && - m_nMousePosY < MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y + MENU_DEFAULT_LINE_HEIGHT)) { + // unused: CFont::GetStringWidth(TheText.Get(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_EntryName), true); + // So they also wanted the compare X, but they abandoned the idea later on + + if (m_nMousePosY > MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y MINUS_SCROLL_OFFSET) && + m_nMousePosY < MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y MINUS_SCROLL_OFFSET PLUS_LINE_HEIGHT_ON_SCREEN)) { static int oldScreen = m_nCurrScreen; m_nOptionMouseHovering = rowToCheck; @@ -3996,7 +4183,7 @@ CMenuManager::UserInput(void) if (m_nMousePosY > SCREEN_HEIGHT) m_nMousePosY = SCREEN_HEIGHT; changeValueBy = 0; - if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS || m_nCurrScreen == MENUPAGE_SKIN_SELECT) { + if (hasNativeList(m_nCurrScreen)) { ProcessList(optionSelected, goBack); } else { AdditionalOptionInput(goBack); @@ -4007,8 +4194,7 @@ CMenuManager::UserInput(void) goDown = true; m_nOptionHighlightTransitionBlend = 0; - } - else if (m_AllowNavigation && + } else if (m_AllowNavigation && (CPad::GetPad(0)->GetUpJustDown() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown())) { m_bShowMouse = false; goUp = true; @@ -4020,8 +4206,7 @@ CMenuManager::UserInput(void) m_bShowMouse = false; optionSelected = true; } - } - else { + } else { if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) { m_bShowMouse = false; optionSelected = true; @@ -4058,6 +4243,27 @@ CMenuManager::UserInput(void) } } +#ifdef SCROLLABLE_PAGES + if (m_nTotalListRow > MAX_VISIBLE_OPTION) { + bool temp = false; + + m_nSelectedListRow = m_nCurrOption; + + // ignore detected back/select states, it's our screen's job + ProcessList(temp, temp); + + // and ignore our screen's goUp/Down, now it's ProcessList's job + goUp = false; + goDown = false; + m_nCurrOption = m_nSelectedListRow; + + if (oldOption != m_nCurrOption) + m_nOptionHighlightTransitionBlend = 0; + } + + // Prevent sound on scroll. Mouse wheel is now belongs to us! + if (!(m_nTotalListRow > MAX_VISIBLE_OPTION && (CPad::GetPad(0)->GetMouseWheelUpJustDown() || CPad::GetPad(0)->GetMouseWheelDownJustDown()))) +#endif if (CPad::GetPad(0)->GetLeftMouseJustUp() || CPad::GetPad(0)->GetLeftJustUp() || CPad::GetPad(0)->GetRightJustUp() || CPad::GetPad(0)->GetDPadLeftJustUp() || CPad::GetPad(0)->GetDPadRightJustUp() || CPad::GetPad(0)->GetAnaloguePadLeftJustUp() || CPad::GetPad(0)->GetAnaloguePadRightJustUp() @@ -4067,7 +4273,7 @@ CMenuManager::UserInput(void) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0); else if (option == MENUACTION_SFXVOLUME) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_AUDIO_TEST, 0); - else if (option == MENUACTION_DRAWDIST || option == MENUACTION_MOUSESTEER) + else if (option == MENUACTION_DRAWDIST || option == MENUACTION_MOUSESENS) DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0); } @@ -4111,10 +4317,15 @@ CMenuManager::UserInput(void) } } - if (CPad::GetPad(0)->GetMouseWheelUpJustDown()) { - changeValueBy = 1; - } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) { - changeValueBy = -1; +#ifdef SCROLLABLE_PAGES + if (!SCREEN_HAS_AUTO_SCROLLBAR) +#endif + { + if (CPad::GetPad(0)->GetMouseWheelUpJustDown()) { + changeValueBy = 1; + } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) { + changeValueBy = -1; + } } if (m_AllowNavigation) { @@ -4147,9 +4358,30 @@ CMenuManager::UserInput(void) } } ProcessUserInput(goDown, goUp, optionSelected, goBack, changeValueBy); +#ifdef CUSTOM_FRONTEND_OPTIONS + if (aScreens[m_nCurrScreen].m_aEntries[oldOption].m_Action < MENUACTION_NOTHING) { // CFO check + CMenuScreenCustom::CMenuEntry &oldEntry = aScreens[m_nCurrScreen].m_aEntries[oldOption]; + if (m_nCurrOption != oldOption) { + if (oldEntry.m_Action == MENUACTION_CFO_DYNAMIC) + if(oldEntry.m_CFODynamic->buttonPressFunc) + oldEntry.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS); + + if (oldEntry.m_Action == MENUACTION_CFO_SELECT && oldEntry.m_CFOSelect->onlyApplyOnEnter) { + if (oldEntry.m_CFOSelect->displayedValue != oldEntry.m_CFOSelect->lastSavedValue) + SetHelperText(3); // Restored original value + + oldEntry.m_CFOSelect->displayedValue = oldEntry.m_CFOSelect->lastSavedValue = *oldEntry.m_CFO->value; + } + } else if (oldEntry.m_Action == MENUACTION_CFO_SELECT && oldEntry.m_CFOSelect->onlyApplyOnEnter) { + if (oldEntry.m_CFOSelect->displayedValue != *oldEntry.m_CFO->value) + SetHelperText(1); // Enter to apply + else if (m_nHelperTextMsgId == 1) + ResetHelperText(); // Applied + } + } +#endif } -// --MIAMI: Done except TODOs void CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, uint8 goBack, int8 changeAmount) { @@ -4260,7 +4492,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u if (optionSelected && m_nMenuFadeAlpha == 255) { if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu == MENUPAGE_NEW_GAME_RELOAD && m_bGameNotLoaded) { DoSettingsBeforeStartingAGame(); - } else if ((m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) || (m_nCurrScreen == MENUPAGE_SKIN_SELECT)) { + } else if (hasNativeList(m_nCurrScreen)) { switch (m_nCurrExLayer) { case HOVEROPTION_LIST: if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { @@ -4428,15 +4660,6 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u SaveSettings(); } break; -#ifdef IMPROVED_VIDEOMODE - case MENUACTION_SCREENFORMAT: - if (m_nSelectedScreenMode != m_nPrefsWindowed) { - m_nPrefsWindowed = m_nSelectedScreenMode; - _psSelectScreenVM(m_nPrefsVideoMode); // apply same resolution - SaveSettings(); - } - break; -#endif case MENUACTION_AUDIOHW: { int selectedProvider = m_nPrefsAudio3DProviderIndex; @@ -4498,6 +4721,13 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u m_PrefsShowHud = true; m_nDisplayVideoMode = m_nPrefsVideoMode; CMBlur::BlurOn = false; +#ifdef CUSTOM_FRONTEND_OPTIONS + extern void RestoreDefGraphics(int8); + extern void RestoreDefDisplay(int8); + + RestoreDefGraphics(FEOPTION_ACTION_SELECT); + RestoreDefDisplay(FEOPTION_ACTION_SELECT); +#endif SaveSettings(); } else if (m_nCurrScreen == MENUPAGE_CONTROLLER_PC) { ControlsManager.MakeControllerActionsBlank(); @@ -4537,6 +4767,33 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u } SaveSettings(); break; +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_CFO_SELECT: + case MENUACTION_CFO_DYNAMIC: + CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption]; + if (option.m_Action == MENUACTION_CFO_SELECT) { + if (!option.m_CFOSelect->onlyApplyOnEnter) { + option.m_CFOSelect->displayedValue++; + if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0) + option.m_CFOSelect->displayedValue = 0; + } + int8 oldValue = *option.m_CFO->value; + + *option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue; + + if (option.m_CFOSelect->save) + SaveSettings(); + + if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc) + option.m_CFOSelect->changeFunc(oldValue, option.m_CFOSelect->displayedValue); + + } else if (option.m_Action == MENUACTION_CFO_DYNAMIC) { + if (option.m_CFODynamic->buttonPressFunc) + option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_SELECT); + } + + break; +#endif } ProcessOnOffMenuOptions(); if (!goBack) { @@ -4553,7 +4810,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u if (m_NoEmptyBinding) { DMAudio.PlayFrontEndSound(SOUND_FRONTEND_BACK, 0); SwitchToNewScreen(-2); - if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) { + if (hasNativeList(m_nCurrScreen)) { m_nTotalListRow = 0; } } else { @@ -4608,11 +4865,6 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u } } break; -#ifdef IMPROVED_VIDEOMODE - case MENUACTION_SCREENFORMAT: - m_nSelectedScreenMode = !m_nSelectedScreenMode; - break; -#endif case MENUACTION_AUDIOHW: if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) { m_nPrefsAudio3DProviderIndex += changeAmount; @@ -4659,6 +4911,36 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u CCamera::m_bUseMouse3rdPerson = !m_ControlMethod; SaveSettings(); break; +#ifdef CUSTOM_FRONTEND_OPTIONS + case MENUACTION_CFO_SELECT: + case MENUACTION_CFO_DYNAMIC: + CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption]; + if (option.m_Action == MENUACTION_CFO_SELECT) { + if (changeAmount > 0) { + option.m_CFOSelect->displayedValue++; + if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts) + option.m_CFOSelect->displayedValue = 0; + } else { + option.m_CFOSelect->displayedValue--; + if (option.m_CFOSelect->displayedValue < 0) + option.m_CFOSelect->displayedValue = option.m_CFOSelect->numRightTexts - 1; + } + if (!option.m_CFOSelect->onlyApplyOnEnter) { + int8 oldValue = *option.m_CFO->value; + + *option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue; + + if (option.m_CFOSelect->save) + SaveSettings(); + + if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc) + option.m_CFOSelect->changeFunc(oldValue, option.m_CFOSelect->displayedValue); + } + } else if (option.m_Action == MENUACTION_CFO_DYNAMIC && option.m_CFODynamic->buttonPressFunc) { + option.m_CFODynamic->buttonPressFunc(changeAmount > 0 ? FEOPTION_ACTION_RIGHT : FEOPTION_ACTION_LEFT); + } + break; +#endif } CheckSliderMovement(changeAmount); ProcessOnOffMenuOptions(); @@ -4672,7 +4954,6 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u } } -// --MIAMI: Done void CMenuManager::ProcessOnOffMenuOptions() { @@ -5029,7 +5310,6 @@ CMenuManager::ProcessFileActions() } } -// --MIAMI: Done void CMenuManager::SwitchMenuOnAndOff() { @@ -5038,7 +5318,11 @@ CMenuManager::SwitchMenuOnAndOff() // Reminder: You need REGISTER_START_BUTTON defined to make it work. if ((CPad::GetPad(0)->GetStartJustDown() || CPad::GetPad(0)->GetEscapeJustDown()) && (!m_bMenuActive || m_nCurrScreen == MENUPAGE_PAUSE_MENU || m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT || m_nCurrScreen == MENUPAGE_SAVE_CHEAT_WARNING) - || m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested) { + || m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested +#ifdef REGISTER_START_BUTTON + || CPad::GetPad(0)->GetStartJustDown() && !m_bGameNotLoaded +#endif + ) { if (m_nCurrScreen != MENUPAGE_LOADING_IN_PROGRESS #ifdef XBOX_MESSAGE_SCREEN @@ -5080,6 +5364,9 @@ CMenuManager::SwitchMenuOnAndOff() } m_StatsScrollSpeed = 150.0f; +#ifdef FIX_BUGS + ThingsToDoBeforeLeavingPage(); +#endif SaveSettings(); pControlEdit = nil; pEditString = nil; @@ -5169,7 +5456,6 @@ CMenuManager::UnloadTextures() CUserDisplay::PlaceName.ProcessAfterFrontEndShutDown(); } -// --MIAMI: Done void CMenuManager::WaitForUserCD() { @@ -5352,8 +5638,8 @@ CMenuManager::PrintMap(void) #endif m_bMenuMapActive = false; - CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN)); - CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN)); + CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); + CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN)); DisplayHelperText("FEH_MPH"); } diff --git a/src/core/Frontend.h b/src/core/Frontend.h index 01eb1c2e..58701ecf 100644 --- a/src/core/Frontend.h +++ b/src/core/Frontend.h @@ -11,7 +11,7 @@ #define MENUHEADER_HEIGHT 2.0f #define MENUHEADER_WIDTH 1.0f -#define MENU_UNK_X_MARGIN 10.0f +#define MENU_X_MARGIN 10.0f #define MENUACTION_SCALE_MULT 0.9f @@ -23,6 +23,8 @@ #define MENU_DEFAULT_CONTENT_Y 100 #define MENU_DEFAULT_LINE_HEIGHT 29 +#define RIGHT_ALIGNED_TEXT_RIGHT_MARGIN(xMargin) (xMargin + 30.0f) + #define MENURADIO_ICON_FIRST_X 238.f #define MENURADIO_ICON_Y 288.0f #define MENURADIO_ICON_SIZE 60.0f @@ -34,17 +36,23 @@ #define MENUSLIDER_SMALLEST_BAR 8.0f #define MENUSLIDER_BIGGEST_BAR 25.0f -#define BIGTEXT2_X_SCALE 0.6f +#define BIGTEXT2_X_SCALE 0.6f // For FONT_STANDARD #define BIGTEXT2_Y_SCALE 1.2f -#define BIGTEXT_X_SCALE 0.6f +#define BIGTEXT_X_SCALE 0.6f // For FONT_HEADING #define BIGTEXT_Y_SCALE 1.0f -#define MEDIUMTEXT_X_SCALE 0.48f +#define MEDIUMTEXT_X_SCALE 0.48f // For FONT_STANDARD #define MEDIUMTEXT_Y_SCALE 1.0f -#define SMALLTEXT_X_SCALE 0.42f +#define SMALLTEXT_X_SCALE 0.42f // For FONT_STANDARD #define SMALLTEXT_Y_SCALE 0.9f -#define SMALLESTTEXT_X_SCALE 0.3f +#define SMALLESTTEXT_X_SCALE 0.3f // For FONT_STANDARD #define SMALLESTTEXT_Y_SCALE 0.7f +#define LISTITEM_X_SCALE 0.4f // Only unproportional and commonly used scale for FONT_STANDARD +#define LISTITEM_Y_SCALE 0.6f + +#define HELPER_TEXT_RIGHT_MARGIN MENU_X_MARGIN +#define HELPER_TEXT_BOTTOM_MARGIN 18.f + #define PLAYERSETUP_LIST_TOP 58.0f #define PLAYERSETUP_LIST_BOTTOM 95.0f #define PLAYERSETUP_LIST_LEFT 200.0f @@ -56,8 +64,6 @@ #endif #define PLAYERSETUP_SCROLLBUTTON_HEIGHT 17.0f #define PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION 64 -#define PLAYERSETUP_ROW_TEXT_X_SCALE 0.4f -#define PLAYERSETUP_ROW_TEXT_Y_SCALE 0.6f #define PLAYERSETUP_SKIN_COLUMN_LEFT 220.0f #define PLAYERSETUP_DATE_COLUMN_RIGHT 56.0f #define PLAYERSETUP_LIST_BODY_TOP 77 @@ -186,7 +192,6 @@ enum eMenuScreen MENUPAGE_MOUSE_CONTROLS = 31, MENUPAGE_PAUSE_MENU = 32, MENUPAGE_NONE = 33, // Then chooses main menu or pause menu - MENUPAGE_OUTRO = 34, #ifdef LEGACY_MENU_OPTIONS MENUPAGE_CONTROLLER_SETTINGS, MENUPAGE_DEBUG_MENU, @@ -196,14 +201,26 @@ enum eMenuScreen MENUPAGE_CONTROLLER_PC_OLD4, MENUPAGE_CONTROLLER_DEBUG, #endif +#ifdef CUSTOM_FRONTEND_OPTIONS + #ifdef GRAPHICS_MENU_OPTIONS MENUPAGE_GRAPHICS_SETTINGS, #endif +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + MENUPAGE_DETECT_JOYSTICK, +#endif + +#endif + MENUPAGE_OUTRO, // Originally 34, but CFO needs last screen to be empty to count number of menu pages MENUPAGES }; enum eMenuAction { +#ifdef CUSTOM_FRONTEND_OPTIONS + MENUACTION_CFO_SELECT = -2, + MENUACTION_CFO_DYNAMIC = -1, +#endif MENUACTION_NOTHING, MENUACTION_LABEL, MENUACTION_YES, @@ -258,29 +275,10 @@ enum eMenuAction MENUACTION_DRAWDIST, MENUACTION_MOUSESENS, MENUACTION_MP3VOLUMEBOOST, -#ifdef IMPROVED_VIDEOMODE - MENUACTION_SCREENFORMAT, -#endif #ifdef LEGACY_MENU_OPTIONS MENUACTION_CTRLVIBRATION, MENUACTION_CTRLCONFIG, #endif -#ifdef ANISOTROPIC_FILTERING - MENUACTION_MIPMAPS, - MENUACTION_TEXTURE_FILTERING, -#endif -#ifdef MULTISAMPLING - MENUACTION_MULTISAMPLING, -#endif -#ifdef NO_ISLAND_LOADING - MENUACTION_ISLANDLOADING, -#endif -#ifdef PS2_ALPHA_TEST - MENUACTION_PS2_ALPHA_TEST, -#endif -#ifdef CUTSCENE_BORDERS_SWITCH - MENUACTION_CUTSCENEBORDERS, -#endif }; enum eCheckHover @@ -326,8 +324,8 @@ enum eCheckHover enum { -#ifdef LEGACY_MENU_OPTIONS - NUM_MENUROWS = 14, +#if defined LEGACY_MENU_OPTIONS || defined CUSTOM_FRONTEND_OPTIONS + NUM_MENUROWS = 18, #else NUM_MENUROWS = 12, #endif @@ -361,6 +359,7 @@ struct BottomBarOption int32 screenId; }; +#ifndef CUSTOM_FRONTEND_OPTIONS struct CMenuScreen { char m_ScreenName[8]; @@ -378,6 +377,88 @@ struct CMenuScreen uint8 m_Align; } m_aEntries[NUM_MENUROWS]; }; +extern CMenuScreen aScreens[MENUPAGES]; +#else +#include "frontendoption.h" +struct CCustomScreenLayout { + int startX; // not used at all if first entry has X and Y values + int startY; // not used at all if first entry has X and Y values + int lineHeight; // used to determine next entry's Y coordinate, if it has 0-0 as coordinates + bool showLeftRightHelper; + bool noInvasiveBorders; // not needed on pages already handled by game + int xMargin; // useful for two part texts - 0/empty = MENU_X_MARGIN +}; + +struct CCFO +{ + int8 *value; + const char *save; +}; + +struct CCFOSelect : CCFO +{ + char** rightTexts; + int8 numRightTexts; + bool onlyApplyOnEnter; + int8 displayedValue; // only if onlyApplyOnEnter enabled for now + int8 lastSavedValue; // only if onlyApplyOnEnter enabled + ChangeFunc changeFunc; + + CCFOSelect() {}; + CCFOSelect(int8* value, const char* save, const char** rightTexts, int8 numRightTexts, bool onlyApplyOnEnter, ChangeFunc changeFunc){ + this->value = value; + if (value) + this->lastSavedValue = this->displayedValue = *value; + + this->save = save; + this->rightTexts = (char**)rightTexts; + this->numRightTexts = numRightTexts; + this->onlyApplyOnEnter = onlyApplyOnEnter; + this->changeFunc = changeFunc; + } +}; + +struct CCFODynamic : CCFO +{ + DrawFunc drawFunc; + ButtonPressFunc buttonPressFunc; + + CCFODynamic() {}; + CCFODynamic(int8* value, const char* save, DrawFunc drawFunc, ButtonPressFunc buttonPressFunc){ + this->value = value; + this->save = save; + this->drawFunc = drawFunc; + this->buttonPressFunc = buttonPressFunc; + } +}; + +struct CMenuScreenCustom +{ + char m_ScreenName[8]; + int32 m_PreviousPage; // eMenuScreen + CCustomScreenLayout *layout; + ReturnPrevPageFunc returnPrevPageFunc; + + struct CMenuEntry + { + int32 m_Action; // eMenuAction - below zero is CFO + char m_EntryName[8]; + struct { + union { + CCFO *m_CFO; // for initializing + CCFOSelect *m_CFOSelect; + CCFODynamic *m_CFODynamic; + }; + int32 m_SaveSlot; // eSaveSlot + int32 m_TargetMenu; // eMenuScreen + }; + uint16 m_X; + uint16 m_Y; + uint8 m_Align; + } m_aEntries[NUM_MENUROWS]; +}; +extern CMenuScreenCustom aScreens[MENUPAGES]; +#endif struct MenuTrapezoid { @@ -617,7 +698,6 @@ public: ISLAND_LOADING_HIGH }; - static int8 m_DisplayIslandLoading; static int8 m_PrefsIslandLoading; #define ISLAND_LOADING_IS(p) if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p) @@ -710,6 +790,5 @@ VALIDATE_SIZE(CMenuManager, 0x688); #endif extern CMenuManager FrontEndMenuManager; -extern CMenuScreen aScreens[]; #endif diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp index 11cd3078..d4d028c9 100644 --- a/src/core/MenuScreens.cpp +++ b/src/core/MenuScreens.cpp @@ -2,44 +2,10 @@ #include "Frontend.h" #ifdef PC_MENU -#ifdef CUTSCENE_BORDERS_SWITCH -#define MENU_CUTSCENE_BORDERS_SWITCH(screen) MENUACTION_CUTSCENEBORDERS, "FEM_CSB", SAVESLOT_NONE, screen, -#else -#define MENU_CUTSCENE_BORDERS_SWITCH(screen) -#endif - -#ifdef IMPROVED_VIDEOMODE -#define MENU_IMPROVED_VIDEOMODE(screen) MENUACTION_SCREENFORMAT, "FEM_SCF", SAVESLOT_NONE, screen, -#else -#define MENU_IMPROVED_VIDEOMODE(screen) -#endif - -#ifdef ANISOTROPIC_FILTERING -#define MENU_MIPMAPS(screen) MENUACTION_MIPMAPS, "FED_MIP", SAVESLOT_NONE, screen, -#define MENU_TEXTURE_FILTERING(screen) MENUACTION_TEXTURE_FILTERING, "FED_FIL", SAVESLOT_NONE, screen, -#else -#define MENU_MIPMAPS(screen) -#define MENU_TEXTURE_FILTERING(screen) -#endif - -#ifdef MULTISAMPLING -#define MENU_MULTISAMPLING(screen) MENUACTION_MULTISAMPLING, "FED_AAS", SAVESLOT_NONE, screen, -#else -#define MENU_MULTISAMPLING(screen) -#endif - -#ifdef NO_ISLAND_LOADING -#define MENU_ISLAND_LOADING(screen) MENUACTION_ISLANDLOADING, "FEM_ISL", SAVESLOT_NONE, screen, -#else -#define MENU_ISLAND_LOADING(screen) -#endif - -#ifdef PS2_ALPHA_TEST -#define MENU_PS2_ALPHA_TEST(screen) MENUACTION_PS2_ALPHA_TEST, "FEM_2PR", SAVESLOT_NONE, screen, -#else -#define MENU_PS2_ALPHA_TEST(screen) -#endif +// Please don't touch this file, except for bug fixing or ports. +// Check MenuScreensCustom.cpp +#ifndef CUSTOM_FRONTEND_OPTIONS CMenuScreen aScreens[] = { // MENUPAGE_STATS = 0 { "FEH_STA", MENUPAGE_NONE, 3, @@ -72,7 +38,7 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, MENUALIGN_CENTER, }, - // MENUPAGE_GRAPHICS_SETTINGS = 4 + // MENUPAGE_DISPLAY_SETTINGS = 4 #ifdef LEGACY_MENU_OPTIONS #define Y_OFFSET 50 #else @@ -95,14 +61,8 @@ CMenuScreen aScreens[] = { MENUACTION_RADARMODE, "FED_RDR", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 228 + Y_OFFSET, MENUALIGN_LEFT, MENUACTION_HUD, "FED_HUD", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 253 + Y_OFFSET, MENUALIGN_LEFT, MENUACTION_SCREENRES, "FED_RES", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 278 + Y_OFFSET, MENUALIGN_LEFT, -#ifdef IMPROVED_VIDEOMODE - MENUACTION_SCREENFORMAT,"FED_POS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 303 + Y_OFFSET, MENUALIGN_LEFT, - MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 320, 328 + Y_OFFSET, MENUALIGN_CENTER, - MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 320, 353 + Y_OFFSET, MENUALIGN_CENTER, -#else - MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 320, 303 + Y_OFFSET, MENUALIGN_CENTER, + MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 320, 303 + Y_OFFSET, MENUALIGN_CENTER, MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 320, 328 + Y_OFFSET, MENUALIGN_CENTER, -#endif }, #undef Y_OFFSET @@ -286,10 +246,8 @@ CMenuScreen aScreens[] = { MENUACTION_CHANGEMENU, "FEP_QUI", SAVESLOT_NONE, MENUPAGE_EXIT, 0, 0, MENUALIGN_CENTER, }, - // TODO(Miami) // MENUPAGE_KEYBOARD_CONTROLS = 30 { "FET_STI", MENUPAGE_CONTROLLER_PC, 1, - MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 0, 0, 0, }, // MENUPAGE_MOUSE_CONTROLS = 31 @@ -314,18 +272,15 @@ CMenuScreen aScreens[] = { // MENUPAGE_NONE = 33 { "", 0, 0, }, - // MENUPAGE_OUTRO = 34 - { "", 0, 0, }, - #ifdef LEGACY_MENU_OPTIONS - // MENUPAGE_CONTROLLER_SETTINGS = 4 + // MENUPAGE_CONTROLLER_SETTINGS { "FET_CON", MENUPAGE_OPTIONS, 0, MENUACTION_CTRLCONFIG, "FEC_CCF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS, 0, 0, 0, MENUACTION_CTRLVIBRATION, "FEC_VIB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS, 0, 0, 0, MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, - // MENUPAGE_DEBUG_MENU = 18 + // MENUPAGE_DEBUG_MENU { "FED_DBG", MENUPAGE_NONE, 0, MENUACTION_RELOADIDE, "FED_RID", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, MENUACTION_SETDBGFLAG, "FED_DFL", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, @@ -334,7 +289,7 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, - // MENUPAGE_CONTROLLER_PC_OLD1 = 36 + // MENUPAGE_CONTROLLER_PC_OLD1 { "FET_CTL", MENUPAGE_CONTROLLER_PC, 0, MENUACTION_GETKEY, "FEC_PLB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0, MENUACTION_GETKEY, "FEC_CWL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1, 0, 0, 0, @@ -348,12 +303,12 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, - // MENUPAGE_CONTROLLER_PC_OLD2 = 37 + // MENUPAGE_CONTROLLER_PC_OLD2 { "FET_CTL", MENUPAGE_CONTROLLER_PC, 1, }, - // MENUPAGE_CONTROLLER_PC_OLD3 = 38 + // MENUPAGE_CONTROLLER_PC_OLD3 { "FET_CTL", MENUPAGE_CONTROLLER_PC, 2, MENUACTION_GETKEY, "FEC_LUP", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, 0, 0, 0, MENUACTION_GETKEY, "FEC_LDN", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3, 0, 0, 0, @@ -362,12 +317,12 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, - // MENUPAGE_CONTROLLER_PC_OLD4 = 39 + // MENUPAGE_CONTROLLER_PC_OLD4 { "FET_CTL", MENUPAGE_CONTROLLER_PC, 3, }, - // MENUPAGE_CONTROLLER_DEBUG = 40 + // MENUPAGE_CONTROLLER_DEBUG { "FEC_DBG", MENUPAGE_CONTROLLER_PC, 3, MENUACTION_GETKEY, "FEC_TGD", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, 0, 0, 0, MENUACTION_GETKEY, "FEC_TDO", SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG, 0, 0, 0, @@ -376,6 +331,10 @@ CMenuScreen aScreens[] = { MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0, }, #endif + + // MENUPAGE_OUTRO - Originally 34 + { "", 0, 0, }, }; #endif +#endif diff --git a/src/core/MenuScreensCustom.cpp b/src/core/MenuScreensCustom.cpp new file mode 100644 index 00000000..5733c369 --- /dev/null +++ b/src/core/MenuScreensCustom.cpp @@ -0,0 +1,734 @@ +#include "common.h" +#include "platform.h" +#include "crossplatform.h" +#include "Renderer.h" +#include "Frontend.h" +#include "Font.h" +#include "Camera.h" +#include "main.h" +#include "MBlur.h" +#include "postfx.h" +#include "custompipes.h" +#include "RwHelper.h" +#include "Text.h" +#include "Streaming.h" +#include "FileLoader.h" +#include "Collision.h" +#include "ModelInfo.h" +#include "Pad.h" + +// Menu screens array is at the bottom of the file. + +#ifdef PC_MENU + +#ifdef CUSTOM_FRONTEND_OPTIONS + +#ifdef IMPROVED_VIDEOMODE + #define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, nil, screenModes, 2, true, ScreenModeAfterChange) }, 0, 0, MENUALIGN_LEFT, +#else + #define VIDEOMODE_SELECTOR +#endif + +#ifdef MULTISAMPLING + #define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) }, 0, 0, MENUALIGN_LEFT, +#else + #define MULTISAMPLING_SELECTOR +#endif + +#ifdef CUTSCENE_BORDERS_SWITCH + #define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&FrontEndMenuManager.m_PrefsCutsceneBorders, "CutsceneBorders", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, +#else + #define CUTSCENE_BORDERS_TOGGLE +#endif + +#ifdef FREE_CAM + #define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "FreeCam", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, +#else + #define FREE_CAM_TOGGLE +#endif + +#ifdef PS2_ALPHA_TEST + #define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "PS2AlphaTest", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, +#else + #define DUALPASS_SELECTOR +#endif + +#ifdef NO_ISLAND_LOADING + #define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&FrontEndMenuManager.m_PrefsIslandLoading, "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) }, 0, 0, MENUALIGN_LEFT, +#else + #define ISLAND_LOADING_SELECTOR +#endif + +#ifdef EXTENDED_COLOURFILTER + #define POSTFX_SELECTORS \ + MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false, nil) }, 0, 0, MENUALIGN_LEFT, \ + MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "MotionBlur", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, +#else + #define POSTFX_SELECTORS +#endif + +#ifdef EXTENDED_PIPELINES + #define PIPELINES_SELECTOR \ + MENUACTION_CFO_SELECT, "FED_VPL", { new CCFOSelect((int8*)&CustomPipes::VehiclePipeSwitch, "VehiclePipeline", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), false, nil) }, 0, 0, MENUALIGN_LEFT, \ + MENUACTION_CFO_SELECT, "FED_PRM", { new CCFOSelect((int8*)&CustomPipes::RimlightEnable, "NeoRimLight", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, \ + MENUACTION_CFO_SELECT, "FED_WLM", { new CCFOSelect((int8*)&CustomPipes::LightmapEnable, "NeoLightMaps", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, \ + MENUACTION_CFO_SELECT, "FED_RGL", { new CCFOSelect((int8*)&CustomPipes::GlossEnable, "NeoRoadGloss", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, +#else + #define PIPELINES_SELECTOR +#endif + +#ifdef INVERT_LOOK_FOR_PAD + #define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_ILU", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, nil, off_on, 2, false, nil) }, 150, 0, MENUALIGN_LEFT, +#else + #define INVERT_PAD_SELECTOR +#endif + +const char *filterNames[] = { "FEM_NON", "FEM_SIM", "FEM_NRM", "FEM_MOB" }; +const char *vehPipelineNames[] = { "FED_MFX", "FED_NEO" }; +const char *off_on[] = { "FEM_OFF", "FEM_ON" }; + +void RestoreDefGraphics(int8 action) { + if (action != FEOPTION_ACTION_SELECT) + return; + + #ifdef PS2_ALPHA_TEST + gPS2alphaTest = false; + #endif + #ifdef MULTISAMPLING + FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel = 0; + #endif + #ifdef NO_ISLAND_LOADING + if (!FrontEndMenuManager.m_bGameNotLoaded) { + FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW; + CCollision::bAlreadyLoaded = false; + CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + CStreaming::RequestIslands(CGame::currLevel); + CStreaming::LoadAllRequestedModels(true); + } else + FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW; + #endif + #ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those + FrontEndMenuManager.m_PrefsFrameLimiter = true; + FrontEndMenuManager.m_PrefsVsyncDisp = true; + #ifdef LEGACY_MENU_OPTIONS + FrontEndMenuManager.m_PrefsVsync = true; + #endif + FrontEndMenuManager.m_PrefsUseWideScreen = false; + FrontEndMenuManager.m_nDisplayVideoMode = FrontEndMenuManager.m_nPrefsVideoMode; + CMBlur::BlurOn = false; + FrontEndMenuManager.SaveSettings(); + #endif +} + +void RestoreDefDisplay(int8 action) { + if (action != FEOPTION_ACTION_SELECT) + return; + + #ifdef CUTSCENE_BORDERS_SWITCH + FrontEndMenuManager.m_PrefsCutsceneBorders = true; + #endif + #ifdef FREE_CAM + TheCamera.bFreeCam = false; + #endif + #ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those + FrontEndMenuManager.m_PrefsBrightness = 256; + FrontEndMenuManager.m_PrefsLOD = 1.2f; + CRenderer::ms_lodDistScale = 1.2f; + FrontEndMenuManager.m_PrefsShowSubtitles = false; + FrontEndMenuManager.m_PrefsShowLegends = true; + FrontEndMenuManager.m_PrefsRadarMode = 0; + FrontEndMenuManager.m_PrefsShowHud = true; + FrontEndMenuManager.SaveSettings(); + #endif +} + +#ifdef NO_ISLAND_LOADING +const char *islandLoadingOpts[] = { "FEM_LOW", "FEM_MED", "FEM_HIG" }; +void IslandLoadingAfterChange(int8 before, int8 after) { + if (!FrontEndMenuManager.m_bGameNotLoaded) { + if (after > FrontEndMenuManager.ISLAND_LOADING_LOW) { + FrontEndMenuManager.m_PrefsIslandLoading = before; // calls below needs previous mode :shrug: + + if (after == FrontEndMenuManager.ISLAND_LOADING_HIGH) + CStreaming::RemoveIslandsNotUsed(LEVEL_GENERIC); + if (before == FrontEndMenuManager.ISLAND_LOADING_LOW) { + if (CGame::currLevel != LEVEL_INDUSTRIAL) + CFileLoader::LoadCollisionFromDatFile(LEVEL_INDUSTRIAL); + if (CGame::currLevel != LEVEL_COMMERCIAL) + CFileLoader::LoadCollisionFromDatFile(LEVEL_COMMERCIAL); + if (CGame::currLevel != LEVEL_SUBURBAN) + CFileLoader::LoadCollisionFromDatFile(LEVEL_SUBURBAN); + CCollision::bAlreadyLoaded = true; + FrontEndMenuManager.m_PrefsIslandLoading = after; + CStreaming::RequestBigBuildings(CGame::currLevel); + + } else if (before == FrontEndMenuManager.ISLAND_LOADING_HIGH) { + FrontEndMenuManager.m_PrefsIslandLoading = after; + CStreaming::RequestIslands(CGame::currLevel); + } else + FrontEndMenuManager.m_PrefsIslandLoading = after; + + } else { // low + CCollision::bAlreadyLoaded = false; + CModelInfo::RemoveColModelsFromOtherLevels(CGame::currLevel); + CStreaming::RemoveUnusedBigBuildings(CGame::currLevel); + CStreaming::RemoveUnusedBuildings(CGame::currLevel); + CStreaming::RequestIslands(CGame::currLevel); + } + + CStreaming::LoadAllRequestedModels(true); + } + + FrontEndMenuManager.SetHelperText(0); +} +#endif + +#ifdef MORE_LANGUAGES +void LangPolSelect(int8 action) +{ + if (action == FEOPTION_ACTION_SELECT) { + FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_POLISH; + FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; + FrontEndMenuManager.InitialiseChangedLanguageSettings(); + FrontEndMenuManager.SaveSettings(); + } +} + +void LangRusSelect(int8 action) +{ + if (action == FEOPTION_ACTION_SELECT) { + FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_RUSSIAN; + FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; + FrontEndMenuManager.InitialiseChangedLanguageSettings(); + FrontEndMenuManager.SaveSettings(); + } +} + +void LangJapSelect(int8 action) +{ + if (action == FEOPTION_ACTION_SELECT) { + FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_JAPANESE; + FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true; + FrontEndMenuManager.InitialiseChangedLanguageSettings(); + FrontEndMenuManager.SaveSettings(); + } +} +#endif + +#ifndef MULTISAMPLING +void GraphicsGoBack() { +} +#else +void GraphicsGoBack() { + FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel; +} + +void MultiSamplingButtonPress(int8 action) { + if (action == FEOPTION_ACTION_SELECT) { + if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) { + FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel; + _psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); + FrontEndMenuManager.SetHelperText(0); + FrontEndMenuManager.SaveSettings(); + } + } else if (action == FEOPTION_ACTION_LEFT || action == FEOPTION_ACTION_RIGHT) { + if (FrontEndMenuManager.m_bGameNotLoaded) { + FrontEndMenuManager.m_nDisplayMSAALevel += (action == FEOPTION_ACTION_RIGHT ? 1 : -1); + + int i = 0; + int maxAA = RwD3D8EngineGetMaxMultiSamplingLevels(); + while (maxAA != 1) { + i++; + maxAA >>= 1; + } + + if (FrontEndMenuManager.m_nDisplayMSAALevel < 0) + FrontEndMenuManager.m_nDisplayMSAALevel = i; + else if (FrontEndMenuManager.m_nDisplayMSAALevel > i) + FrontEndMenuManager.m_nDisplayMSAALevel = 0; + } + } else if (action == FEOPTION_ACTION_FOCUSLOSS) { + if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) { + FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel; + FrontEndMenuManager.SetHelperText(3); + } + } +} + +wchar* MultiSamplingDraw(bool *disabled, bool userHovering) { + static wchar unicodeTemp[64]; + if (userHovering) { + if (FrontEndMenuManager.m_nDisplayMSAALevel == FrontEndMenuManager.m_nPrefsMSAALevel) { + if (FrontEndMenuManager.m_nHelperTextMsgId == 1) // Press enter to apply + FrontEndMenuManager.ResetHelperText(); + } else { + FrontEndMenuManager.SetHelperText(1); + } + } else { + if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) { + FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel; + } + } + + if (!FrontEndMenuManager.m_bGameNotLoaded) + *disabled = true; + + switch (FrontEndMenuManager.m_nDisplayMSAALevel) { + case 0: + return TheText.Get("FEM_OFF"); + default: + sprintf(gString, "%iX", 1 << (FrontEndMenuManager.m_nDisplayMSAALevel)); + AsciiToUnicode(gString, unicodeTemp); + return unicodeTemp; + } +} +#endif + +#ifdef IMPROVED_VIDEOMODE +const char* screenModes[] = { "FED_FLS", "FED_WND" }; +void ScreenModeAfterChange(int8 before, int8 after) +{ + _psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution + FrontEndMenuManager.SetHelperText(0); +} + +#endif + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS +wchar selectedJoystickUnicode[128]; + +wchar* DetectJoystickDraw(bool* disabled, bool userHovering) { + int numButtons; + int found = -1; + const char *joyname; + if (userHovering) { + for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) { + if ((joyname = glfwGetJoystickName(i))) { + const uint8* buttons = glfwGetJoystickButtons(i, &numButtons); + for (int j = 0; j < numButtons; j++) { + if (buttons[j]) { + found = i; + break; + } + } + if (found != -1) + break; + } + } + + if (found != -1 && PSGLOBAL(joy1id) != found) { + if (PSGLOBAL(joy1id) != -1 && PSGLOBAL(joy1id) != found) + PSGLOBAL(joy2id) = PSGLOBAL(joy1id); + else + PSGLOBAL(joy2id) = -1; + + strcpy(gSelectedJoystickName, joyname); + PSGLOBAL(joy1id) = found; + } + } + if (PSGLOBAL(joy1id) == -1) + AsciiToUnicode("Not found", selectedJoystickUnicode); + else + AsciiToUnicode(gSelectedJoystickName, selectedJoystickUnicode); + + return selectedJoystickUnicode; +} +#endif + +CMenuScreenCustom aScreens[] = { + // MENUPAGE_STATS = 0 + { "FEH_STA", MENUPAGE_NONE, nil, nil, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 190, 320, MENUALIGN_RIGHT, + }, + + // MENUPAGE_NEW_GAME = 1 + { "FEP_STG", MENUPAGE_NONE, nil, nil, + MENUACTION_CHANGEMENU, "FES_NGA", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD}, 320, 155, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FES_LOA", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FES_DEL", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT}, 0, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_BRIEFS = 2 + { "FEH_BRI", MENUPAGE_NONE, nil, nil, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 190, 320, MENUALIGN_RIGHT, + }, + + // MENUPAGE_SOUND_SETTINGS = 3 + { "FEH_AUD", MENUPAGE_OPTIONS, nil, nil, + MENUACTION_MUSICVOLUME, "FEA_MUS", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 40, 76, MENUALIGN_LEFT, + MENUACTION_SFXVOLUME, "FEA_SFX", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_MP3VOLUMEBOOST, "FEA_MPB", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_AUDIOHW, "FEA_3DH", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SPEAKERCONF, "FEA_SPK", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_DYNAMICACOUSTIC, "FET_DAM", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_RADIO, "FEA_RSS", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 320, 367, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_DISPLAY_SETTINGS = 4 +#ifndef GRAPHICS_MENU_OPTIONS + { "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil, + MENUACTION_BRIGHTNESS, "FED_BRI", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_DRAWDIST, "FEM_LOD", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#ifdef LEGACY_MENU_OPTIONS + MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#endif + MENUACTION_FRAMELIMIT, "FEM_FRM", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#if defined LEGACY_MENU_OPTIONS && !defined EXTENDED_COLOURFILTER + MENUACTION_TRAILS, "FED_TRA", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#endif + MENUACTION_SUBTITLES, "FED_SUB", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_WIDESCREEN, "FED_WIS", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_LEGENDS, "MAP_LEG", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_RADARMODE, "FED_RDR", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_HUD, "FED_HUD", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SCREENRES, "FED_RES", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT, + VIDEOMODE_SELECTOR + MULTISAMPLING_SELECTOR + ISLAND_LOADING_SELECTOR + DUALPASS_SELECTOR + CUTSCENE_BORDERS_TOGGLE + FREE_CAM_TOGGLE + POSTFX_SELECTORS + PIPELINES_SELECTOR + MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 320, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER, + }, +#else + { "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil, + MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + CUTSCENE_BORDERS_TOGGLE + FREE_CAM_TOGGLE + MENUACTION_LEGENDS, "MAP_LEG", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_RADARMODE, "FED_RDR", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_HUD, "FED_HUD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_SUBTITLES, "FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefDisplay) }, 320, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER, + }, +#endif + + // MENUPAGE_LANGUAGE_SETTINGS = 5 + { "FEH_LAN", MENUPAGE_OPTIONS, nil, nil, + MENUACTION_LANG_ENG, "FEL_ENG", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 320, 132, MENUALIGN_CENTER, + MENUACTION_LANG_FRE, "FEL_FRE", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_LANG_GER, "FEL_GER", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_LANG_ITA, "FEL_ITA", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_LANG_SPA, "FEL_SPA", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, +#ifdef MORE_LANGUAGES + MENUACTION_CFO_DYNAMIC, "FEL_POL", { new CCFODynamic(nil, nil, nil, LangPolSelect) }, 0, 0, MENUALIGN_CENTER, + MENUACTION_CFO_DYNAMIC, "FEL_RUS", { new CCFODynamic(nil, nil, nil, LangRusSelect) }, 0, 0, MENUALIGN_CENTER + MENUACTION_CFO_DYNAMIC, "FEL_JAP", { new CCFODynamic(nil, nil, nil, LangJapSelect) }, 0, 0, MENUALIGN_CENTER, +#endif + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_MAP = 6 + { "FEH_MAP", MENUPAGE_NONE, nil, nil, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 70, 380, MENUALIGN_CENTER, + }, + + // MENUPAGE_NEW_GAME_RELOAD = 7 + { "FES_NGA", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FESZ_QR", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 200, MENUALIGN_CENTER, + MENUACTION_NEWGAME, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_CHOOSE_LOAD_SLOT = 8 + { "FET_LG", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_CHECKSAVE, "FEM_SL1", {nil, SAVESLOT_1, 0}, 40, 90, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL2", {nil, SAVESLOT_2, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL3", {nil, SAVESLOT_3, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL4", {nil, SAVESLOT_4, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL5", {nil, SAVESLOT_5, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL6", {nil, SAVESLOT_6, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL7", {nil, SAVESLOT_7, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL8", {nil, SAVESLOT_8, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER, + }, + + // MENUPAGE_CHOOSE_DELETE_SLOT = 9 + { "FES_DEL", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_CHECKSAVE, "FEM_SL1", {nil, SAVESLOT_1, 0}, 40, 90, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL2", {nil, SAVESLOT_2, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL3", {nil, SAVESLOT_3, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL4", {nil, SAVESLOT_4, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL5", {nil, SAVESLOT_5, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL6", {nil, SAVESLOT_6, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL7", {nil, SAVESLOT_7, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_CHECKSAVE, "FEM_SL8", {nil, SAVESLOT_8, 0}, 0, 0, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER, + }, + + // MENUPAGE_LOAD_SLOT_CONFIRM = 10 + { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil, + MENUACTION_LABEL, "FESZ_QL", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT}, 320, 200, MENUALIGN_CENTER, + MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_DELETE_SLOT_CONFIRM = 11 + { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil, + MENUACTION_LABEL, "FESZ_QD", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT}, 320, 200, MENUALIGN_CENTER, + MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_DELETING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_LOADING_IN_PROGRESS = 12 + { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil, + }, + + // MENUPAGE_DELETING_IN_PROGRESS = 13 + { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil, + }, + + // MENUPAGE_DELETE_SUCCESSFUL = 14 + { "FES_DEL", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FES_DSC", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_CHOOSE_SAVE_SLOT = 15 + { "FET_SG", MENUPAGE_DISABLED, nil, nil, + MENUACTION_SAVEGAME, "FEM_SL1", {nil, SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 40, 90, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL2", {nil, SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL3", {nil, SAVESLOT_3, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL4", {nil, SAVESLOT_4, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL5", {nil, SAVESLOT_5, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL6", {nil, SAVESLOT_6, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL7", {nil, SAVESLOT_7, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_SAVEGAME, "FEM_SL8", {nil, SAVESLOT_8, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT, + MENUACTION_RESUME_FROM_SAVEZONE,"FESZ_CA", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVE_OVERWRITE_CONFIRM = 16 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + MENUACTION_LABEL, "FESZ_QZ", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 200, MENUALIGN_CENTER, + MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_SAVING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVING_IN_PROGRESS = 17 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + }, + + // MENUPAGE_SAVE_SUCCESSFUL = 18 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + MENUACTION_LABEL, "FES_SSC", {nil, SAVESLOT_LABEL, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_RESUME_FROM_SAVEZONE, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVE_CUSTOM_WARNING = 19 + { "FET_SG", MENUPAGE_NONE, nil, nil, + MENUACTION_LABEL, "", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SAVE_CHEAT_WARNING = 20 + { "FET_SG", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FES_CHE", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_SKIN_SELECT = 21 + { "FET_PS", MENUPAGE_OPTIONS, nil, nil, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, 0, + }, + + // MENUPAGE_SAVE_UNUSED = 22 + { "FET_SG", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FED_LWR", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEC_OKK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 0, 0, 0, + }, + + // MENUPAGE_SAVE_FAILED = 23 + { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + MENUACTION_LABEL, "FEC_SVU", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_CHANGEMENU, "FEC_OKK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 0, 0, 0, + }, + + // MENUPAGE_SAVE_FAILED_2 = 24 + { "FET_LG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil, + MENUACTION_LABEL, "FEC_SVU", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + }, + + // MENUPAGE_LOAD_FAILED = 25 + { "FET_LG", MENUPAGE_NEW_GAME, nil, nil, + MENUACTION_LABEL, "FEC_LUN", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC = 26 + { "FET_CTL", MENUPAGE_OPTIONS, new CCustomScreenLayout({0, 0, MENU_DEFAULT_LINE_HEIGHT, false, false, 150}), nil, + MENUACTION_CTRLMETHOD, "FET_STI", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 150, MENUALIGN_CENTER, + MENUACTION_KEYBOARDCTRLS,"FEC_RED", {nil, SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS}, 0, 0, MENUALIGN_CENTER, +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + MENUACTION_CHANGEMENU, "FEC_JOD", {nil, SAVESLOT_NONE, MENUPAGE_DETECT_JOYSTICK}, 0, 0, MENUALIGN_CENTER, +#endif + MENUACTION_CHANGEMENU, "FEC_MOU", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_CENTER, + INVERT_PAD_SELECTOR + MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_OPTIONS = 27 + { "FET_OPT", MENUPAGE_NONE, nil, nil, + MENUACTION_CHANGEMENU, "FEO_CON", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 132, MENUALIGN_CENTER, + MENUACTION_LOADRADIO, "FEO_AUD", {nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEO_DIS", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_CENTER, +#ifdef GRAPHICS_MENU_OPTIONS + MENUACTION_CHANGEMENU, "FET_GRA", {nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS}, 0, 0, MENUALIGN_CENTER, +#endif + MENUACTION_CHANGEMENU, "FEO_LAN", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_PLAYERSETUP, "FET_PS", {nil, SAVESLOT_NONE, MENUPAGE_SKIN_SELECT}, 0, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_EXIT = 28 + { "FET_QG", MENUPAGE_NONE, nil, nil, + MENUACTION_LABEL, "FEQ_SRE", {nil, SAVESLOT_NONE, 0}, 0, 0, 0, + MENUACTION_DONTCANCEL, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 200, MENUALIGN_CENTER, + MENUACTION_CANCELGAME, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 225, MENUALIGN_CENTER, + }, + + // MENUPAGE_START_MENU = 29 + { "FEM_MM", MENUPAGE_DISABLED, nil, nil, + MENUACTION_CHANGEMENU, "FEP_STG", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 170, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_OPT", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_QUI", {nil, SAVESLOT_NONE, MENUPAGE_EXIT}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_KEYBOARD_CONTROLS = 30 + { "FET_STI", MENUPAGE_CONTROLLER_PC, nil, nil, + }, + + // MENUPAGE_MOUSE_CONTROLS = 31 + { "FEC_MOU", MENUPAGE_CONTROLLER_PC, nil, nil, + MENUACTION_MOUSESENS, "FEC_MSH", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 40, 170, MENUALIGN_LEFT, + MENUACTION_INVVERT, "FEC_IVV", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_MOUSESTEER, "FET_MST", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 260, MENUALIGN_CENTER, + }, + + // MENUPAGE_PAUSE_MENU = 32 + { "FET_PAU", MENUPAGE_DISABLED, nil, nil, + MENUACTION_RESUME, "FEP_RES", {nil, SAVESLOT_NONE, 0}, 320, 120, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEH_SGA", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEH_MAP", {nil, SAVESLOT_NONE, MENUPAGE_MAP}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_STA", {nil, SAVESLOT_NONE, MENUPAGE_STATS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEH_BRI", {nil, SAVESLOT_NONE, MENUPAGE_BRIEFS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FET_OPT", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, MENUALIGN_CENTER, + MENUACTION_CHANGEMENU, "FEP_QUI", {nil, SAVESLOT_NONE, MENUPAGE_EXIT}, 0, 0, MENUALIGN_CENTER, + }, + + // MENUPAGE_NONE = 33 + { "", 0, nil, nil, }, + + +#ifdef LEGACY_MENU_OPTIONS + // MENUPAGE_CONTROLLER_SETTINGS = 4 + { "FET_CON", MENUPAGE_OPTIONS, nil, nil, + MENUACTION_CTRLCONFIG, "FEC_CCF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS}, 0, 0, 0, + MENUACTION_CTRLVIBRATION, "FEC_VIB", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, + + // MENUPAGE_DEBUG_MENU = 18 + { "FED_DBG", MENUPAGE_NONE, nil, nil, + MENUACTION_RELOADIDE, "FED_RID", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_SETDBGFLAG, "FED_DFL", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_SWITCHBIGWHITEDEBUGLIGHT, "FED_DLS", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_COLLISIONPOLYS, "FED_SCP", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC_OLD1 = 36 + { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil, + MENUACTION_GETKEY, "FEC_PLB", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_CWL", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_CWR", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_LKT", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_PJP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_PSP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_TLF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_TRG", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_CCM", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC_OLD2 = 37 + { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil, + + }, + + // MENUPAGE_CONTROLLER_PC_OLD3 = 38 + { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil, + MENUACTION_GETKEY, "FEC_LUP", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_LDN", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_SMS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0, + MENUACTION_SHOWHEADBOB, "FEC_GSL", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, + + // MENUPAGE_CONTROLLER_PC_OLD4 = 39 + { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil, + + }, + + // MENUPAGE_CONTROLLER_DEBUG = 40 + { "FEC_DBG", MENUPAGE_CONTROLLER_PC, nil, nil, + MENUACTION_GETKEY, "FEC_TGD", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_TDO", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_TSS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0, + MENUACTION_GETKEY, "FEC_SMS", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG}, 0, 0, 0, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0, + }, +#endif + +#ifdef GRAPHICS_MENU_OPTIONS + // MENUPAGE_GRAPHICS_SETTINGS + { "FET_GRA", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true, true}), GraphicsGoBack, + + MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MENUACTION_WIDESCREEN, "FED_WIS", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT, + VIDEOMODE_SELECTOR +#ifdef LEGACY_MENU_OPTIONS + MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS}, 0, 0, MENUALIGN_LEFT, +#endif + MENUACTION_FRAMELIMIT, "FEM_FRM", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT, + MULTISAMPLING_SELECTOR +#ifdef EXTENDED_COLOURFILTER + POSTFX_SELECTORS +#elif defined LEGACY_MENU_OPTIONS + MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT, +#endif + PIPELINES_SELECTOR + ISLAND_LOADING_SELECTOR + DUALPASS_SELECTOR + MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefGraphics) }, 320, 0, MENUALIGN_CENTER, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER, + }, +#endif + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + // MENUPAGE_DETECT_JOYSTICK + { "FEC_JOD", MENUPAGE_CONTROLLER_PC, nil, nil, + + MENUACTION_LABEL, "FEC_JPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, 0, 0, 0, + MENUACTION_CFO_DYNAMIC, "FEC_JDE", { new CCFODynamic(nil, nil, DetectJoystickDraw, nil) }, 40, 200, MENUALIGN_LEFT, + MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 225, MENUALIGN_CENTER, + }, +#endif + + // MENUPAGE_OUTRO = 34 + { "", 0, nil, nil, }, +}; + +#endif +#endif \ No newline at end of file diff --git a/src/core/config.h b/src/core/config.h index e591a560..4c7900b7 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -226,6 +226,7 @@ enum Config { #define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more //#define MORE_LANGUAGES // Add more translations to the game #define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible +#define LOAD_INI_SETTINGS // as the name suggests. fundamental for CUSTOM_FRONTEND_OPTIONS #define FIX_HIGH_FPS_BUGS_ON_FRONTEND // Just debug menu entries @@ -242,16 +243,13 @@ enum Config { #define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number #define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time #define DISABLE_VSYNC_ON_TEXTURE_CONVERSION // make texture conversion work faster by disabling vsync -//#define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU //#define USE_TEXTURE_POOL -//#define CUTSCENE_BORDERS_SWITCH #ifdef LIBRW //#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur) //#define EXTENDED_PIPELINES // custom render pipelines (includes Neo) //#define SCREEN_DROPLETS // neo water droplets //#define NEW_RENDERER // leeds-like world rendering, needs librw #endif -//#define MULTISAMPLING // adds MSAA option TODO #ifndef EXTENDED_COLOURFILTER #undef SCREEN_DROPLETS // we need the front- (or back-)buffer for this effect @@ -260,11 +258,6 @@ enum Config { #undef SCREEN_DROPLETS // we need neo.txd #endif -#ifdef LIBRW -// these are not supported with librw yet -# undef MULTISAMPLING -#endif - // Water & Particle #define PC_PARTICLE //#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2 @@ -279,7 +272,7 @@ enum Config { #define XINPUT #endif #if !defined(_WIN32) && !defined(__SWITCH__) -#define DONT_TRUST_RECOGNIZED_JOYSTICKS // Then we'll only rely on GLFW gamepad DB, and expect user to enter Controller->Detect joysticks if his joystick isn't on that list. +//#define DONT_TRUST_RECOGNIZED_JOYSTICKS // Then we'll only rely on GLFW gamepad DB, and expect user to enter Controller->Detect joysticks if his joystick isn't on that list. #endif #define DETECT_PAD_INPUT_SWITCH // Adds automatic switch of pad related stuff between controller and kb/m #define KANGAROO_CHEAT @@ -300,16 +293,25 @@ enum Config { # define MAP_ENHANCEMENTS // Adding waypoint and better mouse support # define TRIANGLE_BACK_BUTTON //# define CIRCLE_BACK_BUTTON -//#define CUSTOM_FRONTEND_OPTIONS -# define GRAPHICS_MENU_OPTIONS -#define LEGACY_MENU_OPTIONS +#define LEGACY_MENU_OPTIONS // i.e. frame sync(vsync) #define MUCH_SHORTER_OUTRO_SCREEN // #define XBOX_MESSAGE_SCREEN // Blue background, no "saved successfully press OK" screen etc. +# define CUSTOM_FRONTEND_OPTIONS + +# ifdef CUSTOM_FRONTEND_OPTIONS +# define GRAPHICS_MENU_OPTIONS // otherwise Display settings will be scrollable +//# define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU +# define CUTSCENE_BORDERS_SWITCH +//# define MULTISAMPLING // adds MSAA option +# define INVERT_LOOK_FOR_PAD // enable the hidden option +# endif +#endif // Script #define USE_DEBUG_SCRIPT_LOADER // Loads main.scm by default. Hold R for main_freeroam.scm and D for main_d.scm #define USE_MEASUREMENTS_IN_METERS // makes game use meters instead of feet in script #define USE_PRECISE_MEASUREMENT_CONVERTION // makes game convert feet to meeters more precisely +#ifdef PC_MENU //#define MISSION_REPLAY // mobile feature #endif //#define SIMPLIER_MISSIONS // apply simplifications from mobile @@ -334,8 +336,6 @@ enum Config { // Peds #define PED_SKIN // support for skinned geometry on peds -#define ANIMATE_PED_COL_MODEL -#define VC_PED_PORTS // various ports from VC's CPed, mostly subtle #define CANCELLABLE_CAR_ENTER // Camera @@ -347,10 +347,14 @@ enum Config { //#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS +#ifdef LIBRW +// these are not supported with librw yet +# undef MULTISAMPLING +#endif + //#define SQUEEZE_PERFORMANCE #ifdef SQUEEZE_PERFORMANCE #undef PS2_ALPHA_TEST #undef NO_ISLAND_LOADING #define PC_PARTICLE - #define VC_PED_PORTS // To not process collisions always. But should be tested if that's really beneficial #endif diff --git a/src/core/main.cpp b/src/core/main.cpp index 7fb07fff..74172bf3 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -70,6 +70,7 @@ #include "Ropes.h" #include "postfx.h" #include "custompipes.h" +#include "frontendoption.h" #include "screendroplets.h" GlobalScene Scene; @@ -400,6 +401,13 @@ Initialise3D(void *param) DebugMenuInit(); DebugMenuPopulate(); #endif // !DEBUGMENU +#ifdef CUSTOM_FRONTEND_OPTIONS + // Apparently this func. can be run multiple times at the start. + if (numCustomFrontendOptions == 0 && numCustomFrontendScreens == 0) { + // needs stored language and TheText to be loaded, and last TheText reload is at the start of here + CustomFrontendOptionsPopulate(); + } +#endif bool ret = CGame::InitialiseRenderWare(); #ifdef EXTENDED_PIPELINES CustomPipes::CustomPipeInit(); // need Scene.world for this diff --git a/src/core/main.h b/src/core/main.h index f428224e..d3b5e9d9 100644 --- a/src/core/main.h +++ b/src/core/main.h @@ -39,6 +39,11 @@ void ResetLoadingScreenBar(void); void TheModelViewer(void); #endif +#ifdef LOAD_INI_SETTINGS +void LoadINISettings(); +void SaveINISettings(); +#endif + #ifdef NEW_RENDERER extern bool gbNewRenderer; bool FredIsInFirstPersonCam(void); diff --git a/src/core/re3.cpp b/src/core/re3.cpp index ebfa8de5..3a03461a 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -13,13 +13,10 @@ #include "Vehicle.h" #include "ModelIndices.h" #include "Streaming.h" -#include "PathFind.h" #include "Boat.h" #include "Heli.h" #include "Automobile.h" #include "Bike.h" -#include "Ped.h" -#include "Particle.h" #include "Console.h" #include "Debug.h" #include "Hud.h" @@ -29,7 +26,6 @@ #include "Radar.h" #include "debugmenu.h" #include "Frontend.h" -#include "Text.h" #include "WaterLevel.h" #include "main.h" #include "Script.h" @@ -37,6 +33,11 @@ #include "postfx.h" #include "custompipes.h" +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS +#include "FileMgr.h" +#include "ControllerConfig.h" +#endif + #ifndef _WIN32 #include "assert.h" #include @@ -75,6 +76,169 @@ mysrand(unsigned int seed) myrand_seed = seed; } +#ifdef CUSTOM_FRONTEND_OPTIONS +#include "frontendoption.h" + +void +CustomFrontendOptionsPopulate(void) +{ + // Moved to an array in MenuScreensCustom.cpp, but APIs are still available. see frontendoption.h +} +#endif + +#ifdef LOAD_INI_SETTINGS +#include "ini_parser.hpp" + +linb::ini cfg; +int CheckAndReadIniInt(const char *cat, const char *key, int original) +{ + std::string strval = cfg.get(cat, key, ""); + const char *value = strval.c_str(); + if (value && value[0] != '\0') + return atoi(value); + + return original; +} + +float CheckAndReadIniFloat(const char *cat, const char *key, float original) +{ + std::string strval = cfg.get(cat, key, ""); + const char *value = strval.c_str(); + if (value && value[0] != '\0') + return atof(value); + + return original; +} + +void CheckAndSaveIniInt(const char *cat, const char *key, int val, bool &changed) +{ + char temp[10]; + if (atoi(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it + changed = true; + sprintf(temp, "%u", val); + cfg.set(cat, key, temp); + } +} + +void CheckAndSaveIniFloat(const char *cat, const char *key, float val, bool &changed) +{ + char temp[10]; + if (atof(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it + changed = true; + sprintf(temp, "%f", val); + cfg.set(cat, key, temp); + } +} + +void LoadINISettings() +{ + cfg.load_file("reVC.ini"); + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + // Written by assuming the codes below will run after _InputInitialiseJoys(). + strcpy(gSelectedJoystickName, cfg.get("DetectJoystick", "JoystickName", "").c_str()); + + if(gSelectedJoystickName[0] != '\0') { + for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) { + if (glfwJoystickPresent(i) && strncmp(gSelectedJoystickName, glfwGetJoystickName(i), strlen(gSelectedJoystickName)) == 0) { + if (PSGLOBAL(joy1id) != -1) { + PSGLOBAL(joy2id) = PSGLOBAL(joy1id); + } + PSGLOBAL(joy1id) = i; + int count; + glfwGetJoystickButtons(PSGLOBAL(joy1id), &count); + + // We need to init and reload bindings, because; + // 1-joypad button number may differ with saved/prvly connected one + // 2-bindings are not init'ed if there is no joypad at the start + ControlsManager.InitDefaultControlConfigJoyPad(count); + CFileMgr::SetDirMyDocuments(); + int32 gta3set = CFileMgr::OpenFile("gta3.set", "r"); + if (gta3set) { + ControlsManager.LoadSettings(gta3set); + CFileMgr::CloseFile(gta3set); + } + CFileMgr::SetDir(""); + break; + } + } + } +#endif + +#ifdef CUSTOM_FRONTEND_OPTIONS + for (int i = 0; i < MENUPAGES; i++) { + for (int j = 0; j < NUM_MENUROWS; j++) { + CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j]; + if (option.m_Action == MENUACTION_NOTHING) + break; + + // CFO check + if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) { + // CFO only supports saving uint8 right now + *option.m_CFO->value = CheckAndReadIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value); + if (option.m_Action == MENUACTION_CFO_SELECT) { + option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue = *option.m_CFO->value; + } + } + } + } +#endif + +#ifdef EXTENDED_COLOURFILTER + CPostFX::Intensity = CheckAndReadIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity); +#endif +#ifdef EXTENDED_PIPELINES + CustomPipes::VehicleShininess = CheckAndReadIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess); + CustomPipes::VehicleSpecularity = CheckAndReadIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity); + CustomPipes::RimlightMult = CheckAndReadIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult); + CustomPipes::LightmapMult = CheckAndReadIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult); + CustomPipes::GlossMult = CheckAndReadIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult); +#endif +} + +void SaveINISettings() +{ + bool changed = false; + char temp[4]; + +#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS + if (strncmp(cfg.get("DetectJoystick", "JoystickName", "").c_str(), gSelectedJoystickName, strlen(gSelectedJoystickName)) != 0) { + changed = true; + cfg.set("DetectJoystick", "JoystickName", gSelectedJoystickName); + } +#endif +#ifdef CUSTOM_FRONTEND_OPTIONS + for (int i = 0; i < MENUPAGES; i++) { + for (int j = 0; j < NUM_MENUROWS; j++) { + CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j]; + if (option.m_Action == MENUACTION_NOTHING) + break; + + if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) { + // Beware: CFO only supports saving uint8 right now + CheckAndSaveIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value, changed); + } + } + } +#endif + +#ifdef EXTENDED_COLOURFILTER + CheckAndSaveIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity, changed); +#endif +#ifdef EXTENDED_PIPELINES + CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess, changed); + CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity, changed); + CheckAndSaveIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult, changed); + CheckAndSaveIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult, changed); + CheckAndSaveIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult, changed); +#endif + + if (changed) + cfg.write_file("reVC.ini"); +} + +#endif + #ifdef DEBUGMENU void WeaponCheat1(); void WeaponCheat2(); diff --git a/src/extras/frontendoption.cpp b/src/extras/frontendoption.cpp new file mode 100644 index 00000000..1f154250 --- /dev/null +++ b/src/extras/frontendoption.cpp @@ -0,0 +1,167 @@ +#include "common.h" + +#ifdef CUSTOM_FRONTEND_OPTIONS +#include "Frontend.h" +#include "Text.h" + +int lastOgScreen = MENUPAGES; // means no new pages + +int numCustomFrontendOptions = 0; +int numCustomFrontendScreens = 0; + +int optionCursor = -2; +int currentMenu; +bool optionOverwrite = false; + +void GoBack() +{ + FrontEndMenuManager.SwitchToNewScreen(-1); +} + +uint8 +GetNumberOfMenuOptions(int screen) +{ + uint8 Rows = 0; + for (int i = 0; i < NUM_MENUROWS; i++) { + if (aScreens[screen].m_aEntries[i].m_Action == MENUACTION_NOTHING) + break; + + ++Rows; + } + return Rows; +} + +uint8 +GetLastMenuScreen() +{ + int8 page = -1; + for (int i = 0; i < MENUPAGES; i++) { + if (strcmp(aScreens[i].m_ScreenName, "") == 0 && aScreens[i].m_PreviousPage == MENUPAGE_NONE) + break; + + ++page; + } + return page; +} + +int8 RegisterNewScreen(const char *name, int prevPage, ReturnPrevPageFunc returnPrevPageFunc) +{ + if (lastOgScreen == MENUPAGES) + lastOgScreen = GetLastMenuScreen(); + + numCustomFrontendScreens++; + int id = lastOgScreen + numCustomFrontendScreens; + assert(id < MENUPAGES && "No room for new custom frontend screens! Increase MENUPAGES"); + strncpy(aScreens[id].m_ScreenName, name, 8); + aScreens[id].m_PreviousPage = prevPage; + aScreens[id].returnPrevPageFunc = returnPrevPageFunc; + return id; +} + +int8 RegisterNewOption() +{ + numCustomFrontendOptions++; + uint8 numOptions = GetNumberOfMenuOptions(currentMenu); + uint8 curIdx; + if (optionCursor < 0) { + optionCursor = curIdx = numOptions + optionCursor + 1; + } else + curIdx = optionCursor; + + if (!optionOverwrite) { + if (aScreens[currentMenu].m_aEntries[curIdx].m_Action != MENUACTION_NOTHING) { + for (int i = numOptions - 1; i >= curIdx; i--) { + memcpy(&aScreens[currentMenu].m_aEntries[i + 1], &aScreens[currentMenu].m_aEntries[i], sizeof(CMenuScreenCustom::CMenuEntry)); + } + } + } + optionCursor++; + return curIdx; +} + +void FrontendOptionSetCursor(int screen, int8 option, bool overwrite) +{ + currentMenu = screen; + optionCursor = option; + optionOverwrite = overwrite; +} + +void FrontendOptionAddBuiltinAction(const char* gxtKey, uint16 x, uint16 y, uint8 align, int action, int targetMenu, int saveSlot) { + int8 screenOptionOrder = RegisterNewOption(); + + CMenuScreenCustom::CMenuEntry &option = aScreens[currentMenu].m_aEntries[screenOptionOrder]; + + // We can't use custom text on those :shrug: + switch (action) { + case MENUACTION_SCREENRES: + strcpy(option.m_EntryName, "FED_RES"); + break; + case MENUACTION_AUDIOHW: + strcpy(option.m_EntryName, "FEA_3DH"); + break; + default: + strncpy(option.m_EntryName, gxtKey, 8); + break; + } + option.m_X = x; + option.m_Y = y; + option.m_Align = align; + option.m_Action = action; + option.m_SaveSlot = saveSlot; + option.m_TargetMenu = targetMenu; +} + +void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveName) +{ + int8 screenOptionOrder = RegisterNewOption(); + + CMenuScreenCustom::CMenuEntry &option = aScreens[currentMenu].m_aEntries[screenOptionOrder]; + option.m_Action = MENUACTION_CFO_SELECT; + option.m_X = x; + option.m_Y = y; + option.m_Align = align; + strncpy(option.m_EntryName, gxtKey, 8); + option.m_CFOSelect = new CCFOSelect(); + option.m_CFOSelect->rightTexts = (char**)malloc(numRightTexts * sizeof(char*)); + memcpy(option.m_CFOSelect->rightTexts, rightTexts, numRightTexts * sizeof(char*)); + option.m_CFOSelect->numRightTexts = numRightTexts; + option.m_CFOSelect->value = var; + if (var) { + option.m_CFOSelect->displayedValue = *var; + option.m_CFOSelect->lastSavedValue = *var; + } + option.m_CFOSelect->save = saveName; + option.m_CFOSelect->onlyApplyOnEnter = onlyApplyOnEnter; + option.m_CFOSelect->changeFunc = changeFunc; +} + +void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 align, DrawFunc drawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveName) +{ + int8 screenOptionOrder = RegisterNewOption(); + + CMenuScreenCustom::CMenuEntry &option = aScreens[currentMenu].m_aEntries[screenOptionOrder]; + option.m_Action = MENUACTION_CFO_DYNAMIC; + option.m_X = x; + option.m_Y = y; + option.m_Align = align; + strncpy(option.m_EntryName, gxtKey, 8); + option.m_CFODynamic = new CCFODynamic(); + option.m_CFODynamic->drawFunc = drawFunc; + option.m_CFODynamic->buttonPressFunc = buttonPressFunc; + option.m_CFODynamic->value = var; + option.m_CFODynamic->save = saveName; +} + +// lineHeight = 0 means game will use MENU_DEFAULT_LINE_HEIGHT +uint8 FrontendScreenAdd(const char* gxtKey, int prevPage, int lineHeight, bool showLeftRightHelper, ReturnPrevPageFunc returnPrevPageFunc) { + + uint8 screenOrder = RegisterNewScreen(gxtKey, prevPage, returnPrevPageFunc); + + CCustomScreenLayout *screen = new CCustomScreenLayout(); + aScreens[screenOrder].layout = screen; + screen->lineHeight = lineHeight; + screen->showLeftRightHelper = showLeftRightHelper; + + return screenOrder; +} +#endif diff --git a/src/extras/frontendoption.h b/src/extras/frontendoption.h new file mode 100644 index 00000000..6670c323 --- /dev/null +++ b/src/extras/frontendoption.h @@ -0,0 +1,86 @@ +#pragma once +#include "common.h" + +#ifdef CUSTOM_FRONTEND_OPTIONS + +// ! There are 2 ways to use CFO, +// 1st; by adding a new option to the array in MenuScreensCustom.cpp and passing attributes/CBs to it +// 2nd; by calling the functions listed at the bottom of this file. + +// -- Option types +// +// Static/select: You allocate the variable, pass it to function and game sets it from user input among the strings given to function, +// optionally you can add post-change event via ChangeFunc(only called on enter if onlyApplyOnEnter set, or set immediately) +// You can store the option in an INI file if you pass the key(as a char array) to corresponding parameter. +// +// Dynamic: Passing variable to function is only needed if you want to store it, otherwise you should do +// all the operations with ButtonPressFunc, this includes allocating the variable. +// Left-side text is passed while creating and static, but ofc right-side text is dynamic - +// you should return it in DrawFunc, which is called on every draw. +// +// Built-in action: As the name suggests, any action that game has built-in. But as an extra you can set the option text, + +// -- Returned via ButtonPressFunc() action param. +#define FEOPTION_ACTION_LEFT 0 +#define FEOPTION_ACTION_RIGHT 1 +#define FEOPTION_ACTION_SELECT 2 +#define FEOPTION_ACTION_FOCUSLOSS 3 + +// -- Callbacks + +// pretty much in everything I guess, and optional in all of them +typedef void (*ReturnPrevPageFunc)(); + +// for static options +typedef void (*ChangeFunc)(int8 before, int8 after); // called after updating the value. + // only called on enter if onlyApplyOnEnter set, otherwise called on every value change + +// for dynamic options +typedef wchar* (*DrawFunc)(bool* disabled, bool userHovering); // you must return a pointer for right text. + // you can also set *disabled if you want to gray it out. +typedef void (*ButtonPressFunc)(int8 action); // see FEOPTION_ACTIONs above + +// -- Internal things +void CustomFrontendOptionsPopulate(); +extern int lastOgScreen; // for reloading +extern int numCustomFrontendOptions; +extern int numCustomFrontendScreens; + +// -- To be used in ButtonPressFunc / ChangeFunc(this one would be weird): +void GoBack(void); + +uint8 GetNumberOfMenuOptions(int screen); + +// !!! We're now moved to MenuScreensCustom.cpp, which houses an array that keeps all original+custom options. +// But you can still use the APIs below, and manipulate aScreens while in game. + +// Limits: +// The code relies on that you won't use more then NUM_MENUROWS(18) options on one page, and won't exceed the MENUPAGES of pages. +// Also congrats if you can make 18 options visible at once. + +// Texts: +// All text parameters accept char[8] GXT key. + +// Execute direction: +// All of the calls below eventually manipulate the aScreens array, so keep in mind to add/replace options in order, +// i.e. don't set cursor to 8 first and then 3. + + +// -- Placing the cursor to append/overwrite option +// +// Done via FrontendOptionSetCursor(screen, position, overwrite = false), parameters explained below: +// Screen: as the name suggests. Also accepts the screen IDs returned from FrontendScreenAdd. +// Option: if positive, next AddOption call will put the option to there and progress the cursor. +// if negative, cursor will be placed on bottom-(pos+1), so -1 means the very bottom, -2 means before the back button etc. +// Overwrite: Use to overwrite the options, not appending a new one. AddOption calls will still progress the cursor. + +void FrontendOptionSetCursor(int screen, int8 option, bool overwrite = false); + +// var is optional in AddDynamic, enables you to save them in an INI file(also needs passing char array to saveName param. obv), otherwise pass nil/0 +void FrontendOptionAddBuiltinAction(const char* gxtKey, uint16 x, uint16 y, uint8 align, int action, int targetMenu = MENUPAGE_NONE, int saveSlot = SAVESLOT_NONE); +void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveName = nil); +void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 align, DrawFunc rightTextDrawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveName = nil); + +// lineHeight = 0 means game will use MENU_DEFAULT_LINE_HEIGHT +uint8 FrontendScreenAdd(const char* gxtKey, int prevPage, int lineHeight, bool showLeftRightHelper, ReturnPrevPageFunc returnPrevPageFunc = nil); +#endif diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp index b7623a33..e57671e3 100644 --- a/src/peds/Ped.cpp +++ b/src/peds/Ped.cpp @@ -1771,11 +1771,7 @@ CPed::ProcessControl(void) if (m_nPedState != PED_ARRESTED) { if (m_nPedState == PED_DEAD) { DeadPedMakesTyresBloody(); -#ifndef VC_PED_PORTS - if (CGame::nastyGame) { -#else if (CGame::nastyGame && !bIsInWater) { -#endif uint32 remainingBloodyFpTime = CTimer::GetTimeInMilliseconds() - m_bloodyFootprintCountOrDeathTime; float timeDependentDist; if (remainingBloodyFpTime >= 2000) { @@ -2332,11 +2328,7 @@ CPed::ProcessControl(void) ApplyMoveForce(forceDir); } - if ((bIsInTheAir && !DyingOrDead()) -#ifdef VC_PED_PORTS - || (!bIsStanding && !bWasStanding && m_nPedState == PED_FALL) -#endif - ) { + if ((bIsInTheAir && !DyingOrDead()) || (!bIsStanding && !bWasStanding && m_nPedState == PED_FALL)) { if (m_nPedStateTimer > 0 && m_nPedStateTimer <= 1000) { forceDir = GetPosition() - m_vecHitLastPos; } else { @@ -2357,11 +2349,7 @@ CPed::ProcessControl(void) if (m_nCollisionRecords == 1 && m_aCollisionRecords[0] != nil && m_aCollisionRecords[0]->IsBuilding() && m_nPedStateTimer > 50.0f / (2.0f * adjustedTs) && m_nPedStateTimer * 1.0f / 250.0f > Abs(forceDir.z)) { offsetToCheck.x = -forceDir.y; -#ifdef VC_PED_PORTS offsetToCheck.z = 1.0f; -#else - offsetToCheck.z = 0.0f; -#endif offsetToCheck.y = forceDir.x; offsetToCheck.Normalise(); @@ -2386,7 +2374,6 @@ CPed::ProcessControl(void) } else { obstacleForFlyingOtherDirZ = 501.0f; } -#ifdef VC_PED_PORTS uint8 flyDir = 0; float feetZ = GetPosition().z - FEET_OFFSET; if ((obstacleForFlyingZ <= feetZ || obstacleForFlyingOtherDirZ >= 500.0f) && (obstacleForFlyingZ <= feetZ || obstacleForFlyingOtherDirZ <= feetZ)) { @@ -2403,7 +2390,6 @@ CPed::ProcessControl(void) SetLanding(); bIsStanding = true; } -#endif if (obstacleForFlyingZ < obstacleForFlyingOtherDirZ) { offsetToCheck *= -1.0f; } @@ -2424,12 +2410,6 @@ CPed::ProcessControl(void) } bIsInTheAir = false; } else if (m_vecDamageNormal.z > 0.4f) { -#ifndef VC_PED_PORTS - forceDir = m_vecDamageNormal; - forceDir.z = 0.0f; - forceDir.Normalise(); - ApplyMoveForce(2.0f * forceDir); -#else if (m_nPedState == PED_JUMP) { if (m_nWaitTimer <= 2000) { if (m_nWaitTimer < 1000) @@ -2446,7 +2426,6 @@ CPed::ProcessControl(void) } else { ApplyMoveForce(-4.0f * forceDir); } -#endif } } else if ((CTimer::GetFrameCounter() + m_randomSeed % 256 + 3) & 7) { if (IsPlayer() && m_nPedState != PED_JUMP && pad0->JumpJustDown()) { @@ -2502,17 +2481,12 @@ CPed::ProcessControl(void) offsetToCheck.z += 0.5f; if (CWorld::ProcessVerticalLine(offsetToCheck, GetPosition().z - FEET_OFFSET, foundCol, foundEnt, true, true, false, true, false, false, nil)) { -#ifdef VC_PED_PORTS if (!bHeadStuckInCollision || FEET_OFFSET + foundCol.point.z < GetPosition().z) { GetMatrix().GetPosition().z = FEET_OFFSET + foundCol.point.z; GetMatrix().UpdateRW(); if (bHeadStuckInCollision) bHeadStuckInCollision = false; } -#else - GetMatrix().GetPosition().z = FEET_OFFSET + foundCol.point.z; - GetMatrix().UpdateRW(); -#endif SetLanding(); bIsStanding = true; } @@ -4131,12 +4105,9 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg) } else if (ped->m_objective == OBJECTIVE_NONE && ped->CharCreatedBy != MISSION_CHAR && ped->m_nPedState == PED_IDLE && !ped->IsPlayer()) { ped->SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f)); } - } -#ifdef VC_PED_PORTS - else if (ped->m_nPedState == PED_DRIVING) { + } else if (ped->m_nPedState == PED_DRIVING) { ped->m_nPedState = PED_IDLE; } -#endif if (animAssoc) animAssoc->blendDelta = -1000.0f; diff --git a/src/peds/PedAI.cpp b/src/peds/PedAI.cpp index 1f61118f..fc8472d6 100644 --- a/src/peds/PedAI.cpp +++ b/src/peds/PedAI.cpp @@ -1597,7 +1597,7 @@ CPed::ProcessObjective(void) Say(SOUND_PED_MUGGING); bRichFromMugging = true; - // VC FIX: ClearObjective() clears m_pedInObjective in VC (also same with VC_PED_PORTS), so get it before call + // FIX: ClearObjective() clears m_pedInObjective, so get it before call CPed *victim = m_pedInObjective; ClearObjective(); if (victim->m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT