1
0
Fork 0
mirror of https://git.rip/DMCA_FUCKER/re3.git synced 2024-12-23 06:00:00 +00:00

Revert "remove CFO"

This reverts commit 0418ba597b.
This commit is contained in:
eray orçunus 2020-08-19 20:30:57 +03:00
parent c2e20070ab
commit be638a4973
8 changed files with 533 additions and 21 deletions

View file

@ -36,6 +36,7 @@
#include "Stats.h" #include "Stats.h"
#include "Messages.h" #include "Messages.h"
#include "FileLoader.h" #include "FileLoader.h"
#include "frontendoption.h"
#define TIDY_UP_PBP // ProcessButtonPresses #define TIDY_UP_PBP // ProcessButtonPresses
#define MAX_VISIBLE_LIST_ROW 30 #define MAX_VISIBLE_LIST_ROW 30
@ -431,12 +432,46 @@ CMenuManager::ThingsToDoBeforeGoingBack()
if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) { if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) {
m_nTotalListRow = 0; 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 int8
CMenuManager::GetPreviousPageOption() CMenuManager::GetPreviousPageOption()
{ {
#ifndef CUSTOM_FRONTEND_OPTIONS
return !m_bGameNotLoaded ? aScreens[m_nCurrScreen].m_ParentEntry[1] : aScreens[m_nCurrScreen].m_ParentEntry[0]; 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 // ------ Functions not in the game/inlined ends
@ -955,7 +990,14 @@ CMenuManager::Draw()
} }
#endif #endif
#ifdef CUSTOM_FRONTEND_OPTIONS
static int lastOption = m_nCurrOption;
#endif
for (int i = 0; i < NUM_MENUROWS; ++i) { 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') { 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 *rightText = nil;
wchar *leftText; wchar *leftText;
@ -1232,6 +1274,29 @@ CMenuManager::Draw()
rightText = TheText.Get(gPS2alphaTest ? "FEM_ON" : "FEM_OFF"); rightText = TheText.Get(gPS2alphaTest ? "FEM_ON" : "FEM_OFF");
break; break;
#endif #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; float nextItemY = headerHeight + nextYToUse;
@ -1318,7 +1383,11 @@ CMenuManager::Draw()
|| !strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_AAS") || !strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FED_AAS")
#endif #endif
) )
&& !m_bGameNotLoaded) && !m_bGameNotLoaded
#ifdef CUSTOM_FRONTEND_OPTIONS
|| isOptionDisabled
#endif
)
CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255))); CFont::SetColor(CRGBA(155, 117, 6, FadeIn(255)));
CFont::PrintString(MENU_X_RIGHT_ALIGNED(columnWidth - textLayer), itemY, rightText); CFont::PrintString(MENU_X_RIGHT_ALIGNED(columnWidth - textLayer), itemY, rightText);
@ -1428,6 +1497,20 @@ CMenuManager::Draw()
} }
#endif #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 // Sliders
int lastActiveBarX; int lastActiveBarX;
switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) { 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) { switch (m_nCurrScreen) {
case MENUPAGE_CONTROLLER_SETTINGS: case MENUPAGE_CONTROLLER_SETTINGS:
case MENUPAGE_SOUND_SETTINGS: case MENUPAGE_SOUND_SETTINGS:
@ -3128,6 +3215,10 @@ CMenuManager::InitialiseChangedLanguageSettings()
default: default:
break; break;
} }
#ifdef CUSTOM_FRONTEND_OPTIONS
CustomFrontendOptionsPopulate();
#endif
} }
} }
@ -5005,6 +5096,33 @@ CMenuManager::ProcessButtonPresses(void)
RequestFrontEndShutDown(); RequestFrontEndShutDown();
RetryMission(2, 0); RetryMission(2, 0);
return; 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 #endif
} }
} }
@ -5236,6 +5354,36 @@ CMenuManager::ProcessButtonPresses(void)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0); DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
SaveSettings(); SaveSettings();
break; 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(); ProcessOnOffMenuOptions();
if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) { if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {

View file

@ -381,6 +381,9 @@ enum eMenuAction
#ifdef CUTSCENE_BORDERS_SWITCH #ifdef CUTSCENE_BORDERS_SWITCH
MENUACTION_CUTSCENEBORDERS, MENUACTION_CUTSCENEBORDERS,
#endif #endif
#ifdef CUSTOM_FRONTEND_OPTIONS
MENUACTION_TRIGGERFUNC
#endif
}; };
enum eCheckHover enum eCheckHover
@ -475,7 +478,7 @@ struct CMenuScreen
int32 m_Action; // eMenuAction int32 m_Action; // eMenuAction
char m_EntryName[8]; char m_EntryName[8];
int32 m_SaveSlot; // eSaveSlot int32 m_SaveSlot; // eSaveSlot
int32 m_TargetMenu; // eMenuScreen int32 m_TargetMenu; // eMenuScreen // FrontendOption ID if it's a custom option
} m_aEntries[NUM_MENUROWS]; } m_aEntries[NUM_MENUROWS];
}; };

View file

@ -86,6 +86,7 @@
#include "ZoneCull.h" #include "ZoneCull.h"
#include "Zones.h" #include "Zones.h"
#include "debugmenu.h" #include "debugmenu.h"
#include "frontendoption.h"
#include "postfx.h" #include "postfx.h"
#include "custompipes.h" #include "custompipes.h"
@ -292,6 +293,10 @@ bool CGame::InitialiseOnceAfterRW(void)
DMAudio.SetEffectsFadeVol(127); DMAudio.SetEffectsFadeVol(127);
DMAudio.SetMusicFadeVol(127); DMAudio.SetMusicFadeVol(127);
CWorld::Players[0].SetPlayerSkin(CMenuManager::m_PrefsSkinFile); CWorld::Players[0].SetPlayerSkin(CMenuManager::m_PrefsSkinFile);
#ifdef CUSTOM_FRONTEND_OPTIONS
CustomFrontendOptionsPopulate();
#endif
return true; return true;
} }

View file

@ -2,6 +2,8 @@
#include "Frontend.h" #include "Frontend.h"
#ifdef PC_MENU #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 #ifdef CUTSCENE_BORDERS_SWITCH
#define MENU_CUTSCENE_BORDERS_SWITCH(screen) MENUACTION_CUTSCENEBORDERS, "FEM_CSB", SAVESLOT_NONE, screen, #define MENU_CUTSCENE_BORDERS_SWITCH(screen) MENUACTION_CUTSCENEBORDERS, "FEM_CSB", SAVESLOT_NONE, screen,
#else #else
@ -45,11 +47,7 @@ CMenuScreen aScreens[] = {
{ "", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, }, { "", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0, },
// MENUPAGE_STATS = 1 // 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, { "FET_STA", 1, MENUPAGE_NONE, MENUPAGE_NONE, 5, 2,
#endif
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
}, },
@ -62,11 +60,7 @@ CMenuScreen aScreens[] = {
}, },
// MENUPAGE_BRIEFS = 3 // 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, { "FET_BRE", 1, MENUPAGE_NONE, MENUPAGE_NONE, 6, 3,
#endif
MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
}, },
@ -381,11 +375,7 @@ CMenuScreen aScreens[] = {
}, },
// MENUPAGE_OPTIONS = 41 // 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, { "FET_OPT", 1, MENUPAGE_NONE, MENUPAGE_NONE, 1, 4,
#endif
MENUACTION_CHANGEMENU, "FET_CTL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, MENUACTION_CHANGEMENU, "FET_CTL", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
MENUACTION_LOADRADIO, "FET_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS, MENUACTION_LOADRADIO, "FET_AUD", SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS,
MENUACTION_CHANGEMENU, "FET_DIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, MENUACTION_CHANGEMENU, "FET_DIS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS,
@ -398,11 +388,7 @@ CMenuScreen aScreens[] = {
}, },
// MENUPAGE_EXIT = 42 // 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, { "FET_QG", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 5,
#endif
MENUACTION_LABEL, "FEQ_SRE", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_LABEL, "FEQ_SRE", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_DONTCANCEL, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_DONTCANCEL, "FEM_NO", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CANCELGAME, "FEM_YES", 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, { "FET_PAU", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
MENUACTION_RESUME, "FEM_RES", SAVESLOT_NONE, MENUPAGE_NONE, MENUACTION_RESUME, "FEM_RES", SAVESLOT_NONE, MENUPAGE_NONE,
MENUACTION_CHANGEMENU, "FEN_STA", SAVESLOT_NONE, MENUPAGE_NEW_GAME, 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_STA", SAVESLOT_NONE, MENUPAGE_STATS,
MENUACTION_CHANGEMENU, "FEP_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS, MENUACTION_CHANGEMENU, "FEP_BRI", SAVESLOT_NONE, MENUPAGE_BRIEFS,
MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS, MENUACTION_CHANGEMENU, "FET_OPT", SAVESLOT_NONE, MENUPAGE_OPTIONS,

View file

@ -248,6 +248,7 @@ enum Config {
# define SCROLLABLE_STATS_PAGE // only draggable by mouse atm # define SCROLLABLE_STATS_PAGE // only draggable by mouse atm
# define TRIANGLE_BACK_BUTTON # define TRIANGLE_BACK_BUTTON
//# define CIRCLE_BACK_BUTTON //# define CIRCLE_BACK_BUTTON
# define CUSTOM_FRONTEND_OPTIONS
# define GRAPHICS_MENU_OPTIONS # define GRAPHICS_MENU_OPTIONS
#endif #endif

View file

@ -71,6 +71,115 @@ mysrand(unsigned int seed)
myrand_seed = 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 #ifdef DEBUGMENU
void WeaponCheat(); void WeaponCheat();
void HealthCheat(); void HealthCheat();
@ -405,6 +514,9 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Debug", "Catalina Fly Away", CHeli::MakeCatalinaHeliFlyAway); DebugMenuAddCmd("Debug", "Catalina Fly Away", CHeli::MakeCatalinaHeliFlyAway);
DebugMenuAddVarBool8("Debug", "Script Heli On", &CHeli::ScriptHeliOn, nil); 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); DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", &CPed::bPopHeadsOnHeadshot, nil);
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start); DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);
DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop); DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop);

View file

@ -0,0 +1,173 @@
#include "common.h"
#ifdef CUSTOM_FRONTEND_OPTIONS
#include "frontendoption.h"
int numCustomFrontendOptions = 0;
FrontendOption *customFrontendOptions;
int optionCursor = -1;
eMenuScreen currentMenu;
void ChangeScreen(eMenuScreen screen, int option, bool fadeIn)
{
FrontEndMenuManager.m_nPrevScreen = FrontEndMenuManager.m_nCurrScreen;
FrontEndMenuManager.m_nCurrScreen = screen;
FrontEndMenuManager.m_nCurrOption = option;
if (fadeIn)
FrontEndMenuManager.m_nMenuFadeAlpha = 0;
}
void GoBack(bool fadeIn)
{
int screen = !FrontEndMenuManager.m_bGameNotLoaded ?
aScreens[FrontEndMenuManager.m_nCurrScreen].m_PreviousPage[1] : aScreens[FrontEndMenuManager.m_nCurrScreen].m_PreviousPage[0];
int option = !FrontEndMenuManager.m_bGameNotLoaded ?
aScreens[FrontEndMenuManager.m_nCurrScreen].m_ParentEntry[1] : aScreens[FrontEndMenuManager.m_nCurrScreen].m_ParentEntry[0];
FrontEndMenuManager.ThingsToDoBeforeGoingBack();
ChangeScreen((eMenuScreen)screen, option, fadeIn);
}
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;
}
// Used before populating options, but effective in InitialiseChangedLanguageSettings and debugmenu
void
RemoveCustomFrontendOptions()
{
if (numCustomFrontendOptions == 0)
return;
for (int i = 0; i < MENUPAGES; i++) {
for (int j = 0; j < NUM_MENUROWS; j++) {
if (aScreens[i].m_aEntries[j].m_Action == MENUACTION_TRIGGERFUNC) {
int k;
for (k = j; k < NUM_MENUROWS-1; k++) {
memcpy(&aScreens[i].m_aEntries[k], &aScreens[i].m_aEntries[k+1], sizeof(CMenuScreen::CMenuEntry));
}
aScreens[i].m_aEntries[k].m_Action = MENUACTION_NOTHING;
aScreens[i].m_aEntries[k].m_EntryName[0] = '\0';
j--;
}
}
}
free(customFrontendOptions);
numCustomFrontendOptions = 0;
}
int8 RegisterNewOption(int screen)
{
numCustomFrontendOptions++;
if (numCustomFrontendOptions == 1)
customFrontendOptions = (FrontendOption*)malloc(5 * sizeof(FrontendOption));
else if (numCustomFrontendOptions % 5 == 1)
customFrontendOptions = (FrontendOption*)realloc(customFrontendOptions, (numCustomFrontendOptions + 4) * sizeof(FrontendOption));
assert(customFrontendOptions != nil && "Custom frontend options can't be allocated");
uint8 nth = GetNumberOfMenuOptions(screen);
if (optionCursor < 0) {
if (optionCursor == -1) {
if (!strcmp(aScreens[screen].m_aEntries[nth - 1].m_EntryName, "FEDS_TB") || !strcmp(aScreens[screen].m_aEntries[nth - 1].m_EntryName, "FESZ_CA")) {
// Move back button one below
memcpy(&aScreens[screen].m_aEntries[nth], &aScreens[screen].m_aEntries[nth - 1], sizeof(CMenuScreen::CMenuEntry));
nth--;
}
}
} else {
if (aScreens[screen].m_aEntries[optionCursor].m_Action != MENUACTION_NOTHING) {
for (int i = nth - 1; i >= optionCursor; i--) {
memcpy(&aScreens[screen].m_aEntries[i + 1], &aScreens[screen].m_aEntries[i], sizeof(CMenuScreen::CMenuEntry));
}
}
nth = optionCursor;
optionCursor++;
}
aScreens[screen].m_aEntries[nth].m_Action = MENUACTION_TRIGGERFUNC;
aScreens[screen].m_aEntries[nth].m_TargetMenu = numCustomFrontendOptions - 1;
aScreens[screen].m_aEntries[nth].m_EntryName[0] = 1; // just something to fool it
return nth;
}
void FrontendOptionSetPosition(eMenuScreen screen, int8 option)
{
currentMenu = screen;
optionCursor = option;
}
void FrontendOptionAddSelect(const wchar* leftText, const wchar** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, ReturnPrevPageFunc returnPrevPageFunc)
{
int8 screenOptionOrder = RegisterNewOption(currentMenu);
FrontendOption& option = customFrontendOptions[numCustomFrontendOptions - 1];
option.screen = currentMenu;
option.type = FEOPTION_SELECT;
option.leftText = leftText;
option.rightTexts = rightTexts;
option.numRightTexts = numRightTexts;
option.value = var;
option.displayedValue = *var;
option.onlyApplyOnEnter = onlyApplyOnEnter;
option.changeFunc = changeFunc;
option.screenOptionOrder = screenOptionOrder;
option.returnPrevPageFunc = returnPrevPageFunc;
}
void FrontendOptionAddDynamic(const wchar* leftText, DrawFunc drawFunc, ButtonPressFunc buttonPressFunc, ReturnPrevPageFunc returnPrevPageFunc)
{
int8 screenOptionOrder = RegisterNewOption(currentMenu);
FrontendOption& option = customFrontendOptions[numCustomFrontendOptions - 1];
option.screen = currentMenu;
option.type = FEOPTION_DYNAMIC;
option.drawFunc = drawFunc;
option.buttonPressFunc = buttonPressFunc;
option.leftText = leftText;
option.onlyApplyOnEnter = false;
option.screenOptionOrder = screenOptionOrder;
option.returnPrevPageFunc = returnPrevPageFunc;
}
void FrontendOptionAddRedirect(const wchar* text, eMenuScreen to, int8 selectedOption, bool fadeIn)
{
int8 screenOptionOrder = RegisterNewOption(currentMenu);
FrontendOption &option = customFrontendOptions[numCustomFrontendOptions - 1];
option.screen = currentMenu;
option.type = FEOPTION_REDIRECT;
option.to = to;
option.option = selectedOption;
option.fadeIn = fadeIn;
option.leftText = text;
option.onlyApplyOnEnter = false;
option.screenOptionOrder = screenOptionOrder;
option.returnPrevPageFunc = nil;
}
void FrontendOptionAddBackButton(const wchar* text, bool fadeIn)
{
int8 screenOptionOrder = RegisterNewOption(currentMenu);
FrontendOption& option = customFrontendOptions[numCustomFrontendOptions - 1];
option.screen = currentMenu;
option.type = FEOPTION_GOBACK;
option.fadeIn = fadeIn;
option.leftText = text;
option.onlyApplyOnEnter = false;
option.screenOptionOrder = screenOptionOrder;
option.returnPrevPageFunc = nil;
}
#endif

View file

@ -0,0 +1,87 @@
#pragma once
#include "common.h"
#ifdef CUSTOM_FRONTEND_OPTIONS
#include "Frontend.h"
// Warning: All of the code relies on that you won't use more then NUM_MENUROWS(18) options on one page. Also congrats if you can make 18 options visible at once.
// Static/select: User allocates variable, passes it to function and it's set automatically from input among the strings given to function,
// then you can handle ChangeFunc and ReturnPrevPageFunc if needed.
//
// Dynamic: Function doesn't accept value pointer, user should do operations with handling ButtonPressFunc.
// Right-side text can be set via DrawFunc, which is called on every draw. ReturnPrevPageFunc is also here if needed.
#define FEOPTION_SELECT 0
#define FEOPTION_DYNAMIC 1
#define FEOPTION_REDIRECT 2
#define FEOPTION_GOBACK 3
#define FEOPTION_ACTION_LEFT 0
#define FEOPTION_ACTION_RIGHT 1
#define FEOPTION_ACTION_SELECT 2
#define FEOPTION_ACTION_FOCUSLOSS 3
void RemoveCustomFrontendOptions();
void CustomFrontendOptionsPopulate();
// for static and dynamic options
typedef void (*ReturnPrevPageFunc)();
// for static options
typedef void (*ChangeFunc)(int8 displayedValue); // called before updating the value
// for dynamic options
typedef wchar* (*DrawFunc)(bool* disabled); // should return pointer to right text. *disabled = true will make it dark yellow
typedef void (*ButtonPressFunc)(int8 action); // see FEOPTION_ACTIONs above
struct FrontendOption
{
int8 type;
int8 screenOptionOrder;
eMenuScreen screen;
const wchar* leftText;
ReturnPrevPageFunc returnPrevPageFunc;
union {
// Only for dynamic
struct {
DrawFunc drawFunc;
ButtonPressFunc buttonPressFunc;
};
// Only for static/select
struct {
const wchar** rightTexts;
int8 numRightTexts;
int8 *value;
int8 displayedValue; // if onlyApplyOnEnter enabled
bool onlyApplyOnEnter;
ChangeFunc changeFunc;
};
// Only for redirect
struct {
eMenuScreen to;
int8 option;
bool fadeIn;
};
};
};
extern int numCustomFrontendOptions;
extern FrontendOption* customFrontendOptions;
// To be used in ButtonPressFunc / ChangeFunc(but that would be weird):
void ChangeScreen(eMenuScreen screen, int option = 0, bool fadeIn = true);
void GoBack(bool fadeIn = true);
// If option is positive number, all calls will increase it before using it (you can think it as cursor). -1 means before the back button, -2 is end of page
void FrontendOptionSetPosition(eMenuScreen screen, int8 option = -1);
void FrontendOptionAddSelect(const wchar* leftText, const wchar** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, ReturnPrevPageFunc returnPrevPageFunc);
void FrontendOptionAddDynamic(const wchar* leftText, DrawFunc rightTextDrawFunc, ButtonPressFunc buttonPressFunc, ReturnPrevPageFunc returnPrevPageFunc);
void FrontendOptionAddRedirect(const wchar* text, eMenuScreen to, int8 selectedOption = 0, bool fadeIn = true);
void FrontendOptionAddBackButton(const wchar* text, bool fadeIn = true);
#endif