-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/>.
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#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);
bnr_fp = fopen(GamePath, "rb");
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);
fread(opening_bnr, 1, fst[i].FileLength, f);
fclose(f);
}
}
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;
}

View File

@ -18,6 +18,7 @@
#define _GCDISC_HPP_
#include <gccore.h>
#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

View File

@ -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);

View File

@ -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);

View File

@ -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(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);
disc.clear();
GC_Disc_Reader.clear();
}
m->m_gameSound.Load(gc_ogg, gc_ogg_size, false);
if(m->m_gameSound.IsLoaded())
m->m_gamesound_changed = true;