-fixed possible wiiflow crash when exiting plugin flow or starting a game from it

-cleaned up the gamecube automatic banner creation
-added new quadforce ids, RELSAB, MKAGP1 and MKAGP2
This commit is contained in:
fix94.1 2013-09-21 14:03:45 +00:00
parent 2b3cdc3d67
commit ab7ecc61b7
5 changed files with 83 additions and 65 deletions

View File

@ -15,39 +15,36 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <string>
#include "gc.hpp" #include "gc.hpp"
#include "gcdisc.hpp" #include "gcdisc.hpp"
#include "fileOps/fileOps.h"
#include "loader/gc_disc_dump.hpp" #include "loader/gc_disc_dump.hpp"
#include "gecko/gecko.hpp" #include "gecko/gecko.hpp"
#include "memory/mem2.hpp" #include "memory/mem2.hpp"
#include "gui/fmt.h"
using namespace std; GC_Disc GC_Disc_Reader;
void GC_Disc::init(const char *path) void GC_Disc::init(const char *path)
{ {
strncpy(GamePath, path, MAX_FAT_PATH);
opening_bnr = NULL; opening_bnr = NULL;
FSTable = NULL; FSTable = NULL;
strncpy(GamePath, path, sizeof(GamePath));
FILE *f = NULL; FILE *f = NULL;
if(strcasestr(GamePath, "boot.bin") != NULL) u32 FSTSize = 0;
if(strstr(GamePath, "boot.bin") != NULL)
{ {
GameType = TYPE_FST; GameType = TYPE_FST;
string fst(GamePath); if(strchr(GamePath, '/') != NULL) //boot.bin
fst.erase(fst.end() - 8, fst.end()); *strrchr(GamePath, '/') = '\0';
fst.append("fst.bin"); if(strchr(GamePath, '/') != NULL) //sys
f = fopen(fst.c_str(), "rb"); *strrchr(GamePath, '/') = '\0';
if(f == NULL) const char *FstPath = fmt("%s/sys/fst.bin", GamePath);
return; fsop_GetFileSizeBytes(FstPath, &FSTSize);
fseek(f, 0, SEEK_END); f = fopen(FstPath, "rb");
u32 size = ftell(f);
fseek(f, 0, SEEK_SET);
Read_FST(f, size);
fclose(f);
} }
else else
{ {
@ -55,14 +52,17 @@ void GC_Disc::init(const char *path)
f = fopen(GamePath, "rb"); f = fopen(GamePath, "rb");
if(f == NULL) if(f == NULL)
return; return;
u8 *ReadBuffer = (u8*)malloc(0x440); u8 *ReadBuffer = (u8*)MEM2_alloc(0x440);
if(ReadBuffer == NULL) if(ReadBuffer == NULL)
return; return;
fread(ReadBuffer, 1, 0x440, f); fread(ReadBuffer, 1, 0x440, f);
u32 FSTOffset = *(vu32*)(ReadBuffer+0x424); u32 FSTOffset = *(u32*)(ReadBuffer + 0x424);
u32 FSTSize = *(vu32*)(ReadBuffer+0x428); FSTSize = *(u32*)(ReadBuffer + 0x428);
free(ReadBuffer); MEM2_free(ReadBuffer);
fseek(f, FSTOffset, SEEK_SET); fseek(f, FSTOffset, SEEK_SET);
}
if(f != NULL)
{
Read_FST(f, FSTSize); Read_FST(f, FSTSize);
fclose(f); fclose(f);
} }
@ -70,60 +70,65 @@ void GC_Disc::init(const char *path)
void GC_Disc::clear() void GC_Disc::clear()
{ {
if(opening_bnr) if(opening_bnr != NULL)
{ {
free(opening_bnr); MEM2_free(opening_bnr);
opening_bnr = NULL; opening_bnr = NULL;
} }
if(FSTable) if(FSTable != NULL)
{ {
free(FSTable); MEM2_free(FSTable);
FSTable = NULL; FSTable = NULL;
} }
} }
void GC_Disc::Read_FST(FILE *f, u32 FST_size) 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) if(FSTable == NULL)
return; return;
fread(FSTable, 1, FST_size, f); fread(FSTable, 1, FST_size, f);
FSTEnt = *(vu32*)(FSTable+0x08); FSTEnt = *(u32*)(FSTable + 0x08);
FSTNameOff = (char*)(FSTable + FSTEnt * 0x0C); FSTNameOff = (char*)(FSTable + FSTEnt * 0x0C);
} }
u8 *GC_Disc::GetGameCubeBanner() u8 *GC_Disc::GetGameCubeBanner()
{ {
if(FSTable == NULL) if(FSTable == NULL || GamePath == NULL)
return 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) for(u32 i = 1; i < FSTEnt; ++i)
{ {
if(fst[i].Type) //Folder if(fst[i].Type) //Folder
continue; 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) if(GameType == TYPE_FST)
{ bnr_fp = fopen(fmt("%s/root/opening.bnr", GamePath), "rb");
string path(GamePath);
path.erase(path.end() - 12, path.end());
path.append("root/opening.bnr");
f = fopen(path.c_str(), "rb");
}
else else
{ {
f = fopen(GamePath, "rb"); bnr_fp = fopen(GamePath, "rb");
fseek(f, fst[i].FileOffset, SEEK_SET); if(bnr_fp != NULL)
fseek(bnr_fp, fst[i].FileOffset, SEEK_SET);
} }
if(f) BnrSize = fst[i].FileLength;
break;
}
}
if(bnr_fp != NULL)
{ {
opening_bnr = (u8*)malloc(fst[i].FileLength); opening_bnr = (u8*)MEM2_alloc(BnrSize);
fread(opening_bnr, 1, fst[i].FileLength, f); if(opening_bnr != NULL && fread(opening_bnr, 1, BnrSize, bnr_fp) != BnrSize)
fclose(f); MEM2_free(opening_bnr);
} fclose(bnr_fp);
}
} }
return opening_bnr; return opening_bnr;
} }

View File

@ -18,6 +18,7 @@
#define _GCDISC_HPP_ #define _GCDISC_HPP_
#include <gccore.h> #include <gccore.h>
#include "loader/utils.h"
#include "banner/AnimatedBanner.h" #include "banner/AnimatedBanner.h"
#include "banner/BannerWindow.hpp" #include "banner/BannerWindow.hpp"
@ -35,7 +36,7 @@ public:
u8 *GetGameCubeBanner(); u8 *GetGameCubeBanner();
private: private:
void Read_FST(FILE *f, u32 FST_size); void Read_FST(FILE *f, u32 FST_size);
char GamePath[1024]; char GamePath[MAX_FAT_PATH];
u8 GameType; u8 GameType;
u8 *FSTable; u8 *FSTable;
u32 FSTEnt; u32 FSTEnt;
@ -43,4 +44,5 @@ private:
u8 *opening_bnr; u8 *opening_bnr;
}; };
extern GC_Disc GC_Disc_Reader;
#endif #endif

View File

@ -529,6 +529,7 @@ void CMenu::cleanup()
//gprintf("MEM1_freesize(): %i\nMEM2_freesize(): %i\n", MEM1_freesize(), MEM2_freesize()); //gprintf("MEM1_freesize(): %i\nMEM2_freesize(): %i\n", MEM1_freesize(), MEM2_freesize());
m_btnMgr.hide(m_mainLblCurMusic); m_btnMgr.hide(m_mainLblCurMusic);
_cleanupDefaultFont(); _cleanupDefaultFont();
CoverFlow.shutdown(); /* possibly plugin flow crash so cleanup early */
m_banner.DeleteBanner(); m_banner.DeleteBanner();
m_plugin.Cleanup(); m_plugin.Cleanup();
m_source.unload(); m_source.unload();
@ -541,7 +542,6 @@ void CMenu::cleanup()
soundDeinit(); soundDeinit();
m_vid.cleanup(); m_vid.cleanup();
CoverFlow.shutdown();
wiiLightOff(); wiiLightOff();
LWP_MutexDestroy(m_mutex); LWP_MutexDestroy(m_mutex);

View File

@ -1048,6 +1048,7 @@ private:
void _netInit(); void _netInit();
bool _loadFile(u8 * &buffer, u32 &size, const char *path, const char *file); bool _loadFile(u8 * &buffer, u32 &size, const char *path, const char *file);
int _loadIOS(u8 ios, int userIOS, string id, bool RealNAND_Channels = false); 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 _launch(const dir_discHdr *hdr);
void _launchGame(dir_discHdr *hdr, bool dvd); void _launchGame(dir_discHdr *hdr, bool dvd);
void _launchChannel(dir_discHdr *hdr); void _launchChannel(dir_discHdr *hdr);

View File

@ -832,16 +832,31 @@ void CMenu::_launch(const dir_discHdr *hdr)
Sys_Exit(); Sys_Exit();
} }
// taken from Postloader by Stfour // taken from Postloader by Stfour
#define QFIDN 6 #define QFIDN 9
static const char *qfid[QFIDN] = { static const char qfid[QFIDN][7] = {
"RELSAB", //Sample Header?
"GGPE01", //Mario Kart Arcade GP "GGPE01", //Mario Kart Arcade GP
"MKAGP1", //Mario Kart Arcade GP (Alt ID)
"GGPE02", //Mario Kart Arcade GP 2 "GGPE02", //Mario Kart Arcade GP 2
"MKAGP2", //Mario Kart Arcade GP 2 (Alt ID)
"GFZJ8P", //F-Zero AX "GFZJ8P", //F-Zero AX
"GVSJ8P", // Virtua Striker 4 "GVSJ8P", // Virtua Striker 4 Ver.2006 (PAL)
"GVS46E", // Virtua Striker 4 Ver.2006 "GVS46E", // Virtua Striker 4 Ver.2006 (NTSC)
"GVS46J", // Virtua Striker 4 Ver.2006 "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) void CMenu::_launchGC(dir_discHdr *hdr, bool disc)
{ {
const char *id = hdr->id; const char *id = hdr->id;
@ -885,19 +900,13 @@ void CMenu::_launchGC(dir_discHdr *hdr, bool disc)
else else
m_cfg.setString(GC_DOMAIN, "current_item", id); m_cfg.setString(GC_DOMAIN, "current_item", id);
bool isqf = false;
const char *mios_wad = NULL; const char *mios_wad = NULL;
if(loader == 0) //auto selected if(loader == 0) //auto selected
{ {
gprintf("Auto installing MIOS\n"); gprintf("Auto installing MIOS\n");
_showWaitMessage(); _showWaitMessage();
for(u8 i = 0; i < QFIDN; i++) if(_QF_Game(id) == true)
{
if(strncmp(id, qfid[i], strlen(qfid[i])) == 0)
isqf = true;
}
if(isqf == true)
{ {
if(currentPartition == SD && (m_mios_ver != 2 || m_sd_dm == false)) if(currentPartition == SD && (m_mios_ver != 2 || m_sd_dm == false))
mios_wad = fmt("%s/qfsd.wad", m_miosDir.c_str()); 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) if(custom_bnr_file == NULL && GameHdr->type == TYPE_GC_GAME)
{ {
GC_Disc disc; if(m->_QF_Game(GameHdr->id) == false)
disc.init(GameHdr->path); {
u8 *opening_bnr = disc.GetGameCubeBanner(); GC_Disc_Reader.init(GameHdr->path);
u8 *opening_bnr = GC_Disc_Reader.GetGameCubeBanner();
if(opening_bnr != NULL) if(opening_bnr != NULL)
m_banner.CreateGCBanner(opening_bnr, m->m_wbf1_font, m->m_wbf2_font, GameHdr->title); m_banner.CreateGCBanner(opening_bnr, m->m_wbf1_font, m->m_wbf2_font, GameHdr->title);
disc.clear(); GC_Disc_Reader.clear();
}
m->m_gameSound.Load(gc_ogg, gc_ogg_size, false); m->m_gameSound.Load(gc_ogg, gc_ogg_size, false);
if(m->m_gameSound.IsLoaded()) if(m->m_gameSound.IsLoaded())
m->m_gamesound_changed = true; m->m_gamesound_changed = true;