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) \
-DNGC -DWORDS_BIGENDIAN -DC_CORE -DFINAL_VERSION \
-DNGC -DWII_DVD -DWORDS_BIGENDIAN -DC_CORE -DFINAL_VERSION \
-DSDL -DNO_PNG -DHAVE_ZUTIL_H
CXXFLAGS = $(CFLAGS)
LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref

View File

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

View File

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

View File

@ -23,20 +23,6 @@
#include "menudraw.h"
#include "filesel.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;
@ -177,7 +163,7 @@ ParseFATdirectory(int method)
* LoadFATFile
***************************************************************************/
int
LoadFATFile (char * rbuffer)
LoadFATFile (char * rbuffer, int length)
{
char zipbuffer[2048];
char filepath[MAXPATHLEN];
@ -195,6 +181,13 @@ LoadFATFile (char * rbuffer)
handle = fopen (filepath, "rb");
if (handle > 0)
{
if(length > 0)
{
fread (rbuffer, 1, length, handle);
size = length;
}
else // load whole file
{
fread (zipbuffer, 1, 2048, handle);
@ -211,6 +204,7 @@ LoadFATFile (char * rbuffer)
memcpy (rbuffer, zipbuffer, 2048); // copy what we already read
fread (rbuffer + 2048, 1, size - 2048, handle);
}
}
fclose (handle);
return size;
}
@ -219,8 +213,6 @@ LoadFATFile (char * rbuffer)
WaitPrompt((char*) "Error opening file");
return 0;
}
return 0;
}
/****************************************************************************
@ -233,8 +225,6 @@ LoadBufferFromFAT (char *filepath, bool silent)
int boffset = 0;
int read = 0;
ClearSaveBuffer ();
handle = fopen (filepath, "rb");
if (handle <= 0)
@ -282,7 +272,5 @@ SaveBufferToFAT (char *filepath, int datasize, bool silent)
fwrite (savebuffer, 1, datasize, handle);
fclose (handle);
}
ClearSaveBuffer ();
return datasize;
}

View File

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

View File

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

View File

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

View File

@ -16,9 +16,11 @@
#include "dvd.h"
#include "smbop.h"
#include "fileop.h"
#include "video.h"
#include "menudraw.h"
#include "gcunzip.h"
#include "vba.h"
/*
* PKWare Zip Header - adopted into zip standard
@ -59,7 +61,7 @@ FLIP16 (u16 b)
* IsZipFile
*
* Returns TRUE when PKZIPID is first four characters of buffer
****************************************************************************/
***************************************************************************/
int
IsZipFile (char *buffer)
{
@ -77,7 +79,7 @@ IsZipFile (char *buffer)
* unzip
*
* It should be noted that there is a limit of 5MB total size for any ROM
******************************************************************************/
*****************************************************************************/
FILE* fatfile; // FAT
u64 discoffset; // DVD
SMBFILE smbfile; // SMB
@ -119,8 +121,7 @@ UnZipBuffer (unsigned char *outbuffer, short where)
pkzip.uncompressedSize = FLIP32 (pkzip.uncompressedSize);
sprintf (msg, "Unzipping %d bytes ... Wait",
pkzip.uncompressedSize);
sprintf (msg, "Unzipping %d bytes ... Wait", pkzip.uncompressedSize);
ShowAction (msg);
/*** Prepare the zip stream ***/
@ -227,3 +228,41 @@ UnZipFile (unsigned char *outbuffer, SMBFILE infile)
smbfile = infile;
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>
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, u64 inoffset); // Reading from DVD
int UnZipFile (unsigned char *outbuffer, SMBFILE infile); // Reading from SMB

View File

@ -334,16 +334,16 @@ u32 GetJoy()
{
if (GCSettings.AutoSave == 1)
{
SaveBattery(GCSettings.SaveMethod, SILENT);
SaveBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // save battery
}
else if (GCSettings.AutoSave == 2)
{
SaveState(GCSettings.SaveMethod, SILENT);
SaveBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // save state
}
else if(GCSettings.AutoSave == 3)
{
SaveBattery(GCSettings.SaveMethod, SILENT);
SaveState(GCSettings.SaveMethod, SILENT);
SaveBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // save battery
SaveBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // save state
}
MainMenu(3);
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 int menu;
extern int ROMSize;
extern bool ROMLoaded;
#define SOFTRESET_ADR ((volatile u32*)0xCC003024)
@ -83,9 +83,9 @@ LoadManager ()
if ( loadROM == 1 ) // if ROM was loaded, load the battery / state
{
if (GCSettings.AutoLoad == 1)
LoadBattery(GCSettings.SaveMethod, SILENT);
LoadBatteryOrState(GCSettings.SaveMethod, 0, SILENT); // load battery
else if (GCSettings.AutoLoad == 2)
LoadState(GCSettings.SaveMethod, SILENT);
LoadBatteryOrState(GCSettings.SaveMethod, 1, SILENT); // load state
}
return loadROM;
@ -123,8 +123,6 @@ PreferencesMenu ()
// they need to be skipped in the order they were enumerated in vba.h
// skip
if(GCSettings.LoadMethod == METHOD_DVD)
GCSettings.LoadMethod++;
if(GCSettings.SaveMethod == METHOD_MC_SLOTA)
GCSettings.SaveMethod++;
if(GCSettings.SaveMethod == METHOD_MC_SLOTB)
@ -140,12 +138,6 @@ PreferencesMenu ()
GCSettings.SaveMethod++;
#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
if(GCSettings.SaveMethod == METHOD_DVD)
GCSettings.SaveMethod++;
@ -306,20 +298,20 @@ GameMenu ()
break;
case 2: // Load Battery
quit = retval = LoadBattery(GCSettings.SaveMethod, NOTSILENT);
quit = retval = LoadBatteryOrState(GCSettings.SaveMethod, 0, NOTSILENT);
emulator.emuReset();
break;
case 3: // Save Battery
SaveBattery(GCSettings.SaveMethod, NOTSILENT);
SaveBatteryOrState(GCSettings.SaveMethod, 0, NOTSILENT);
break;
case 4: // Load State
quit = retval = LoadState(GCSettings.SaveMethod, NOTSILENT);
quit = retval = LoadBatteryOrState(GCSettings.SaveMethod, 1, NOTSILENT);
break;
case 5: // Save State
SaveState(GCSettings.SaveMethod, NOTSILENT);
SaveBatteryOrState(GCSettings.SaveMethod, 1, NOTSILENT);
break;
case -1: // Button B
@ -630,7 +622,7 @@ MainMenu (int selectedMenu)
int ret;
// disable game-specific menu items if a ROM isn't loaded
if (ROMSize == 0 )
if (!ROMLoaded)
menuitems[3][0] = '\0';
else
sprintf (menuitems[3], "Game Menu");
@ -697,6 +689,7 @@ MainMenu (int selectedMenu)
case -1: // Button B
// Return to Game
if(ROMLoaded)
quit = 1;
break;
}

View File

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

View File

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

View File

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

View File

@ -17,9 +17,9 @@ bool ConnectShare (bool silent);
char * SMBPath(char * path);
int UpdateSMBdirname();
int ParseSMBdirectory ();
int LoadSMBFile (char * fbuffer);
int LoadSMBFile (char * fbuffer, int length);
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);
#endif

View File

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

View File

@ -27,16 +27,19 @@
#include "vba.h"
#include "fileop.h"
#include "dvd.h"
#include "smbop.h"
#include "memcardop.h"
#include "audio.h"
#include "vmmem.h"
#include "input.h"
#include "video.h"
#include "menudraw.h"
#include "gcunzip.h"
extern "C"
{
#include "tbtime.h"
#include "sdfileio.h"
}
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 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];
bool result = false;
int offset = 0;
char ext[4];
if(action == 0)
sprintf(ext, "sav");
else
sprintf(ext, "sgm");
ShowAction ((char*) "Loading...");
if(method == METHOD_AUTO)
method = autoSaveMethod(); // we use 'Save' because we need R/W
AllocSaveBuffer();
// load the file into savebuffer
if(method == METHOD_SD || method == METHOD_USB)
{
ChangeFATInterface(method, NOTSILENT);
sprintf (filepath, "%s/%s/%s.sav", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
result = emulator.emuReadBattery(filepath);
if(ChangeFATInterface(method, NOTSILENT))
{
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");
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
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");
}
else
{
if(action == 0)
WaitPrompt ((char*) "Invalid save file");
else
WaitPrompt ((char*) "Invalid state file");
}
}
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];
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...");
if(method == METHOD_AUTO)
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);
sprintf (filepath, "%s/%s/%s.sgm", ROOTFATDIR, GCSettings.SaveFolder, ROMFilename);
result = emulator.emuWriteState(filepath);
if(cartridgeType == 1)
datasize = MemgbWriteBatteryFile((char *)savebuffer);
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)
WaitPrompt ((char*) "Save successful");
else
WaitPrompt ((char*) "Save failed");
if(method == METHOD_SD || method == METHOD_USB)
{
if(ChangeFATInterface(method, NOTSILENT))
{
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;
}
@ -343,42 +499,72 @@ void systemDrawScreen()
}
extern bool gbUpdateSizes();
bool LoadGBROM()
bool LoadGBROM(int method)
{
char filepath[1024];
sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename);
int size = 0;
// cleanup GB memory
if(gbRom != NULL)
{
gbCleanUp();
}
gbRom = (u8 *)malloc(1024*1024*4); // allocate 4 MB to GB ROM
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
gbRom = utilLoad(filepath,
utilIsGBImage,
NULL,
size);
if(method == METHOD_AUTO)
method = autoLoadMethod();
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)
return false;
gbRomSize = size;
return gbUpdateSizes();
}
int LoadVBAROM(int method)
bool LoadVBAROM(int method)
{
int type = 2;
int type = 0;
bool loaded = false;
// image type (checks file extension)
/* if(utilIsGBAImage(filename))
if(utilIsGBAImage(filelist[selection].filename))
type = 2;
else if(utilIsGBImage(filename))
else if(utilIsGBImage(filelist[selection].filename))
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;
srcWidth = 0;
srcHeight = 0;
@ -394,7 +580,7 @@ int LoadVBAROM(int method)
emulator = GBASystem;
srcWidth = 240;
srcHeight = 160;
VMCPULoadROM(method);
loaded = VMCPULoadROM(method);
// Actual Visual Aspect is 1.57
hAspect = 70;
vAspect = 46;
@ -410,7 +596,7 @@ int LoadVBAROM(int method)
emulator = GBSystem;
srcWidth = 160;
srcHeight = 144;
LoadGBROM();
loaded = LoadGBROM(method);
// Actual physical aspect is 1.0
hAspect = 60;
vAspect = 46;
@ -418,13 +604,15 @@ int LoadVBAROM(int method)
soundQuality = 1;
soundBufferLen = 1470 * 2;
break;
default:
WaitPrompt((char *)"Unknown Image");
return 0;
break;
}
if(!loaded)
{
WaitPrompt((char *)"Error loading game!");
return false;
}
else
{
// Set defaults
flashSetSize(0x20000); // 128K saves
rtcEnable(true);
@ -460,7 +648,8 @@ int LoadVBAROM(int method)
// Start system clock
mftb(&start);
return 1;
return true;
}
}
/****************************************************************************

View File

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

View File

@ -100,7 +100,7 @@ static void VMClose( void )
* MEM2 version of GBA CPULoadROM
****************************************************************************/
int VMCPULoadROM(int method)
bool VMCPULoadROM(int method)
{
VMClose();
VMAllocGBA();
@ -114,24 +114,28 @@ int VMCPULoadROM(int method)
{
case METHOD_SD:
case METHOD_USB:
GBAROMSize = LoadFATFile ((char *)rom);
GBAROMSize = LoadFATFile ((char *)rom, 0);
break;
case METHOD_DVD:
GBAROMSize = LoadDVDFile ((unsigned char *)rom);
GBAROMSize = LoadDVDFile ((unsigned char *)rom, 0);
break;
case METHOD_SMB:
GBAROMSize = LoadSMBFile ((char *)rom);
GBAROMSize = LoadSMBFile ((char *)rom, 0);
break;
}
if(GBAROMSize)
{
CPUUpdateRenderBuffers( true );
return true;
}
else
{
VMClose();
return GBAROMSize;
return false;
}
}
@ -202,6 +206,9 @@ u8 VMRead8( u32 address )
#include "Port.h"
#include "menudraw.h"
#include "filesel.h"
#include "vba.h"
#include "fileop.h"
extern "C" {
#include "tbtime.h"
@ -237,7 +244,6 @@ static char *gbabase = NULL;
static FILE* romfile = NULL;
static int useVM = 0;
static u32 GBAROMSize = 0;
static char romfilename[1024];
/**
* GBA Memory
@ -365,10 +371,12 @@ static void VMClose( void )
*
* VM version of GBA CPULoadROM
****************************************************************************/
int VMCPULoadROM( char *filename )
int VMCPULoadROM(int method)
{
int res;
char msg[512];
char filepath[MAXPATHLEN];
/** Fix VM **/
VMClose();
@ -377,9 +385,41 @@ int VMCPULoadROM( char *filename )
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 )
{
WaitPrompt((char*) "Error opening file!");
@ -408,8 +448,6 @@ int VMCPULoadROM( char *filename )
vmpage[0].pagetype = MEM_VM;
useVM = 1;
strcpy( romfilename, filename );
CPUUpdateRenderBuffers( true );
return 1;

View File

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

View File

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

View File

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

View File

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

View File

@ -2303,6 +2303,8 @@ static bool gbWriteSaveState(gzFile gzFile)
return true;
}
extern void SetFileBytesWritten(int bytes); // Tantric - Wii/GameCube addition - store # bytes written
bool gbWriteMemSaveState(char *memory, int available)
{
gzFile gzFile = utilMemGzOpen(memory, available, "w");
@ -2319,6 +2321,8 @@ bool gbWriteMemSaveState(char *memory, int available)
if(pos >= (available))
res = false;
SetFileBytesWritten((int)pos); // Tantric - Wii/GameCube addition - store # bytes written
utilGzClose(gzFile);
return res;
@ -3469,3 +3473,320 @@ struct EmulatedSystem GBSystem =
1000,
#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;
bool MemgbReadBatteryFile(char * membuffer, int read);
int MemgbWriteBatteryFile(char * membuffer);
#endif