bug fixes for RAM/state saves, optimize boot sequence, more intelligent device auto-detect

This commit is contained in:
dborth 2008-12-22 08:38:49 +00:00
parent c7b15e4a89
commit 7ffa0c17db
7 changed files with 236 additions and 171 deletions

View File

@ -183,59 +183,59 @@ int main(int argc, char *argv[])
int selectedMenu = -1; int selectedMenu = -1;
InitDeviceThread();
InitGCVideo ();
ResetVideo_Menu (); // change to menu video mode
// Controllers
PAD_Init();
#ifdef HW_RVL #ifdef HW_RVL
WPAD_Init(); WPAD_Init();
// read wiimote accelerometer and IR data // read wiimote accelerometer and IR data
WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR); WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR);
WPAD_SetVRes(WPAD_CHAN_ALL,640,480); WPAD_SetVRes(WPAD_CHAN_ALL,640,480);
#endif
PAD_Init();
// Wii Power/Reset buttons // Wii Power/Reset buttons
#ifdef HW_RVL
WPAD_SetPowerButtonCallback((WPADShutdownCallback)ShutdownCB); WPAD_SetPowerButtonCallback((WPADShutdownCallback)ShutdownCB);
SYS_SetPowerCallback(ShutdownCB); SYS_SetPowerCallback(ShutdownCB);
SYS_SetResetCallback(ResetCB); SYS_SetResetCallback(ResetCB);
#endif #endif
InitGCVideo (); // Initialise FreeType
ResetVideo_Menu (); // change to menu video mode
/*** Initialise freetype ***/
if (FT_Init ()) if (FT_Init ())
{ {
printf ("Cannot initialise font subsystem!\n"); printf ("Cannot initialise font subsystem!\n");
while (1); while (1);
} }
InitialiseAudio(); InitialiseAudio();
// Initialize libFAT for SD and USB // Initialize libFAT for SD and USB
MountAllFAT(); MountAllFAT();
InitDeviceThread();
// Initialize DVD subsystem (GameCube only) // Initialize DVD subsystem (GameCube only)
#ifdef HW_DOL #ifdef HW_DOL
DVD_Init (); DVD_Init ();
#endif #endif
// allocate memory to store rom // allocate memory to store rom
nesrom = (unsigned char *)malloc(1024*1024*3); // 3 MB should be plenty nesrom = (unsigned char *)malloc(1024*1024*3); // 3 MB should be plenty
/*** Minimal Emulation Loop ***/ /*** Minimal Emulation Loop ***/
if ( !FCEUI_Initialize() ) if ( !FCEUI_Initialize() )
{ {
WaitPrompt("Unable to initialize FCE Ultra\n"); WaitPrompt("Unable to initialize FCE Ultra\n");
ExitToLoader(); ExitToLoader();
} }
FCEUI_SetGameGenie(0); // 0 - OFF, 1 - ON FCEUI_SetGameGenie(0); // 0 - OFF, 1 - ON
memset(FDSBIOS, 0, sizeof(FDSBIOS)); // clear FDS BIOS memory memset(FDSBIOS, 0, sizeof(FDSBIOS)); // clear FDS BIOS memory
cleanSFMDATA(); // clear state data cleanSFMDATA(); // clear state data
// Set defaults // Set defaults
DefaultSettings(); DefaultSettings();
// store path app was loaded from // store path app was loaded from

View File

@ -39,15 +39,42 @@
#include "fileop.h" #include "fileop.h"
#include "smbop.h" #include "smbop.h"
extern const unsigned short saveicon[1024];
extern u32 iNESGameCRC32; extern u32 iNESGameCRC32;
extern CartInfo iNESCart; extern CartInfo iNESCart;
extern CartInfo UNIFCart; extern CartInfo UNIFCart;
int NGCFCEU_GameSave(CartInfo *LocalHWInfo, int operation) int NGCFCEU_GameSave(CartInfo *LocalHWInfo, int operation, int method)
{ {
int size = 0; int offset = 0;
char comment[2][32];
memset(comment, 0, 64);
if(LocalHWInfo->battery && LocalHWInfo->SaveGame[0]) if(LocalHWInfo->battery && LocalHWInfo->SaveGame[0])
{ {
// add save icon and comments for Memory Card saves
if(operation == 0 &&
(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB))
{
// Copy in save icon
memcpy(savebuffer, saveicon, sizeof(saveicon));
offset += sizeof(saveicon);
// And the comments
sprintf (comment[0], "%s RAM", VERSIONSTR);
strncpy (comment[1],romFilename,31); // we only have 32 chars to work with!
comment[1][31] = 0;
memcpy(savebuffer+offset, comment, 64);
offset += 64;
}
// skip save icon and comments for Memory Card saves
else if(operation == 1 &&
(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB))
{
offset += sizeof(saveicon);
offset += 64; // sizeof prefscomment
}
int x; int x;
for(x=0;x<4;x++) for(x=0;x<4;x++)
@ -55,18 +82,14 @@ int NGCFCEU_GameSave(CartInfo *LocalHWInfo, int operation)
if(LocalHWInfo->SaveGame[x]) if(LocalHWInfo->SaveGame[x])
{ {
if(operation == 0) // save to file if(operation == 0) // save to file
{ memcpy(savebuffer+offset, LocalHWInfo->SaveGame[x], LocalHWInfo->SaveGameLen[x]);
memcpy(savebuffer, LocalHWInfo->SaveGame[x], LocalHWInfo->SaveGameLen[x]);
}
else // load from file else // load from file
{ memcpy(LocalHWInfo->SaveGame[x], savebuffer+offset, LocalHWInfo->SaveGameLen[x]);
memcpy(LocalHWInfo->SaveGame[x], savebuffer, LocalHWInfo->SaveGameLen[x]); offset += LocalHWInfo->SaveGameLen[x];
}
size += LocalHWInfo->SaveGameLen[x];
} }
} }
} }
return size; return offset;
} }
bool SaveRAM (int method, bool silent) bool SaveRAM (int method, bool silent)
@ -84,7 +107,7 @@ bool SaveRAM (int method, bool silent)
} }
if(method == METHOD_AUTO) if(method == METHOD_AUTO)
method = autoSaveMethod(); method = autoSaveMethod(silent);
if (!MakeFilePath(filepath, FILE_RAM, method)) if (!MakeFilePath(filepath, FILE_RAM, method))
return false; return false;
@ -95,9 +118,9 @@ bool SaveRAM (int method, bool silent)
// save game save to savebuffer // save game save to savebuffer
if(nesGameType == 1) if(nesGameType == 1)
datasize = NGCFCEU_GameSave(&iNESCart, 0); datasize = NGCFCEU_GameSave(&iNESCart, 0, method);
else if(nesGameType == 2) else if(nesGameType == 2)
datasize = NGCFCEU_GameSave(&UNIFCart, 0); datasize = NGCFCEU_GameSave(&UNIFCart, 0, method);
if (datasize) if (datasize)
{ {
@ -133,7 +156,7 @@ bool LoadRAM (int method, bool silent)
} }
if(method == METHOD_AUTO) if(method == METHOD_AUTO)
method = autoSaveMethod(); // we use 'Save' because we need R/W method = autoSaveMethod(silent); // we use 'Save' because we need R/W
if (!MakeFilePath(filepath, FILE_RAM, method)) if (!MakeFilePath(filepath, FILE_RAM, method))
return false; return false;
@ -147,9 +170,9 @@ bool LoadRAM (int method, bool silent)
if (offset > 0) if (offset > 0)
{ {
if(nesGameType == 1) if(nesGameType == 1)
NGCFCEU_GameSave(&iNESCart, 1); NGCFCEU_GameSave(&iNESCart, 1, method);
else if(nesGameType == 2) else if(nesGameType == 2)
NGCFCEU_GameSave(&UNIFCart, 1); NGCFCEU_GameSave(&UNIFCart, 1, method);
ResetNES(); ResetNES();
retval = true; retval = true;

View File

@ -19,6 +19,7 @@
#include <fat.h> #include <fat.h>
#include "types.h" #include "types.h"
#include "state.h" #include "state.h"
#include "x6502.h"
#include "images/saveicon.h" #include "images/saveicon.h"
#include "fceugx.h" #include "fceugx.h"
@ -32,10 +33,10 @@
/*** External functions ***/ /*** External functions ***/
extern void FCEUPPU_SaveState(void); extern void FCEUPPU_SaveState(void);
extern void FCEUSND_SaveState(void); extern void FCEUSND_SaveState(void);
extern void FCEUPPU_LoadState(int version);
extern void FCEUSND_LoadState(int version);
extern void FlipByteOrder(uint8 *src, uint32 count); extern void FlipByteOrder(uint8 *src, uint32 count);
extern void FCEUD_SetPalette(unsigned char index, unsigned char r, unsigned char g, unsigned char b); extern void (*GameStateRestore)(int version);
extern void FCEU_ResetPalette(void);
extern void FCEUI_DisableSpriteLimitation( int a );
/*** External save structures ***/ /*** External save structures ***/
extern SFORMAT SFCPU[]; extern SFORMAT SFCPU[];
@ -47,7 +48,6 @@ extern SFORMAT SFMDATA[64];
extern u32 iNESGameCRC32; extern u32 iNESGameCRC32;
#define RLSB 0x80000000 #define RLSB 0x80000000
#define FILESIZEOFFSET 2116
int sboffset; /*** Used as a basic fileptr ***/ int sboffset; /*** Used as a basic fileptr ***/
int mcversion = 0x981211; int mcversion = 0x981211;
@ -57,9 +57,9 @@ int mcversion = 0x981211;
****************************************************************************/ ****************************************************************************/
/*** Open a file ***/ /*** Open a file ***/
void memopen() { void memopen()
{
sboffset = 0; sboffset = 0;
memset(savebuffer, 0, SAVEBUFFERSIZE);
} }
/*** Close a file ***/ /*** Close a file ***/
@ -95,47 +95,59 @@ void memfread( void *buffer, int len ) {
* *
* Read the array of SFORMAT structures to memory * Read the array of SFORMAT structures to memory
****************************************************************************/ ****************************************************************************/
int GCReadChunk( int chunkid, SFORMAT *sf ) { int GCReadChunk(int chunkid, SFORMAT *sf)
int csize; {
static char chunk[6]; int csize;
int chunklength; static char chunk[6];
int thischunk; int chunklength;
char info[128]; int thischunk;
char info[128];
memfread(&chunk, 4); memfread(&chunk, 4);
memfread(&thischunk, 4); memfread(&thischunk, 4);
memfread(&chunklength, 4); memfread(&chunklength, 4);
if (strcmp(chunk, "CHNK") == 0) { if (strcmp(chunk, "CHNK") == 0)
if (chunkid == thischunk) { {
/*** Now decode the array of chunks to this one ***/ if (chunkid == thischunk)
while (sf->v) { {
memfread(&chunk, 4); /*** Now decode the array of chunks to this one ***/
if ( memcmp(&chunk, "CHKE", 4) == 0 ) while (sf->v)
return 1; {
memfread(&chunk, 4);
if (memcmp(&chunk, "CHKE", 4) == 0)
return 1;
if (memcmp(&chunk, sf->desc, 4) == 0) { if (memcmp(&chunk, sf->desc, 4) == 0)
memfread(&csize, 4); {
if (csize == (sf->s & (~RLSB ))) { memfread(&csize, 4);
memfread( sf->v, csize ); if (csize == (sf->s & (~RLSB)))
sprintf(info,"%s %d", chunk, csize); {
} else { memfread(sf->v, csize);
WaitPrompt("Bad chunk link"); sprintf(info, "%s %d", chunk, csize);
return 0; }
} else
} else { {
sprintf(info, "No Sync %s %s", chunk, sf->desc); WaitPrompt("Bad chunk link");
WaitPrompt(info); return 0;
return 0; }
} }
sf++; else
} {
} else sprintf(info, "No Sync %s %s", chunk, sf->desc);
return 0; WaitPrompt(info);
} else return 0;
return 0; }
sf++;
}
}
else
return 0;
}
else
return 0;
return 1; return 1;
} }
/**************************************************************************** /****************************************************************************
@ -143,28 +155,47 @@ int GCReadChunk( int chunkid, SFORMAT *sf ) {
* *
* Reads the SFORMAT arrays * Reads the SFORMAT arrays
****************************************************************************/ ****************************************************************************/
int GCFCEUSS_Load() { int GCFCEUSS_Load(int method)
int totalsize = 0; {
memopen(); // reset file pointer
sboffset = 16 + sizeof(saveicon) + 64; /*** Reset memory file pointer ***/ // skip save icon and comments for Memory Card saves
if (method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{
sboffset += sizeof(saveicon);
sboffset += 64; // sizeof prefscomment
}
memcpy(&totalsize, &savebuffer[FILESIZEOFFSET], 4); sboffset += 16; // skip FCEU header
/*** Now read the chunks back ***/ // Now read the chunks back
if (GCReadChunk(1, SFCPU)) { if (GCReadChunk(1, SFCPU))
if (GCReadChunk(2, SFCPUC)) { {
if (GCReadChunk(3, FCEUPPU_STATEINFO)) { if (GCReadChunk(2, SFCPUC))
if (GCReadChunk(4, FCEUCTRL_STATEINFO)) { {
if (GCReadChunk(5, FCEUSND_STATEINFO)) { X.mooPI = X.P; // Quick and dirty hack.
if (GCReadChunk(0x10, SFMDATA)) if (GCReadChunk(3, FCEUPPU_STATEINFO))
return 1; {
} if (GCReadChunk(4, FCEUCTRL_STATEINFO))
} {
} if (GCReadChunk(5, FCEUSND_STATEINFO))
} {
} if (GCReadChunk(0x10, SFMDATA))
{
if (GameStateRestore)
GameStateRestore(FCEU_VERSION_NUMERIC);
return 0; FCEUPPU_LoadState(FCEU_VERSION_NUMERIC);
FCEUSND_LoadState(FCEU_VERSION_NUMERIC);
return 1;
}
}
}
}
}
}
return 0;
} }
/**************************************************************************** /****************************************************************************
@ -172,7 +203,8 @@ int GCFCEUSS_Load() {
* *
* Write the array of SFORMAT structures to the file * Write the array of SFORMAT structures to the file
****************************************************************************/ ****************************************************************************/
int GCSaveChunk(int chunkid, SFORMAT *sf) { int GCSaveChunk(int chunkid, SFORMAT *sf)
{
int chnkstart; int chnkstart;
int csize = 0; int csize = 0;
int chsize = 0; int chsize = 0;
@ -199,8 +231,10 @@ int GCSaveChunk(int chunkid, SFORMAT *sf) {
memfwrite( &chsize, 4); memfwrite( &chsize, 4);
if ( chsize > 0 ) if ( chsize > 0 )
{
/*** Write the actual data ***/ /*** Write the actual data ***/
memfwrite( sf->v, chsize ); memfwrite( sf->v, chsize );
}
csize += 8; csize += 8;
csize += chsize; csize += chsize;
@ -224,59 +258,62 @@ int GCSaveChunk(int chunkid, SFORMAT *sf) {
extern void (*SPreSave)(void); extern void (*SPreSave)(void);
extern void (*SPostSave)(void); extern void (*SPostSave)(void);
int GCFCEUSS_Save() int GCFCEUSS_Save(int method)
{ {
int totalsize = 0; int totalsize = 0;
static unsigned char header[16] = "FCS\xff"; static unsigned char header[16] = "FCS\xff";
char chunk[] = "CHKE"; char chunk[] = "CHKE";
int zero = 0; int zero = 0;
char Comment[2][100] = { { MENU_CREDITS_TITLE }, { "GAME" } }; char comment[2][32];
memset(comment, 0, 64);
memopen(); /*** Reset Memory File ***/ memopen(); // Reset Memory File
/*** Add version ID ***/ // add save icon and comments for Memory Card saves
memcpy(&header[8], &mcversion, 4); if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{
// Copy in save icon
memfwrite(&saveicon, sizeof(saveicon));
totalsize += sizeof(saveicon);
/*** Do internal Saving ***/ // And the comments
FCEUPPU_SaveState(); sprintf (comment[0], "%s State", VERSIONSTR);
FCEUSND_SaveState(); strncpy (comment[1],romFilename,31); // we only have 32 chars to work with!
comment[1][31] = 0;
memfwrite(&comment[0], 64);
totalsize += 64;
}
/*** Write Icon ***/ // Add version ID
memfwrite(&saveicon, sizeof(saveicon)); memcpy(&header[8], &mcversion, 4);
totalsize += sizeof(saveicon);
/*** And Comments ***/ // Do internal Saving
strncpy (Comment[1],romFilename,31); // we only have 32 chars to work with! FCEUPPU_SaveState();
Comment[1][31] = 0; FCEUSND_SaveState();
memfwrite(&Comment[0], 64);
totalsize += 64;
/*** Write header ***/ // Write header
memfwrite(&header, 16); memfwrite(&header, 16);
totalsize += 16; totalsize += 16;
totalsize += GCSaveChunk(1, SFCPU); totalsize += GCSaveChunk(1, SFCPU);
totalsize += GCSaveChunk(2, SFCPUC); totalsize += GCSaveChunk(2, SFCPUC);
totalsize += GCSaveChunk(3, FCEUPPU_STATEINFO); totalsize += GCSaveChunk(3, FCEUPPU_STATEINFO);
totalsize += GCSaveChunk(4, FCEUCTRL_STATEINFO); totalsize += GCSaveChunk(4, FCEUCTRL_STATEINFO);
totalsize += GCSaveChunk(5, FCEUSND_STATEINFO); totalsize += GCSaveChunk(5, FCEUSND_STATEINFO);
if(nesGameType == 4) // FDS if(nesGameType == 4) // FDS
SPreSave(); SPreSave();
totalsize += GCSaveChunk(0x10, SFMDATA); totalsize += GCSaveChunk(0x10, SFMDATA);
if(nesGameType == 4) // FDS if(nesGameType == 4) // FDS
SPostSave(); SPostSave();
/*** Add terminating CHNK ***/ // Add terminating CHNK
memfwrite(&chunk,4); memfwrite(&chunk,4);
memfwrite(&zero,4); memfwrite(&zero,4);
totalsize += 8; totalsize += 8;
/*** Update size element ***/ return totalsize;
memcpy(&savebuffer[FILESIZEOFFSET], &totalsize, 4);
return totalsize;
} }
bool SaveState (int method, bool silent) bool SaveState (int method, bool silent)
@ -287,7 +324,7 @@ bool SaveState (int method, bool silent)
int offset = 0; int offset = 0;
if(method == METHOD_AUTO) if(method == METHOD_AUTO)
method = autoSaveMethod(); method = autoSaveMethod(silent);
if (!MakeFilePath(filepath, FILE_STATE, method)) if (!MakeFilePath(filepath, FILE_STATE, method))
return false; return false;
@ -296,7 +333,7 @@ bool SaveState (int method, bool silent)
AllocSaveBuffer (); AllocSaveBuffer ();
datasize = GCFCEUSS_Save(); datasize = GCFCEUSS_Save(method);
if (datasize) if (datasize)
{ {
@ -320,7 +357,7 @@ bool LoadState (int method, bool silent)
bool retval = false; bool retval = false;
if(method == METHOD_AUTO) if(method == METHOD_AUTO)
method = autoSaveMethod(); // we use 'Save' because we need R/W method = autoSaveMethod(silent); // we use 'Save' because we need R/W
if (!MakeFilePath(filepath, FILE_STATE, method)) if (!MakeFilePath(filepath, FILE_STATE, method))
return false; return false;
@ -333,7 +370,7 @@ bool LoadState (int method, bool silent)
if (offset > 0) if (offset > 0)
{ {
GCFCEUSS_Load(); GCFCEUSS_Load(method);
retval = true; retval = true;
} }
else else

View File

@ -233,15 +233,15 @@ bool ChangeInterface(int method, bool silent)
WaitPrompt ("USB drive not found!"); WaitPrompt ("USB drive not found!");
#endif #endif
} }
else if(method == METHOD_SMB)
{
sprintf(rootdir, "smb:/");
mounted = ConnectShare(NOTSILENT);
}
else if(method == METHOD_DVD) else if(method == METHOD_DVD)
{ {
sprintf(rootdir, "/"); sprintf(rootdir, "/");
mounted = MountDVD(NOTSILENT); mounted = MountDVD(silent);
}
else if(method == METHOD_SMB)
{
sprintf(rootdir, "smb:/");
mounted = ConnectShare(silent);
} }
return mounted; return mounted;

View File

@ -83,19 +83,21 @@ int autoLoadMethod()
{ {
ShowAction ("Attempting to determine load method..."); ShowAction ("Attempting to determine load method...");
int method = 0;
if(ChangeInterface(METHOD_SD, SILENT)) if(ChangeInterface(METHOD_SD, SILENT))
return METHOD_SD; method = METHOD_SD;
else if(ChangeInterface(METHOD_USB, SILENT)) else if(ChangeInterface(METHOD_USB, SILENT))
return METHOD_USB; method = METHOD_USB;
else if(ChangeInterface(METHOD_DVD, SILENT)) else if(ChangeInterface(METHOD_DVD, SILENT))
return METHOD_DVD; method = METHOD_DVD;
else if(ChangeInterface(METHOD_SMB, SILENT)) else if(ChangeInterface(METHOD_SMB, SILENT))
return METHOD_SMB; method = METHOD_SMB;
else else
{
WaitPrompt("Unable to auto-determine load method!"); WaitPrompt("Unable to auto-determine load method!");
return 0; // no method found
} GCSettings.LoadMethod = method; // save method found for later use
return method;
} }
/**************************************************************************** /****************************************************************************
@ -103,25 +105,28 @@ int autoLoadMethod()
* Auto-determines and sets the save method * Auto-determines and sets the save method
* Returns method set * Returns method set
****************************************************************************/ ****************************************************************************/
int autoSaveMethod() int autoSaveMethod(bool silent)
{ {
ShowAction ("Attempting to determine save method..."); if(!silent)
ShowAction ("Attempting to determine save method...");
int method = 0;
if(ChangeInterface(METHOD_SD, SILENT)) if(ChangeInterface(METHOD_SD, SILENT))
return METHOD_SD; method = METHOD_SD;
else if(ChangeInterface(METHOD_USB, SILENT)) else if(ChangeInterface(METHOD_USB, SILENT))
return METHOD_USB; method = METHOD_USB;
else if(TestCard(CARD_SLOTA, SILENT)) else if(TestCard(CARD_SLOTA, SILENT))
return METHOD_MC_SLOTA; method = METHOD_MC_SLOTA;
else if(TestCard(CARD_SLOTB, SILENT)) else if(TestCard(CARD_SLOTB, SILENT))
return METHOD_MC_SLOTB; method = METHOD_MC_SLOTB;
else if(ChangeInterface(METHOD_SMB, SILENT)) else if(ChangeInterface(METHOD_SMB, SILENT))
return METHOD_SMB; method = METHOD_SMB;
else else if(!silent)
{
WaitPrompt("Unable to auto-determine save method!"); WaitPrompt("Unable to auto-determine save method!");
return 0; // no method found
} GCSettings.SaveMethod = method; // save method found for later use
return method;
} }
/**************************************************************************** /****************************************************************************

View File

@ -44,7 +44,7 @@ void FreeSaveBuffer();
bool MakeFilePath(char filepath[], int type, int method); bool MakeFilePath(char filepath[], int type, int method);
int OpenROM (int method); int OpenROM (int method);
int autoLoadMethod(); int autoLoadMethod();
int autoSaveMethod(); int autoSaveMethod(bool silent);
int FileSortCallback(const void *f1, const void *f2); int FileSortCallback(const void *f1, const void *f2);
void StripExt(char* returnstring, char * inputstring); void StripExt(char* returnstring, char * inputstring);

View File

@ -326,7 +326,7 @@ SavePrefs (bool silent)
// We'll save using the first available method (probably SD) since this // We'll save using the first available method (probably SD) since this
// is the method preferences will be loaded from by default // is the method preferences will be loaded from by default
int method = autoSaveMethod(); int method = autoSaveMethod(silent);
if(!MakeFilePath(filepath, FILE_PREF, method)) if(!MakeFilePath(filepath, FILE_PREF, method))
return false; return false;