mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-12-25 03:11:58 +01:00
-reduced the memory usage of each game by 320 bytes, should increase
the maximum games you can have and should increase wiiflows cache reloading speed -hopefully fixed that gc disc 2 hide problem correctly now
This commit is contained in:
parent
991ed5d628
commit
a40bd5286a
@ -15,6 +15,7 @@
|
|||||||
#include "fonts.h"
|
#include "fonts.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "gecko/gecko.hpp"
|
#include "gecko/gecko.hpp"
|
||||||
|
#include "menu/menu.hpp"
|
||||||
#include "memory/mem2.hpp"
|
#include "memory/mem2.hpp"
|
||||||
#include "wstringEx/wstringEx.hpp"
|
#include "wstringEx/wstringEx.hpp"
|
||||||
|
|
||||||
@ -77,19 +78,14 @@ CCoverFlow::CCover::CCover(void)
|
|||||||
targetScale = Vector3D(1.f, 1.f, 1.f);
|
targetScale = Vector3D(1.f, 1.f, 1.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
CCoverFlow::CItem::CItem(dir_discHdr *itemHdr, const char *itemPic, const char *itemBoxPic, const char *itemBlankBoxPic, int playcount, unsigned int lastPlayed) :
|
CCoverFlow::CItem::CItem(dir_discHdr *itemHdr, int playcount, unsigned int lastPlayed) :
|
||||||
hdr(itemHdr),
|
hdr(itemHdr),
|
||||||
playcount(playcount),
|
playcount(playcount),
|
||||||
lastPlayed(lastPlayed),
|
lastPlayed(lastPlayed),
|
||||||
boxTexture(false),
|
boxTexture(false),
|
||||||
state(STATE_Loading)
|
state(STATE_Loading)
|
||||||
{
|
{
|
||||||
strncpy(picPath, itemPic, 127);
|
|
||||||
picPath[127] = '\0';
|
|
||||||
strncpy(boxPicPath, itemBoxPic, 127);
|
|
||||||
boxPicPath[127] = '\0';
|
|
||||||
strncpy(blankBoxPicPath, itemBlankBoxPic, 63);
|
|
||||||
blankBoxPicPath[63] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline wchar_t upperCaseWChar(wchar_t c)
|
static inline wchar_t upperCaseWChar(wchar_t c)
|
||||||
@ -708,10 +704,10 @@ void CCoverFlow::reserve(u32 capacity)
|
|||||||
m_items.reserve(capacity);
|
m_items.reserve(capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCoverFlow::addItem(dir_discHdr *hdr, const char *picPath, const char *boxPicPath, const char *blankBoxPicPath, int playcount, unsigned int lastPlayed)
|
void CCoverFlow::addItem(dir_discHdr *hdr, int playcount, unsigned int lastPlayed)
|
||||||
{
|
{
|
||||||
if (m_covers != NULL) return;
|
if (m_covers != NULL) return;
|
||||||
m_items.push_back(CCoverFlow::CItem(hdr, picPath, boxPicPath, blankBoxPicPath, playcount, lastPlayed));
|
m_items.push_back(CCoverFlow::CItem(hdr, playcount, lastPlayed));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draws a plane in the Z-Buffer only.
|
// Draws a plane in the Z-Buffer only.
|
||||||
@ -2622,8 +2618,8 @@ bool CCoverFlow::_loadCoverTexPNG(u32 i, bool box, bool hq, bool blankBoxCover)
|
|||||||
if (!m_loadingCovers) return false;
|
if (!m_loadingCovers) return false;
|
||||||
|
|
||||||
u8 textureFmt = m_compressTextures ? GX_TF_CMPR : GX_TF_RGB565;
|
u8 textureFmt = m_compressTextures ? GX_TF_CMPR : GX_TF_RGB565;
|
||||||
const char *path = box ? (blankBoxCover ? m_items[i].blankBoxPicPath :
|
const char *path = box ? (blankBoxCover ? mainMenu.getBlankCoverPath(m_items[i].hdr) :
|
||||||
m_items[i].boxPicPath) : m_items[i].picPath;
|
mainMenu.getBoxPath(m_items[i].hdr)) : mainMenu.getFrontPath(m_items[i].hdr);
|
||||||
TexData tex;
|
TexData tex;
|
||||||
tex.thread = true;
|
tex.thread = true;
|
||||||
m_renderingTex = &tex;
|
m_renderingTex = &tex;
|
||||||
@ -2653,7 +2649,11 @@ bool CCoverFlow::_loadCoverTexPNG(u32 i, bool box, bool hq, bool blankBoxCover)
|
|||||||
{
|
{
|
||||||
const char *gamePath = NULL;
|
const char *gamePath = NULL;
|
||||||
if(blankBoxCover)
|
if(blankBoxCover)
|
||||||
gamePath = strrchr(m_items[i].blankBoxPicPath, '/') + 1;
|
{
|
||||||
|
const char *menuPath = mainMenu.getBlankCoverPath(m_items[i].hdr);
|
||||||
|
if(menuPath != NULL && strrchr(menuPath, '/') != NULL)
|
||||||
|
gamePath = strrchr(menuPath, '/') + 1;
|
||||||
|
}
|
||||||
else if(NoGameID(m_items[i].hdr->type))
|
else if(NoGameID(m_items[i].hdr->type))
|
||||||
{
|
{
|
||||||
if(strrchr(m_items[i].hdr->path, '/') != NULL)
|
if(strrchr(m_items[i].hdr->path, '/') != NULL)
|
||||||
@ -2663,7 +2663,10 @@ bool CCoverFlow::_loadCoverTexPNG(u32 i, bool box, bool hq, bool blankBoxCover)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
gamePath = m_items[i].hdr->id;
|
gamePath = m_items[i].hdr->id;
|
||||||
FILE *file = fopen(fmt("%s/%s.wfc", m_cachePath.c_str(), gamePath), "wb");
|
|
||||||
|
FILE *file = NULL;
|
||||||
|
if(gamePath != NULL)
|
||||||
|
file = fopen(fmt("%s/%s.wfc", m_cachePath.c_str(), gamePath), "wb");
|
||||||
if(file != NULL)
|
if(file != NULL)
|
||||||
{
|
{
|
||||||
SWFCHeader header(tex, box, m_compressCache);
|
SWFCHeader header(tex, box, m_compressCache);
|
||||||
@ -2735,7 +2738,11 @@ CCoverFlow::CLRet CCoverFlow::_loadCoverTex(u32 i, bool box, bool hq, bool blank
|
|||||||
{
|
{
|
||||||
const char *gamePath = NULL;
|
const char *gamePath = NULL;
|
||||||
if(blankBoxCover)
|
if(blankBoxCover)
|
||||||
gamePath = strrchr(m_items[i].blankBoxPicPath, '/') + 1;
|
{
|
||||||
|
const char *menuPath = mainMenu.getBlankCoverPath(m_items[i].hdr);
|
||||||
|
if(menuPath != NULL && strrchr(menuPath, '/') != NULL)
|
||||||
|
gamePath = strrchr(menuPath, '/') + 1;
|
||||||
|
}
|
||||||
else if(NoGameID(m_items[i].hdr->type))
|
else if(NoGameID(m_items[i].hdr->type))
|
||||||
{
|
{
|
||||||
if(strrchr(m_items[i].hdr->path, '/') != NULL)
|
if(strrchr(m_items[i].hdr->path, '/') != NULL)
|
||||||
@ -2745,7 +2752,13 @@ CCoverFlow::CLRet CCoverFlow::_loadCoverTex(u32 i, bool box, bool hq, bool blank
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
gamePath = m_items[i].hdr->id;
|
gamePath = m_items[i].hdr->id;
|
||||||
FILE *fp = fopen(fmt("%s/%s.wfc", m_cachePath.c_str(), gamePath), "rb");
|
|
||||||
|
FILE *fp = NULL;
|
||||||
|
if(gamePath != NULL)
|
||||||
|
{
|
||||||
|
const char *path = fmt("%s/%s.wfc", m_cachePath.c_str(), gamePath);
|
||||||
|
fp = fopen(path, "rb");
|
||||||
|
}
|
||||||
if(fp != NULL)
|
if(fp != NULL)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
@ -44,7 +44,7 @@ public:
|
|||||||
void clear(void);
|
void clear(void);
|
||||||
void shutdown(void);
|
void shutdown(void);
|
||||||
void reserve(u32 capacity);
|
void reserve(u32 capacity);
|
||||||
void addItem(dir_discHdr *hdr, const char *picPath, const char *boxPicPath, const char *blankBoxPicPath, int playcount = 0, unsigned int lastPlayed = 0);
|
void addItem(dir_discHdr *hdr, int playcount = 0, unsigned int lastPlayed = 0);
|
||||||
bool empty(void) const { return m_items.empty(); }
|
bool empty(void) const { return m_items.empty(); }
|
||||||
//
|
//
|
||||||
bool start();
|
bool start();
|
||||||
@ -194,12 +194,8 @@ private:
|
|||||||
enum TexState { STATE_Loading, STATE_Ready, STATE_NoCover };
|
enum TexState { STATE_Loading, STATE_Ready, STATE_NoCover };
|
||||||
struct CItem
|
struct CItem
|
||||||
{
|
{
|
||||||
CItem(dir_discHdr *itemHdr, const char *itemPic, const char *itemBoxPic,
|
CItem(dir_discHdr *itemHdr, int playcount, unsigned int lastPlayed);
|
||||||
const char *itemBlankBoxPic, int playcount, unsigned int lastPlayed);
|
|
||||||
dir_discHdr *hdr;
|
dir_discHdr *hdr;
|
||||||
char picPath[128];
|
|
||||||
char boxPicPath[128];
|
|
||||||
char blankBoxPicPath[64];
|
|
||||||
int playcount;
|
int playcount;
|
||||||
unsigned int lastPlayed;
|
unsigned int lastPlayed;
|
||||||
TexData texture;
|
TexData texture;
|
||||||
|
@ -1649,35 +1649,32 @@ void CMenu::_initCF(void)
|
|||||||
for(vector<dir_discHdr>::iterator element = m_gameList.begin(); element != m_gameList.end(); ++element)
|
for(vector<dir_discHdr>::iterator element = m_gameList.begin(); element != m_gameList.end(); ++element)
|
||||||
{
|
{
|
||||||
string id;
|
string id;
|
||||||
string tempname = element->path;
|
char tmp_id[256];
|
||||||
u64 chantitle = TITLE_ID(element->settings[0],element->settings[1]);
|
u64 chantitle = TITLE_ID(element->settings[0],element->settings[1]);
|
||||||
if(element->type == TYPE_HOMEBREW)
|
if(element->type == TYPE_HOMEBREW)
|
||||||
{
|
id = strrchr(element->path, '/') + 1;
|
||||||
tempname.assign(&tempname[tempname.find_last_of('/') + 1]);
|
|
||||||
id = tempname;
|
|
||||||
}
|
|
||||||
else if(element->type == TYPE_PLUGIN)
|
else if(element->type == TYPE_PLUGIN)
|
||||||
{
|
{
|
||||||
if(tempname.find(':') != string::npos)
|
if(strchr(element->path, ':') != NULL)
|
||||||
{
|
{
|
||||||
if(tempname.empty() || tempname.find_first_of('/') == string::npos)
|
if(strchr(element->path, '/') == NULL)
|
||||||
continue;
|
continue;
|
||||||
tempname.erase(0, tempname.find_first_of('/')+1);
|
memset(tmp_id, 0, 256);
|
||||||
string dirName = tempname.substr(0, tempname.find_first_of('/')+1);
|
strncpy(tmp_id, strchr(element->path, '/') + 1, 255);
|
||||||
if (tempname.find_first_of('/') == string::npos)
|
if(strchr(tmp_id, '/') == NULL)
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
/* first subpath */
|
||||||
tempname.assign(&tempname[tempname.find_last_of('/') + 1]);
|
*(strchr(tmp_id, '/') + 1) = '\0';
|
||||||
if(tempname.find_last_of('.') == string::npos)
|
id.append(tmp_id);
|
||||||
{
|
/* filename */
|
||||||
|
strncpy(tmp_id, strrchr(element->path, '/') + 1, 255);
|
||||||
|
if(strchr(tmp_id, '.') == NULL)
|
||||||
continue;
|
continue;
|
||||||
}
|
*strchr(tmp_id, '.') = '\0';
|
||||||
tempname.erase(tempname.find_last_of('.'), tempname.size() - tempname.find_last_of('.'));
|
id.append(tmp_id);
|
||||||
id = dirName+tempname;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
id = tempname;
|
id = element->path;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1857,66 +1854,25 @@ void CMenu::_initCF(void)
|
|||||||
if(dumpGameLst)
|
if(dumpGameLst)
|
||||||
dump.setWString(domain, id, element->title);
|
dump.setWString(domain, id, element->title);
|
||||||
|
|
||||||
const char *blankCoverKey = NULL;
|
if(element->type == TYPE_PLUGIN && EnabledPlugins.size() > 0)
|
||||||
switch(element->type)
|
|
||||||
{
|
{
|
||||||
case TYPE_CHANNEL:
|
for(u8 j = 0; j < EnabledPlugins.size(); j++)
|
||||||
blankCoverKey = "channels";
|
|
||||||
break;
|
|
||||||
case TYPE_HOMEBREW:
|
|
||||||
blankCoverKey = "homebrew";
|
|
||||||
break;
|
|
||||||
case TYPE_GC_GAME:
|
|
||||||
blankCoverKey = "gamecube";
|
|
||||||
break;
|
|
||||||
case TYPE_PLUGIN:
|
|
||||||
char PluginMagicWord[9];
|
|
||||||
memset(PluginMagicWord, 0, sizeof(PluginMagicWord));
|
|
||||||
strncpy(PluginMagicWord, fmt("%08x", element->settings[0]), 8);
|
|
||||||
blankCoverKey = PluginMagicWord;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
blankCoverKey = "wii";
|
|
||||||
}
|
|
||||||
const string &blankCoverName = m_theme.getString("BLANK_COVERS", blankCoverKey, fmt("%s.jpg", blankCoverKey));
|
|
||||||
if(element->type == TYPE_PLUGIN)
|
|
||||||
{
|
|
||||||
string tempname(element->path);
|
|
||||||
if(tempname.find_last_of("/") != string::npos)
|
|
||||||
tempname.assign(&tempname[tempname.find_last_of("/") + 1]);
|
|
||||||
string coverFolder(m_plugin.GetCoverFolderName(element->settings[0]));
|
|
||||||
if(EnabledPlugins.size() == 0) //all plugins
|
|
||||||
{
|
{
|
||||||
if(coverFolder.size() > 0)
|
if(EnabledPlugins.at(j) == true && element->settings[0] == m_plugin.getPluginMagic(j))
|
||||||
CoverFlow.addItem(&(*element), fmt("%s/%s/%s.png", m_picDir.c_str(), coverFolder.c_str(), tempname.c_str()), fmt("%s/%s/%s.png", m_boxPicDir.c_str(), coverFolder.c_str(), tempname.c_str()), fmt("%s/%s", m_boxPicDir.c_str(), blankCoverName.c_str()), playcount, lastPlayed);
|
|
||||||
else
|
|
||||||
CoverFlow.addItem(&(*element), fmt("%s/%s.png", m_picDir.c_str(), tempname.c_str()), fmt("%s/%s.png", m_boxPicDir.c_str(), tempname.c_str()), fmt("%s/%s", m_boxPicDir.c_str(), blankCoverName.c_str()), playcount, lastPlayed);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(u8 j = 0; j < EnabledPlugins.size(); j++)
|
|
||||||
{
|
{
|
||||||
if(EnabledPlugins.at(j) == true && element->settings[0] == m_plugin.getPluginMagic(j))
|
CoverFlow.addItem(&(*element), playcount, lastPlayed);
|
||||||
{
|
break;
|
||||||
if(coverFolder.size() > 0)
|
|
||||||
CoverFlow.addItem(&(*element), fmt("%s/%s/%s.png", m_picDir.c_str(), coverFolder.c_str(), tempname.c_str()), fmt("%s/%s/%s.png", m_boxPicDir.c_str(), coverFolder.c_str(), tempname.c_str()), fmt("%s/%s", m_boxPicDir.c_str(), blankCoverName.c_str()), playcount, lastPlayed);
|
|
||||||
else
|
|
||||||
CoverFlow.addItem(&(*element), fmt("%s/%s.png", m_picDir.c_str(), tempname.c_str()), fmt("%s/%s.png", m_boxPicDir.c_str(), tempname.c_str()), fmt("%s/%s", m_boxPicDir.c_str(), blankCoverName.c_str()), playcount, lastPlayed);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(element->type == TYPE_HOMEBREW)
|
|
||||||
CoverFlow.addItem(&(*element), fmt("%s/icon.png", element->path), fmt("%s/%s.png", m_boxPicDir.c_str(), id.c_str()), fmt("%s/%s", m_boxPicDir.c_str(), blankCoverName.c_str()), playcount, lastPlayed);
|
|
||||||
else
|
else
|
||||||
CoverFlow.addItem(&(*element), fmt("%s/%s.png", m_picDir.c_str(), element->id), fmt("%s/%s.png", m_boxPicDir.c_str(), element->id), fmt("%s/%s", m_boxPicDir.c_str(), blankCoverName.c_str()), playcount, lastPlayed);
|
CoverFlow.addItem(&(*element), playcount, lastPlayed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(gametdb.IsLoaded())
|
if(gametdb.IsLoaded())
|
||||||
gametdb.CloseFile();
|
gametdb.CloseFile();
|
||||||
m_gcfg1.unload();
|
m_gcfg1.unload();
|
||||||
if (dumpGameLst)
|
if (dumpGameLst)
|
||||||
{
|
{
|
||||||
dump.save(true);
|
dump.save(true);
|
||||||
m_cfg.setBool(domain, "dump_list", false);
|
m_cfg.setBool(domain, "dump_list", false);
|
||||||
@ -2592,7 +2548,15 @@ const char *CMenu::_getId()
|
|||||||
id = tmp;
|
id = tmp;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
id = CoverFlow.getId();
|
{
|
||||||
|
id = hdr->id;
|
||||||
|
if(hdr->type == TYPE_GC_GAME && hdr->settings[0] == 1) /* disc 2 */
|
||||||
|
{
|
||||||
|
tmp[0] = '\0';
|
||||||
|
strcat(tmp, fmt("%.6s_2", hdr->id));
|
||||||
|
id = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2694,3 +2658,65 @@ void CMenu::TempLoadIOS(int IOS)
|
|||||||
_netInit();
|
_netInit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *CMenu::getBlankCoverPath(const dir_discHdr *element)
|
||||||
|
{
|
||||||
|
const char *blankCoverKey = NULL;
|
||||||
|
switch(element->type)
|
||||||
|
{
|
||||||
|
case TYPE_CHANNEL:
|
||||||
|
blankCoverKey = "channels";
|
||||||
|
break;
|
||||||
|
case TYPE_HOMEBREW:
|
||||||
|
blankCoverKey = "homebrew";
|
||||||
|
break;
|
||||||
|
case TYPE_GC_GAME:
|
||||||
|
blankCoverKey = "gamecube";
|
||||||
|
break;
|
||||||
|
case TYPE_PLUGIN:
|
||||||
|
char PluginMagicWord[9];
|
||||||
|
memset(PluginMagicWord, 0, sizeof(PluginMagicWord));
|
||||||
|
strncpy(PluginMagicWord, fmt("%08x", element->settings[0]), 8);
|
||||||
|
blankCoverKey = PluginMagicWord;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
blankCoverKey = "wii";
|
||||||
|
}
|
||||||
|
return m_theme.getString("BLANK_COVERS", blankCoverKey, fmt("%s.jpg", blankCoverKey)).c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *CMenu::getBoxPath(const dir_discHdr *element)
|
||||||
|
{
|
||||||
|
if(element->type == TYPE_PLUGIN)
|
||||||
|
{
|
||||||
|
const char *tempname = element->path;
|
||||||
|
if(strchr(element->path, '/') != NULL)
|
||||||
|
tempname = strrchr(element->path, '/') + 1;
|
||||||
|
const char *coverFolder = m_plugin.GetCoverFolderName(element->settings[0]);
|
||||||
|
if(strlen(coverFolder) > 0)
|
||||||
|
return fmt("%s/%s/%s.png", m_boxPicDir.c_str(), coverFolder, tempname);
|
||||||
|
else
|
||||||
|
return fmt("%s/%s.png", m_boxPicDir.c_str(), tempname);
|
||||||
|
}
|
||||||
|
else if(element->type == TYPE_HOMEBREW)
|
||||||
|
return fmt("%s/%s.png", m_boxPicDir.c_str(), strrchr(element->path, '/') + 1);
|
||||||
|
return fmt("%s/%s.png", m_boxPicDir.c_str(), element->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *CMenu::getFrontPath(const dir_discHdr *element)
|
||||||
|
{
|
||||||
|
if(element->type == TYPE_PLUGIN)
|
||||||
|
{
|
||||||
|
const char *tempname = element->path;
|
||||||
|
if(strchr(element->path, '/') != NULL)
|
||||||
|
tempname = strrchr(element->path, '/') + 1;
|
||||||
|
const char *coverFolder = m_plugin.GetCoverFolderName(element->settings[0]);
|
||||||
|
if(strlen(coverFolder) > 0)
|
||||||
|
return fmt("%s/%s/%s.png", m_picDir.c_str(), coverFolder, tempname);
|
||||||
|
else
|
||||||
|
return fmt("%s/%s.png", m_picDir.c_str(), tempname);
|
||||||
|
}
|
||||||
|
else if(element->type == TYPE_HOMEBREW)
|
||||||
|
return fmt("%s/icon.png", element->path);
|
||||||
|
return fmt("%s/%s.png", m_picDir.c_str(), element->id);
|
||||||
|
}
|
||||||
|
@ -42,6 +42,11 @@ public:
|
|||||||
void cleanup(void);
|
void cleanup(void);
|
||||||
void loadDefaultFont(void);
|
void loadDefaultFont(void);
|
||||||
void TempLoadIOS(int IOS = 0);
|
void TempLoadIOS(int IOS = 0);
|
||||||
|
|
||||||
|
const char *getBoxPath(const dir_discHdr *element);
|
||||||
|
const char *getFrontPath(const dir_discHdr *element);
|
||||||
|
const char *getBlankCoverPath(const dir_discHdr *element);
|
||||||
|
|
||||||
u8 m_current_view;
|
u8 m_current_view;
|
||||||
int m_last_view;
|
int m_last_view;
|
||||||
u8 enabledPluginPos;
|
u8 enabledPluginPos;
|
||||||
@ -1107,6 +1112,8 @@ private:
|
|||||||
static const u32 SVN_REV_NUM;
|
static const u32 SVN_REV_NUM;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern CMenu mainMenu;
|
||||||
|
|
||||||
#define ARRAY_SIZE(a) (sizeof a / sizeof a[0])
|
#define ARRAY_SIZE(a) (sizeof a / sizeof a[0])
|
||||||
|
|
||||||
#endif // !defined(__MENU_HPP)
|
#endif // !defined(__MENU_HPP)
|
||||||
|
Loading…
Reference in New Issue
Block a user