diff --git a/README.md b/README.md
index 6ec751c64..7ae1af1be 100644
--- a/README.md
+++ b/README.md
@@ -115,6 +115,25 @@ that contains the preferred partition name (for example `__common`).
+
NBD Server
diff --git a/ee_core/include/coreconfig.h b/ee_core/include/coreconfig.h
index b3d6a0a77..eac6e6ab2 100644
--- a/ee_core/include/coreconfig.h
+++ b/ee_core/include/coreconfig.h
@@ -45,7 +45,7 @@ struct EECoreConfig_t
char g_ps2_gateway[16];
unsigned char g_ps2_ETHOpMode;
- unsigned int *gCheatList; // Store hooks/codes addr+val pairs
+ u32 *gCheatList; // Store hooks/codes addr+val pairs
void *eeloadCopy;
void *initUserMemory;
diff --git a/include/cheatman.h b/include/cheatman.h
index 2068a1736..7d828e4f3 100644
--- a/include/cheatman.h
+++ b/include/cheatman.h
@@ -34,11 +34,12 @@
#include
#include
-#define CHEAT_VERSION "0.5.3.65.g774d1"
+#define CHEAT_VERSION "0.5.3.7"
-#define MAX_HOOKS 5
-#define MAX_CODES 250
-#define MAX_CHEATLIST (MAX_HOOKS * 2 + MAX_CODES * 2)
+#define MAX_HOOKS 5
+#define MAX_CODES 250
+#define MAX_CHEATLIST (MAX_HOOKS * 2 + MAX_CODES * 2)
+#define CHEAT_NAME_MAX 128
/* Some character defines */
#define NUL 0x00
@@ -59,9 +60,19 @@ typedef struct
u32 val;
} code_t;
+typedef struct
+{
+ char name[CHEAT_NAME_MAX + 1];
+ code_t codes[MAX_CHEATLIST];
+ int enabled;
+} cheat_entry_t;
+
+extern cheat_entry_t gCheats[MAX_CODES];
+
void InitCheatsConfig(config_set_t *configSet);
int GetCheatsEnabled(void);
const u32 *GetCheatsList(void);
int load_cheats(const char *cheatfile);
+void set_cheats_list(void);
#endif /* _CHEATMAN_H_ */
diff --git a/include/fntsys.h b/include/fntsys.h
index ea58879aa..2706fe30d 100644
--- a/include/fntsys.h
+++ b/include/fntsys.h
@@ -6,6 +6,8 @@
/// Value returned on errors
#define FNT_ERROR (-1)
+#define FNTSYS_DEFAULT_SIZE 17
+
/** Initializes the font subsystem */
void fntInit();
@@ -15,7 +17,7 @@ void fntEnd();
/** Loads a font from a file path
* @param path The path to the font file
* @return font slot id (negative value means error happened) */
-int fntLoadFile(char *path);
+int fntLoadFile(char *path, int fontSize);
/** Reloads the default font */
int fntLoadDefault(char *path);
diff --git a/include/gui.h b/include/gui.h
index 7b51cb4d6..44c697409 100644
--- a/include/gui.h
+++ b/include/gui.h
@@ -156,4 +156,6 @@ int guiConfirmVideoMode(void);
int guiGameShowRemoveSettings(config_set_t *configSet, config_set_t *configGame);
+void guiManageCheats(void);
+
#endif
diff --git a/lng_tmpl/_base.yml b/lng_tmpl/_base.yml
index 37ca324bd..89eae9a57 100644
--- a/lng_tmpl/_base.yml
+++ b/lng_tmpl/_base.yml
@@ -680,3 +680,7 @@ gui_strings:
string: Analog X-Axis Sensitivity
- label: YSENSITIVITY
string: Analog Y-Axis Sensitivity
+- label: FILE_COUNT
+ string: 'Files found: %i'
+- label: CHEAT_SELECTION
+ string: Cheat Selection
diff --git a/src/cheatman.c b/src/cheatman.c
index 22cea59f5..5fb538b10 100644
--- a/src/cheatman.c
+++ b/src/cheatman.c
@@ -30,6 +30,7 @@ static int gEnableCheat; // Enables PS2RD Cheat Engine - 0 for Off, 1 for On
static int gCheatMode; // Cheat Mode - 0 Enable all cheats, 1 Cheats selected by user
static u32 gCheatList[MAX_CHEATLIST]; // Store hooks/codes addr+val pairs
+cheat_entry_t gCheats[MAX_CODES];
void InitCheatsConfig(config_set_t *configSet)
{
@@ -39,7 +40,6 @@ void InitCheatsConfig(config_set_t *configSet)
gCheatSource = 0;
gEnableCheat = 0;
gCheatMode = 0;
- memset(gCheatList, 0, sizeof(gCheatList));
if (configGetInt(configSet, CONFIG_ITEM_CHEATSSOURCE, &gCheatSource)) {
// Load the rest of the per-game CHEAT configuration if CHEAT is enabled.
@@ -80,6 +80,8 @@ static code_t make_code(const char *s)
s++;
}
+ digits[i] = '\0';
+
sscanf(digits, "%08X %08X", &address, &value);
// Return Code Address and Value
@@ -244,17 +246,18 @@ static int parse_buf(const char *buf)
code_t code;
char line[CHEAT_LINE_MAX + 1];
int linenumber = 1;
+ int cheat_index = -1; // Starts at -1.. indicating no cheat being processed yet
+ int code_index = 0;
+ char temp_name[CHEAT_NAME_MAX + 1] = {0};
if (buf == NULL)
return -1;
- int i = 0;
-
while (*buf) {
/* Scanner */
int len = chr_idx(buf, LF);
if (len < 0)
- len = strlen(line);
+ len = strlen(buf);
else if (len > CHEAT_LINE_MAX)
len = CHEAT_LINE_MAX;
@@ -266,23 +269,35 @@ static int parse_buf(const char *buf)
term_str(line, is_cmt_str);
trim_str(line);
- /* Parser */
- code = parse_line(line, linenumber);
- if (!((code.addr == 0) && (code.val == 0))) {
- gCheatList[i] = code.addr;
- i++;
- gCheatList[i] = code.val;
- i++;
+ // Check if the line is a cheat name
+ if (!is_cheat_code(line) && strlen(line) > 0) {
+ // Store the cheat name temporarily
+ strncpy(temp_name, line, CHEAT_NAME_MAX);
+ temp_name[CHEAT_NAME_MAX] = NUL;
+ // Reset code index in case this is a new cheat
+ code_index = 0;
+ } else {
+ /* Parser */
+ code = parse_line(line, linenumber);
+ if (!(code.addr == 0 && code.val == 0)) {
+ // Only add the cheat entry if we have a valid cheat name in temp_name
+ if (cheat_index < MAX_CODES && temp_name[0] != NUL) {
+ cheat_index++; // Move to the next cheat entry
+ strncpy(gCheats[cheat_index].name, temp_name, CHEAT_NAME_MAX);
+ gCheats[cheat_index].name[CHEAT_NAME_MAX] = NUL;
+ gCheats[cheat_index].enabled = 1; // Set cheat as enabled
+ temp_name[0] = NUL; // Clear temp_name after use
+ }
+ // Add the cheat code to the current cheat entry
+ if (cheat_index >= 0 && code_index < MAX_CHEATLIST)
+ gCheats[cheat_index].codes[code_index++] = code;
+ }
}
}
linenumber++;
buf += len + 1;
}
- gCheatList[i] = 0;
- i++;
- gCheatList[i] = 0;
-
return 0;
}
@@ -304,15 +319,23 @@ static inline char *read_text_file(const char *filename, int maxsize)
}
filesize = lseek(fd, 0, SEEK_END);
- if (maxsize && filesize > maxsize) {
+ if (filesize < 0) {
+ LOG("%s: Can't seek in text file %s\n", __FUNCTION__, filename);
+ close(fd);
+ return NULL;
+ }
+
+ if (maxsize > 0 && filesize > maxsize) {
LOG("%s: Text file too large: %i bytes, max: %i bytes\n", __FUNCTION__, filesize, maxsize);
- goto end;
+ close(fd);
+ return NULL;
}
buf = malloc(filesize + 1);
if (buf == NULL) {
LOG("%s: Unable to allocate %i bytes\n", __FUNCTION__, filesize + 1);
- goto end;
+ close(fd);
+ return NULL;
}
if (filesize > 0) {
@@ -320,14 +343,14 @@ static inline char *read_text_file(const char *filename, int maxsize)
if (read(fd, buf, filesize) != filesize) {
LOG("%s: Can't read from text file %s\n", __FUNCTION__, filename);
free(buf);
- buf = NULL;
- goto end;
+ close(fd);
+ return NULL;
}
}
buf[filesize] = '\0';
-end:
close(fd);
+
return buf;
}
@@ -339,19 +362,52 @@ int load_cheats(const char *cheatfile)
char *buf = NULL;
int ret;
- memset(gCheatList, 0, sizeof(gCheatList));
+ memset(gCheats, 0, sizeof(gCheats));
- LOG("%s: Reading cheat file '%s'...", __FUNCTION__, cheatfile);
+ LOG("%s: Reading cheat file '%s'...\n", __FUNCTION__, cheatfile);
buf = read_text_file(cheatfile, 0);
if (buf == NULL) {
- LOG("\n%s: Could not read cheats file '%s'\n", __FUNCTION__, cheatfile);
+ LOG("%s: Could not read cheats file '%s'\n", __FUNCTION__, cheatfile);
return -1;
}
- LOG("Ok!\n");
+
ret = parse_buf(buf);
free(buf);
+
if (ret < 0)
- return -1;
- else
- return 0;
+ return ret;
+
+ return (gCheatMode == 0) ? 0 : 1;
+}
+
+void set_cheats_list(void)
+{
+ int cheatCount = 0;
+
+ memset((void *)gCheatList, 0, sizeof(gCheatList));
+
+ // Populate the cheat list
+ for (int i = 0; i < MAX_CODES; ++i) {
+ if (gCheats[i].enabled) {
+ for (int j = 0; j < MAX_CHEATLIST && gCheats[i].codes[j].addr != 0; ++j) {
+ if (cheatCount + 2 <= MAX_CHEATLIST) {
+ // Store the address and value in gCheatList
+ gCheatList[cheatCount++] = gCheats[i].codes[j].addr;
+ gCheatList[cheatCount++] = gCheats[i].codes[j].val;
+ LOG("%s: Setting cheat for eecore:\n%s\n%08X %08X\n", __FUNCTION__, gCheats[i].name, gCheats[i].codes[j].addr, gCheats[i].codes[j].val);
+ } else
+ break;
+ }
+ }
+ }
+
+ // Append a blank cheat entry if theres space
+ if (cheatCount < MAX_CHEATLIST) {
+ gCheatList[cheatCount++] = 0; // addr
+ gCheatList[cheatCount++] = 0; // val
+ } else {
+ // Overwrite the last cheat with a blank cheat if we are at max
+ gCheatList[cheatCount - 2] = 0; // addr
+ gCheatList[cheatCount - 1] = 0; // val
+ }
}
diff --git a/src/fntsys.c b/src/fntsys.c
index 0e55a10c3..35f50f10d 100644
--- a/src/fntsys.c
+++ b/src/fntsys.c
@@ -27,8 +27,6 @@ extern int size_poeveticanew_raw;
/// Atlas height in pixels
#define ATLAS_HEIGHT 256
-#define FNTSYS_CHAR_SIZE 17
-
// freetype vars
static FT_Library font_library;
@@ -76,6 +74,8 @@ typedef struct
/// Nonzero if font is used
int isValid;
+ int fontSize;
+
/// Texture atlases (default to NULL)
atlas_t *atlases[ATLAS_MAX];
@@ -200,6 +200,7 @@ static void fntInitSlot(font_t *font)
font->cacheMaxPageID = -1;
font->dataPtr = NULL;
font->isValid = 0;
+ font->fontSize = 0;
int aid = 0;
for (; aid < ATLAS_MAX; ++aid)
@@ -220,6 +221,7 @@ static void fntDeleteSlot(font_t *font)
}
font->isValid = 0;
+ font->fontSize = 0;
}
void fntRelease(int id)
@@ -228,7 +230,7 @@ void fntRelease(int id)
fntDeleteSlot(&fonts[id]);
}
-static int fntLoadSlot(font_t *font, char *path)
+static int fntLoadSlot(font_t *font, char *path, int fontSize)
{
void *buffer = NULL;
int bufferSize = -1;
@@ -256,6 +258,7 @@ static int fntLoadSlot(font_t *font, char *path)
}
font->isValid = 1;
+ font->fontSize = fontSize;
fntUpdateAspectRatio();
return 0;
@@ -285,14 +288,14 @@ void fntInit()
fntLoadDefault(NULL);
}
-int fntLoadFile(char *path)
+int fntLoadFile(char *path, int fontSize)
{
font_t *font;
int i = 1;
for (; i < FNT_MAX_COUNT; i++) {
font = &fonts[i];
if (!font->isValid) {
- if (fntLoadSlot(font, path) != FNT_ERROR)
+ if (fntLoadSlot(font, path, fontSize) != FNT_ERROR)
return i;
break;
}
@@ -305,7 +308,7 @@ int fntLoadDefault(char *path)
{
font_t newFont, oldFont;
- if (fntLoadSlot(&newFont, path) != FNT_ERROR) {
+ if (fntLoadSlot(&newFont, path, FNTSYS_DEFAULT_SIZE) != FNT_ERROR) {
// copy over the new font definition
// we have to lock this phase, as the old font may still be used
// Note: No check for concurrency is done here, which is kinda funky!
@@ -454,7 +457,7 @@ void fntUpdateAspectRatio()
if (fonts[i].isValid) {
fntCacheFlush(&fonts[i]);
// TODO: this seems correct, but the rest of the OPL UI (i.e. spacers) doesn't seem to be correctly scaled.
- FT_Set_Char_Size(fonts[i].face, FNTSYS_CHAR_SIZE * 64, FNTSYS_CHAR_SIZE * 64, fDPI * ws, fDPI * hs);
+ FT_Set_Char_Size(fonts[i].face, fonts[i].fontSize * 64, fonts[i].fontSize * 64, fDPI * ws, fDPI * hs);
}
}
}
@@ -518,9 +521,9 @@ int fntRenderString(int id, int x, int y, short aligned, size_t width, size_t he
}
if (aligned & ALIGN_VCENTER) {
- y += rmScaleY(FNTSYS_CHAR_SIZE - 4) >> 1;
+ y += rmScaleY(fonts[id].fontSize - 4) >> 1;
} else {
- y += rmScaleY(FNTSYS_CHAR_SIZE - 2);
+ y += rmScaleY(fonts[id].fontSize - 2);
}
quad.color = colour;
@@ -644,9 +647,9 @@ int fntRenderString(int id, int x, int y, short aligned, size_t width, size_t he
}
if (aligned & ALIGN_VCENTER) {
- y += rmScaleY(FNTSYS_CHAR_SIZE - 4) >> 1;
+ y += rmScaleY(fonts[id].fontSize - 4) >> 1;
} else {
- y += rmScaleY(FNTSYS_CHAR_SIZE - 2);
+ y += rmScaleY(fonts[id].fontSize - 2);
}
quad.color = colour;
diff --git a/src/gui.c b/src/gui.c
index e200d4c6f..a8ed33f73 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -1837,3 +1837,80 @@ int guiGameShowRemoveSettings(config_set_t *configSet, config_set_t *configGame)
return 1;
}
+
+void guiManageCheats(void)
+{
+ int offset = 0;
+ int terminate = 0;
+ int cheatCount = 0;
+ int selectedCheat = 0;
+ int visibleCheats = 10; // Maximum number of cheats visible on screen
+
+ while (cheatCount < MAX_CODES && strlen(gCheats[cheatCount].name) > 0)
+ cheatCount++;
+
+ sfxPlay(SFX_MESSAGE);
+
+ while (!terminate) {
+ guiStartFrame();
+ readPads();
+
+ if (getKeyOn(KEY_UP) && selectedCheat > 0) {
+ selectedCheat -= 1;
+ if (selectedCheat < offset)
+ offset = selectedCheat;
+ }
+
+ if (getKeyOn(KEY_DOWN) && selectedCheat < cheatCount - 1) {
+ selectedCheat += 1;
+ if (selectedCheat >= offset + visibleCheats)
+ offset = selectedCheat - visibleCheats + 1;
+ }
+
+ if (getKeyOn(gSelectButton)) {
+ if (!(strncasecmp(gCheats[selectedCheat].name, "mastercode", 10) == 0 || strncasecmp(gCheats[selectedCheat].name, "master code", 11) == 0))
+ gCheats[selectedCheat].enabled = !gCheats[selectedCheat].enabled;
+ }
+
+ if (getKeyOn(KEY_START))
+ terminate = 1;
+
+ guiShow();
+
+ rmDrawRect(0, 0, screenWidth, screenHeight, gColDarker);
+ rmDrawLine(50, 75, screenWidth - 50, 75, gColWhite);
+ rmDrawLine(50, 410, screenWidth - 50, 410, gColWhite);
+
+ fntRenderString(gTheme->fonts[0], screenWidth >> 1, 60, ALIGN_CENTER, 0, 0, _l(_STR_CHEAT_SELECTION), gTheme->textColor);
+
+ int renderedCheats = 0;
+ for (int i = offset; renderedCheats < visibleCheats && i < cheatCount; i++) {
+ if (strlen(gCheats[i].name) == 0)
+ continue;
+
+ int enabled = gCheats[i].enabled;
+
+ int boxX = 50;
+ int boxY = 100 + (renderedCheats * 30);
+ int boxWidth = rmWideScale(25);
+ int boxHeight = 17;
+
+ if (enabled) {
+ rmDrawRect(boxX, boxY + 3, boxWidth, boxHeight, gTheme->textColor);
+ rmDrawRect(boxX + 2, boxY + 5, boxWidth - 4, boxHeight - 4, gTheme->selTextColor);
+ }
+
+ u32 textColour = (i == selectedCheat) ? gTheme->selTextColor : gTheme->textColor;
+ fntRenderString(gTheme->fonts[0], boxX + 35, boxY + 3, ALIGN_LEFT, 0, 0, gCheats[i].name, textColour);
+
+ renderedCheats++;
+ }
+
+ guiDrawIconAndText(gSelectButton == KEY_CIRCLE ? CIRCLE_ICON : CROSS_ICON, _STR_SELECT, gTheme->fonts[0], 70, 417, gTheme->selTextColor);
+ guiDrawIconAndText(START_ICON, _STR_RUN, gTheme->fonts[0], 500, 417, gTheme->selTextColor);
+
+ guiEndFrame();
+ }
+
+ sfxPlay(SFX_CONFIRM);
+}
diff --git a/src/opl.c b/src/opl.c
index 290b9638f..72a1993f4 100644
--- a/src/opl.c
+++ b/src/opl.c
@@ -893,7 +893,7 @@ static void _loadConfig()
if (!(getKeyPressed(KEY_TRIANGLE) && getKeyPressed(KEY_CROSS))) {
configGetInt(configOPL, CONFIG_OPL_VMODE, &gVMode);
} else {
- LOG("--- Select held at boot - setting Video Mode to Auto ---\n");
+ LOG("--- Triangle + Cross held at boot - setting Video Mode to Auto ---\n");
gVMode = 0;
configSetInt(configOPL, CONFIG_OPL_VMODE, gVMode);
}
@@ -1177,6 +1177,13 @@ void applyConfig(int themeID, int langID, int skipDeviceRefresh)
moduleUpdateMenuInternal(&list_support[i], changed, langChanged);
}
+ } else {
+ if (changed) {
+ for (int i = 0; i < MODE_COUNT; i++) {
+ if (list_support[i].support && list_support[i].subMenu)
+ submenuRebuildCache(list_support[i].subMenu);
+ }
+ }
}
bgmUnMute();
diff --git a/src/supportbase.c b/src/supportbase.c
index e3c9366a8..b7df52908 100644
--- a/src/supportbase.c
+++ b/src/supportbase.c
@@ -10,6 +10,7 @@
#include "include/pggsm.h"
#include "include/cheatman.h"
#include "include/ps2cnf.h"
+#include "include/gui.h"
#define NEWLIB_PORT_AWARE
#include // fileXioMount("iso:", ***), fileXioUmount("iso:")
@@ -838,28 +839,20 @@ void sbCreateFolders(const char *path, int createDiscImgFolders)
int sbLoadCheats(const char *path, const char *file)
{
char cheatfile[64];
- const u32 *cheatList;
- int result;
+ int cheatMode = 0;
if (GetCheatsEnabled()) {
snprintf(cheatfile, sizeof(cheatfile), "%sCHT/%s.cht", path, file);
LOG("Loading Cheat File %s\n", cheatfile);
- if ((result = load_cheats(cheatfile)) < 0) {
- LOG("Error: failed to load cheats\n");
- } else {
- cheatList = GetCheatsList();
- if (!((cheatList[0] == 0) && (cheatList[1] == 0))) {
- LOG("Cheats found\n");
- result = 0;
- } else {
- LOG("No cheats found\n");
- result = -ENOENT;
- }
+ if ((cheatMode = load_cheats(cheatfile)) < 0)
+ LOG("Error: failed to load cheats\n");
+ else {
+ LOG("Cheats found\n");
+ if ((gAutoLaunchGame == NULL) && (gAutoLaunchBDMGame == NULL) && (cheatMode == 1))
+ guiManageCheats();
}
- } else {
- result = 0;
}
- return result;
+ return cheatMode;
}
diff --git a/src/system.c b/src/system.c
index 011070922..5211dd379 100644
--- a/src/system.c
+++ b/src/system.c
@@ -895,9 +895,14 @@ void sysLaunchLoaderElf(const char *filename, const char *mode_str, int size_cdv
config->EnableDebug = gEnableDebug;
config->HDDSpindown = gHDDSpindown;
- config->gCheatList = GetCheatsEnabled() ? (unsigned int *)GetCheatsList() : NULL;
config->g_ps2_ETHOpMode = gETHOpMode;
+ if (GetCheatsEnabled()) {
+ set_cheats_list();
+ config->gCheatList = GetCheatsList();
+ } else
+ config->gCheatList = NULL;
+
sprintf(config->g_ps2_ip, "%u.%u.%u.%u", local_ip_address[0], local_ip_address[1], local_ip_address[2], local_ip_address[3]);
sprintf(config->g_ps2_netmask, "%u.%u.%u.%u", local_netmask[0], local_netmask[1], local_netmask[2], local_netmask[3]);
sprintf(config->g_ps2_gateway, "%u.%u.%u.%u", local_gateway[0], local_gateway[1], local_gateway[2], local_gateway[3]);
diff --git a/src/themes.c b/src/themes.c
index 2e5a58649..338dcb1c7 100644
--- a/src/themes.c
+++ b/src/themes.c
@@ -47,7 +47,7 @@ enum ELEM_ATTRIBUTE_TYPE {
ELEM_TYPE_INFO_HINT_TEXT,
ELEM_TYPE_LOADING_ICON,
ELEM_TYPE_BDM_INDEX,
-
+ ELEM_TYPE_GAME_COUNT_TEXT,
ELEM_TYPE_COUNT
};
@@ -76,7 +76,7 @@ static const char *elementsType[ELEM_TYPE_COUNT] = {
"InfoHintText",
"LoadingIcon",
"BdmIndex",
-};
+ "GameCountText"};
// Common functions for Text ////////////////////////////////////////////////////////////////////////////////////////////////
@@ -198,6 +198,42 @@ static void initStaticText(const char *themePath, config_set_t *themeConfig, the
LOG("THEMES StaticText %s: NO value, elem disabled !!\n", name);
}
+// GameCountText ////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static int getGameCount(void *support)
+{
+ item_list_t *list = (item_list_t *)support;
+ return list->itemGetCount(list);
+}
+
+static void drawGameCountText(struct menu_list *menu, struct submenu_list *item, config_set_t *config, struct theme_element *elem)
+{
+ mutable_text_t *mutableText = (mutable_text_t *)elem->extended;
+
+ if (config) {
+ if (mutableText->currentConfigId != config->uid) {
+ // force refresh
+ mutableText->currentConfigId = config->uid;
+
+ int count = getGameCount(menu->item->userdata);
+ snprintf(mutableText->value, sizeof(char) * 60, _l(_STR_FILE_COUNT), count);
+ }
+ }
+
+ fntRenderString(elem->font, elem->posX, elem->posY, elem->aligned, 0, 0, mutableText->value, elem->color);
+}
+
+static void initGameCountText(const char *themePath, config_set_t *themeConfig, theme_t *theme, theme_element_t *elem, const char *name)
+{
+ int length = 60;
+ char *countStr = (char *)malloc(length * sizeof(char));
+ memset(countStr, 0, length * sizeof(char));
+
+ elem->extended = initMutableText(themePath, themeConfig, theme, name, ELEM_TYPE_ATTRIBUTE_TEXT, elem, countStr, NULL, DISPLAY_ALWAYS, SIZING_NONE);
+ elem->endElem = &endMutableText;
+ elem->drawElem = &drawGameCountText;
+}
+
// AttributeText ////////////////////////////////////////////////////////////////////////////////////////////////////////////
static void drawAttributeText(struct menu_list *menu, struct submenu_list *item, config_set_t *config, struct theme_element *elem)
@@ -990,6 +1026,9 @@ static int addGUIElem(const char *themePath, config_set_t *themeConfig, theme_t
} else if (!strcmp(elementsType[ELEM_TYPE_STATIC_TEXT], type)) {
elem = initBasic(themePath, themeConfig, theme, name, ELEM_TYPE_STATIC_TEXT, 0, 0, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, SCALING_RATIO, theme->textColor, theme->fonts[0]);
initStaticText(themePath, themeConfig, theme, elem, name);
+ } else if (!strcmp(elementsType[ELEM_TYPE_GAME_COUNT_TEXT], type)) {
+ elem = initBasic(themePath, themeConfig, theme, name, ELEM_TYPE_STATIC_TEXT, 0, 0, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, SCALING_RATIO, theme->textColor, theme->fonts[0]);
+ initGameCountText(themePath, themeConfig, theme, elem, name);
} else if (!strcmp(elementsType[ELEM_TYPE_ATTRIBUTE_IMAGE], type)) {
elem = initBasic(themePath, themeConfig, theme, name, ELEM_TYPE_ATTRIBUTE_IMAGE, 0, 0, ALIGN_CENTER, DIM_UNDEF, DIM_UNDEF, SCALING_RATIO, gDefaultCol, theme->fonts[0]);
initAttributeImage(themePath, themeConfig, theme, elem, name);
@@ -1185,8 +1224,18 @@ static void thmLoadFonts(config_set_t *themeConfig, const char *themePath, theme
const char *fntFile;
if (configGetStr(themeConfig, fntKey, &fntFile)) {
snprintf(fullPath, sizeof(fullPath), "%s%s", themePath, fntFile);
- int fntHandle = fntLoadFile(fullPath);
+ int fontSize;
+ char sizeKey[64];
+ if (fntID == 0)
+ snprintf(sizeKey, sizeof(sizeKey), "default_font_size");
+ else
+ snprintf(sizeKey, sizeof(sizeKey), "font%d_size", fntID);
+
+ if (!configGetInt(themeConfig, sizeKey, &fontSize) || fontSize <= 0)
+ fontSize = FNTSYS_DEFAULT_SIZE;
+
+ int fntHandle = fntLoadFile(fullPath, fontSize);
// Do we have a valid font? Assign the font handle to the theme font slot
if (fntHandle != FNT_ERROR)
theme->fonts[fntID] = fntHandle;