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;