mirror of
https://github.com/dborth/fceugx.git
synced 2024-10-31 22:45:05 +01:00
write save states to WiiSD
This commit is contained in:
parent
cf054d59d6
commit
4ff5f2f63c
@ -16,9 +16,15 @@
|
||||
#include "sz.h"
|
||||
#include "gcdvd.h"
|
||||
|
||||
#ifdef HW_RVL
|
||||
#include "wiisd/sdio.h"
|
||||
#include "wiisd/tff.h"
|
||||
|
||||
/*Front SCARD*/
|
||||
FATFS frontfs;
|
||||
FILINFO finfo;
|
||||
#endif
|
||||
|
||||
/*** Simplified Directory Entry Record
|
||||
I only care about a couple of values ***/
|
||||
#define RECLEN 0
|
||||
@ -28,16 +34,12 @@
|
||||
#define FILENAME_LENGTH 32
|
||||
#define FILENAME 33
|
||||
|
||||
#define PAGESIZE 10
|
||||
#define PAGESIZE 11
|
||||
|
||||
#define FCEUDIR "fceu"
|
||||
#define SAVEDIR "saves"
|
||||
#define ROMSDIR "roms"
|
||||
|
||||
/*Front SCARD*/
|
||||
FATFS frontfs;
|
||||
FILINFO finfo;
|
||||
|
||||
FILEENTRIES filelist[MAXFILES];
|
||||
int maxfiles = 0;
|
||||
int offset = 0;
|
||||
@ -605,11 +607,11 @@ void ShowFiles( int offset, int selection ) {
|
||||
else
|
||||
dir[0] = 0;
|
||||
|
||||
writex(CentreTextPosition(dir), 32, GetTextWidth(dir), font_height, dir, 0);
|
||||
writex(CentreTextPosition(dir), 22, GetTextWidth(dir), font_height, dir, 0);
|
||||
while (GetTextWidth(text) > 620)
|
||||
text[strlen(text)-2] = 0;
|
||||
|
||||
writex( CentreTextPosition(text), ( j * font_height ) + 130, GetTextWidth(text), font_height, text, j == ( selection - offset ) );
|
||||
writex( CentreTextPosition(text), ( j * font_height ) + 110, GetTextWidth(text), font_height, text, j == ( selection - offset ) );
|
||||
|
||||
j++;
|
||||
}
|
||||
@ -732,6 +734,7 @@ void FileSelector() {
|
||||
maxfiles = parsedir();
|
||||
}
|
||||
} else {
|
||||
#ifdef HW_RVL
|
||||
if (UseFrontSDCARD) {
|
||||
strncpy(finfo.fname, filelist[selection].filename, 12);
|
||||
int l = strlen(finfo.fname);
|
||||
@ -740,6 +743,7 @@ void FileSelector() {
|
||||
finfo.fsize = filelist[selection].length;
|
||||
finfo.fattrib = filelist[selection].flags ? AM_DIR : 0;
|
||||
}
|
||||
#endif
|
||||
rootdir = filelist[selection].offset;
|
||||
rootdirlength = filelist[selection].length;
|
||||
// Now load the DVD file to it's offset
|
||||
@ -766,7 +770,6 @@ int LoadDVDFile( unsigned char *buffer ) {
|
||||
u32 bytes_read_total;
|
||||
|
||||
if(UseFrontSDCARD) {
|
||||
WaitPrompt("WiiSD Read");
|
||||
ShowAction((char*)"Loading ... Wait");
|
||||
char filename[1024];
|
||||
sprintf(filename, "%s/%s", rootWiiSDdir, finfo.fname);
|
||||
@ -824,7 +827,6 @@ int LoadDVDFile( unsigned char *buffer ) {
|
||||
}
|
||||
#endif
|
||||
|
||||
WaitPrompt("Not WiiSD");
|
||||
/*** SDCard Addition ***/
|
||||
if (UseSDCARD) GetSDInfo();
|
||||
if (rootdirlength == 0) return 0;
|
||||
@ -955,6 +957,7 @@ int OpenFrontSD () {
|
||||
|
||||
int OpenSD () {
|
||||
UseSDCARD = 1;
|
||||
UseFrontSDCARD = 0;
|
||||
char msg[128];
|
||||
|
||||
if (ChosenSlot != sdslot) haveSDdir = 0;
|
||||
|
@ -537,23 +537,12 @@ void ConfigPAD()
|
||||
/****************************************************************************
|
||||
* Save Game Manager
|
||||
****************************************************************************/
|
||||
|
||||
int mccount = 5;
|
||||
char mcmenu[5][30] = {
|
||||
{ "Use: SLOT A" }, { "Device: MCARD" },
|
||||
{ "Save Game State" }, { "Load Game State" },
|
||||
{ "Return to Main Menu" }
|
||||
};
|
||||
|
||||
unsigned char sgmtext[][512] = {
|
||||
//Save game
|
||||
{ "From where do you wish to load/save your game?" },
|
||||
{ "Hard time making up your mind?" }
|
||||
};
|
||||
|
||||
int slot = 0;
|
||||
int device = 0;
|
||||
|
||||
int SdSlotCount = 3;
|
||||
char SdSlots[3][10] = {
|
||||
{ "Slot A" }, { "Slot B" }, { "Wii SD"}
|
||||
@ -564,55 +553,67 @@ enum SLOTS {
|
||||
int ChosenSlot = 0;
|
||||
int ChosenDevice = 1;
|
||||
|
||||
int mccount = 5;
|
||||
char mcmenu[5][30] = {
|
||||
{ "Save State" }, { "Load State" },
|
||||
{ "Device" }, { "Slot" },
|
||||
//{ "Use: SLOT A" }, { "Device: MCARD" },
|
||||
//{ "Save Game State" }, { "Load Game State" },
|
||||
{ "Return to Main Menu" }
|
||||
};
|
||||
|
||||
int StateManager() {
|
||||
int menu = 0;
|
||||
enum SAVE_MENU {
|
||||
SAVE_SAVE, SAVE_LOAD,
|
||||
SAVE_DEVICE, SAVE_SLOT,
|
||||
SAVE_EXIT
|
||||
};
|
||||
int ChosenMenu = 0;
|
||||
int quit = 0;
|
||||
short j;
|
||||
int redraw = 1;
|
||||
//int i;
|
||||
|
||||
line = 0;
|
||||
scrollerx = 320 - MARGIN;
|
||||
|
||||
while ( quit == 0 )
|
||||
{
|
||||
|
||||
if ( redraw ){
|
||||
sprintf(mcmenu[0], (slot == 0) ? "Use: SLOT A" : "Use: SLOT B");
|
||||
sprintf(mcmenu[1], (device == 0) ? "Device: MCARD" : "Device: SDCARD");
|
||||
DrawMenu(&mcmenu[0], mccount, menu);
|
||||
while ( quit == 0 ) {
|
||||
if ( redraw ) {
|
||||
sprintf(mcmenu[SAVE_SLOT], "%s: %s", ChosenDevice ? "SDCard" : "MemCard",
|
||||
SdSlots[ChosenSlot]);
|
||||
sprintf(mcmenu[SAVE_DEVICE], "Device: %s", ChosenDevice ? "SDCard" : "MemCard");
|
||||
DrawMenu(mcmenu, mccount, ChosenMenu);
|
||||
redraw = 0;
|
||||
}
|
||||
|
||||
redraw = 0;
|
||||
|
||||
j = PAD_ButtonsDown(0);
|
||||
|
||||
if ( j & PAD_BUTTON_DOWN ) {
|
||||
menu++;
|
||||
ChosenMenu++;
|
||||
redraw = 1;
|
||||
}
|
||||
|
||||
if ( j & PAD_BUTTON_UP ) {
|
||||
menu--;
|
||||
ChosenMenu--;
|
||||
redraw = 1;
|
||||
}
|
||||
|
||||
if ( j & PAD_BUTTON_A ) {
|
||||
redraw = 1;
|
||||
switch( menu ) {
|
||||
case 0 :
|
||||
slot ^= 1;
|
||||
switch( ChosenMenu ) {
|
||||
case SAVE_SAVE:
|
||||
ManageState(0, ChosenSlot, ChosenDevice); //Save
|
||||
break;
|
||||
case 1 :
|
||||
device ^= 1;
|
||||
case SAVE_LOAD:
|
||||
ManageState(1, ChosenSlot, ChosenDevice); //Load
|
||||
break;
|
||||
case 2 :
|
||||
ManageState(0, slot, device); //Save
|
||||
case SAVE_DEVICE:
|
||||
ChosenDevice ^= 1;
|
||||
break;
|
||||
case 3 :
|
||||
ManageState(1, slot, device); //Load
|
||||
case SAVE_SLOT:
|
||||
ChosenSlot++;
|
||||
if (ChosenSlot >= SdSlotCount)
|
||||
ChosenSlot = 0;
|
||||
break;
|
||||
case 4 :
|
||||
case SAVE_EXIT:
|
||||
quit = 1;//return 0 ;
|
||||
break;
|
||||
default:
|
||||
@ -620,13 +621,37 @@ int StateManager() {
|
||||
}
|
||||
}
|
||||
|
||||
if (j & PAD_BUTTON_RIGHT) {
|
||||
if (ChosenMenu == SAVE_SLOT) {
|
||||
ChosenSlot++;
|
||||
if (ChosenSlot >= SdSlotCount)
|
||||
ChosenSlot = SdSlotCount - 1;
|
||||
redraw = 1;
|
||||
} else if (ChosenMenu == SAVE_DEVICE) {
|
||||
ChosenDevice ^= 1;
|
||||
redraw = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (j & PAD_BUTTON_LEFT) {
|
||||
if (ChosenMenu == SAVE_SLOT) {
|
||||
ChosenSlot--;
|
||||
if (ChosenSlot < 0)
|
||||
ChosenSlot = 0;
|
||||
redraw = 1;
|
||||
} else if (ChosenMenu == SAVE_DEVICE) {
|
||||
ChosenDevice ^= 1;
|
||||
redraw = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ( j & PAD_BUTTON_B ) quit = 1;
|
||||
|
||||
if ( menu < 0 )
|
||||
menu = mccount - 1;
|
||||
if ( ChosenMenu < 0 )
|
||||
ChosenMenu = mccount - 1;
|
||||
|
||||
if ( menu == mccount )
|
||||
menu = 0;
|
||||
if ( ChosenMenu == mccount )
|
||||
ChosenMenu = 0;
|
||||
|
||||
scroller(SCROLLY, &sgmtext[0], 2);
|
||||
VIDEO_WaitVSync();
|
||||
@ -908,6 +933,7 @@ int MediaSelect() {
|
||||
quit = 1;
|
||||
#else
|
||||
UseSDCARD = 0; //DVD
|
||||
UseFrontSDCARD = 0;
|
||||
OpenDVD();
|
||||
return 1;
|
||||
#endif
|
||||
|
@ -11,8 +11,12 @@
|
||||
#include "../../types.h"
|
||||
#include "../../state.h"
|
||||
#include "saveicon.h"
|
||||
|
||||
#define SAVEDIR "fceu\\saves"
|
||||
#ifdef HW_RVL
|
||||
#include "wiisd/tff.h"
|
||||
#include "wiisd/integer.h"
|
||||
#endif
|
||||
#define FCEUDIR "fceu"
|
||||
#define SAVEDIR "saves"
|
||||
|
||||
/*** External functions ***/
|
||||
extern void FCEUPPU_SaveState(void);
|
||||
@ -39,7 +43,9 @@ int sboffset; /*** Used as a basic fileptr ***/
|
||||
int mcversion = 0x981211;
|
||||
|
||||
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
extern FILINFO finfo;
|
||||
extern int ChosenSlot;
|
||||
extern int ChosenDevice;
|
||||
/****************************************************************************
|
||||
* Memory based file functions
|
||||
****************************************************************************/
|
||||
@ -478,63 +484,167 @@ void MCManage(int mode, int slot) {
|
||||
}
|
||||
}
|
||||
|
||||
void SD_Manage(int mode, int slot){
|
||||
|
||||
sd_file *handle;
|
||||
void SD_Manage(int mode, int slot) {
|
||||
char path[1024];
|
||||
char msg[128];
|
||||
int offset = 0;
|
||||
int filesize = 0;
|
||||
int len = 0;
|
||||
|
||||
sprintf (path, "dev%d:\\%s\\%08x.fcs", slot, SAVEDIR, iNESGameCRC32);
|
||||
if (slot < 2) {
|
||||
sd_file *handle;
|
||||
sprintf (path, "dev%d:\\%s\\%s\\%08x.fcs", ChosenSlot, FCEUDIR, SAVEDIR, iNESGameCRC32);
|
||||
|
||||
if (mode == 0) ShowAction ("Saving STATE to SD...");
|
||||
else ShowAction ("Loading STATE from SD...");
|
||||
if (mode == 0) ShowAction ("Saving STATE to SD...");
|
||||
else ShowAction ("Loading STATE from SD...");
|
||||
|
||||
handle = SDCARD_OpenFile(path, (mode == 0) ? "wb" : "rb");
|
||||
handle = SDCARD_OpenFile(path, (mode == 0) ? "wb" : "rb");
|
||||
|
||||
if (handle == NULL){
|
||||
sprintf(msg, "Couldn't open %s", path);
|
||||
WaitPrompt(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == 0){ //Save
|
||||
filesize = GCFCEUSS_Save();
|
||||
|
||||
len = SDCARD_WriteFile (handle, statebuffer, filesize);
|
||||
SDCARD_CloseFile (handle);
|
||||
|
||||
if (len != filesize){
|
||||
sprintf (msg, "Error writing %s", path);
|
||||
WaitPrompt (msg);
|
||||
return;
|
||||
if (handle == NULL){
|
||||
sprintf(msg, "Couldn't open %s", path);
|
||||
WaitPrompt(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf (msg, "Saved %d bytes successfully", filesize);
|
||||
WaitPrompt (msg);
|
||||
}
|
||||
else{ //Load
|
||||
if (mode == 0){ //Save
|
||||
filesize = GCFCEUSS_Save();
|
||||
|
||||
memopen();
|
||||
while ((len = SDCARD_ReadFile (handle, &statebuffer[offset], 1024)) > 0) offset += len;
|
||||
SDCARD_CloseFile (handle);
|
||||
len = SDCARD_WriteFile (handle, statebuffer, filesize);
|
||||
SDCARD_CloseFile (handle);
|
||||
|
||||
sprintf (msg, "Loaded %d bytes successfully", offset);
|
||||
ShowAction(msg);
|
||||
if (len != filesize){
|
||||
sprintf (msg, "Error writing %s", path);
|
||||
WaitPrompt (msg);
|
||||
return;
|
||||
}
|
||||
|
||||
GCFCEUSS_Load();
|
||||
return ;
|
||||
sprintf (msg, "Saved %d bytes successfully", filesize);
|
||||
WaitPrompt (msg);
|
||||
}
|
||||
else{ //Load
|
||||
|
||||
memopen();
|
||||
while ((len = SDCARD_ReadFile (handle, &statebuffer[offset], 1024)) > 0) offset += len;
|
||||
SDCARD_CloseFile (handle);
|
||||
|
||||
sprintf (msg, "Loaded %d bytes successfully", offset);
|
||||
ShowAction(msg);
|
||||
|
||||
GCFCEUSS_Load();
|
||||
return ;
|
||||
}
|
||||
} else { // WiiSD
|
||||
#ifdef HW_RVL
|
||||
if (mode == 0) ShowAction ("Saving State to WiiSD...");
|
||||
else ShowAction ("Loading State from WiiSD...");
|
||||
|
||||
sprintf(path, "/%s/%s/%08X.fcs", FCEUDIR, SAVEDIR, iNESGameCRC32);
|
||||
FIL fp;
|
||||
int res;
|
||||
u32 offset = 0;
|
||||
|
||||
if (mode == 0)
|
||||
res = f_open(&fp, path, FA_CREATE_ALWAYS | FA_WRITE);
|
||||
else {
|
||||
if ((res=f_stat(path, &finfo)) != FR_OK) {
|
||||
if (res == FR_NO_FILE) {
|
||||
sprintf(msg, "Unable to find %s.", path);
|
||||
}
|
||||
else {
|
||||
sprintf(msg, "f_stat failed, error %d", res);
|
||||
}
|
||||
WaitPrompt(msg);
|
||||
return;
|
||||
}
|
||||
res = f_open(&fp, path, FA_READ);
|
||||
}
|
||||
|
||||
if (res != FR_OK) {
|
||||
sprintf(msg, "Failed to open %s, error %d.", path, res);
|
||||
WaitPrompt(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == 0) { // Save
|
||||
WORD written = 0;
|
||||
u32 total_written = 0;
|
||||
|
||||
filesize = GCFCEUSS_Save();
|
||||
sprintf(msg, "Writing %d bytes..", filesize);
|
||||
ShowAction(msg);
|
||||
|
||||
offset = filesize;
|
||||
// Can only write 64k at a time
|
||||
while (offset > 65000) {
|
||||
if ((res = f_write(&fp, &statebuffer[total_written], 65000, &written)) != FR_OK) {
|
||||
sprintf(msg, "f_write failed, error %d", res);
|
||||
WaitPrompt(msg);
|
||||
f_close(&fp);
|
||||
return;
|
||||
}
|
||||
offset -= written;
|
||||
total_written += written;
|
||||
}
|
||||
// Write last 64k
|
||||
if ((res = f_write(&fp, statebuffer+total_written, offset, &written)) != FR_OK) {
|
||||
sprintf(msg, "f_write failed, error %d", res);
|
||||
WaitPrompt(msg);
|
||||
f_close(&fp);
|
||||
return;
|
||||
}
|
||||
offset -= written;
|
||||
total_written += written;
|
||||
if (total_written == filesize) {
|
||||
sprintf(msg, "Wrote %d bytes.", total_written);
|
||||
ShowAction(msg);
|
||||
f_close(&fp);
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(msg, "Write size mismatch, %d of %d bytes", written, filesize);
|
||||
WaitPrompt(msg);
|
||||
sprintf(msg, "Unable to save %s", path);
|
||||
WaitPrompt(msg);
|
||||
f_close(&fp);
|
||||
return;
|
||||
} else { // Load
|
||||
WORD bytes_read = 0;
|
||||
u32 bytes_read_total = 0;
|
||||
|
||||
memopen();
|
||||
while(bytes_read_total < finfo.fsize) {
|
||||
if (f_read(&fp, &statebuffer[bytes_read_total], 0x200, &bytes_read) != FR_OK) {
|
||||
WaitPrompt((char*)"f_read failed");
|
||||
f_close(&fp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bytes_read == 0)
|
||||
break;
|
||||
bytes_read_total += bytes_read;
|
||||
}
|
||||
|
||||
if (bytes_read_total < finfo.fsize) {
|
||||
WaitPrompt((char*)"read failed");
|
||||
f_close(&fp);
|
||||
return;
|
||||
}
|
||||
sprintf(msg, "Read %d of %ld bytes.", bytes_read_total, finfo.fsize);
|
||||
ShowAction(msg);
|
||||
f_close(&fp);
|
||||
offset = bytes_read_total;
|
||||
GCFCEUSS_Load();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void ManageState(int mode, int slot, int device){
|
||||
|
||||
if (device == 0){
|
||||
void ManageState(int mode, int slot, int device) {
|
||||
if (device == 0) {
|
||||
MCManage(mode, slot);
|
||||
}
|
||||
else{
|
||||
else {
|
||||
SD_Manage(mode, slot);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user