summaryrefslogtreecommitdiffstats
path: root/src/extras
diff options
context:
space:
mode:
Diffstat (limited to 'src/extras')
-rw-r--r--src/extras/frontendoption.cpp238
-rw-r--r--src/extras/frontendoption.h121
2 files changed, 82 insertions, 277 deletions
diff --git a/src/extras/frontendoption.cpp b/src/extras/frontendoption.cpp
index 88a930a9..a3c4b9e3 100644
--- a/src/extras/frontendoption.cpp
+++ b/src/extras/frontendoption.cpp
@@ -1,19 +1,13 @@
#include "common.h"
#ifdef CUSTOM_FRONTEND_OPTIONS
-#include "frontendoption.h"
+#include "Frontend.h"
#include "Text.h"
-int numCustomFrontendOptions = 0;
-FrontendOption *customFrontendOptions;
+int lastOgScreen = MENUPAGES; // means no new pages
+int numCustomFrontendOptions = 0;
int numCustomFrontendScreens = 0;
-FrontendScreen* customFrontendScreens;
-
-int numFrontendOptionReplacements = 0;
-CMenuScreen::CMenuEntry* frontendOptionReplacements;
-
-int lastOgScreen = MENUPAGES; // means no new pages
int optionCursor = -2;
int currentMenu;
@@ -32,8 +26,7 @@ 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];
+ int option = FrontEndMenuManager.GetPreviousPageOption();
FrontEndMenuManager.ThingsToDoBeforeGoingBack();
@@ -58,7 +51,7 @@ GetLastMenuScreen()
{
int8 page = -1;
for (int i = 0; i < MENUPAGES; i++) {
- if (strcmp(aScreens[i].m_ScreenName, "") == 0 && aScreens[i].unk == 0)
+ if (strcmp(aScreens[i].m_ScreenName, "") == 0 && aScreens[i].m_PreviousPage[0] == MENUPAGE_NONE)
break;
++page;
@@ -66,89 +59,23 @@ GetLastMenuScreen()
return page;
}
-// Used before populating options, but effective in InitialiseChangedLanguageSettings and debugmenu
-void
-RemoveCustomFrontendOptions()
-{
- if (numCustomFrontendOptions != 0) {
-
- for (int i = 0; i < MENUPAGES; i++) {
- for (int j = 0; j < NUM_MENUROWS; j++) {
- if (aScreens[i].m_aEntries[j].m_SaveSlot == SAVESLOT_CFO) {
- int ogOptionId = customFrontendOptions[aScreens[i].m_aEntries[j].m_TargetMenu].ogOptionId;
-
- if (customFrontendOptions[aScreens[i].m_aEntries[j].m_TargetMenu].type == FEOPTION_SELECT)
- free(customFrontendOptions[aScreens[i].m_aEntries[j].m_TargetMenu].rightTexts);
-
- if (ogOptionId == -1) {
- 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_SaveSlot = SAVESLOT_NONE;
- aScreens[i].m_aEntries[k].m_EntryName[0] = '\0';
- j--;
- } else {
- memcpy(&aScreens[i].m_aEntries[j], &frontendOptionReplacements[ogOptionId], sizeof(CMenuScreen::CMenuEntry));
- }
- }
- }
- }
- free(customFrontendOptions);
- numCustomFrontendOptions = 0;
-
- if (numFrontendOptionReplacements != 0) {
- free(frontendOptionReplacements);
- numFrontendOptionReplacements = 0;
- }
- }
-
- if (numCustomFrontendScreens == 0)
- return;
-
- for (int i = 0; i < MENUPAGES; i++) {
- if (i > lastOgScreen) {
- aScreens[i].m_ScreenName[0] = '\0';
- aScreens[i].unk = 0;
- }
- }
- free(customFrontendScreens);
- numCustomFrontendScreens = 0;
- lastOgScreen = MENUPAGES;
-}
-
-int8 RegisterNewScreen(const char *name, int prevPage)
+int8 RegisterNewScreen(const char *name, int prevPage, ReturnPrevPageFunc returnPrevPageFunc)
{
if (lastOgScreen == MENUPAGES)
lastOgScreen = GetLastMenuScreen();
numCustomFrontendScreens++;
- if (numCustomFrontendScreens == 1)
- customFrontendScreens = (FrontendScreen*)malloc(5 * sizeof(FrontendScreen));
- else if (numCustomFrontendScreens % 5 == 1)
- customFrontendScreens = (FrontendScreen*)realloc(customFrontendScreens, (numCustomFrontendScreens + 4) * sizeof(FrontendScreen));
-
- assert(customFrontendScreens != nil && "Custom frontend screens can't be allocated");
-
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[0] = aScreens[id].m_PreviousPage[1] = prevPage;
- aScreens[id].unk = 1;
+ aScreens[id].returnPrevPageFunc = returnPrevPageFunc;
return id;
}
int8 RegisterNewOption()
{
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 numOptions = GetNumberOfMenuOptions(currentMenu);
uint8 curIdx;
if (optionCursor < 0) {
@@ -159,30 +86,11 @@ int8 RegisterNewOption()
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(CMenuScreen::CMenuEntry));
+ memcpy(&aScreens[currentMenu].m_aEntries[i + 1], &aScreens[currentMenu].m_aEntries[i], sizeof(CMenuScreenCustom::CMenuEntry));
}
}
}
optionCursor++;
-
- if (optionOverwrite) {
- numFrontendOptionReplacements++;
- if (numFrontendOptionReplacements == 1)
- frontendOptionReplacements = (CMenuScreen::CMenuEntry*)malloc(5 * sizeof(CMenuScreen::CMenuEntry));
- else if (numFrontendOptionReplacements % 5 == 1)
- frontendOptionReplacements = (CMenuScreen::CMenuEntry*)realloc(frontendOptionReplacements, (numFrontendOptionReplacements + 4) * sizeof(CMenuScreen::CMenuEntry));
-
- memcpy(&frontendOptionReplacements[numFrontendOptionReplacements - 1], &aScreens[currentMenu].m_aEntries[curIdx], sizeof(CMenuScreen::CMenuEntry));
- customFrontendOptions[numCustomFrontendOptions - 1].ogOptionId = numFrontendOptionReplacements - 1;
- } else {
- customFrontendOptions[numCustomFrontendOptions - 1].ogOptionId = -1;
- }
- customFrontendOptions[numCustomFrontendOptions - 1].screen = currentMenu;
-
- aScreens[currentMenu].m_aEntries[curIdx].m_Action = MENUACTION_TRIGGERFUNC;
- aScreens[currentMenu].m_aEntries[curIdx].m_SaveSlot = SAVESLOT_CFO;
- aScreens[currentMenu].m_aEntries[curIdx].m_TargetMenu = numCustomFrontendOptions - 1;
- aScreens[currentMenu].m_aEntries[curIdx].m_EntryName[0] = 1; // just something to fool it
return curIdx;
}
@@ -193,110 +101,78 @@ void FrontendOptionSetCursor(int screen, int8 option, bool overwrite)
optionOverwrite = overwrite;
}
-void FrontendOptionAddBuiltinAction(const wchar* leftText, int action, ButtonPressFunc buttonPressFunc, ReturnPrevPageFunc returnPrevPageFunc) {
+void FrontendOptionAddBuiltinAction(const char* gxtKey, int action, int targetMenu, int saveSlot) {
int8 screenOptionOrder = RegisterNewOption();
- FrontendOption& option = customFrontendOptions[numCustomFrontendOptions - 1];
+ CMenuScreenCustom::CMenuEntry &option = aScreens[currentMenu].m_aEntries[screenOptionOrder];
- // To fool the Frontend, we will still display the text passed via first param.
+ // We can't use custom text on those :shrug:
switch (action) {
case MENUACTION_SCREENRES:
- strcpy(aScreens[currentMenu].m_aEntries[screenOptionOrder].m_EntryName, "FED_RES");
+ strcpy(option.m_EntryName, "FED_RES");
break;
case MENUACTION_AUDIOHW:
- strcpy(aScreens[currentMenu].m_aEntries[screenOptionOrder].m_EntryName, "FEA_3DH");
+ strcpy(option.m_EntryName, "FEA_3DH");
+ break;
+ default:
+ strncpy(option.m_EntryName, gxtKey, 8);
break;
}
- aScreens[currentMenu].m_aEntries[screenOptionOrder].m_Action = action;
- option.type = FEOPTION_BUILTIN_ACTION;
- option.buttonPressFunc = buttonPressFunc;
- TextCopy(option.leftText, leftText);
- option.screenOptionOrder = screenOptionOrder;
- option.returnPrevPageFunc = returnPrevPageFunc;
- option.save = nil;
-}
-
-void FrontendOptionAddSelect(const wchar* leftText, const wchar** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, ReturnPrevPageFunc returnPrevPageFunc, const char* saveName)
-{
- int8 screenOptionOrder = RegisterNewOption();
-
- FrontendOption& option = customFrontendOptions[numCustomFrontendOptions - 1];
- option.type = FEOPTION_SELECT;
- TextCopy(option.leftText, leftText);
- option.rightTexts = (wchar**)malloc(numRightTexts * sizeof(wchar*));
- memcpy(option.rightTexts, rightTexts, numRightTexts * sizeof(wchar*));
- option.numRightTexts = numRightTexts;
- option.value = var;
- option.displayedValue = *var;
- option.lastSavedValue = *var;
- option.save = saveName;
- option.onlyApplyOnEnter = onlyApplyOnEnter;
- option.changeFunc = changeFunc;
- option.screenOptionOrder = screenOptionOrder;
- option.returnPrevPageFunc = returnPrevPageFunc;
+ option.m_Action = action;
+ option.m_SaveSlot = saveSlot;
+ option.m_TargetMenu = targetMenu;
}
-void FrontendOptionAddDynamic(const wchar* leftText, DrawFunc drawFunc, int8 *var, ButtonPressFunc buttonPressFunc, ReturnPrevPageFunc returnPrevPageFunc, const char* saveName)
-{
+void FrontendOptionAddSelect(const char* gxtKey, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveName)
+{
int8 screenOptionOrder = RegisterNewOption();
- FrontendOption& option = customFrontendOptions[numCustomFrontendOptions - 1];
- option.type = FEOPTION_DYNAMIC;
- option.drawFunc = drawFunc;
- option.buttonPressFunc = buttonPressFunc;
- TextCopy(option.leftText, leftText);
- option.value = var;
- option.save = saveName;
- option.screenOptionOrder = screenOptionOrder;
- option.returnPrevPageFunc = returnPrevPageFunc;
-}
-
-void FrontendOptionAddRedirect(const wchar* text, int to, int8 selectedOption, bool fadeIn)
-{
- int8 screenOptionOrder = RegisterNewOption();
-
- FrontendOption &option = customFrontendOptions[numCustomFrontendOptions - 1];
- option.type = FEOPTION_REDIRECT;
- option.to = to;
- option.option = selectedOption;
- option.fadeIn = fadeIn;
- TextCopy(option.leftText, text);
- option.screenOptionOrder = screenOptionOrder;
- option.returnPrevPageFunc = nil;
- option.save = nil;
+ CMenuScreenCustom::CMenuEntry &option = aScreens[currentMenu].m_aEntries[screenOptionOrder];
+ option.m_Action = MENUACTION_CFO_SELECT;
+ 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 FrontendOptionAddBackButton(const wchar* text, bool fadeIn)
+void FrontendOptionAddDynamic(const char* gxtKey, DrawFunc drawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveName)
{
int8 screenOptionOrder = RegisterNewOption();
- FrontendOption& option = customFrontendOptions[numCustomFrontendOptions - 1];
- option.type = FEOPTION_GOBACK;
- option.fadeIn = fadeIn;
- TextCopy(option.leftText, text);
- option.screenOptionOrder = screenOptionOrder;
- option.returnPrevPageFunc = nil;
- option.save = nil;
+ CMenuScreenCustom::CMenuEntry &option = aScreens[currentMenu].m_aEntries[screenOptionOrder];
+ option.m_Action = MENUACTION_CFO_DYNAMIC;
+ 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;
}
uint8 FrontendScreenAdd(const char* gxtKey, eMenuSprites sprite, int prevPage, int columnWidth, int headerHeight, int lineHeight,
int8 font, float fontScaleX, float fontScaleY, int8 alignment, bool showLeftRightHelper, ReturnPrevPageFunc returnPrevPageFunc) {
- uint8 screenOrder = RegisterNewScreen(gxtKey, prevPage);
-
- FrontendScreen &screen = customFrontendScreens[numCustomFrontendScreens - 1];
- screen.id = screenOrder;
- screen.sprite = sprite;
- screen.prevPage = prevPage;
- strncpy(screen.name, gxtKey, 8);
- screen.columnWidth = columnWidth;
- screen.headerHeight = headerHeight;
- screen.lineHeight = lineHeight;
- screen.font = font;
- screen.fontScaleX = fontScaleX;
- screen.fontScaleY = fontScaleY;
- screen.alignment = alignment;
- screen.returnPrevPageFunc = returnPrevPageFunc;
+ uint8 screenOrder = RegisterNewScreen(gxtKey, prevPage, returnPrevPageFunc);
+
+ CCustomScreenLayout *screen = new CCustomScreenLayout();
+ aScreens[screenOrder].layout = screen;
+ screen->sprite = sprite;
+ screen->columnWidth = columnWidth;
+ screen->headerHeight = headerHeight;
+ screen->lineHeight = lineHeight;
+ screen->font = font;
+ screen->fontScaleX = fontScaleX;
+ screen->fontScaleY = fontScaleY;
+ screen->alignment = alignment;
return screenOrder;
}
diff --git a/src/extras/frontendoption.h b/src/extras/frontendoption.h
index dac6be62..19340b20 100644
--- a/src/extras/frontendoption.h
+++ b/src/extras/frontendoption.h
@@ -2,47 +2,23 @@
#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.
-
-// About texts:
-// All text parameters accept wchar(including hardcoded wchar* and TheText.Get)
-// except FrontendScreenAdd(it's char[8] GXT key by the design of Frontend).
-// All texts reload if custom options reloaded too, which includes language changes and via live reload feature in debug menu!
-
-// 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.
-
-// Live reload:
-// You can add/change/undo the new options in-game if you use VS. Change what you want, build the changed bits via "Edit and Continue",
-// and hit the "Reload custom frontend options" from debug menu. Or call CustomFrontendOptionsPopulate() from somewhere else.
+// ! 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,
-// then you can handle ChangeFunc(only called on enter if onlyApplyOnEnter set, or set immediately)
-// and ReturnPrevPageFunc optionally. You can store the option in an INI file if you pass the key(as a char array) to corresponding parameter.
+// 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. ReturnPrevPageFunc is also here if needed.
-//
-// Redirect: Redirection to another screen. selectedOption parameter is the highlighted option user will see after the redirection.
+// 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,
-// and can be informed on button press/focus loss via buttonPressFunc. ReturnPrevPageFunc is also here.
-
-#define FEOPTION_SELECT 0
-#define FEOPTION_DYNAMIC 1
-#define FEOPTION_REDIRECT 2
-#define FEOPTION_GOBACK 3
-#define FEOPTION_BUILTIN_ACTION 4
// -- Returned via ButtonPressFunc() action param.
#define FEOPTION_ACTION_LEFT 0
@@ -61,7 +37,7 @@
typedef void (*ReturnPrevPageFunc)();
// for static options
-typedef void (*ChangeFunc)(int8 displayedValue); // called before updating the value.
+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
@@ -69,71 +45,11 @@ typedef wchar* (*DrawFunc)(bool* disabled, bool userHovering); // you must retur
// you can also set *disabled if you want to gray it out.
typedef void (*ButtonPressFunc)(int8 action); // see FEOPTION_ACTIONs above
-struct FrontendScreen
-{
- int id;
- char name[8];
- eMenuSprites sprite;
- int prevPage;
- int columnWidth;
- int headerHeight;
- int lineHeight;
- int8 font;
- float fontScaleX;
- float fontScaleY;
- int8 alignment;
- bool showLeftRightHelper;
- ReturnPrevPageFunc returnPrevPageFunc;
-};
-
-struct FrontendOption
-{
- int8 type;
- int8 screenOptionOrder;
- int32 screen;
- wchar leftText[128];
- ReturnPrevPageFunc returnPrevPageFunc;
- int8* value;
- int8 displayedValue; // only if onlyApplyOnEnter enabled for now
- const char* save;
- int32 ogOptionId; // for replacements, see overwrite parameter of SetCursor
-
- union {
- // Only for dynamic / built-in action
- struct {
- DrawFunc drawFunc;
- ButtonPressFunc buttonPressFunc;
- };
-
- // Only for static/select
- struct {
- wchar** rightTexts;
- int8 numRightTexts;
- bool onlyApplyOnEnter;
- ChangeFunc changeFunc;
- int8 lastSavedValue; // only if onlyApplyOnEnter enabled
- };
-
- // Only for redirect
- struct {
- int to;
- int8 option;
- bool fadeIn;
- };
- };
-};
-
// -- Internal things
-void RemoveCustomFrontendOptions();
void CustomFrontendOptionsPopulate();
-
extern int lastOgScreen; // for reloading
-
extern int numCustomFrontendOptions;
-extern FrontendOption* customFrontendOptions;
-
extern int numCustomFrontendScreens;
-extern FrontendScreen* customFrontendScreens;
// -- To be used in ButtonPressFunc / ChangeFunc(this one would be weird):
void ChangeScreen(int screen, int option = 0, bool fadeIn = true);
@@ -141,6 +57,21 @@ void GoBack(bool fadeIn = true);
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:
@@ -152,11 +83,9 @@ uint8 GetNumberOfMenuOptions(int screen);
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 wchar* leftText, int action, ButtonPressFunc buttonPressFunc, ReturnPrevPageFunc returnPrevPageFunc);
-void FrontendOptionAddSelect(const wchar* leftText, const wchar** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, ReturnPrevPageFunc returnPrevPageFunc, const char* saveName = nil);
-void FrontendOptionAddDynamic(const wchar* leftText, DrawFunc rightTextDrawFunc, int8 *var, ButtonPressFunc buttonPressFunc, ReturnPrevPageFunc returnPrevPageFunc, const char* saveName = nil);
-void FrontendOptionAddRedirect(const wchar* text, int to, int8 selectedOption = 0, bool fadeIn = true);
-void FrontendOptionAddBackButton(const wchar* text, bool fadeIn = true);
+void FrontendOptionAddBuiltinAction(const char* gxtKey, int action, int targetMenu = MENUPAGE_NONE, int saveSlot = SAVESLOT_NONE);
+void FrontendOptionAddSelect(const char* gxtKey, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveName = nil);
+void FrontendOptionAddDynamic(const char* gxtKey, DrawFunc rightTextDrawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveName = nil);
uint8 FrontendScreenAdd(const char* gxtKey, eMenuSprites sprite, int prevPage, int columnWidth, int headerHeight, int lineHeight, int8 font, float fontScaleX, float fontScaleY, int8 alignment, bool showLeftRightHelper, ReturnPrevPageFunc returnPrevPageFunc = nil);
#endif