2008-08-06 03:09:59 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* Snes9x 1.50
|
|
|
|
*
|
2008-09-05 00:42:33 +02:00
|
|
|
* Nintendo Wii/Gamecube Port
|
|
|
|
*
|
2008-08-06 03:09:59 +02:00
|
|
|
* crunchy2 April 2007-July 2007
|
2008-09-05 00:42:33 +02:00
|
|
|
* Tantric September 2008
|
2008-08-06 03:09:59 +02:00
|
|
|
*
|
|
|
|
* sram.cpp
|
|
|
|
*
|
|
|
|
* SRAM save/load/import/export handling
|
|
|
|
****************************************************************************/
|
|
|
|
#include <gccore.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <ogcsys.h>
|
|
|
|
|
|
|
|
#include "snes9x.h"
|
|
|
|
#include "memmap.h"
|
|
|
|
#include "srtc.h"
|
2008-08-10 05:14:39 +02:00
|
|
|
|
|
|
|
#include "snes9xGx.h"
|
2008-08-12 05:25:16 +02:00
|
|
|
#include "images/saveicon.h"
|
2008-08-07 07:19:17 +02:00
|
|
|
#include "menudraw.h"
|
2008-08-12 05:25:16 +02:00
|
|
|
#include "memcardop.h"
|
2008-08-07 07:19:17 +02:00
|
|
|
#include "fileop.h"
|
2008-08-10 05:14:39 +02:00
|
|
|
#include "smbop.h"
|
2008-08-07 05:25:02 +02:00
|
|
|
#include "filesel.h"
|
2008-08-06 03:09:59 +02:00
|
|
|
|
|
|
|
extern unsigned char savebuffer[];
|
|
|
|
extern int padcal;
|
|
|
|
extern unsigned short gcpadmap[];
|
|
|
|
|
2008-08-22 04:47:08 +02:00
|
|
|
char sramcomment[2][32];
|
2008-08-06 03:09:59 +02:00
|
|
|
|
|
|
|
/****************************************************************************
|
2008-09-02 22:15:59 +02:00
|
|
|
* Prepare SRAM Save Data
|
2008-08-06 03:09:59 +02:00
|
|
|
*
|
|
|
|
* This sets up the save buffer for saving in a format compatible with
|
2008-08-17 07:25:33 +02:00
|
|
|
* snes9x on other platforms. This is used when saving to SD / USB / SMB.
|
2008-08-06 03:09:59 +02:00
|
|
|
****************************************************************************/
|
|
|
|
int
|
2008-09-02 22:15:59 +02:00
|
|
|
preparesavedata (int method)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2008-09-02 22:15:59 +02:00
|
|
|
int offset = 0;
|
|
|
|
int size;
|
2008-08-06 03:09:59 +02:00
|
|
|
|
2008-09-02 22:15:59 +02:00
|
|
|
ClearSaveBuffer ();
|
2008-08-06 03:09:59 +02:00
|
|
|
|
2008-09-02 22:15:59 +02:00
|
|
|
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
|
|
|
{
|
|
|
|
// Copy in save icon
|
|
|
|
memcpy (savebuffer, saveicon, sizeof(saveicon));
|
|
|
|
offset += sizeof (saveicon);
|
|
|
|
}
|
2008-08-06 03:09:59 +02:00
|
|
|
|
2008-09-02 22:15:59 +02:00
|
|
|
// Copy in the sramcomments
|
|
|
|
sprintf (sramcomment[0], "%s SRAM", VERSIONSTR);
|
|
|
|
sprintf (sramcomment[1], Memory.ROMName);
|
|
|
|
memcpy (savebuffer + offset, sramcomment, 64);
|
|
|
|
offset += 64;
|
2008-08-06 03:09:59 +02:00
|
|
|
|
2008-09-02 22:15:59 +02:00
|
|
|
if(method != METHOD_MC_SLOTA && method != METHOD_MC_SLOTB)
|
|
|
|
{
|
|
|
|
// make it a 512 byte header so it is compatible with other platforms
|
|
|
|
if (offset <= 512)
|
|
|
|
offset = 512;
|
|
|
|
// header was longer than 512 bytes - hopefully this never happens!
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
2008-08-07 05:25:02 +02:00
|
|
|
|
2008-09-02 22:15:59 +02:00
|
|
|
// Copy in the SRAM
|
2008-08-06 03:09:59 +02:00
|
|
|
size = Memory.SRAMSize ? (1 << (Memory.SRAMSize + 3)) * 128 : 0;
|
2008-08-07 05:25:02 +02:00
|
|
|
|
2008-08-06 03:09:59 +02:00
|
|
|
if (size > 0x20000)
|
2008-09-02 22:15:59 +02:00
|
|
|
size = 0x20000;
|
2008-08-07 05:25:02 +02:00
|
|
|
|
2008-08-06 03:09:59 +02:00
|
|
|
if (size != 0)
|
|
|
|
{
|
2008-09-02 22:15:59 +02:00
|
|
|
memcpy (savebuffer + offset, Memory.SRAM, size);
|
|
|
|
offset += size;
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
2008-09-05 00:42:33 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
offset = 0;
|
2008-09-08 01:50:57 +02:00
|
|
|
WaitPrompt((char *)"No SRAM data to save!");
|
2008-09-05 00:42:33 +02:00
|
|
|
}
|
2008-08-07 05:25:02 +02:00
|
|
|
|
2008-08-06 03:09:59 +02:00
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
|
|
* Decode Save Data
|
|
|
|
****************************************************************************/
|
|
|
|
void
|
2008-09-02 22:15:59 +02:00
|
|
|
decodesavedata (int method, int readsize)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2008-09-05 00:42:33 +02:00
|
|
|
int offset = 0;
|
2008-09-02 22:15:59 +02:00
|
|
|
char sramsavecomment[32];
|
2008-08-07 05:25:02 +02:00
|
|
|
|
2008-09-02 22:15:59 +02:00
|
|
|
int size = Memory.SRAMSize ? (1 << (Memory.SRAMSize + 3)) * 128 : 0;
|
2008-08-07 05:25:02 +02:00
|
|
|
|
2008-09-02 22:15:59 +02:00
|
|
|
if (size > 0x20000)
|
|
|
|
size = 0x20000;
|
2008-08-07 05:25:02 +02:00
|
|
|
|
2008-09-02 22:15:59 +02:00
|
|
|
// memory card save
|
|
|
|
if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
2008-09-05 00:42:33 +02:00
|
|
|
offset = sizeof (saveicon); // skip save icon
|
2008-08-06 03:09:59 +02:00
|
|
|
|
2008-09-05 00:42:33 +02:00
|
|
|
// Check for sram comment
|
2008-09-02 22:15:59 +02:00
|
|
|
memcpy (sramsavecomment, savebuffer+offset, 32);
|
2008-08-07 05:25:02 +02:00
|
|
|
|
2008-09-05 00:42:33 +02:00
|
|
|
// version 0xx found!
|
|
|
|
if ( (strncmp (sramsavecomment, "Snes9x GX 0", 11) == 0) )
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2008-09-05 00:42:33 +02:00
|
|
|
// adjust offset
|
|
|
|
if(method == METHOD_MC_SLOTA && method == METHOD_MC_SLOTB)
|
|
|
|
offset = 512; // skip entire 512 byte header
|
|
|
|
else
|
|
|
|
offset += 64; // skip savecomments
|
|
|
|
|
2008-09-02 22:15:59 +02:00
|
|
|
// import the SRAM
|
|
|
|
memcpy (Memory.SRAM, savebuffer + offset, size);
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
2008-09-02 22:15:59 +02:00
|
|
|
// check for SRAM from other version/platform of snes9x
|
|
|
|
else if ( readsize == size || readsize == size + SRTC_SRAM_PAD)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
|
|
|
// SRAM data should be at the start of the file, just import it and
|
|
|
|
// ignore anything after the SRAM
|
|
|
|
memcpy (Memory.SRAM, savebuffer, size);
|
2008-09-02 22:15:59 +02:00
|
|
|
}
|
|
|
|
else if ( readsize == size + 512 )
|
|
|
|
{
|
2008-08-06 03:09:59 +02:00
|
|
|
// SRAM has a 512 byte header - remove it, then import the SRAM,
|
|
|
|
// ignoring anything after the SRAM
|
2008-09-02 22:15:59 +02:00
|
|
|
memcpy(Memory.SRAM, savebuffer+512, size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WaitPrompt((char*)"Incompatible SRAM save!");
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-08-07 05:25:02 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* Load SRAM
|
|
|
|
****************************************************************************/
|
2008-08-10 05:14:39 +02:00
|
|
|
int
|
2008-08-07 05:25:02 +02:00
|
|
|
LoadSRAM (int method, bool silent)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2008-08-12 05:25:16 +02:00
|
|
|
ShowAction ((char*) "Loading...");
|
|
|
|
|
2008-08-07 05:25:02 +02:00
|
|
|
if(method == METHOD_AUTO)
|
2008-08-17 07:25:33 +02:00
|
|
|
method = autoSaveMethod(); // we use 'Save' because SRAM needs R/W
|
2008-08-07 05:25:02 +02:00
|
|
|
|
|
|
|
char filepath[1024];
|
|
|
|
int offset = 0;
|
|
|
|
|
|
|
|
if(method == METHOD_SD || method == METHOD_USB)
|
|
|
|
{
|
2008-08-12 05:25:16 +02:00
|
|
|
ChangeFATInterface(method, NOTSILENT);
|
2008-08-08 09:57:01 +02:00
|
|
|
sprintf (filepath, "%s/%s/%s.srm", ROOTFATDIR, GCSettings.SaveFolder, Memory.ROMFilename);
|
2008-08-07 05:25:02 +02:00
|
|
|
offset = LoadBufferFromFAT (filepath, silent);
|
|
|
|
}
|
|
|
|
else if(method == METHOD_SMB)
|
|
|
|
{
|
2008-08-10 05:14:39 +02:00
|
|
|
sprintf (filepath, "%s/%s.srm", GCSettings.SaveFolder, Memory.ROMFilename);
|
2008-08-07 05:25:02 +02:00
|
|
|
offset = LoadBufferFromSMB (filepath, silent);
|
|
|
|
}
|
2008-08-17 07:25:33 +02:00
|
|
|
else if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
2008-08-07 05:25:02 +02:00
|
|
|
{
|
2008-08-17 07:25:33 +02:00
|
|
|
sprintf (filepath, "%s.srm", Memory.ROMName);
|
|
|
|
|
|
|
|
if(method == METHOD_MC_SLOTA)
|
|
|
|
offset = LoadBufferFromMC (savebuffer, CARD_SLOTA, filepath, silent);
|
|
|
|
else
|
|
|
|
offset = LoadBufferFromMC (savebuffer, CARD_SLOTB, filepath, silent);
|
2008-08-07 05:25:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (offset > 0)
|
|
|
|
{
|
2008-09-02 22:15:59 +02:00
|
|
|
decodesavedata (method, offset);
|
2008-08-07 05:25:02 +02:00
|
|
|
S9xSoftReset();
|
2008-08-10 05:14:39 +02:00
|
|
|
return 1;
|
2008-08-07 05:25:02 +02:00
|
|
|
}
|
2008-08-10 05:14:39 +02:00
|
|
|
|
2008-08-12 05:25:16 +02:00
|
|
|
// if we reached here, nothing was done!
|
2008-08-10 05:14:39 +02:00
|
|
|
if(!silent)
|
|
|
|
WaitPrompt ((char*) "SRAM file not found");
|
|
|
|
|
|
|
|
return 0;
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|
|
|
|
|
2008-08-07 05:25:02 +02:00
|
|
|
/****************************************************************************
|
|
|
|
* Save SRAM
|
|
|
|
****************************************************************************/
|
|
|
|
bool
|
|
|
|
SaveSRAM (int method, bool silent)
|
2008-08-06 03:09:59 +02:00
|
|
|
{
|
2008-08-12 05:25:16 +02:00
|
|
|
ShowAction ((char*) "Saving...");
|
|
|
|
|
2008-08-07 05:25:02 +02:00
|
|
|
if(method == METHOD_AUTO)
|
|
|
|
method = autoSaveMethod();
|
|
|
|
|
|
|
|
bool retval = false;
|
|
|
|
char filepath[1024];
|
|
|
|
int datasize;
|
|
|
|
int offset = 0;
|
|
|
|
|
2008-09-02 22:15:59 +02:00
|
|
|
datasize = preparesavedata (method);
|
2008-08-07 05:25:02 +02:00
|
|
|
|
|
|
|
if ( datasize )
|
|
|
|
{
|
|
|
|
if(method == METHOD_SD || method == METHOD_USB)
|
|
|
|
{
|
2008-08-12 05:25:16 +02:00
|
|
|
if(ChangeFATInterface(method, NOTSILENT))
|
|
|
|
{
|
|
|
|
sprintf (filepath, "%s/%s/%s.srm", ROOTFATDIR, GCSettings.SaveFolder, Memory.ROMFilename);
|
|
|
|
offset = SaveBufferToFAT (filepath, datasize, silent);
|
|
|
|
}
|
2008-08-07 05:25:02 +02:00
|
|
|
}
|
|
|
|
else if(method == METHOD_SMB)
|
|
|
|
{
|
2008-08-10 05:14:39 +02:00
|
|
|
sprintf (filepath, "%s/%s.srm", GCSettings.SaveFolder, Memory.ROMFilename);
|
2008-08-07 05:25:02 +02:00
|
|
|
offset = SaveBufferToSMB (filepath, datasize, silent);
|
|
|
|
}
|
2008-08-17 07:25:33 +02:00
|
|
|
else if(method == METHOD_MC_SLOTA || method == METHOD_MC_SLOTB)
|
2008-08-07 05:25:02 +02:00
|
|
|
{
|
2008-08-17 07:25:33 +02:00
|
|
|
sprintf (filepath, "%s.srm", Memory.ROMName);
|
|
|
|
|
|
|
|
if(method == METHOD_MC_SLOTA)
|
|
|
|
offset = SaveBufferToMC (savebuffer, CARD_SLOTA, filepath, datasize, silent);
|
|
|
|
else
|
|
|
|
offset = SaveBufferToMC (savebuffer, CARD_SLOTB, filepath, datasize, silent);
|
2008-08-07 05:25:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (offset > 0)
|
|
|
|
{
|
|
|
|
if ( !silent )
|
2008-08-12 05:25:16 +02:00
|
|
|
WaitPrompt((char *)"Save successful");
|
2008-08-07 05:25:02 +02:00
|
|
|
retval = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return retval;
|
2008-08-06 03:09:59 +02:00
|
|
|
}
|