memory based battery/state working, GC version working

This commit is contained in:
dborth 2008-09-29 07:35:26 +00:00
parent 2522d87963
commit af596450f7
26 changed files with 892 additions and 287 deletions

View File

@ -26,7 +26,7 @@ INCLUDES := source/vba source/ngc
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \ CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) \
-DNGC -DWORDS_BIGENDIAN -DC_CORE -DFINAL_VERSION \ -DNGC -DWII_DVD -DWORDS_BIGENDIAN -DC_CORE -DFINAL_VERSION \
-DSDL -DNO_PNG -DHAVE_ZUTIL_H -DSDL -DNO_PNG -DHAVE_ZUTIL_H
CXXFLAGS = $(CFLAGS) CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref

View File

@ -434,7 +434,7 @@ bool SwitchDVDFolder(char origdir[])
***************************************************************************/ ***************************************************************************/
int int
LoadDVDFile (unsigned char *buffer) LoadDVDFile (unsigned char *buffer, int length)
{ {
int offset; int offset;
int blocks; int blocks;
@ -447,6 +447,13 @@ LoadDVDFile (unsigned char *buffer)
offset = 0; offset = 0;
discoffset = dvddir; discoffset = dvddir;
ShowAction ((char*) "Loading..."); ShowAction ((char*) "Loading...");
if(length > 0)
{
dvd_read (buffer, length, discoffset);
}
else // load whole file
{
dvd_read (readbuffer, 2048, discoffset); dvd_read (readbuffer, 2048, discoffset);
if (!IsZipFile (readbuffer)) if (!IsZipFile (readbuffer))
@ -471,6 +478,7 @@ LoadDVDFile (unsigned char *buffer)
{ {
return UnZipFile (buffer, discoffset); // unzip from dvd return UnZipFile (buffer, discoffset); // unzip from dvd
} }
}
return dvddirlength; return dvddirlength;
} }

View File

@ -13,7 +13,7 @@
int getpvd (); int getpvd ();
int ParseDVDdirectory (); int ParseDVDdirectory ();
int LoadDVDFile (unsigned char *buffer); int LoadDVDFile (unsigned char *buffer, int length);
bool TestDVD(); bool TestDVD();
int dvd_read (void *dst, unsigned int len, u64 offset); int dvd_read (void *dst, unsigned int len, u64 offset);
bool SwitchDVDFolder(char dir[]); bool SwitchDVDFolder(char dir[]);

View File

@ -23,20 +23,6 @@
#include "menudraw.h" #include "menudraw.h"
#include "filesel.h" #include "filesel.h"
#include "preferences.h" #include "preferences.h"
#include "sdfileio.h"
// temporary
#include "vmmem.h"
#include "agb/GBA.h"
#include "agb/agbprint.h"
#include "Flash.h"
#include "Port.h"
#include "RTC.h"
#include "Sound.h"
#include "unzip.h"
#include "Util.h"
#include "dmg/GB.h"
#include "dmg/gbGlobals.h"
FILE * filehandle; FILE * filehandle;
@ -177,7 +163,7 @@ ParseFATdirectory(int method)
* LoadFATFile * LoadFATFile
***************************************************************************/ ***************************************************************************/
int int
LoadFATFile (char * rbuffer) LoadFATFile (char * rbuffer, int length)
{ {
char zipbuffer[2048]; char zipbuffer[2048];
char filepath[MAXPATHLEN]; char filepath[MAXPATHLEN];
@ -195,6 +181,13 @@ LoadFATFile (char * rbuffer)
handle = fopen (filepath, "rb"); handle = fopen (filepath, "rb");
if (handle > 0) if (handle > 0)
{
if(length > 0)
{
fread (rbuffer, 1, length, handle);
size = length;
}
else // load whole file
{ {
fread (zipbuffer, 1, 2048, handle); fread (zipbuffer, 1, 2048, handle);
@ -211,6 +204,7 @@ LoadFATFile (char * rbuffer)
memcpy (rbuffer, zipbuffer, 2048); // copy what we already read memcpy (rbuffer, zipbuffer, 2048); // copy what we already read
fread (rbuffer + 2048, 1, size - 2048, handle); fread (rbuffer + 2048, 1, size - 2048, handle);
} }
}
fclose (handle); fclose (handle);
return size; return size;
} }
@ -219,8 +213,6 @@ LoadFATFile (char * rbuffer)
WaitPrompt((char*) "Error opening file"); WaitPrompt((char*) "Error opening file");
return 0; return 0;
} }
return 0;
} }
/**************************************************************************** /****************************************************************************
@ -233,8 +225,6 @@ LoadBufferFromFAT (char *filepath, bool silent)
int boffset = 0; int boffset = 0;
int read = 0; int read = 0;
ClearSaveBuffer ();
handle = fopen (filepath, "rb"); handle = fopen (filepath, "rb");
if (handle <= 0) if (handle <= 0)
@ -282,7 +272,5 @@ SaveBufferToFAT (char *filepath, int datasize, bool silent)
fwrite (savebuffer, 1, datasize, handle); fwrite (savebuffer, 1, datasize, handle);
fclose (handle); fclose (handle);
} }
ClearSaveBuffer ();
return datasize; return datasize;
} }

View File

@ -23,7 +23,7 @@
bool ChangeFATInterface(int method, bool silent); bool ChangeFATInterface(int method, bool silent);
int ParseFATdirectory(int method); int ParseFATdirectory(int method);
int LoadFATFile (char * fbuffer); int LoadFATFile (char * fbuffer, int length);
int SaveBufferToFAT (char *filepath, int datasize, bool silent); int SaveBufferToFAT (char *filepath, int datasize, bool silent);
int LoadBufferFromFAT (char *filepath, bool silent); int LoadBufferFromFAT (char *filepath, bool silent);

View File

@ -49,24 +49,37 @@ int hasloaded = 0;
FILEENTRIES filelist[MAXFILES]; FILEENTRIES filelist[MAXFILES];
char ROMFilename[512]; char ROMFilename[512];
int ROMSize = 0; bool ROMLoaded = false;
unsigned char *savebuffer = NULL; unsigned char *savebuffer = NULL;
/**************************************************************************** /****************************************************************************
* ClearSaveBuffer () * AllocSaveBuffer ()
* Allocate and clear the savebuffer * Clear and allocate the savebuffer
***************************************************************************/ ***************************************************************************/
void void
ClearSaveBuffer () AllocSaveBuffer ()
{ {
if (savebuffer) if (savebuffer != NULL)
free(savebuffer); free(savebuffer);
savebuffer = (unsigned char *) memalign(32, SAVEBUFFERSIZE); savebuffer = (unsigned char *) memalign(32, SAVEBUFFERSIZE);
memset (savebuffer, 0, SAVEBUFFERSIZE); memset (savebuffer, 0, SAVEBUFFERSIZE);
} }
/****************************************************************************
* FreeSaveBuffer ()
* Free the savebuffer memory
***************************************************************************/
void
FreeSaveBuffer ()
{
if (savebuffer != NULL)
free(savebuffer);
savebuffer = NULL;
}
/**************************************************************************** /****************************************************************************
* autoLoadMethod() * autoLoadMethod()
* Auto-determines and sets the load method * Auto-determines and sets the load method
@ -216,7 +229,7 @@ void StripExt(char* returnstring, char * inputstring)
strcpy (returnstring, inputstring); strcpy (returnstring, inputstring);
loc_dot = strrchr(returnstring,'.'); loc_dot = strrchr(returnstring,'.');
if (loc_dot != NULL) if (loc_dot != NULL)
*loc_dot = '\0'; // strip file extension *loc_dot = 0; // strip file extension
} }
/**************************************************************************** /****************************************************************************
@ -321,9 +334,9 @@ int FileSelector (int method)
dvddirlength = filelist[selection].length; dvddirlength = filelist[selection].length;
} }
ROMSize = LoadVBAROM(method); ROMLoaded = LoadVBAROM(method);
if (ROMSize > 0) if (ROMLoaded)
{ {
return 1; return 1;
} }

View File

@ -36,7 +36,8 @@ extern int maxfiles;
extern char ROMFilename[512]; extern char ROMFilename[512];
void ClearSaveBuffer (); void AllocSaveBuffer();
void FreeSaveBuffer();
int OpenROM (int method); int OpenROM (int method);
int autoLoadMethod(); int autoLoadMethod();
int autoSaveMethod(); int autoSaveMethod();

View File

@ -16,9 +16,11 @@
#include "dvd.h" #include "dvd.h"
#include "smbop.h" #include "smbop.h"
#include "fileop.h"
#include "video.h" #include "video.h"
#include "menudraw.h" #include "menudraw.h"
#include "gcunzip.h" #include "gcunzip.h"
#include "vba.h"
/* /*
* PKWare Zip Header - adopted into zip standard * PKWare Zip Header - adopted into zip standard
@ -59,7 +61,7 @@ FLIP16 (u16 b)
* IsZipFile * IsZipFile
* *
* Returns TRUE when PKZIPID is first four characters of buffer * Returns TRUE when PKZIPID is first four characters of buffer
****************************************************************************/ ***************************************************************************/
int int
IsZipFile (char *buffer) IsZipFile (char *buffer)
{ {
@ -77,7 +79,7 @@ IsZipFile (char *buffer)
* unzip * unzip
* *
* It should be noted that there is a limit of 5MB total size for any ROM * It should be noted that there is a limit of 5MB total size for any ROM
******************************************************************************/ *****************************************************************************/
FILE* fatfile; // FAT FILE* fatfile; // FAT
u64 discoffset; // DVD u64 discoffset; // DVD
SMBFILE smbfile; // SMB SMBFILE smbfile; // SMB
@ -119,8 +121,7 @@ UnZipBuffer (unsigned char *outbuffer, short where)
pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize); pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize);
sprintf (msg, "Unzipping %d bytes ... Wait", sprintf (msg, "Unzipping %d bytes ... Wait", pkzip.uncompressedSize);
pkzip.uncompressedSize);
ShowAction (msg); ShowAction (msg);
/*** Prepare the zip stream ***/ /*** Prepare the zip stream ***/
@ -227,3 +228,41 @@ UnZipFile (unsigned char *outbuffer, SMBFILE infile)
smbfile = infile; smbfile = infile;
return UnZipBuffer(outbuffer, 2); return UnZipBuffer(outbuffer, 2);
} }
/****************************************************************************
* GetFirstZipFilename
*
* Returns the filename of the first file in the zipped archive
* The idea here is to do the least amount of work required
***************************************************************************/
char *
GetFirstZipFilename (int method)
{
char testbuffer[ZIPCHUNK];
// read start of ZIP
switch (method)
{
case METHOD_SD: // SD Card
case METHOD_USB: // USB
LoadFATFile (testbuffer, ZIPCHUNK);
break;
case METHOD_DVD: // DVD
LoadDVDFile ((unsigned char *)testbuffer, ZIPCHUNK);
break;
case METHOD_SMB: // From SMB
LoadSMBFile (testbuffer, ZIPCHUNK);
break;
}
testbuffer[28] = 0; // truncate - filename length is 2 bytes long (bytes 26-27)
int namelength = testbuffer[26]; // filename length starts 26 bytes in
char * firstFilename = &testbuffer[30]; // first filename of a ZIP starts 31 bytes in
firstFilename[namelength] = 0; // truncate at filename length
return firstFilename;
}

View File

@ -12,8 +12,8 @@
#include <smb.h> #include <smb.h>
extern int IsZipFile (char *buffer); int IsZipFile (char *buffer);
char * GetFirstZipFilename(int method);
int UnZipFile (unsigned char *outbuffer, FILE* infile); // Reading from FAT int UnZipFile (unsigned char *outbuffer, FILE* infile); // Reading from FAT
int UnZipFile (unsigned char *outbuffer, u64 inoffset); // Reading from DVD int UnZipFile (unsigned char *outbuffer, u64 inoffset); // Reading from DVD
int UnZipFile (unsigned char *outbuffer, SMBFILE infile); // Reading from SMB int UnZipFile (unsigned char *outbuffer, SMBFILE infile); // Reading from SMB

View File

@ -334,16 +334,16 @@ u32 GetJoy()
{ {
if (GCSettings.AutoSave == 1) if (GCSettings.AutoSave == 1)
{ {
SaveBattery(GCSettings.SaveMethod, SILENT); SaveBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // save battery
} }
else if (GCSettings.AutoSave == 2) else if (GCSettings.AutoSave == 2)
{ {
SaveState(GCSettings.SaveMethod, SILENT); SaveBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // save state
} }
else if(GCSettings.AutoSave == 3) else if(GCSettings.AutoSave == 3)
{ {
SaveBattery(GCSettings.SaveMethod, SILENT); SaveBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // save battery
SaveState(GCSettings.SaveMethod, SILENT); SaveBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // save state
} }
MainMenu(3); MainMenu(3);
return 0; return 0;

View File

@ -44,7 +44,7 @@ extern "C"
extern void DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsize); extern void DrawMenu (char items[][50], char *title, int maxitems, int selected, int fontsize);
extern int menu; extern int menu;
extern int ROMSize; extern bool ROMLoaded;
#define SOFTRESET_ADR ((volatile u32*)0xCC003024) #define SOFTRESET_ADR ((volatile u32*)0xCC003024)
@ -83,9 +83,9 @@ LoadManager ()
if ( loadROM == 1 ) // if ROM was loaded, load the battery / state if ( loadROM == 1 ) // if ROM was loaded, load the battery / state
{ {
if (GCSettings.AutoLoad == 1) if (GCSettings.AutoLoad == 1)
LoadBattery(GCSettings.SaveMethod, SILENT); LoadBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // load battery
else if (GCSettings.AutoLoad == 2) else if (GCSettings.AutoLoad == 2)
LoadState(GCSettings.SaveMethod, SILENT); LoadBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // load state
} }
return loadROM; return loadROM;
@ -123,8 +123,6 @@ PreferencesMenu ()
// they need to be skipped in the order they were enumerated in vba.h // they need to be skipped in the order they were enumerated in vba.h
// skip // skip
if(GCSettings.LoadMethod == METHOD_DVD)
GCSettings.LoadMethod++;
if(GCSettings.SaveMethod == METHOD_MC_SLOTA) if(GCSettings.SaveMethod == METHOD_MC_SLOTA)
GCSettings.SaveMethod++; GCSettings.SaveMethod++;
if(GCSettings.SaveMethod == METHOD_MC_SLOTB) if(GCSettings.SaveMethod == METHOD_MC_SLOTB)
@ -140,12 +138,6 @@ PreferencesMenu ()
GCSettings.SaveMethod++; GCSettings.SaveMethod++;
#endif #endif
// check if DVD access in Wii mode is disabled
#ifndef WII_DVD
if(GCSettings.LoadMethod == METHOD_DVD)
GCSettings.LoadMethod++;
#endif
// saving to DVD is impossible // saving to DVD is impossible
if(GCSettings.SaveMethod == METHOD_DVD) if(GCSettings.SaveMethod == METHOD_DVD)
GCSettings.SaveMethod++; GCSettings.SaveMethod++;
@ -306,20 +298,20 @@ GameMenu ()
break; break;
case 2: // Load Battery case 2: // Load Battery
quit = retval = LoadBattery(GCSettings.SaveMethod, NOTSILENT); quit = retval = LoadBatteryOrState(GCSettings.SaveMethod, 0, NOTSILENT);
emulator.emuReset(); emulator.emuReset();
break; break;
case 3: // Save Battery case 3: // Save Battery
SaveBattery(GCSettings.SaveMethod, NOTSILENT); SaveBatteryOrState(GCSettings.SaveMethod, 0, NOTSILENT);
break; break;
case 4: // Load State case 4: // Load State
quit = retval = LoadState(GCSettings.SaveMethod, NOTSILENT); quit = retval = LoadBatteryOrState(GCSettings.SaveMethod, 1, NOTSILENT);
break; break;
case 5: // Save State case 5: // Save State
SaveState(GCSettings.SaveMethod, NOTSILENT); SaveBatteryOrState(GCSettings.SaveMethod, 1, NOTSILENT);
break; break;
case -1: // Button B case -1: // Button B
@ -630,7 +622,7 @@ MainMenu (int selectedMenu)
int ret; int ret;
// disable game-specific menu items if a ROM isn't loaded // disable game-specific menu items if a ROM isn't loaded
if (ROMSize == 0 ) if (!ROMLoaded)
menuitems[3][0] = '\0'; menuitems[3][0] = '\0';
else else
sprintf (menuitems[3], "Game Menu"); sprintf (menuitems[3], "Game Menu");
@ -697,6 +689,7 @@ MainMenu (int selectedMenu)
case -1: // Button B case -1: // Button B
// Return to Game // Return to Game
if(ROMLoaded)
quit = 1; quit = 1;
break; break;
} }

View File

@ -366,7 +366,7 @@ WaitPrompt (char *msg)
ypos += 32; ypos += 32;
clearscreen (); clearscreen ();
setfontsize(20); setfontsize(16);
DrawText (-1, ypos, msg); DrawText (-1, ypos, msg);
ypos += 30; ypos += 30;
DrawText (-1, ypos, (char*)"Press A to continue"); DrawText (-1, ypos, (char*)"Press A to continue");

View File

@ -25,12 +25,6 @@
extern int currconfig[4]; extern int currconfig[4];
// button map configurations
extern unsigned int gcpadmap[];
extern unsigned int wmpadmap[];
extern unsigned int ccpadmap[];
extern unsigned int ncpadmap[];
#define PREFS_FILE_NAME "VBAGX.xml" #define PREFS_FILE_NAME "VBAGX.xml"
char prefscomment[2][32]; char prefscomment[2][32];
@ -46,7 +40,7 @@ mxml_node_t *section;
mxml_node_t *item; mxml_node_t *item;
mxml_node_t *elem; mxml_node_t *elem;
char temp[200]; char temp[20];
const char * toStr(int i) const char * toStr(int i)
{ {
@ -116,7 +110,6 @@ int
preparePrefsData (int method) preparePrefsData (int method)
{ {
int offset = 0; int offset = 0;
ClearSaveBuffer();
// add save icon and comments for Memory Card saves // add save icon and comments for Memory Card saves
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB) if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
@ -305,6 +298,8 @@ SavePrefs (int method, bool silent)
int datasize; int datasize;
int offset = 0; int offset = 0;
AllocSaveBuffer ();
datasize = preparePrefsData (method); datasize = preparePrefsData (method);
if (!silent) if (!silent)
@ -332,6 +327,8 @@ SavePrefs (int method, bool silent)
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, datasize, silent); offset = SaveBufferToMC (savebuffer, CARD_SLOTB, (char *)PREFS_FILE_NAME, datasize, silent);
} }
FreeSaveBuffer ();
if (offset > 0) if (offset > 0)
{ {
if (!silent) if (!silent)
@ -351,6 +348,8 @@ LoadPrefsFromMethod (int method)
char filepath[1024]; char filepath[1024];
int offset = 0; int offset = 0;
AllocSaveBuffer ();
if(method == METHOD_SD || method == METHOD_USB) if(method == METHOD_SD || method == METHOD_USB)
{ {
if(ChangeFATInterface(method, NOTSILENT)) if(ChangeFATInterface(method, NOTSILENT))
@ -376,6 +375,8 @@ LoadPrefsFromMethod (int method)
if (offset > 0) if (offset > 0)
retval = decodePrefsData (method); retval = decodePrefsData (method);
FreeSaveBuffer ();
return retval; return retval;
} }

View File

@ -212,9 +212,11 @@ ParseSMBdirectory ()
/**************************************************************************** /****************************************************************************
* Load SMB file * Load SMB file
* rom - pointer to memory where ROM will be stored
* length - # bytes to read (0 for all)
****************************************************************************/ ****************************************************************************/
int int
LoadSMBFile (char * rom) LoadSMBFile (char * rom, int length)
{ {
char filepath[MAXPATHLEN]; char filepath[MAXPATHLEN];
@ -226,7 +228,7 @@ LoadSMBFile (char * rom)
WaitPrompt((char*) "Maximum filepath length reached!"); WaitPrompt((char*) "Maximum filepath length reached!");
return -1; return -1;
} }
return LoadBufferFromSMB(rom, SMBPath(filepath), NOTSILENT); return LoadBufferFromSMB(rom, SMBPath(filepath), length, NOTSILENT);
} }
/**************************************************************************** /****************************************************************************
@ -269,8 +271,6 @@ SaveBufferToSMB (char *filepath, int datasize, bool silent)
sprintf(msg, "Couldn't save SMB: %s", SMBPath(filepath)); sprintf(msg, "Couldn't save SMB: %s", SMBPath(filepath));
WaitPrompt (msg); WaitPrompt (msg);
} }
ClearSaveBuffer ();
return boffset; return boffset;
} }
@ -282,12 +282,11 @@ SaveBufferToSMB (char *filepath, int datasize, bool silent)
int int
LoadBufferFromSMB (char *filepath, bool silent) LoadBufferFromSMB (char *filepath, bool silent)
{ {
ClearSaveBuffer (); return LoadBufferFromSMB((char *)savebuffer, filepath, 0, silent);
return LoadBufferFromSMB((char *)savebuffer, filepath, silent);
} }
int int
LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent) LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent)
{ {
if(!ConnectShare (NOTSILENT)) if(!ConnectShare (NOTSILENT))
return 0; return 0;
@ -310,10 +309,17 @@ LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent)
return 0; return 0;
} }
if(length > 0)
{
boffset = SMB_ReadFile (sbuffer, length, 0, smbfile);
}
else // load whole file
{
ret = SMB_ReadFile (sbuffer, 1024, boffset, smbfile); ret = SMB_ReadFile (sbuffer, 1024, boffset, smbfile);
if (IsZipFile (sbuffer)) if (IsZipFile (sbuffer))
{ {
WaitPrompt("In a ZIP");
boffset = UnZipFile ((unsigned char *)sbuffer, smbfile); // unzip from SMB boffset = UnZipFile ((unsigned char *)sbuffer, smbfile); // unzip from SMB
} }
else else
@ -322,6 +328,7 @@ LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent)
while ((ret = SMB_ReadFile (sbuffer + boffset, 1024, boffset, smbfile)) > 0) while ((ret = SMB_ReadFile (sbuffer + boffset, 1024, boffset, smbfile)) > 0)
boffset += ret; boffset += ret;
} }
}
SMB_CloseFile (smbfile); SMB_CloseFile (smbfile);
return boffset; return boffset;

View File

@ -17,9 +17,9 @@ bool ConnectShare (bool silent);
char * SMBPath(char * path); char * SMBPath(char * path);
int UpdateSMBdirname(); int UpdateSMBdirname();
int ParseSMBdirectory (); int ParseSMBdirectory ();
int LoadSMBFile (char * fbuffer); int LoadSMBFile (char * fbuffer, int length);
int LoadBufferFromSMB (char *filepath, bool silent); int LoadBufferFromSMB (char *filepath, bool silent);
int LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent); int LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent);
int SaveBufferToSMB (char *filepath, int datasize, bool silent); int SaveBufferToSMB (char *filepath, int datasize, bool silent);
#endif #endif

View File

@ -38,7 +38,7 @@ extern "C" {
#include "video.h" #include "video.h"
#include "vbaconfig.h" #include "vbaconfig.h"
extern int ROMSize; extern bool ROMLoaded;
extern int emulating; extern int emulating;
@ -98,7 +98,7 @@ int main()
selectedMenu = 2; // change to preferences menu selectedMenu = 2; // change to preferences menu
} }
while (ROMSize == 0) while (!ROMLoaded)
{ {
MainMenu (selectedMenu); MainMenu (selectedMenu);
} }

View File

@ -27,16 +27,19 @@
#include "vba.h" #include "vba.h"
#include "fileop.h" #include "fileop.h"
#include "dvd.h"
#include "smbop.h"
#include "memcardop.h"
#include "audio.h" #include "audio.h"
#include "vmmem.h" #include "vmmem.h"
#include "input.h" #include "input.h"
#include "video.h" #include "video.h"
#include "menudraw.h" #include "menudraw.h"
#include "gcunzip.h"
extern "C" extern "C"
{ {
#include "tbtime.h" #include "tbtime.h"
#include "sdfileio.h"
} }
static tb_t start, now; static tb_t start, now;
@ -181,108 +184,261 @@ void debuggerOutput(const char *s, u32 addr) {}
void (*dbgOutput)(const char *s, u32 addr) = debuggerOutput; void (*dbgOutput)(const char *s, u32 addr) = debuggerOutput;
void systemMessage(int num, const char *msg, ...) {} void systemMessage(int num, const char *msg, ...) {}
bool MemCPUReadBatteryFile(char * membuffer, int size)
{
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
if(size == 512 || size == 0x2000)
{
memcpy(eepromData, membuffer, size);
}
else
{
if(size == 0x20000)
{
memcpy(flashSaveMemory, membuffer, 0x20000);
flashSetSize(0x20000);
}
else
{
memcpy(flashSaveMemory, membuffer, 0x10000);
flashSetSize(0x10000);
}
}
return true;
}
extern int gbaSaveType;
int MemCPUWriteBatteryFile(char * membuffer)
{
int result = 0;
if(gbaSaveType == 0)
{
if(eepromInUse)
gbaSaveType = 3;
else
switch(saveType)
{
case 1:
gbaSaveType = 1;
break;
case 2:
gbaSaveType = 2;
break;
}
}
if((gbaSaveType) && (gbaSaveType!=5))
{
// only save if Flash/Sram in use or EEprom in use
if(gbaSaveType != 3)
{
if(gbaSaveType == 2)
{
memcpy(membuffer, flashSaveMemory, flashSize);
result = flashSize;
}
else
{
memcpy(membuffer, flashSaveMemory, 0x10000);
result = 0x10000;
}
}
else
{
memcpy(membuffer, eepromData, eepromSize);
result = eepromSize;
}
}
return result;
}
/**************************************************************************** /****************************************************************************
* Saves * SetFileBytesWritten
* Sets the # of bytes written into a file
* Used by GBA.cpp and GB.cpp
****************************************************************************/ ****************************************************************************/
bool LoadBattery(int method, bool silent) void SetFileBytesWritten(int bytes)
{
//datasize = bytes;
}
/****************************************************************************
* LoadBatteryOrState
* Load Battery/State file into memory
* action = 0 - Load battery
* action = 1 - Load state
****************************************************************************/
bool LoadBatteryOrState(int method, int action, bool silent)
{ {
char filepath[1024]; char filepath[1024];
bool result = false; bool result = false;
int offset = 0;
char ext[4];
if(action == 0)
sprintf(ext, "sav");
else
sprintf(ext, "sgm");
ShowAction ((char*) "Loading..."); ShowAction ((char*) "Loading...");
if(method == METHOD_AUTO) if(method == METHOD_AUTO)
method = autoSaveMethod(); // we use 'Save' because we need R/W method = autoSaveMethod(); // we use 'Save' because we need R/W
AllocSaveBuffer();
// load the file into savebuffer
if(method == METHOD_SD || method == METHOD_USB) if(method == METHOD_SD || method == METHOD_USB)
{ {
ChangeFATInterface(method, NOTSILENT); if(ChangeFATInterface(method, NOTSILENT))
sprintf (filepath, "%s/%s/%s.sav", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename); {
result = emulator.emuReadBattery(filepath); sprintf (filepath, "%s/%s/%s.%s", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename, ext);
offset = LoadBufferFromFAT (filepath, silent);
}
}
else if(method == METHOD_SMB)
{
sprintf (filepath, "%s/%s.%s", GCSettings.SaveFolder, ROMFilename, ext);
offset = LoadBufferFromSMB (filepath, silent);
}
else if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{
sprintf (filepath, "%s.%s", ROMFilename, ext);
if(method == METHOD_MC_SLOTA)
offset = LoadBufferFromMC (savebuffer, CARD_SLOTA, filepath, silent);
else
offset = LoadBufferFromMC (savebuffer, CARD_SLOTB, filepath, silent);
} }
if(!result && !silent) // load savebuffer into VBA memory
if (offset > 0)
{
if(action == 0)
{
if(cartridgeType == 1)
result = MemgbReadBatteryFile((char *)savebuffer, offset);
else
result = MemCPUReadBatteryFile((char *)savebuffer, offset);
}
else
{
result = emulator.emuReadMemState((char *)savebuffer, offset);
}
}
FreeSaveBuffer();
if(!silent && !result)
{
if(offset == 0)
{
if(action == 0)
WaitPrompt ((char*) "Save file not found"); WaitPrompt ((char*) "Save file not found");
return result;
}
bool SaveBattery(int method, bool silent)
{
char filepath[1024];
bool result = false;
ShowAction ((char*) "Saving...");
if(method == METHOD_AUTO)
method = autoSaveMethod(); // we use 'Save' because we need R/W
if(method == METHOD_SD || method == METHOD_USB)
{
ChangeFATInterface(method, NOTSILENT);
sprintf (filepath, "%s/%s/%s.sav", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
result = emulator.emuWriteBattery(filepath);
}
if(!silent)
{
if(result)
WaitPrompt ((char*) "Save successful");
else else
WaitPrompt ((char*) "Save failed");
}
return result;
}
bool LoadState(int method, bool silent)
{
char filepath[1024];
bool result = false;
ShowAction ((char*) "Loading...");
if(method == METHOD_AUTO)
method = autoSaveMethod(); // we use 'Save' because we need R/W
if(method == METHOD_SD || method == METHOD_USB)
{
ChangeFATInterface(method, NOTSILENT);
sprintf (filepath, "%s/%s/%s.sgm", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
result = emulator.emuReadState(filepath);
}
if(!result && !silent)
WaitPrompt ((char*) "State file not found"); WaitPrompt ((char*) "State file not found");
}
else
{
if(action == 0)
WaitPrompt ((char*) "Invalid save file");
else
WaitPrompt ((char*) "Invalid state file");
}
}
return result; return result;
} }
bool SaveState(int method, bool silent)
/****************************************************************************
* SaveBatteryOrState
* Save Battery/State file into memory
* action = 0 - Save battery
* action = 1 - Save state
****************************************************************************/
bool SaveBatteryOrState(int method, int action, bool silent)
{ {
char filepath[1024]; char filepath[1024];
bool result = false; bool result = false;
int offset = 0;
char ext[4];
int datasize = 0; // we need the actual size of the data written
if(action == 0)
sprintf(ext, "sav");
else
sprintf(ext, "sgm");
ShowAction ((char*) "Saving..."); ShowAction ((char*) "Saving...");
if(method == METHOD_AUTO) if(method == METHOD_AUTO)
method = autoSaveMethod(); // we use 'Save' because we need R/W method = autoSaveMethod(); // we use 'Save' because we need R/W
if(method == METHOD_SD || method == METHOD_USB) AllocSaveBuffer();
// put VBA memory into savebuffer, sets datasize to size of memory written
if(action == 0)
{ {
ChangeFATInterface(method, NOTSILENT); if(cartridgeType == 1)
sprintf (filepath, "%s/%s/%s.sgm", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename); datasize = MemgbWriteBatteryFile((char *)savebuffer);
result = emulator.emuWriteState(filepath); else
datasize = MemCPUWriteBatteryFile((char *)savebuffer);
}
else
{
bool written = emulator.emuWriteMemState((char *)savebuffer, SAVEBUFFERSIZE);
// we really should set datasize to the exact memory size written
// but instead we'll set it at 128K - although much of it will go unused
if(written)
datasize = (512*256);
} }
if(!silent) // write savebuffer into file
if(datasize > 0)
{ {
if(result) if(method == METHOD_SD || method == METHOD_USB)
WaitPrompt ((char*) "Save successful"); {
else if(ChangeFATInterface(method, NOTSILENT))
WaitPrompt ((char*) "Save failed"); {
sprintf (filepath, "%s/%s/%s.%s", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename, ext);
offset = SaveBufferToFAT (filepath, datasize, silent);
} }
}
else if(method == METHOD_SMB)
{
sprintf (filepath, "%s/%s.%s", GCSettings.SaveFolder, ROMFilename, ext);
offset = SaveBufferToSMB (filepath, datasize, silent);
}
else if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
{
sprintf (filepath, "%s.%s", ROMFilename, ext);
if(method == METHOD_MC_SLOTA)
offset = SaveBufferToMC (savebuffer, CARD_SLOTA, filepath, datasize, silent);
else
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, filepath, datasize, silent);
}
if(offset > 0)
{
if(!silent)
WaitPrompt ((char*) "Save successful");
result = true;
}
}
else
{
if(!silent)
WaitPrompt((char *)"No data to save!");
}
FreeSaveBuffer();
return result; return result;
} }
@ -343,42 +499,72 @@ void systemDrawScreen()
} }
extern bool gbUpdateSizes(); extern bool gbUpdateSizes();
bool LoadGBROM() bool LoadGBROM(int method)
{ {
char filepath[1024]; // cleanup GB memory
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename);
int size = 0;
if(gbRom != NULL) if(gbRom != NULL)
{
gbCleanUp(); gbCleanUp();
}
gbRom = (u8 *)malloc(1024*1024*4); // allocate 4 MB to GB ROM
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
gbRom = utilLoad(filepath, if(method == METHOD_AUTO)
utilIsGBImage, method = autoLoadMethod();
NULL,
size); switch (method)
{
case METHOD_SD:
case METHOD_USB:
gbRomSize = LoadFATFile ((char *)gbRom, 0);
break;
case METHOD_DVD:
gbRomSize = LoadDVDFile ((unsigned char *)gbRom, 0);
break;
case METHOD_SMB:
gbRomSize = LoadSMBFile ((char *)gbRom, 0);
break;
}
if(!gbRom) if(!gbRom)
return false; return false;
gbRomSize = size;
return gbUpdateSizes(); return gbUpdateSizes();
} }
int LoadVBAROM(int method) bool LoadVBAROM(int method)
{ {
int type = 2; int type = 0;
bool loaded = false;
// image type (checks file extension) // image type (checks file extension)
/* if(utilIsGBAImage(filename)) if(utilIsGBAImage(filelist[selection].filename))
type = 2; type = 2;
else if(utilIsGBImage(filename)) else if(utilIsGBImage(filelist[selection].filename))
type = 1; type = 1;
*/ else if(utilIsZipFile(filelist[selection].filename))
{
// we need to check the file extension of the first file in the archive
char * zippedFilename = GetFirstZipFilename (method);
if(strlen(zippedFilename) > 0)
{
if(utilIsGBAImage(zippedFilename))
type = 2;
else if(utilIsGBImage(zippedFilename))
type = 1;
}
}
// leave before we do anything
if(type != 1 && type != 2)
{
WaitPrompt((char *)"Unknown game image!");
return false;
}
cartridgeType = 0; cartridgeType = 0;
srcWidth = 0; srcWidth = 0;
srcHeight = 0; srcHeight = 0;
@ -394,7 +580,7 @@ int LoadVBAROM(int method)
emulator = GBASystem; emulator = GBASystem;
srcWidth = 240; srcWidth = 240;
srcHeight = 160; srcHeight = 160;
VMCPULoadROM(method); loaded = VMCPULoadROM(method);
// Actual Visual Aspect is 1.57 // Actual Visual Aspect is 1.57
hAspect = 70; hAspect = 70;
vAspect = 46; vAspect = 46;
@ -410,7 +596,7 @@ int LoadVBAROM(int method)
emulator = GBSystem; emulator = GBSystem;
srcWidth = 160; srcWidth = 160;
srcHeight = 144; srcHeight = 144;
LoadGBROM(); loaded = LoadGBROM(method);
// Actual physical aspect is 1.0 // Actual physical aspect is 1.0
hAspect = 60; hAspect = 60;
vAspect = 46; vAspect = 46;
@ -418,13 +604,15 @@ int LoadVBAROM(int method)
soundQuality = 1; soundQuality = 1;
soundBufferLen = 1470 * 2; soundBufferLen = 1470 * 2;
break; break;
default:
WaitPrompt((char *)"Unknown Image");
return 0;
break;
} }
if(!loaded)
{
WaitPrompt((char *)"Error loading game!");
return false;
}
else
{
// Set defaults // Set defaults
flashSetSize(0x20000); // 128K saves flashSetSize(0x20000); // 128K saves
rtcEnable(true); rtcEnable(true);
@ -460,7 +648,8 @@ int LoadVBAROM(int method)
// Start system clock // Start system clock
mftb(&start); mftb(&start);
return 1; return true;
}
} }
/**************************************************************************** /****************************************************************************

View File

@ -12,9 +12,7 @@
extern struct EmulatedSystem emulator; extern struct EmulatedSystem emulator;
extern u32 loadtimeradjust; extern u32 loadtimeradjust;
int LoadVBAROM(int method); bool LoadVBAROM(int method);
void InitialisePalette(); void InitialisePalette();
bool LoadBattery(int method, bool silent); bool LoadBatteryOrState(int method, int action, bool silent);
bool SaveBattery(int method, bool silent); bool SaveBatteryOrState(int method, int action, bool silent);
bool LoadState(int method, bool silent);
bool SaveState(int method, bool silent);

View File

@ -100,7 +100,7 @@ static void VMClose( void )
* MEM2 version of GBA CPULoadROM * MEM2 version of GBA CPULoadROM
****************************************************************************/ ****************************************************************************/
int VMCPULoadROM(int method) bool VMCPULoadROM(int method)
{ {
VMClose(); VMClose();
VMAllocGBA(); VMAllocGBA();
@ -114,24 +114,28 @@ int VMCPULoadROM(int method)
{ {
case METHOD_SD: case METHOD_SD:
case METHOD_USB: case METHOD_USB:
GBAROMSize = LoadFATFile ((char *)rom); GBAROMSize = LoadFATFile ((char *)rom, 0);
break; break;
case METHOD_DVD: case METHOD_DVD:
GBAROMSize = LoadDVDFile ((unsigned char *)rom); GBAROMSize = LoadDVDFile ((unsigned char *)rom, 0);
break; break;
case METHOD_SMB: case METHOD_SMB:
GBAROMSize = LoadSMBFile ((char *)rom); GBAROMSize = LoadSMBFile ((char *)rom, 0);
break; break;
} }
if(GBAROMSize) if(GBAROMSize)
{
CPUUpdateRenderBuffers( true ); CPUUpdateRenderBuffers( true );
return true;
}
else else
{
VMClose(); VMClose();
return false;
return GBAROMSize; }
} }
@ -202,6 +206,9 @@ u8 VMRead8( u32 address )
#include "Port.h" #include "Port.h"
#include "menudraw.h" #include "menudraw.h"
#include "filesel.h"
#include "vba.h"
#include "fileop.h"
extern "C" { extern "C" {
#include "tbtime.h" #include "tbtime.h"
@ -237,7 +244,6 @@ static char *gbabase = NULL;
static FILE* romfile = NULL; static FILE* romfile = NULL;
static int useVM = 0; static int useVM = 0;
static u32 GBAROMSize = 0; static u32 GBAROMSize = 0;
static char romfilename[1024];
/** /**
* GBA Memory * GBA Memory
@ -365,10 +371,12 @@ static void VMClose( void )
* *
* VM version of GBA CPULoadROM * VM version of GBA CPULoadROM
****************************************************************************/ ****************************************************************************/
int VMCPULoadROM( char *filename )
int VMCPULoadROM(int method)
{ {
int res; int res;
char msg[512]; char msg[512];
char filepath[MAXPATHLEN];
/** Fix VM **/ /** Fix VM **/
VMClose(); VMClose();
@ -377,9 +385,41 @@ int VMCPULoadROM( char *filename )
loadtimeradjust = useVM = GBAROMSize = 0; loadtimeradjust = useVM = GBAROMSize = 0;
//printf("Filename %s\n", filename); if(method == METHOD_AUTO)
method = autoLoadMethod();
romfile = gen_fopen(filename, "rb"); switch (method)
{
case METHOD_SD:
case METHOD_USB:
if(!ChangeFATInterface(method, NOTSILENT))
{
VMClose();
return 0;
}
break;
case METHOD_DVD:
VMClose();
return 0; // not implemented
break;
case METHOD_SMB:
VMClose();
return 0; // not implemented
break;
}
/* Check filename length */
if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN)
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename);
else
{
WaitPrompt((char*) "Maximum filepath length reached!");
return -1;
}
romfile = fopen(filepath, "rb");
if ( romfile == NULL ) if ( romfile == NULL )
{ {
WaitPrompt((char*) "Error opening file!"); WaitPrompt((char*) "Error opening file!");
@ -408,8 +448,6 @@ int VMCPULoadROM( char *filename )
vmpage[0].pagetype = MEM_VM; vmpage[0].pagetype = MEM_VM;
useVM = 1; useVM = 1;
strcpy( romfilename, filename );
CPUUpdateRenderBuffers( true ); CPUUpdateRenderBuffers( true );
return 1; return 1;

View File

@ -11,7 +11,7 @@
#ifndef __VBAVMHDR__ #ifndef __VBAVMHDR__
#define __VBAVMHDR__ #define __VBAVMHDR__
int VMCPULoadROM(int method); bool VMCPULoadROM(int method);
u32 VMRead32( u32 address ); u32 VMRead32( u32 address );
u16 VMRead16( u32 address ); u16 VMRead16( u32 address );
u8 VMRead8( u32 address ); u8 VMRead8( u32 address );

View File

@ -609,7 +609,7 @@ IMAGE_TYPE utilFindType(const char *file)
return IMAGE_UNKNOWN; return IMAGE_UNKNOWN;
} }
static int utilGetSize(int size) int utilGetSize(int size)
{ {
int res = 1; int res = 1;
while(res < size) while(res < size)

View File

@ -35,12 +35,14 @@ typedef struct {
int size; int size;
} variable_desc; } variable_desc;
extern int utilGetSize(int size);
extern bool utilWritePNGFile(const char *, int, int, u8 *); extern bool utilWritePNGFile(const char *, int, int, u8 *);
extern bool utilWriteBMPFile(const char *, int, int, u8 *); extern bool utilWriteBMPFile(const char *, int, int, u8 *);
extern void utilApplyIPS(const char *ips, u8 **rom, int *size); extern void utilApplyIPS(const char *ips, u8 **rom, int *size);
extern bool utilIsGBAImage(const char *); extern bool utilIsGBAImage(const char *);
extern bool utilIsGBImage(const char *); extern bool utilIsGBImage(const char *);
extern bool utilIsGzipFile(const char *); extern bool utilIsGzipFile(const char *);
extern bool utilIsZipFile(const char *);
extern void utilStripDoubleExtension(const char *, char *); extern void utilStripDoubleExtension(const char *, char *);
extern IMAGE_TYPE utilFindType(const char *); extern IMAGE_TYPE utilFindType(const char *);
extern u8 *utilLoad(const char *, extern u8 *utilLoad(const char *,

View File

@ -653,6 +653,8 @@ bool CPUWriteState(const char *file)
return res; return res;
} }
extern void SetFileBytesWritten(int bytes); // Tantric - Wii/GameCube addition - store # bytes written
bool CPUWriteMemState(char *memory, int available) bool CPUWriteMemState(char *memory, int available)
{ {
gzFile gzFile = utilMemGzOpen(memory, available, "w"); gzFile gzFile = utilMemGzOpen(memory, available, "w");
@ -668,6 +670,8 @@ bool CPUWriteMemState(char *memory, int available)
if(pos >= (available)) if(pos >= (available))
res = false; res = false;
SetFileBytesWritten((int)pos); // Tantric - Wii/GameCube addition - store # bytes written
utilGzClose(gzFile); utilGzClose(gzFile);
return res; return res;

View File

@ -2303,6 +2303,8 @@ static bool gbWriteSaveState(gzFile gzFile)
return true; return true;
} }
extern void SetFileBytesWritten(int bytes); // Tantric - Wii/GameCube addition - store # bytes written
bool gbWriteMemSaveState(char *memory, int available) bool gbWriteMemSaveState(char *memory, int available)
{ {
gzFile gzFile = utilMemGzOpen(memory, available, "w"); gzFile gzFile = utilMemGzOpen(memory, available, "w");
@ -2319,6 +2321,8 @@ bool gbWriteMemSaveState(char *memory, int available)
if(pos >= (available)) if(pos >= (available))
res = false; res = false;
SetFileBytesWritten((int)pos); // Tantric - Wii/GameCube addition - store # bytes written
utilGzClose(gzFile); utilGzClose(gzFile);
return res; return res;
@ -3469,3 +3473,320 @@ struct EmulatedSystem GBSystem =
1000, 1000,
#endif #endif
}; };
/****************************************************************************
* Nintendo Wii/Gamecube Port Additions
*
* Duplicate versions of save functions above, using memory
* I want to kill whoever wrote so many stupid functions, and did so without
* doing it memory-based
* Tantric - October 2008
***************************************************************************/
int MemgbWriteSaveMBC1(char * membuffer) {
if (gbRam) {
memcpy(membuffer, gbRam, (gbRamSizeMask + 1));
return (gbRamSizeMask + 1);
}
return 0;
}
int MemgbWriteSaveMBC2(char * membuffer) {
if (gbRam) {
memcpy(membuffer, &gbMemory[0xa000], 256);
return 256;
}
return 0;
}
int MemgbWriteSaveMBC3(char * membuffer, bool extendedSave) {
int offset = 0;
if (gbRam || extendedSave) {
if (gbRam) {
memcpy(membuffer, gbRam, (gbRamSizeMask + 1));
offset += (gbRamSizeMask + 1);
}
if (extendedSave)
{
memcpy(membuffer+offset, &gbDataMBC3.mapperSeconds, (10 * sizeof(int)
+ sizeof(time_t)));
offset += (10 * sizeof(int) + sizeof(time_t));
}
}
return offset;
}
int MemgbWriteSaveMBC5(char * membuffer) {
if (gbRam) {
memcpy(membuffer, gbRam, (gbRamSizeMask + 1));
return (gbRamSizeMask + 1);
}
return 0;
}
int MemgbWriteSaveMBC7(char * membuffer) {
if (gbRam) {
memcpy(membuffer, &gbMemory[0xa000], 256);
return 256;
}
return 0;
}
int MemgbWriteSaveTAMA5(char * membuffer, bool extendedSave) {
int offset = 0;
/* if (gbRam)
{
memcpy(membuffer, gbRam, (gbRamSizeMask + 1));
offset += (gbRamSizeMask + 1);
}
memcpy(membuffer+offset, gbTAMA5ram, (gbTAMA5ramSize));
offset += (gbTAMA5ramSize);
if (extendedSave)
{
memcpy(membuffer+offset, &gbDataTAMA5.mapperSeconds, (14 * sizeof(int) + sizeof(time_t)));
offset += (14 * sizeof(int) + sizeof(time_t));
}*/
return offset;
}
int MemgbWriteSaveMMM01(char * membuffer) {
if (gbRam) {
memcpy(membuffer, gbRam, (gbRamSizeMask + 1));
return (gbRamSizeMask + 1);
}
return 0;
}
bool MemgbReadSaveMBC1(char * membuffer, int read) {
if (gbRam)
{
if (read != (gbRamSizeMask + 1))
return false;
else
memcpy(gbRam, membuffer, read);
return true;
}
return false;
}
bool MemgbReadSaveMBC2(char * membuffer, int read) {
if (gbRam)
{
if (read != 256)
return false;
else
memcpy(&gbMemory[0xa000], membuffer, read);
return true;
}
return false;
}
bool MemgbReadSaveMBC3(char * membuffer, int read) {
int offset = 0;
if (gbRam)
{
if(read < (gbRamSizeMask + 1))
return false;
memcpy(gbRam, membuffer, (gbRamSizeMask + 1));
offset += (gbRamSizeMask + 1);
}
int gbRomType = gbRom[0x147];
if ((gbRomType == 0xf) || (gbRomType == 0x10))
{
if((uint)read < (offset + sizeof(int) * 10 + sizeof(time_t)))
return false;
memcpy(&gbDataMBC3.mapperSeconds, membuffer+offset, sizeof(int) * 10 + sizeof(time_t));
}
return true;
}
bool MemgbReadSaveMBC5(char * membuffer, int read) {
if (gbRam)
{
if (read != (gbRamSizeMask + 1))
return false;
else
memcpy(gbRam, membuffer, read);
return true;
}
return false;
}
bool MemgbReadSaveMBC7(char * membuffer, int read) {
if (gbRam)
{
if (read != 256)
return false;
else
memcpy(&gbMemory[0xa000], membuffer, read);
return true;
}
return false;
}
bool MemgbReadSaveTAMA5(char * membuffer, int read) {
/* if (gbRam)
{
if (gbRamSizeMask + gbTAMA5ramSize + 1)
return false;
memcpy(gbRam, membuffer, (gbRamSizeMask + 1));
int offset = (gbRamSizeMask + 1);
memcpy(&gbDataTAMA5.mapperSeconds, membuffer+offset, sizeof(int) * 14 + sizeof(time_t));
return true;
}*/
return false;
}
bool MemgbReadSaveMMM01(char * membuffer, int read) {
if (gbRam)
{
if (read != (gbRamSizeMask + 1))
return false;
else
memcpy(gbRam, membuffer, read);
return true;
}
return false;
}
int MemgbWriteBatteryFile(char * membuffer)
{
int result = 0;
if(gbBattery)
{
int type = gbRom[0x147];
bool extendedSave = true;
switch(type)
{
case 0x03:
result = MemgbWriteSaveMBC1(membuffer);
break;
case 0x06:
result = MemgbWriteSaveMBC2(membuffer);
break;
case 0x0d:
result = MemgbWriteSaveMMM01(membuffer);
break;
case 0x0f:
case 0x10:
result = MemgbWriteSaveMBC3(membuffer, extendedSave);
break;
case 0x13:
case 0xfc:
result = MemgbWriteSaveMBC3(membuffer, false);
case 0x1b:
case 0x1e:
result = MemgbWriteSaveMBC5(membuffer);
break;
case 0x22:
result = MemgbWriteSaveMBC7(membuffer);
break;
case 0xfd:
result = MemgbWriteSaveTAMA5(membuffer, extendedSave);
break;
case 0xff:
result = MemgbWriteSaveMBC1(membuffer);
break;
}
}
return result;
}
bool MemgbReadBatteryFile(char * membuffer, int read)
{
bool res = false;
if (gbBattery) {
int type = gbRom[0x147];
switch (type) {
case 0x03:
res = MemgbReadSaveMBC1(membuffer, read);
break;
case 0x06:
res = MemgbReadSaveMBC2(membuffer, read);
break;
case 0x0d:
res = MemgbReadSaveMMM01(membuffer, read);
break;
case 0x0f:
case 0x10:
res = MemgbReadSaveMBC3(membuffer, read);
if (!res) {
time(&gbDataMBC3.mapperLastTime);
struct tm *lt;
lt = localtime(&gbDataMBC3.mapperLastTime);
gbDataMBC3.mapperSeconds = lt->tm_sec;
gbDataMBC3.mapperMinutes = lt->tm_min;
gbDataMBC3.mapperHours = lt->tm_hour;
gbDataMBC3.mapperDays = lt->tm_yday & 255;
gbDataMBC3.mapperControl = (gbDataMBC3.mapperControl & 0xfe)
| (lt->tm_yday > 255 ? 1 : 0);
res = 0;
break;
}
break;
case 0x13:
case 0xfc:
res = MemgbReadSaveMBC3(membuffer, read);
break;
case 0x1b:
case 0x1e:
res = MemgbReadSaveMBC5(membuffer, read);
break;
case 0x22:
res = MemgbReadSaveMBC7(membuffer, read);
break;
case 0xfd:
/* res = MemgbReadSaveTAMA5(membuffer, read);
if (!res) {
u8 gbDaysinMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30,
31, 30, 31 };
time(&gbDataTAMA5.mapperLastTime);
struct tm *lt;
lt = localtime(&gbDataTAMA5.mapperLastTime);
gbDataTAMA5.mapperSeconds = lt->tm_sec;
gbDataTAMA5.mapperMinutes = lt->tm_min;
gbDataTAMA5.mapperHours = lt->tm_hour;
gbDataTAMA5.mapperDays = 1;
gbDataTAMA5.mapperMonths = 1;
gbDataTAMA5.mapperYears = 1970;
int days = lt->tm_yday + 365 * 3;
while (days) {
gbDataTAMA5.mapperDays++;
days--;
if (gbDataTAMA5.mapperDays
> gbDaysinMonth[gbDataTAMA5.mapperMonths - 1]) {
gbDataTAMA5.mapperDays = 1;
gbDataTAMA5.mapperMonths++;
if (gbDataTAMA5.mapperMonths > 12) {
gbDataTAMA5.mapperMonths = 1;
gbDataTAMA5.mapperYears++;
if ((gbDataTAMA5.mapperYears & 3) == 0)
gbDaysinMonth[1] = 29;
else
gbDaysinMonth[1] = 28;
}
}
}
gbDataTAMA5.mapperControl = (gbDataTAMA5.mapperControl & 0xfe)
| (lt->tm_yday > 255 ? 1 : 0);
res = false;
break;
}*/
break;
case 0xff:
res = MemgbReadSaveMBC1(membuffer, read);
break;
}
}
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
return res;
}

View File

@ -59,4 +59,7 @@ extern bool gbReadGSASnapshot(const char *);
extern struct EmulatedSystem GBSystem; extern struct EmulatedSystem GBSystem;
bool MemgbReadBatteryFile(char * membuffer, int read);
int MemgbWriteBatteryFile(char * membuffer);
#endif #endif