diff --git a/source/gc/gcdisc.cpp b/source/gc/gcdisc.cpp index 68bb710f..5fc65fa7 100644 --- a/source/gc/gcdisc.cpp +++ b/source/gc/gcdisc.cpp @@ -15,39 +15,36 @@ * along with this program. If not, see . ****************************************************************************/ #include -#include #include -#include #include "gc.hpp" #include "gcdisc.hpp" +#include "fileOps/fileOps.h" #include "loader/gc_disc_dump.hpp" #include "gecko/gecko.hpp" #include "memory/mem2.hpp" +#include "gui/fmt.h" -using namespace std; +GC_Disc GC_Disc_Reader; void GC_Disc::init(const char *path) { + strncpy(GamePath, path, MAX_FAT_PATH); opening_bnr = NULL; FSTable = NULL; - strncpy(GamePath, path, sizeof(GamePath)); FILE *f = NULL; - if(strcasestr(GamePath, "boot.bin") != NULL) + u32 FSTSize = 0; + if(strstr(GamePath, "boot.bin") != NULL) { GameType = TYPE_FST; - string fst(GamePath); - fst.erase(fst.end() - 8, fst.end()); - fst.append("fst.bin"); - f = fopen(fst.c_str(), "rb"); - if(f == NULL) - return; - fseek(f, 0, SEEK_END); - u32 size = ftell(f); - fseek(f, 0, SEEK_SET); - Read_FST(f, size); - fclose(f); + if(strchr(GamePath, '/') != NULL) //boot.bin + *strrchr(GamePath, '/') = '\0'; + if(strchr(GamePath, '/') != NULL) //sys + *strrchr(GamePath, '/') = '\0'; + const char *FstPath = fmt("%s/sys/fst.bin", GamePath); + fsop_GetFileSizeBytes(FstPath, &FSTSize); + f = fopen(FstPath, "rb"); } else { @@ -55,14 +52,17 @@ void GC_Disc::init(const char *path) f = fopen(GamePath, "rb"); if(f == NULL) return; - u8 *ReadBuffer = (u8*)malloc(0x440); + u8 *ReadBuffer = (u8*)MEM2_alloc(0x440); if(ReadBuffer == NULL) return; fread(ReadBuffer, 1, 0x440, f); - u32 FSTOffset = *(vu32*)(ReadBuffer+0x424); - u32 FSTSize = *(vu32*)(ReadBuffer+0x428); - free(ReadBuffer); + u32 FSTOffset = *(u32*)(ReadBuffer + 0x424); + FSTSize = *(u32*)(ReadBuffer + 0x428); + MEM2_free(ReadBuffer); fseek(f, FSTOffset, SEEK_SET); + } + if(f != NULL) + { Read_FST(f, FSTSize); fclose(f); } @@ -70,60 +70,65 @@ void GC_Disc::init(const char *path) void GC_Disc::clear() { - if(opening_bnr) + if(opening_bnr != NULL) { - free(opening_bnr); + MEM2_free(opening_bnr); opening_bnr = NULL; } - if(FSTable) + if(FSTable != NULL) { - free(FSTable); + MEM2_free(FSTable); FSTable = NULL; } } void GC_Disc::Read_FST(FILE *f, u32 FST_size) { - FSTable = (u8*)malloc(FST_size); + if(f == NULL) + return; + FSTable = (u8*)MEM2_alloc(FST_size); if(FSTable == NULL) return; fread(FSTable, 1, FST_size, f); - FSTEnt = *(vu32*)(FSTable+0x08); + FSTEnt = *(u32*)(FSTable + 0x08); FSTNameOff = (char*)(FSTable + FSTEnt * 0x0C); } u8 *GC_Disc::GetGameCubeBanner() { - if(FSTable == NULL) + if(FSTable == NULL || GamePath == NULL) return NULL; - FILE *f = NULL; - FST *fst = (FST *)(FSTable); + + FILE *bnr_fp = NULL; + u32 BnrSize = 0; + + FST *fst = (FST*)FSTable; for(u32 i = 1; i < FSTEnt; ++i) { if(fst[i].Type) //Folder continue; - else if(strcasecmp(FSTNameOff + fst[i].NameOffset, "opening.bnr") == 0) + else if(strcmp(FSTNameOff + fst[i].NameOffset, "opening.bnr") == 0) { if(GameType == TYPE_FST) - { - string path(GamePath); - path.erase(path.end() - 12, path.end()); - path.append("root/opening.bnr"); - f = fopen(path.c_str(), "rb"); - } + bnr_fp = fopen(fmt("%s/root/opening.bnr", GamePath), "rb"); else { - f = fopen(GamePath, "rb"); - fseek(f, fst[i].FileOffset, SEEK_SET); - } - if(f) - { - opening_bnr = (u8*)malloc(fst[i].FileLength); - fread(opening_bnr, 1, fst[i].FileLength, f); - fclose(f); + bnr_fp = fopen(GamePath, "rb"); + if(bnr_fp != NULL) + fseek(bnr_fp, fst[i].FileOffset, SEEK_SET); } + BnrSize = fst[i].FileLength; + break; } } + + if(bnr_fp != NULL) + { + opening_bnr = (u8*)MEM2_alloc(BnrSize); + if(opening_bnr != NULL && fread(opening_bnr, 1, BnrSize, bnr_fp) != BnrSize) + MEM2_free(opening_bnr); + fclose(bnr_fp); + } return opening_bnr; } diff --git a/source/gc/gcdisc.hpp b/source/gc/gcdisc.hpp index e7bdd795..f1c6d2cb 100644 --- a/source/gc/gcdisc.hpp +++ b/source/gc/gcdisc.hpp @@ -18,6 +18,7 @@ #define _GCDISC_HPP_ #include +#include "loader/utils.h" #include "banner/AnimatedBanner.h" #include "banner/BannerWindow.hpp" @@ -35,7 +36,7 @@ public: u8 *GetGameCubeBanner(); private: void Read_FST(FILE *f, u32 FST_size); - char GamePath[1024]; + char GamePath[MAX_FAT_PATH]; u8 GameType; u8 *FSTable; u32 FSTEnt; @@ -43,4 +44,5 @@ private: u8 *opening_bnr; }; +extern GC_Disc GC_Disc_Reader; #endif diff --git a/source/menu/menu.cpp b/source/menu/menu.cpp index d74d0573..76d39028 100644 --- a/source/menu/menu.cpp +++ b/source/menu/menu.cpp @@ -529,6 +529,7 @@ void CMenu::cleanup() //gprintf("MEM1_freesize(): %i\nMEM2_freesize(): %i\n", MEM1_freesize(), MEM2_freesize()); m_btnMgr.hide(m_mainLblCurMusic); _cleanupDefaultFont(); + CoverFlow.shutdown(); /* possibly plugin flow crash so cleanup early */ m_banner.DeleteBanner(); m_plugin.Cleanup(); m_source.unload(); @@ -541,7 +542,6 @@ void CMenu::cleanup() soundDeinit(); m_vid.cleanup(); - CoverFlow.shutdown(); wiiLightOff(); LWP_MutexDestroy(m_mutex); diff --git a/source/menu/menu.hpp b/source/menu/menu.hpp index 47d0fdf4..1e27bd44 100644 --- a/source/menu/menu.hpp +++ b/source/menu/menu.hpp @@ -1048,6 +1048,7 @@ private: void _netInit(); bool _loadFile(u8 * &buffer, u32 &size, const char *path, const char *file); int _loadIOS(u8 ios, int userIOS, string id, bool RealNAND_Channels = false); + bool _QF_Game(const char *game_id); void _launch(const dir_discHdr *hdr); void _launchGame(dir_discHdr *hdr, bool dvd); void _launchChannel(dir_discHdr *hdr); diff --git a/source/menu/menu_game.cpp b/source/menu/menu_game.cpp index 5843712f..da207917 100644 --- a/source/menu/menu_game.cpp +++ b/source/menu/menu_game.cpp @@ -832,16 +832,31 @@ void CMenu::_launch(const dir_discHdr *hdr) Sys_Exit(); } // taken from Postloader by Stfour -#define QFIDN 6 -static const char *qfid[QFIDN] = { +#define QFIDN 9 +static const char qfid[QFIDN][7] = { +"RELSAB", //Sample Header? "GGPE01", //Mario Kart Arcade GP +"MKAGP1", //Mario Kart Arcade GP (Alt ID) "GGPE02", //Mario Kart Arcade GP 2 +"MKAGP2", //Mario Kart Arcade GP 2 (Alt ID) "GFZJ8P", //F-Zero AX -"GVSJ8P", // Virtua Striker 4 -"GVS46E", // Virtua Striker 4 Ver.2006 -"GVS46J", // Virtua Striker 4 Ver.2006 +"GVSJ8P", // Virtua Striker 4 Ver.2006 (PAL) +"GVS46E", // Virtua Striker 4 Ver.2006 (NTSC) +"GVS46J", // Virtua Striker 4 Ver.2006 (JAP) }; +bool CMenu::_QF_Game(const char *game_id) +{ + if(game_id == NULL) + return false; + for(u8 i = 0; i < QFIDN; i++) + { + if(memcmp(game_id, qfid[i], 7) == 0) + return true; + } + return false; +} + void CMenu::_launchGC(dir_discHdr *hdr, bool disc) { const char *id = hdr->id; @@ -885,19 +900,13 @@ void CMenu::_launchGC(dir_discHdr *hdr, bool disc) else m_cfg.setString(GC_DOMAIN, "current_item", id); - bool isqf = false; const char *mios_wad = NULL; if(loader == 0) //auto selected { gprintf("Auto installing MIOS\n"); _showWaitMessage(); - for(u8 i = 0; i < QFIDN; i++) - { - if(strncmp(id, qfid[i], strlen(qfid[i])) == 0) - isqf = true; - } - if(isqf == true) + if(_QF_Game(id) == true) { if(currentPartition == SD && (m_mios_ver != 2 || m_sd_dm == false)) mios_wad = fmt("%s/qfsd.wad", m_miosDir.c_str()); @@ -1615,13 +1624,14 @@ void CMenu::_gameSoundThread(CMenu *m) } if(custom_bnr_file == NULL && GameHdr->type == TYPE_GC_GAME) { - GC_Disc disc; - disc.init(GameHdr->path); - u8 *opening_bnr = disc.GetGameCubeBanner(); - if(opening_bnr != NULL) - m_banner.CreateGCBanner(opening_bnr, m->m_wbf1_font, m->m_wbf2_font, GameHdr->title); - disc.clear(); - + if(m->_QF_Game(GameHdr->id) == false) + { + GC_Disc_Reader.init(GameHdr->path); + u8 *opening_bnr = GC_Disc_Reader.GetGameCubeBanner(); + if(opening_bnr != NULL) + m_banner.CreateGCBanner(opening_bnr, m->m_wbf1_font, m->m_wbf2_font, GameHdr->title); + GC_Disc_Reader.clear(); + } m->m_gameSound.Load(gc_ogg, gc_ogg_size, false); if(m->m_gameSound.IsLoaded()) m->m_gamesound_changed = true;