summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/Frontend.cpp150
-rw-r--r--src/core/Frontend.h5
-rw-r--r--src/core/Game.cpp5
-rw-r--r--src/core/MenuScreens.cpp21
-rw-r--r--src/core/config.h1
-rw-r--r--src/core/re3.cpp112
6 files changed, 273 insertions, 21 deletions
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index d82c5df4..0c813cbb 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -36,6 +36,7 @@
#include "Stats.h"
#include "Messages.h"
#include "FileLoader.h"
+#include "frontendoption.h"
#define TIDY_UP_PBP // ProcessButtonPresses
#define MAX_VISIBLE_LIST_ROW 30
@@ -431,12 +432,46 @@ CMenuManager::ThingsToDoBeforeGoingBack()
if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) {
m_nTotalListRow = 0;
}
+
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ for (int i = 0; i < numCustomFrontendOptions; i++) {
+ FrontendOption &option = customFrontendOptions[i];
+ if (option.type != FEOPTION_REDIRECT && option.type != FEOPTION_GOBACK && m_nCurrScreen == option.screen) {
+ if (option.returnPrevPageFunc)
+ option.returnPrevPageFunc();
+
+ if (m_nCurrOption == option.screenOptionOrder && option.type == FEOPTION_DYNAMIC)
+ option.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS);
+
+ if (option.onlyApplyOnEnter)
+ option.displayedValue = *option.value;
+ }
+ }
+#endif
}
int8
CMenuManager::GetPreviousPageOption()
{
+#ifndef CUSTOM_FRONTEND_OPTIONS
+ return !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0];
+#else
+ int8 prevPage = !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_PreviousPage[1] : aScreens[m_nCurrScreen].m_PreviousPage[0];
+
+ 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_TargetMenu == m_nCurrScreen) {
+ return i;
+ }
+ }
+
+ // Couldn't find current screen option on previous page, use default behaviour (maybe save-related screen?)
return !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0];
+#endif
}
// ------ Functions not in the game/inlined ends
@@ -955,7 +990,14 @@ CMenuManager::Draw()
}
#endif
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ static int lastOption = m_nCurrOption;
+#endif
+
for (int i = 0; i < NUM_MENUROWS; ++i) {
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ bool isOptionDisabled = false;
+#endif
if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action != MENUACTION_LABEL && aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName[0] != '\0') {
wchar *rightText = nil;
wchar *leftText;
@@ -1232,6 +1274,29 @@ CMenuManager::Draw()
rightText = TheText.Get(gPS2alphaTest ? "FEM_ON" : "FEM_OFF");
break;
#endif
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ case MENUACTION_TRIGGERFUNC:
+ FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu];
+ if (m_nCurrScreen == option.screen && i == option.screenOptionOrder) {
+ leftText = (wchar*)option.leftText;
+ if (option.type == FEOPTION_SELECT) {
+ if (option.displayedValue >= option.numRightTexts || option.displayedValue < 0)
+ option.displayedValue = 0;
+
+ rightText = (wchar*)option.rightTexts[option.displayedValue];
+
+ } else if (option.type == FEOPTION_DYNAMIC) {
+ if (option.drawFunc) {
+ rightText = option.drawFunc(&isOptionDisabled);
+ }
+ }
+ } else {
+ debug("A- screen:%d option:%d - totalCo: %d, coId: %d, coScreen:%d, coOption:%d\n", m_nCurrScreen, i, numCustomFrontendOptions, aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu, option.screen, option.screenOptionOrder);
+ assert(0 && "Custom frontend options is borked");
+ }
+
+ break;
+#endif
}
float nextItemY = headerHeight + nextYToUse;
@@ -1318,7 +1383,11 @@ CMenuManager::Draw()
|| !strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_AAS")
#endif
)
- && !m_bGameNotLoaded)
+ && !m_bGameNotLoaded
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ || isOptionDisabled
+#endif
+ )
CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255)));
CFont::PrintString(MENU_X_RIGHT_ALIGNED(columnWidth - textLayer), itemY, rightText);
@@ -1428,6 +1497,20 @@ CMenuManager::Draw()
}
#endif
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_TRIGGERFUNC) {
+ FrontendOption &option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[i].m_TargetMenu];
+ if (option.onlyApplyOnEnter && m_nCurrOption != i)
+ option.displayedValue = *option.value;
+
+ if (m_nCurrOption != lastOption && lastOption == i) {
+ FrontendOption &oldOption = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[lastOption].m_TargetMenu];
+ if (oldOption.type == FEOPTION_DYNAMIC)
+ oldOption.buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS);
+ }
+ }
+#endif
+
// Sliders
int lastActiveBarX;
switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) {
@@ -1471,6 +1554,10 @@ CMenuManager::Draw()
}
}
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ lastOption = m_nCurrOption;
+#endif
+
switch (m_nCurrScreen) {
case MENUPAGE_CONTROLLER_SETTINGS:
case MENUPAGE_SOUND_SETTINGS:
@@ -3128,6 +3215,10 @@ CMenuManager::InitialiseChangedLanguageSettings()
default:
break;
}
+
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ CustomFrontendOptionsPopulate();
+#endif
}
}
@@ -5006,6 +5097,33 @@ CMenuManager::ProcessButtonPresses(void)
RetryMission(2, 0);
return;
#endif
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ case MENUACTION_TRIGGERFUNC:
+ FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu];
+ if (m_nCurrScreen == option.screen && m_nCurrOption == option.screenOptionOrder) {
+ if (option.type == FEOPTION_SELECT) {
+ if (!option.onlyApplyOnEnter) {
+ option.displayedValue++;
+ if (option.displayedValue >= option.numRightTexts || option.displayedValue < 0)
+ option.displayedValue = 0;
+ }
+ option.changeFunc(option.displayedValue);
+ *option.value = option.displayedValue;
+
+ } else if (option.type == FEOPTION_DYNAMIC) {
+ option.buttonPressFunc(FEOPTION_ACTION_SELECT);
+ } else if (option.type == FEOPTION_REDIRECT) {
+ ChangeScreen(option.to, option.option, true, option.fadeIn);
+ } else if (option.type == FEOPTION_GOBACK) {
+ goBack = true;
+ }
+ } else {
+ debug("B- screen:%d option:%d - totalCo: %d, coId: %d, coScreen:%d, coOption:%d\n", m_nCurrScreen, m_nCurrOption, numCustomFrontendOptions, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, option.screen, option.screenOptionOrder);
+ assert(0 && "Custom frontend options are borked");
+ }
+
+ break;
+#endif
}
}
ProcessOnOffMenuOptions();
@@ -5236,6 +5354,36 @@ CMenuManager::ProcessButtonPresses(void)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
SaveSettings();
break;
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ case MENUACTION_TRIGGERFUNC:
+ FrontendOption& option = customFrontendOptions[aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu];
+ if (m_nCurrScreen == option.screen && m_nCurrOption == option.screenOptionOrder) {
+ if (option.type == FEOPTION_SELECT) {
+ if (changeValueBy > 0) {
+ option.displayedValue++;
+ if (option.displayedValue >= option.numRightTexts)
+ option.displayedValue = 0;
+ } else {
+ option.displayedValue--;
+ if (option.displayedValue < 0)
+ option.displayedValue = option.numRightTexts - 1;
+ }
+ if (!option.onlyApplyOnEnter) {
+ option.changeFunc(option.displayedValue);
+ *option.value = option.displayedValue;
+ }
+ } else if (option.type == FEOPTION_DYNAMIC) {
+ option.buttonPressFunc(changeValueBy > 0 ? FEOPTION_ACTION_RIGHT : FEOPTION_ACTION_LEFT);
+ }
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
+ }
+ else {
+ debug("C- screen:%d option:%d - totalCo: %d, coId: %d, coScreen:%d, coOption:%d\n", m_nCurrScreen, m_nCurrOption, numCustomFrontendOptions, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu, option.screen, option.screenOptionOrder);
+ assert(0 && "Custom frontend options are borked");
+ }
+
+ break;
+#endif
}
ProcessOnOffMenuOptions();
if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index cf112b3d..fa3652a1 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -381,6 +381,9 @@ enum eMenuAction
#ifdef CUTSCENE_BORDERS_SWITCH
MENUACTION_CUTSCENEBORDERS,
#endif
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ MENUACTION_TRIGGERFUNC
+#endif
};
enum eCheckHover
@@ -475,7 +478,7 @@ struct CMenuScreen
int32 m_Action; // eMenuAction
char m_EntryName[8];
int32 m_SaveSlot; // eSaveSlot
- int32 m_TargetMenu; // eMenuScreen
+ int32 m_TargetMenu; // eMenuScreen // FrontendOption ID if it's a custom option
} m_aEntries[NUM_MENUROWS];
};
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index a95c479a..c0530709 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -86,6 +86,7 @@
#include "ZoneCull.h"
#include "Zones.h"
#include "debugmenu.h"
+#include "frontendoption.h"
#include "postfx.h"
#include "custompipes.h"
@@ -292,6 +293,10 @@ bool CGame::InitialiseOnceAfterRW(void)
DMAudio.SetEffectsFadeVol(127);
DMAudio.SetMusicFadeVol(127);
CWorld::Players[0].SetPlayerSkin(CMenuManager::m_PrefsSkinFile);
+
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ CustomFrontendOptionsPopulate();
+#endif
return true;
}
diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp
index 5dfcc8fe..02c004b3 100644
--- a/src/core/MenuScreens.cpp
+++ b/src/core/MenuScreens.cpp
@@ -2,6 +2,8 @@
#include "Frontend.h"
#ifdef PC_MENU
+// If you want to add new options, please don't do that here and see CustomFrontendOptionsPopulate in re3.cpp.
+
#ifdef CUTSCENE_BORDERS_SWITCH
#define MENU_CUTSCENE_BORDERS_SWITCH(screen) MENUACTION_CUTSCENEBORDERS, "FEM_CSB", SAVESLOT_NONE, screen,
#else
@@ -45,11 +47,7 @@ CMenuScreen aScreens[] = {
{ "", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, },
// MENUPAGE_STATS = 1
-#ifdef MENU_MAP
- { "FET_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 3,
-#else
{ "FET_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 2,
-#endif
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
},
@@ -62,11 +60,7 @@ CMenuScreen aScreens[] = {
},
// MENUPAGE_BRIEFS = 3
-#ifdef MENU_MAP
- { "FET_BRE", 1, MENUPAGE_NONE, MENUPAGE_NONE, 6, 4,
-#else
{ "FET_BRE", 1, MENUPAGE_NONE, MENUPAGE_NONE, 6, 3,
-#endif
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
},
@@ -381,11 +375,7 @@ CMenuScreen aScreens[] = {
},
// MENUPAGE_OPTIONS = 41
-#ifdef MENU_MAP
- { "FET_OPT", 1, MENUPAGE_NONE, MENUPAGE_NONE, 1, 5,
-#else
{ "FET_OPT", 1, MENUPAGE_NONE, MENUPAGE_NONE, 1, 4,
-#endif
MENUACTION_CHANGEMENU, "FET_CTL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
MENUACTION_LOADRADIO, "FET_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
MENUACTION_CHANGEMENU, "FET_DIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
@@ -398,11 +388,7 @@ CMenuScreen aScreens[] = {
},
// MENUPAGE_EXIT = 42
-#ifdef MENU_MAP
- { "FET_QG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 6,
-#else
{ "FET_QG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 5,
-#endif
MENUACTION_LABEL, "FEQ_SRE", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_DONTCANCEL, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CANCELGAME, "FEM_YES", SAVESLOT_NONE, MENUPAGE_NONE,
@@ -463,9 +449,6 @@ CMenuScreen aScreens[] = {
{ "FET_PAU", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_RESUME, "FEM_RES", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME,
-#ifdef MENU_MAP
- MENUACTION_CHANGEMENU, "FEG_MAP", SAVESLOT_NONE, MENUPAGE_MAP,
-#endif
MENUACTION_CHANGEMENU, "FEP_STA", SAVESLOT_NONE, MENUPAGE_STATS,
MENUACTION_CHANGEMENU, "FEP_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS,
MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS,
diff --git a/src/core/config.h b/src/core/config.h
index 8e91853d..ac3ba109 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -248,6 +248,7 @@ enum Config {
# define SCROLLABLE_STATS_PAGE // only draggable by mouse atm
# define TRIANGLE_BACK_BUTTON
//# define CIRCLE_BACK_BUTTON
+# define CUSTOM_FRONTEND_OPTIONS
# define GRAPHICS_MENU_OPTIONS
#endif
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index 27ec336d..dd116e27 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -71,6 +71,115 @@ mysrand(unsigned int seed)
myrand_seed = seed;
}
+#ifdef CUSTOM_FRONTEND_OPTIONS
+#include "frontendoption.h"
+#include "platform.h"
+
+void ReloadFrontendOptions(void)
+{
+ CustomFrontendOptionsPopulate();
+}
+
+#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
+
+/*#ifdef IMPROVED_VIDEOMODE
+void ScreenModeChange(int8 displayedValue)
+{
+ if (displayedValue != FrontEndMenuManager.m_nPrefsWindowed) {
+ FrontEndMenuManager.m_nPrefsWindowed = displayedValue;
+ _psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution
+ FrontEndMenuManager.SetHelperText(0);
+ FrontEndMenuManager.SaveSettings();
+ }
+}
+#endif*/
+
+#ifdef FREE_CAM
+void ToggleFreeCam(int8 action)
+{
+ if (action == FEOPTION_ACTION_SELECT) {
+ TheCamera.bFreeCam = !TheCamera.bFreeCam;
+ FrontEndMenuManager.SaveSettings();
+ }
+}
+#endif
+
+//#ifdef CUTSCENE_BORDERS_SWITCH
+//void BorderModeChange(int8 displayedValue)
+//{
+// CMenuManager::m_PrefsCutsceneBorders = !!displayedValue;
+// FrontEndMenuManager.SaveSettings();
+//}
+//#endif
+
+// Reloaded on language change, so you can use hardcoded wchar* and TheText.Get with peace of mind
+void
+CustomFrontendOptionsPopulate(void)
+{
+ RemoveCustomFrontendOptions(); // if exist
+
+#ifdef MORE_LANGUAGES
+ FrontendOptionSetPosition(MENUPAGE_LANGUAGE_SETTINGS);
+ FrontendOptionAddDynamic(TheText.Get("FEL_POL"), nil, LangPolSelect, nil);
+ FrontendOptionAddDynamic(TheText.Get("FEL_RUS"), nil, LangRusSelect, nil);
+ FrontendOptionAddDynamic(TheText.Get("FEL_JAP"), nil, LangJapSelect, nil);
+#endif
+
+/*#ifdef IMPROVED_VIDEOMODE
+ static const wchar *screenModes[] = { (wchar*)L"FULLSCREEN", (wchar*)L"WINDOWED" };
+ FrontendOptionSetPosition(MENUPAGE_GRAPHICS_SETTINGS, 8);
+ FrontendOptionAddSelect(TheText.Get("SCRFOR"), screenModes, 2, (int8*)&FrontEndMenuManager.m_nPrefsWindowed, true, ScreenModeChange, nil);
+#endif*/
+
+#ifdef MENU_MAP
+ FrontendOptionSetPosition(MENUPAGE_PAUSE_MENU, 2);
+ FrontendOptionAddRedirect(TheText.Get("FEG_MAP"), MENUPAGE_MAP);
+#endif
+
+#ifdef FREE_CAM
+ static const wchar *text = (wchar*)L"TOGGLE FREE CAM";
+ FrontendOptionSetPosition(MENUPAGE_CONTROLLER_PC, 1);
+ FrontendOptionAddDynamic(text, nil, ToggleFreeCam, nil);
+#endif
+
+/*#ifdef CUTSCENE_BORDERS_SWITCH
+ static const wchar *off_on[] = { TheText.Get("FEM_OFF"), TheText.Get("FEM_ON") };
+ FrontendOptionSetPosition(MENUPAGE_DISPLAY_SETTINGS, 3);
+ FrontendOptionAddSelect((const wchar *)L"CUTSCENE BORDERS", off_on, 2, (int8 *)&CMenuManager::m_PrefsCutsceneBorders, false, BorderModeChange, nil);
+#endif*/
+}
+#endif
+
#ifdef DEBUGMENU
void WeaponCheat();
void HealthCheat();
@@ -405,6 +514,9 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Debug", "Catalina Fly Away", CHeli::MakeCatalinaHeliFlyAway);
DebugMenuAddVarBool8("Debug", "Script Heli On", &CHeli::ScriptHeliOn, nil);
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ DebugMenuAddCmd("Debug", "Reload custom frontend options", ReloadFrontendOptions);
+#endif
DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", &CPed::bPopHeadsOnHeadshot, nil);
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);
DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop);