diff --git a/out/bins/ext_booter.bin b/out/bins/ext_booter.bin index b452d68c..33cb07b3 100644 Binary files a/out/bins/ext_booter.bin and b/out/bins/ext_booter.bin differ diff --git a/out/boot.dol b/out/boot.dol index d6100d5b..78cf1d11 100644 Binary files a/out/boot.dol and b/out/boot.dol differ diff --git a/source/defines.h b/source/defines.h index 1ff7ebae..ffa61137 100644 --- a/source/defines.h +++ b/source/defines.h @@ -1,6 +1,6 @@ #define APP_NAME "WiiFlow WFL" -#define APP_VERSION "5.4.0" +#define APP_VERSION "5.4.1" #define APP_DATA_DIR "wiiflow" #define APPS_DIR "apps/wiiflow" diff --git a/source/gc/gc.cpp b/source/gc/gc.cpp index d4e84ec2..6ac38d68 100644 --- a/source/gc/gc.cpp +++ b/source/gc/gc.cpp @@ -72,6 +72,7 @@ u8 get_wii_language() // Nintendont NIN_CFG NinCfg; +bool slippi; /* since Nintendont v1.98 argsboot is supported. since v3.324 '$$Version:' string was added for loaders to detect. @@ -90,9 +91,13 @@ void Nintendont_SetOptions(const char *gamePath, const char *gameID, const char u32 NIN_cfg_version = NIN_CFG_VERSION; char NINVersion[7]= ""; u32 NINRev = 0; + const char *dol_path = NULL; for(u8 i = SD; i < MAXDEVICES; ++i) { - const char *dol_path = fmt(NIN_LOADER_PATH, DeviceName[i]); + if(slippi) + dol_path = fmt(NIN_SLIPPI_PATH, DeviceName[i]); + else + dol_path = fmt(NIN_LOADER_PATH, DeviceName[i]); if(!fsop_FileExist(dol_path)) continue; u8 *buffer = NULL; @@ -213,12 +218,17 @@ bool Nintendont_Installed() return false; } -bool Nintendont_GetLoader() +bool Nintendont_GetLoader(bool use_slippi) { + slippi = use_slippi; bool ret = false; + const char *dol_path = NULL; for(u8 i = SD; i < MAXDEVICES; ++i) { - const char *dol_path = fmt(NIN_LOADER_PATH, DeviceName[i]); + if(slippi) + dol_path = fmt(NIN_SLIPPI_PATH, DeviceName[i]); + else + dol_path = fmt(NIN_LOADER_PATH, DeviceName[i]); ret = (LoadHomebrew(dol_path) == 1); if(ret == true) { diff --git a/source/gc/gc.hpp b/source/gc/gc.hpp index 009ea869..7225492d 100644 --- a/source/gc/gc.hpp +++ b/source/gc/gc.hpp @@ -22,9 +22,10 @@ // Nintendont #include "nin_cfg.h" #define NIN_LOADER_PATH "%s:/apps/nintendont/boot.dol" +#define NIN_SLIPPI_PATH "%s:/apps/nintendont slippi/boot.dol" bool Nintendont_Installed(); -bool Nintendont_GetLoader(); +bool Nintendont_GetLoader(bool use_slippi); void Nintendont_SetOptions(const char *gamePath, const char *gameID, const char *CheatPath, u8 lang, u32 n_cfg, u32 n_vm, s8 vidscale, s8 vidoffset, u8 netprofile); diff --git a/source/gui/GameTDB.cpp b/source/gui/GameTDB.cpp index 4c5de27a..8e226180 100644 --- a/source/gui/GameTDB.cpp +++ b/source/gui/GameTDB.cpp @@ -841,6 +841,7 @@ int GameTDB::GetWifiPlayers(const char *id) players = atoi(PlayersNode); + MEM2_free(data); return players; } @@ -912,6 +913,7 @@ int GameTDB::GetPlayers(const char *id) players = atoi(PlayersNode); + MEM2_free(data); return players; } @@ -1005,15 +1007,16 @@ int GameTDB::GetCaseVersions(const char *id) return altcase; } - char *PlayersNode = GetNodeText(data, "case versions=\"", "\""); - if(!PlayersNode) + char *CaseVersionsNode = GetNodeText(data, "case versions=\"", "\""); + if(!CaseVersionsNode) { MEM2_free(data); return altcase; } - altcase = atoi(PlayersNode); + altcase = atoi(CaseVersionsNode); + MEM2_free(data); return altcase; } diff --git a/source/gui/video.cpp b/source/gui/video.cpp index d15200e2..5deffed8 100644 --- a/source/gui/video.cpp +++ b/source/gui/video.cpp @@ -272,7 +272,7 @@ void CVideo::setup2DProjection(bool setViewPort, bool noScale) if (setViewPort) _setViewPort(0, 0, m_rmode->fbWidth, m_rmode->efbHeight); - guOrtho(projMtx, y, height2D + y, x, width2D + x, 0.f, 1000.0f); + guOrtho(projMtx, y, height2D - 1 + y, x, width2D - 1 + x, 0.f, 1000.0f); GX_LoadProjectionMtx(projMtx, GX_ORTHOGRAPHIC); } @@ -299,7 +299,8 @@ void CVideo::set2DViewport(u32 w, u32 h, int x, int y) } /* this takes what is drawn in the frame buffer and copies it to make a new texture/image set as whatever TexData &tex is */ -/* this is used by coverflow and updatebg */ +/* this is used by updatebg to fade old bg into new bg */ +/* and coverflow after drawing bg and covers to make mirror bg with blur */ void CVideo::renderToTexture(TexData &tex, bool clear) { if(tex.data == NULL) diff --git a/source/list/ListGenerator.cpp b/source/list/ListGenerator.cpp index dbf9730c..c58acec4 100644 --- a/source/list/ListGenerator.cpp +++ b/source/list/ListGenerator.cpp @@ -296,7 +296,79 @@ static void Add_Plugin_Game(char *FullPath) m_cacheList.push_back(ListElement); } -/* note: scummvm games have list generator in plugin.cpp */ +/* notes: "description" is used as the title because it basically is the title */ +/* the [GameDomain] is used as the path even though it isn't the path */ +/* the [GameDomain] is usually short without any '/' */ +/* in scummvm.ini the path is the path without the exe or main app file added on */ +void ListGenerator::ParseScummvmINI(Config &ini, const char *Device, const char *datadir, const char *platform, const string& DBName, bool UpdateCache) +{ + Clear(); + if(!DBName.empty()) + { + if(UpdateCache) + fsop_deleteFile(DBName.c_str()); + else + { + CCache(*this, DBName, LOAD); + if(!this->empty()) + return; + fsop_deleteFile(DBName.c_str()); + } + } + + gprintf("Parsing scummvm.ini\n"); + if(!ini.loaded()) + return; + + Config m_crc; + if(platform != NULL) + m_crc.load(fmt("%s/%s/%s.ini", datadir, platform, platform)); + + const char *GameDomain = ini.firstDomain().c_str(); + while(1) + { + if(strlen(GameDomain) < 2) + break; + char GameName[64]; + memset(GameName, 0, sizeof(GameName)); + strncpy(GameName, ini.getString(GameDomain, "description").c_str(), 63); + if(strlen(GameName) < 2 || strncasecmp(Device, ini.getString(GameDomain, "path").c_str(), 2) != 0) + { + GameDomain = ini.nextDomain().c_str(); + continue; + } + + /* get shortName */ + char *cp; + if((cp = strstr(GameName, " (")) != NULL) + *cp = '\0'; + + /* get Game ID */ + string GameID = "PLUGIN"; + // Get game ID based on GameName + if(m_crc.loaded() && m_crc.has(platform, GameName)) + { + vector searchID = m_crc.getStrings(platform, GameName, '|'); + if(!searchID[0].empty()) + GameID = searchID[0]; + } + + memset((void*)&ListElement, 0, sizeof(dir_discHdr)); + memcpy(ListElement.id, GameID.c_str(), 6); + mbstowcs(ListElement.title, GameName, 63); + strncpy(ListElement.path, GameDomain, sizeof(ListElement.path)); + ListElement.settings[0] = m_cacheList.Magic; //scummvm magic + ListElement.casecolor = m_cacheList.Color; + ListElement.type = TYPE_PLUGIN; + m_cacheList.push_back(ListElement); + GameDomain = ini.nextDomain().c_str(); + } + m_crc.unload(); + if(!this->empty() && !DBName.empty()) /* Write a new Cache */ + CCache(*this, DBName, SAVE); +} + +/* note: scummvm games are parsed above */ void ListGenerator::CreateRomList(Config &platform_cfg, const string& romsDir, const vector& FileTypes, const string& DBName, bool UpdateCache) { Clear(); @@ -313,6 +385,7 @@ void ListGenerator::CreateRomList(Config &platform_cfg, const string& romsDir, c } } + platformName = ""; if(platform_cfg.loaded()) { /* Search platform.ini to find plugin magic to get platformName */ @@ -344,8 +417,7 @@ void ListGenerator::CreateRomList(Config &platform_cfg, const string& romsDir, c CCache(*this, DBName, SAVE); } -void ListGenerator::CreateList(u32 Flow, const string& Path, const vector& FileTypes, - const string& DBName, bool UpdateCache) +void ListGenerator::CreateList(u32 Flow, const string& Path, const vector& FileTypes, const string& DBName, bool UpdateCache) { Clear(); if(!DBName.empty()) diff --git a/source/list/ListGenerator.hpp b/source/list/ListGenerator.hpp index c008d988..7846aee0 100644 --- a/source/list/ListGenerator.hpp +++ b/source/list/ListGenerator.hpp @@ -37,6 +37,7 @@ public: void createSFList(u8 maxBtns, Config &m_sourceMenuCfg, const string& sourceDir); void Init(const char *settingsDir, const char *Language, const char *plgnsDataDir); void Clear(); + void ParseScummvmINI(Config &ini, const char *Device, const char *datadir, const char *platform, const string& DBName, bool UpdateCache); void CreateRomList(Config &platform_cfg, const string& romsDir, const vector& FileTypes, const string& DBName, bool UpdateCache); void CreateList(u32 Flow, const string& Path, const vector& FileTypes, const string& DBName, bool UpdateCache); u32 Color; diff --git a/source/menu/menu.cpp b/source/menu/menu.cpp index e7ab81d4..d675129e 100644 --- a/source/menu/menu.cpp +++ b/source/menu/menu.cpp @@ -1641,9 +1641,9 @@ void CMenu::_mainLoopCommon(bool withCF, bool adjusting) MusicPlayer.Pause();//note - bg music is paused but sound thread is still running. so banner gamesound still plays m_btnMgr.tick(); m_vid.prepare(); - m_vid.setup2DProjection(false, true); + m_vid.setup2DProjection(false, true);// false = prepare() already set view port, true = no scaling - draw at 640x480 _updateBg(); - m_vid.setup2DProjection(); + m_vid.setup2DProjection();// this time set the view port and allow scaling _drawBg(); m_btnMgr.draw(); m_vid.render(); @@ -1680,7 +1680,6 @@ void CMenu::_mainLoopCommon(bool withCF, bool adjusting) CoverFlow.draw(); m_vid.setup2DProjection(false, true); CoverFlow.drawEffect(); - //if(startGameSound == 1 && !m_soundThrdBusy && !m_banner.GetSelectedGame() && !m_snapshot_loaded) if(!m_soundThrdBusy && !m_banner.GetSelectedGame() && !m_snapshot_loaded) CoverFlow.drawText(adjusting); m_vid.renderAAPass(i); @@ -2524,7 +2523,9 @@ bool CMenu::_loadPluginList() } else { - vector scummvmList; + string cachedListFile(fmt("%s/%s_%s.db", m_listCacheDir.c_str(), DeviceName[currentPartition], m_plugin.PluginMagicWord)); + if(updateCache || !fsop_FileExist(cachedListFile.c_str())) + cacheCovers = true; Config scummvm; if(!scummvm.load(fmt("%s/scummvm.ini", m_pluginsDir.c_str()))) { @@ -2534,11 +2535,11 @@ bool CMenu::_loadPluginList() string platformName = ""; if(m_platform.loaded())/* convert plugin magic to platform name */ platformName = m_platform.getString("PLUGINS", m_plugin.PluginMagicWord); - scummvmList = m_plugin.ParseScummvmINI(scummvm, DeviceName[currentPartition], Magic, m_pluginDataDir.c_str(), platformName.c_str()); - for(vector::iterator tmp_itr = scummvmList.begin(); tmp_itr != scummvmList.end(); tmp_itr++) + m_cacheList.Color = m_plugin.GetCaseColor(i); + m_cacheList.Magic = Magic; + m_cacheList.ParseScummvmINI(scummvm, DeviceName[currentPartition], m_pluginDataDir.c_str(), platformName.c_str(), cachedListFile, updateCache); + for(vector::iterator tmp_itr = m_cacheList.begin(); tmp_itr != m_cacheList.end(); tmp_itr++) m_gameList.push_back(*tmp_itr); - scummvmList.clear(); - vector().swap(scummvmList); scummvm.unload(); } } diff --git a/source/menu/menu.hpp b/source/menu/menu.hpp index 2269d953..b731a273 100644 --- a/source/menu/menu.hpp +++ b/source/menu/menu.hpp @@ -660,6 +660,8 @@ private: s16 m_gameinfoLblOverlay; s16 m_gameLblSnap; s16 m_gameLblOverlay; + TexData m_game_snap; + TexData m_game_overlay; TexData m_snap; TexData m_cart; TexData m_overlay; @@ -1104,7 +1106,7 @@ private: void _about(bool help = false); bool _wbfsOp(WBFS_OP op); void _cfTheme(void); - void _gameinfo(void); + bool _gameinfo(void); void _gameSettings(const dir_discHdr *GameHdr, bool disc = false); void _CoverBanner(void); int _cacheCovers(void); @@ -1129,7 +1131,7 @@ private: bool _srcTierBack(bool home); void _srcTierLoad(string fn); void _restoreSrcTiers(); - void _setSrcFlowBg(); + void _getSFlowBgTex(); void _mainLoopCommon(bool withCF = false, bool adjusting = false); void _netInit(); void _loadDefaultFont(void); diff --git a/source/menu/menu_game.cpp b/source/menu/menu_game.cpp index 309f17db..a8ea9dbc 100644 --- a/source/menu/menu_game.cpp +++ b/source/menu/menu_game.cpp @@ -505,8 +505,12 @@ void CMenu::_game(bool launch) { _hideGame(); m_banner.SetShowBanner(false); - _gameinfo(); + m_gameSelected = false; + launch = _gameinfo(); + m_gameSelected = true; _showGame(); + if(m_newGame) + startGameSound = -10; m_banner.SetShowBanner(true); } /* play or stop a trailer video */ @@ -930,8 +934,8 @@ void CMenu::_game(bool launch) TexData emptyTex; m_btnMgr.setTexture(m_gameLblSnap, emptyTex); m_btnMgr.setTexture(m_gameLblOverlay, emptyTex); - TexHandle.Cleanup(m_snap); - TexHandle.Cleanup(m_overlay); + TexHandle.Cleanup(m_game_snap); + TexHandle.Cleanup(m_game_overlay); m_gameSelected = false; MEM2_free(hdr); _hideGame(); @@ -988,8 +992,8 @@ void CMenu::_initGameMenu() m_gameBtnToggle = _addPicButton("GAME/TOOGLE_BTN", texToggleBanner, texToggleBanner, 385, 31, 246, 135); m_gameBtnToggleFull = _addPicButton("GAME/TOOGLE_FULL_BTN", texToggleBanner, texToggleBanner, 20, 12, 608, 344); m_gameLblSnapBg = _addLabel("GAME/SNAP_BG", theme.txtFont, L"", 385, 31, 246, 170, theme.txtFontColor, 0, texSnapShotBg); - m_gameLblSnap = _addLabel("GAME/SNAP", theme.txtFont, L"", 385, 31, 100, 100, theme.txtFontColor, 0, m_snap); - m_gameLblOverlay = _addLabel("GAME/OVERLAY", theme.txtFont, L"", 385, 31, 100, 100, theme.txtFontColor, 0, m_overlay); + m_gameLblSnap = _addLabel("GAME/SNAP", theme.txtFont, L"", 385, 31, 100, 100, theme.txtFontColor, 0, m_game_snap); + m_gameLblOverlay = _addLabel("GAME/OVERLAY", theme.txtFont, L"", 385, 31, 100, 100, theme.txtFontColor, 0, m_game_overlay); // 8 pixel width frames m_gameLblSnapFrame = _addLabel("GAME/SNAP_FRAME", theme.txtFont, L"", 377, 23, 262, 186, theme.txtFontColor, 0, texSnapShotFrame); m_gameLblBannerFrame = _addLabel("GAME/BANNER_FRAME", theme.txtFont, L"", 377, 23, 262, 151, theme.txtFontColor, 0, texBannerFrame); @@ -1168,10 +1172,10 @@ void * CMenu::_gameSoundThread(void *obj) if(fsop_FileExist(snap_path)) { m->m_snapshot_loaded = true; - TexHandle.fromImageFile(m->m_snap, snap_path); + TexHandle.fromImageFile(m->m_game_snap, snap_path); /* get snapshot position and dimensions to center it on the snap background */ - int snap_w = m->m_snap.width; - int snap_h = m->m_snap.height; + int snap_w = m->m_game_snap.width; + int snap_h = m->m_game_snap.height; int width_over = snap_w - m->snapbg_w; int height_over = snap_h - m->snapbg_h; float aspect_ratio = (float)snap_w / (float)snap_h; @@ -1191,24 +1195,24 @@ void * CMenu::_gameSoundThread(void *obj) int x_pos = (m->snapbg_w - snap_w) / 2 + m->snapbg_x; int y_pos = (m->snapbg_h - snap_h) / 2 + m->snapbg_y; - m_btnMgr.setTexture(m->m_gameLblSnap, m->m_snap, x_pos, y_pos, snap_w, snap_h); + m_btnMgr.setTexture(m->m_gameLblSnap, m->m_game_snap, x_pos, y_pos, snap_w, snap_h); /* get possible overlay */ const char *overlay_path = fmt("%s/%s_overlay.png", m->m_snapDir.c_str(), platformName); if(fsop_FileExist(overlay_path)) { - TexHandle.fromImageFile(m->m_overlay, overlay_path); - m_btnMgr.setTexture(m->m_gameLblOverlay, m->m_overlay, x_pos, y_pos, snap_w, snap_h); + TexHandle.fromImageFile(m->m_game_overlay, overlay_path); + m_btnMgr.setTexture(m->m_gameLblOverlay, m->m_game_overlay, x_pos, y_pos, snap_w, snap_h); } else - TexHandle.Cleanup(m->m_overlay); + TexHandle.Cleanup(m->m_game_overlay); } } } if(!m->m_snapshot_loaded) { - TexHandle.Cleanup(m->m_snap); - TexHandle.Cleanup(m->m_overlay); + TexHandle.Cleanup(m->m_game_snap); + TexHandle.Cleanup(m->m_game_overlay); } } if(custom_bnr_size == 0 || custom_bnr_file == NULL) diff --git a/source/menu/menu_game_boot.cpp b/source/menu/menu_game_boot.cpp index 8976c1c3..19eb865a 100644 --- a/source/menu/menu_game_boot.cpp +++ b/source/menu/menu_game_boot.cpp @@ -427,6 +427,9 @@ void CMenu::_launchGC(dir_discHdr *hdr, bool disc) u8 netprofile = 0; if(!IsOnWiiU()) netprofile = m_gcfg2.getUInt(id, "net_profile", 0); + // project slippi is a mod of nintendont to play patched version of smash bros melee + bool use_slippi = (m_cfg.getBool(GC_DOMAIN, "use_slippi", false) && strncasecmp(hdr->id, "GAL", 3) == 0); + gprintf("use slippi %s\n", use_slippi ? "yes" : "no"); /* configs no longer needed */ m_gcfg1.save(true); @@ -434,7 +437,7 @@ void CMenu::_launchGC(dir_discHdr *hdr, bool disc) m_cat.save(true); m_cfg.save(true); - bool ret = (Nintendont_GetLoader() && LoadAppBooter(fmt("%s/app_booter.bin", m_binsDir.c_str()))); + bool ret = (Nintendont_GetLoader(use_slippi) && LoadAppBooter(fmt("%s/app_booter.bin", m_binsDir.c_str()))); if(ret == false) { error(_t("errgame14", L"app_booter.bin not found!")); diff --git a/source/menu/menu_gameinfo.cpp b/source/menu/menu_gameinfo.cpp index 97f430ab..2bd77206 100644 --- a/source/menu/menu_gameinfo.cpp +++ b/source/menu/menu_gameinfo.cpp @@ -18,23 +18,50 @@ int synopsis_h; int rominfo_h; int rominfo_th = 0; -void CMenu::_gameinfo(void) +bool CMenu::_gameinfo(void) { u8 page = 1; int pixels_to_skip = 10; int amount_of_skips = 0; int xtra_skips = 0; int synopsis_th = 0; - + bool launchGame = false; + SetupInput(); _showGameInfo(); while(!m_exit) { _mainLoopCommon(); - if(BTN_HOME_PRESSED || BTN_B_PRESSED || !tdb_found) + CoverFlow.tick(); + if(BTN_HOME_PRESSED || BTN_B_PRESSED) break; - if((BTN_DOWN_PRESSED || BTN_DOWN_HELD)) + else if(BTN_PLUS_PRESSED) + { + _hideGameInfo(false); + CoverFlow.right(); + m_newGame = true; + page = 1; + amount_of_skips = 0; + xtra_skips = 0; + _showGameInfo(); + } + else if(BTN_MINUS_PRESSED) + { + _hideGameInfo(false); + CoverFlow.left(); + m_newGame = true; + page = 1; + amount_of_skips = 0; + xtra_skips = 0; + _showGameInfo(); + } + else if(BTN_A_PRESSED) + { + launchGame = true; + break; + } + else if((BTN_DOWN_PRESSED || BTN_DOWN_HELD)) { if(page == 2 && synopsis_th > synopsis_h) { @@ -179,11 +206,9 @@ void CMenu::_gameinfo(void) } _hideGameInfo(false); TexHandle.Cleanup(m_cart); - if(m_banner.GetSelectedGame())// if banner is available we need to clear snap and overlay here. - { - TexHandle.Cleanup(m_snap); - TexHandle.Cleanup(m_overlay); - } + TexHandle.Cleanup(m_snap); + TexHandle.Cleanup(m_overlay); + return launchGame; } void CMenu::_hideGameInfo(bool instant) @@ -221,11 +246,16 @@ void CMenu::_showGameInfo(void) _textGameInfo(); - if(tdb_found) + m_btnMgr.show(m_gameinfoLblTitle); + + if(CoverFlow.getHdr()->type == TYPE_PLUGIN) { - m_btnMgr.show(m_gameinfoLblTitle); - - if(CoverFlow.getHdr()->type == TYPE_PLUGIN) + if(!tdb_found) + { + m_btnMgr.setText(m_gameinfoLblRomInfo, _t("errgame18", L"No game info!")); + m_btnMgr.show(m_gameinfoLblRomInfo); + } + else { m_btnMgr.reset(m_gameinfoLblRomInfo); m_btnMgr.show(m_gameinfoLblRomInfo, false); @@ -235,6 +265,14 @@ void CMenu::_showGameInfo(void) m_btnMgr.show(m_gameinfoLblCartDisk); m_btnMgr.show(m_gameinfoLblOverlay); } + } + else + { + if(!tdb_found) + { + m_btnMgr.setText(m_gameinfoLblID, _t("errgame18", L"No game info!")); + m_btnMgr.show(m_gameinfoLblID); + } else { m_btnMgr.show(m_gameinfoLblID); @@ -246,21 +284,19 @@ void CMenu::_showGameInfo(void) m_btnMgr.show(m_gameinfoLblGenre); m_btnMgr.show(m_gameinfoLblWifiplayers); } - - for(u8 i = 0; i < ARRAY_SIZE(m_gameinfoLblUser); ++i) - if(i < ARRAY_SIZE(m_gameinfoLblUser) / 2) - m_btnMgr.show(m_gameinfoLblUser[i]); - - for(u8 i = 0; i < ARRAY_SIZE(m_gameinfoLblControlsReq); ++i) - if(m_gameinfoLblControlsReq[i] != -1 && i < cnt_controlsreq) - m_btnMgr.show(m_gameinfoLblControlsReq[i]); - - for(u8 i = 0; i < ARRAY_SIZE(m_gameinfoLblControls); ++i) - if(m_gameinfoLblControls[i] != -1 && i < cnt_controls) - m_btnMgr.show(m_gameinfoLblControls[i]); } - else - error(_t("errgame18", L"No game info!")); + + for(u8 i = 0; i < ARRAY_SIZE(m_gameinfoLblUser); ++i) + if(i < ARRAY_SIZE(m_gameinfoLblUser) / 2) + m_btnMgr.show(m_gameinfoLblUser[i]); + + for(u8 i = 0; i < ARRAY_SIZE(m_gameinfoLblControlsReq); ++i) + if(m_gameinfoLblControlsReq[i] != -1 && i < cnt_controlsreq) + m_btnMgr.show(m_gameinfoLblControlsReq[i]); + + for(u8 i = 0; i < ARRAY_SIZE(m_gameinfoLblControls); ++i) + if(m_gameinfoLblControls[i] != -1 && i < cnt_controls) + m_btnMgr.show(m_gameinfoLblControls[i]); } void CMenu::_initGameInfoMenu() @@ -342,6 +378,9 @@ void CMenu::_textGameInfo(void) // We can't use magic # directly since it'd require hardcoding values and a # can be several systems(genplus) // We can't rely on coverfolder either. Different systems can share the same folder. Or combined plugins used for the same system. + // Get title + m_btnMgr.setText(m_gameinfoLblTitle, GameHdr->title); + /* is platform.ini available? */ if(!m_platform.loaded()) return;// no platform.ini found @@ -387,37 +426,27 @@ void CMenu::_textGameInfo(void) m_btnMgr.setTexture(m_gameinfoLblCartDisk, emptyTex); m_btnMgr.setTexture(m_gameinfoLblOverlay, emptyTex); - if(m_banner.GetSelectedGame()) - { - const char *snap_path = NULL; - if(strcasestr(platformName, "ARCADE") || strcasestr(platformName, "CPS") || !strncasecmp(platformName, "NEOGEO", 6)) - snap_path = fmt("%s/%s/%s.png", m_snapDir.c_str(), platformName, ShortName.c_str()); - else if(gametdb.GetName(GameID, TMP_Char)) - snap_path = fmt("%s/%s/%s.png", m_snapDir.c_str(), platformName, TMP_Char); - - if(snap_path == NULL || !fsop_FileExist(snap_path)) - snap_path = fmt("%s/%s/%s.png", m_snapDir.c_str(), platformName, GameID); + const char *snap_path = NULL; + if(strcasestr(platformName, "ARCADE") || strcasestr(platformName, "CPS") || !strncasecmp(platformName, "NEOGEO", 6)) + snap_path = fmt("%s/%s/%s.png", m_snapDir.c_str(), platformName, ShortName.c_str()); + else if(gametdb.GetName(GameID, TMP_Char)) + snap_path = fmt("%s/%s/%s.png", m_snapDir.c_str(), platformName, TMP_Char); + + if(snap_path == NULL || !fsop_FileExist(snap_path)) + snap_path = fmt("%s/%s/%s.png", m_snapDir.c_str(), platformName, GameID); - if(fsop_FileExist(snap_path)) - { - TexHandle.fromImageFile(m_snap, snap_path); - m_btnMgr.setTexture(m_gameinfoLblSnap, m_snap, m_snap.width, m_snap.height); - } - } - else if(m_snap.data != NULL) - m_btnMgr.setTexture(m_gameinfoLblSnap, m_snap, m_snap.width, m_snap.height); - - if(m_banner.GetSelectedGame()) + if(fsop_FileExist(snap_path)) { - const char *overlay_path = fmt("%s/%s_overlay.png", m_snapDir.c_str(), platformName); - if(fsop_FileExist(overlay_path)) - { - TexHandle.fromImageFile(m_overlay, overlay_path); - m_btnMgr.setTexture(m_gameinfoLblOverlay, m_overlay, m_overlay.width, m_overlay.height); - } + TexHandle.fromImageFile(m_snap, snap_path); + m_btnMgr.setTexture(m_gameinfoLblSnap, m_snap, m_snap.width, m_snap.height); } - else if(m_overlay.data != NULL) + + const char *overlay_path = fmt("%s/%s_overlay.png", m_snapDir.c_str(), platformName); + if(fsop_FileExist(overlay_path)) + { + TexHandle.fromImageFile(m_overlay, overlay_path); m_btnMgr.setTexture(m_gameinfoLblOverlay, m_overlay, m_overlay.width, m_overlay.height); + } const char *cart_path = NULL; if(strcasestr(platformName, "ARCADE") || strcasestr(platformName, "CPS") || !strncasecmp(platformName, "NEOGEO", 6)) @@ -439,9 +468,6 @@ void CMenu::_textGameInfo(void) else TexHandle.Cleanup(m_cart); - // Get title - m_btnMgr.setText(m_gameinfoLblTitle, GameHdr->title); - // Get Synopsis if(gametdb.GetSynopsis(GameID, TMP_Char)) gameinfo_Synopsis_w.fromUTF8(TMP_Char); @@ -545,6 +571,8 @@ void CMenu::_textGameInfo(void) /******************* Wii and GameCube game infos **********************/ + m_btnMgr.setText(m_gameinfoLblTitle, GameHdr->title); + gametdb.OpenFile(fmt("%s/wiitdb.xml", m_settingsDir.c_str())); tdb_found = gametdb.IsLoaded(); if(!tdb_found) @@ -554,7 +582,6 @@ void CMenu::_textGameInfo(void) strncpy(GameID, CoverFlow.getId(), 6); - m_btnMgr.setText(m_gameinfoLblTitle, GameHdr->title); /*if(gametdb.GetTitle(GameID, TMP_Char)) { gameinfo_Title_w.fromUTF8(TMP_Char); diff --git a/source/menu/menu_home.cpp b/source/menu/menu_home.cpp index 517dee2b..f4956217 100644 --- a/source/menu/menu_home.cpp +++ b/source/menu/menu_home.cpp @@ -498,11 +498,8 @@ int CMenu::_cacheCovers() m_thrdMessage = wfmt(_fmt("dlmsg31", L"converting cover %i of %i"), index, total); m_thrdMessageAdded = true; - /* get game name or ID */ - const char *gameNameOrID = NULL; - gameNameOrID = CoverFlow.getFilenameId(&(*hdr));// &(*hdr) converts iterator to pointer to mem address - /* get cover png path */ + bool blankCover = false; bool fullCover = true; strlcpy(coverPath, getBoxPath(&(*hdr)), sizeof(coverPath)); if(!fsop_FileExist(coverPath) || smallBox) @@ -513,7 +510,7 @@ int CMenu::_cacheCovers() { fullCover = true; strlcpy(coverPath, getBlankCoverPath(&(*hdr)), sizeof(coverPath)); - gameNameOrID = strrchr(coverPath, '/') + 1; + blankCover = true; if(!fsop_FileExist(coverPath)) continue; } @@ -529,6 +526,13 @@ int CMenu::_cacheCovers() else snprintf(cachePath, sizeof(cachePath), "%s", m_cacheDir.c_str()); + /* get game name or ID */ + const char *gameNameOrID = NULL; + if(!blankCover) + gameNameOrID = CoverFlow.getFilenameId(&(*hdr));// &(*hdr) converts iterator to pointer to mem address + else + gameNameOrID = strrchr(coverPath, '/') + 1; + /* get cover wfc path */ if(smallBox) snprintf(wfcPath, sizeof(wfcPath), "%s/%s_small.wfc", cachePath, gameNameOrID); diff --git a/source/menu/menu_main.cpp b/source/menu/menu_main.cpp index a8d9df3f..fbb5b4c3 100644 --- a/source/menu/menu_main.cpp +++ b/source/menu/menu_main.cpp @@ -44,14 +44,11 @@ void CMenu::_hideMain(bool instant) void CMenu::_getCustomBgTex() { - curCustBg += 1; - if(curCustBg == 2) - curCustBg = 0; if(m_sourceflow) - _setSrcFlowBg(); + _getSFlowBgTex(); else { - TexHandle.Cleanup(m_mainCustomBg[curCustBg]); + curCustBg = loopNum(curCustBg + 1, 2); string fn = ""; if(m_platform.loaded()) { @@ -94,6 +91,7 @@ void CMenu::_getCustomBgTex() { if(TexHandle.fromImageFile(m_mainCustomBg[curCustBg], fmt("%s/%s.jpg", m_bckgrndsDir.c_str(), fn.c_str())) != TE_OK) { + curCustBg = loopNum(curCustBg + 1, 2);// reset it customBg = false; return; } @@ -103,7 +101,10 @@ void CMenu::_getCustomBgTex() customBg = true; } else + { + curCustBg = loopNum(curCustBg + 1, 2);// reset it customBg = false; + } } } @@ -394,9 +395,12 @@ int CMenu::main(void) gprintf("Bootup completed!\n"); - m_refreshGameList = true; - _getCustomBgTex(); - _showMain(); + if(!m_source_on_start) + { + _getCustomBgTex(); + _setMainBg(); + _showCF(true); + } if(show_mem) { m_btnMgr.show(m_mem1FreeSize); @@ -421,15 +425,14 @@ int CMenu::main(void) { if(m_sourceflow)//back a tier or exit sourceflow { - m_refreshGameList = true; - if(!_srcTierBack(false))// back a tier + if(!_srcTierBack(false))// not back a tier - exit sourceflow and return to coverflow { - // not back a tier - exit sourceflow and return to coverflow _restoreSrcTiers(); - m_sourceflow = false;// if not back a tier then exit sourceflow + m_sourceflow = false; } _getCustomBgTex(); - _showMain(); + _setMainBg(); + _showCF(true);//refresh coverflow or sourceflow list continue; } else if(m_use_source)//if source_menu enabled @@ -437,12 +440,12 @@ int CMenu::main(void) _hideMain(); if(m_cfg.getBool(SOURCEFLOW_DOMAIN, "enabled", false))//if sourceflow show it { - m_refreshGameList = true; sm_numbers_backup = m_cfg.getString(SOURCEFLOW_DOMAIN, "numbers");//backup for possible restore later sm_tiers_backup = m_cfg.getString(SOURCEFLOW_DOMAIN, "tiers"); m_sourceflow = true; _getCustomBgTex(); - _showMain(); + _setMainBg(); + _showCF(true);//refresh sourceflow list } else //show source menu { @@ -450,7 +453,8 @@ int CMenu::main(void) if(BTN_B_HELD) bUsed = true; _getCustomBgTex(); - _showMain(); + _setMainBg(); + _showCF(m_refreshGameList);//refresh coverflow list if new source selected } continue; } @@ -460,14 +464,14 @@ int CMenu::main(void) { if(m_sourceflow)//back to base tier or exit sourceflow { - m_refreshGameList = true; if(!_srcTierBack(true))// if already on base tier exit sourceflow { _restoreSrcTiers(); m_sourceflow = false; } _getCustomBgTex(); - _showMain(); + _setMainBg(); + _showCF(true);//refresh coverflow or sourceflow list } else { @@ -608,10 +612,10 @@ int CMenu::main(void) _hideMain(); if(m_sourceflow) { - m_refreshGameList = true; - _sourceFlow();// set the source selected + _sourceFlow();// set the source selected or new source tier _getCustomBgTex(); - _showMain(); + _setMainBg(); + _showCF(true);// refresh coverflow or sourceflow list continue; } else @@ -625,11 +629,10 @@ int CMenu::main(void) bUsed = true; } _setMainBg(); - if(m_refreshGameList) + if(m_refreshGameList)// if changes were made to favorites, parental lock, or categories { - /* if changes were made to favorites, parental lock, or categories */ - _initCF(); m_refreshGameList = false; + _initCF(); } else CoverFlow.cancel(); diff --git a/source/menu/menu_source.cpp b/source/menu/menu_source.cpp index 724fcc82..ddc4b8dc 100644 --- a/source/menu/menu_source.cpp +++ b/source/menu/menu_source.cpp @@ -25,6 +25,11 @@ int curflow = 1; bool sm_tier = false; int channels_type; +static inline int loopNum(int i, int s) +{ + return (i + s) % s; +} + /* this is what happens when a sourceflow cover is clicked on */ void CMenu::_sourceFlow() { @@ -106,29 +111,7 @@ void CMenu::_sourceFlow() m_cfg.setString(SOURCEFLOW_DOMAIN, "tiers", trs); m_cfg.setString(SOURCEFLOW_DOMAIN, "numbers", numbers); - m_source.unload(); - m_source.load(fmt("%s/%s", m_sourceDir.c_str(), fn.c_str())); - SF_cacheCovers = true; - fn.replace(fn.find("."), 4, "_flow"); - if(m_source.has("general", "flow")) - curflow = m_source.getInt("general", "flow", 1); - else - curflow = m_cfg.getInt(SOURCEFLOW_DOMAIN, fn, m_cfg.getInt(SOURCEFLOW_DOMAIN, "last_cf_mode", 1)); - /* get max source button # */ - m_max_source_btn = 0; - const char *srcDomain = m_source.firstDomain().c_str(); - while(1) - { - if(strlen(srcDomain) < 2) - break; - if(strrchr(srcDomain, '_') != NULL) - { - int srcBtnNumber = atoi(strrchr(srcDomain, '_') + 1); - if(srcBtnNumber > m_max_source_btn) - m_max_source_btn = srcBtnNumber; - } - srcDomain = m_source.nextDomain().c_str(); - } + _srcTierLoad(fn); return; } } @@ -198,6 +181,11 @@ void CMenu::_srcTierLoad(string fn) curflow = m_source.getInt("general", "flow", 1); else curflow = m_cfg.getInt(SOURCEFLOW_DOMAIN, fn, m_cfg.getInt(SOURCEFLOW_DOMAIN, "last_cf_mode", 1)); + if(m_source.has("general", "box_mode")) + m_cfg.setBool(SOURCEFLOW_DOMAIN, "box_mode", m_source.getBool("general", "box_mode", true)); + if(m_source.has("general", "smallbox")) + m_cfg.setBool(SOURCEFLOW_DOMAIN, "smallbox", m_source.getBool("general", "smallbox", false)); + SF_cacheCovers = true; /* get max source button # */ m_max_source_btn = 0; const char *srcDomain = m_source.firstDomain().c_str(); @@ -234,10 +222,10 @@ void CMenu::_restoreSrcTiers() _srcTierLoad(tiers[tiers.size() - 1]); } -/* set custom sourceflow background image if available */ -void CMenu::_setSrcFlowBg(void) +/* get custom sourceflow background image if available */ +void CMenu::_getSFlowBgTex(void) { - TexHandle.Cleanup(m_mainCustomBg[curCustBg]); + curCustBg = loopNum(curCustBg + 1, 2); string fn = m_source.getString("general", "background", ""); if(fn.length() > 0) { @@ -245,14 +233,18 @@ void CMenu::_setSrcFlowBg(void) { if(TexHandle.fromImageFile(m_mainCustomBg[curCustBg], fmt("%s/backgrounds/%s", m_sourceDir.c_str(), fn.c_str())) != TE_OK) { - _setBg(m_mainBg, m_mainBgLQ); + curCustBg = loopNum(curCustBg + 1, 2);//reset it + customBg = false; return; } } - _setBg(m_mainCustomBg[curCustBg], m_mainCustomBg[curCustBg]); + customBg = true; } else - _setBg(m_mainBg, m_mainBgLQ); + { + curCustBg = loopNum(curCustBg + 1, 2);//reset it + customBg = false; + } } /* end of sourceflow stuff - start of source menu stuff */ diff --git a/source/plugin/plugin.cpp b/source/plugin/plugin.cpp index 457977d5..1673dd4f 100644 --- a/source/plugin/plugin.cpp +++ b/source/plugin/plugin.cpp @@ -226,66 +226,6 @@ const vector &Plugin::GetEnabledPlugins(Config &cfg, u8 *num) return enabledPlugins; } -/* notes: "description" is used as the title because it basically is the title */ -/* the [GameDomain] is used as the path even though it isn't the path */ -/* the [GameDomain] is usually short without any '/' */ -/* in scummvm.ini the path is the path without the exe or main app file added on */ -vector Plugin::ParseScummvmINI(Config &ini, const char *Device, u32 Magic, const char *datadir, const char *platform) -{ - gprintf("Parsing scummvm.ini\n"); - vector ScummvmList; - if(!ini.loaded()) - return ScummvmList; - - Config m_crc; - if(platform != NULL) - m_crc.load(fmt("%s/%s/%s.ini", datadir, platform, platform)); - dir_discHdr ListElement; - - const char *GameDomain = ini.firstDomain().c_str(); - while(1) - { - if(strlen(GameDomain) < 2) - break; - char GameName[64]; - memset(GameName, 0, sizeof(GameName)); - strncpy(GameName, ini.getString(GameDomain, "description").c_str(), 63); - if(strlen(GameName) < 2 || strncasecmp(Device, ini.getString(GameDomain, "path").c_str(), 2) != 0) - { - GameDomain = ini.nextDomain().c_str(); - continue; - } - - /* get shortName */ - char *cp; - if((cp = strstr(GameName, " (")) != NULL) - *cp = '\0'; - - /* get Game ID */ - string GameID = "PLUGIN"; - // Get game ID based on GameName - if(m_crc.loaded() && m_crc.has(platform, GameName)) - { - vector searchID = m_crc.getStrings(platform, GameName, '|'); - if(!searchID[0].empty()) - GameID = searchID[0]; - } - - memset((void*)&ListElement, 0, sizeof(dir_discHdr)); - memcpy(ListElement.id, GameID.c_str(), 6); - ListElement.casecolor = Plugins.back().caseColor; - mbstowcs(ListElement.title, GameName, 63); - strncpy(ListElement.path, GameDomain, sizeof(ListElement.path)); - //gprintf("Found: %s\n", GameDomain); - ListElement.settings[0] = Magic; - ListElement.type = TYPE_PLUGIN; - ScummvmList.push_back(ListElement); - GameDomain = ini.nextDomain().c_str(); - } - m_crc.unload(); - return ScummvmList; -} - vector Plugin::CreateArgs(const char *device, const char *path, const char *title, const char *loader, u32 title_len_no_ext, u32 magic) { diff --git a/source/plugin/plugin.hpp b/source/plugin/plugin.hpp index 856ac55f..17b39570 100644 --- a/source/plugin/plugin.hpp +++ b/source/plugin/plugin.hpp @@ -85,7 +85,6 @@ public: vector CreateArgs(const char *device, const char *path, const char *title, const char *loader, u32 title_len_no_ext, u32 magic); - vector ParseScummvmINI(Config &ini, const char *Device, u32 Magic, const char *datadir, const char *platform); string GenerateCoverLink(dir_discHdr gameHeader, const string& constURL, Config &Checksums); char PluginMagicWord[9];