mirror of
https://github.com/dborth/fceugx.git
synced 2024-11-01 06:55: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 "sz.h"
|
||||||
#include "gcdvd.h"
|
#include "gcdvd.h"
|
||||||
|
|
||||||
|
#ifdef HW_RVL
|
||||||
#include "wiisd/sdio.h"
|
#include "wiisd/sdio.h"
|
||||||
#include "wiisd/tff.h"
|
#include "wiisd/tff.h"
|
||||||
|
|
||||||
|
/*Front SCARD*/
|
||||||
|
FATFS frontfs;
|
||||||
|
FILINFO finfo;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*** Simplified Directory Entry Record
|
/*** Simplified Directory Entry Record
|
||||||
I only care about a couple of values ***/
|
I only care about a couple of values ***/
|
||||||
#define RECLEN 0
|
#define RECLEN 0
|
||||||
@ -28,16 +34,12 @@
|
|||||||
#define FILENAME_LENGTH 32
|
#define FILENAME_LENGTH 32
|
||||||
#define FILENAME 33
|
#define FILENAME 33
|
||||||
|
|
||||||
#define PAGESIZE 10
|
#define PAGESIZE 11
|
||||||
|
|
||||||
#define FCEUDIR "fceu"
|
#define FCEUDIR "fceu"
|
||||||
#define SAVEDIR "saves"
|
#define SAVEDIR "saves"
|
||||||
#define ROMSDIR "roms"
|
#define ROMSDIR "roms"
|
||||||
|
|
||||||
/*Front SCARD*/
|
|
||||||
FATFS frontfs;
|
|
||||||
FILINFO finfo;
|
|
||||||
|
|
||||||
FILEENTRIES filelist[MAXFILES];
|
FILEENTRIES filelist[MAXFILES];
|
||||||
int maxfiles = 0;
|
int maxfiles = 0;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
@ -605,11 +607,11 @@ void ShowFiles( int offset, int selection ) {
|
|||||||
else
|
else
|
||||||
dir[0] = 0;
|
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)
|
while (GetTextWidth(text) > 620)
|
||||||
text[strlen(text)-2] = 0;
|
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++;
|
j++;
|
||||||
}
|
}
|
||||||
@ -732,6 +734,7 @@ void FileSelector() {
|
|||||||
maxfiles = parsedir();
|
maxfiles = parsedir();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef HW_RVL
|
||||||
if (UseFrontSDCARD) {
|
if (UseFrontSDCARD) {
|
||||||
strncpy(finfo.fname, filelist[selection].filename, 12);
|
strncpy(finfo.fname, filelist[selection].filename, 12);
|
||||||
int l = strlen(finfo.fname);
|
int l = strlen(finfo.fname);
|
||||||
@ -740,6 +743,7 @@ void FileSelector() {
|
|||||||
finfo.fsize = filelist[selection].length;
|
finfo.fsize = filelist[selection].length;
|
||||||
finfo.fattrib = filelist[selection].flags ? AM_DIR : 0;
|
finfo.fattrib = filelist[selection].flags ? AM_DIR : 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
rootdir = filelist[selection].offset;
|
rootdir = filelist[selection].offset;
|
||||||
rootdirlength = filelist[selection].length;
|
rootdirlength = filelist[selection].length;
|
||||||
// Now load the DVD file to it's offset
|
// Now load the DVD file to it's offset
|
||||||
@ -766,7 +770,6 @@ int LoadDVDFile( unsigned char *buffer ) {
|
|||||||
u32 bytes_read_total;
|
u32 bytes_read_total;
|
||||||
|
|
||||||
if(UseFrontSDCARD) {
|
if(UseFrontSDCARD) {
|
||||||
WaitPrompt("WiiSD Read");
|
|
||||||
ShowAction((char*)"Loading ... Wait");
|
ShowAction((char*)"Loading ... Wait");
|
||||||
char filename[1024];
|
char filename[1024];
|
||||||
sprintf(filename, "%s/%s", rootWiiSDdir, finfo.fname);
|
sprintf(filename, "%s/%s", rootWiiSDdir, finfo.fname);
|
||||||
@ -824,7 +827,6 @@ int LoadDVDFile( unsigned char *buffer ) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WaitPrompt("Not WiiSD");
|
|
||||||
/*** SDCard Addition ***/
|
/*** SDCard Addition ***/
|
||||||
if (UseSDCARD) GetSDInfo();
|
if (UseSDCARD) GetSDInfo();
|
||||||
if (rootdirlength == 0) return 0;
|
if (rootdirlength == 0) return 0;
|
||||||
@ -955,6 +957,7 @@ int OpenFrontSD () {
|
|||||||
|
|
||||||
int OpenSD () {
|
int OpenSD () {
|
||||||
UseSDCARD = 1;
|
UseSDCARD = 1;
|
||||||
|
UseFrontSDCARD = 0;
|
||||||
char msg[128];
|
char msg[128];
|
||||||
|
|
||||||
if (ChosenSlot != sdslot) haveSDdir = 0;
|
if (ChosenSlot != sdslot) haveSDdir = 0;
|
||||||
|
@ -537,23 +537,12 @@ void ConfigPAD()
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Save Game Manager
|
* 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] = {
|
unsigned char sgmtext[][512] = {
|
||||||
//Save game
|
//Save game
|
||||||
{ "From where do you wish to load/save your game?" },
|
{ "From where do you wish to load/save your game?" },
|
||||||
{ "Hard time making up your mind?" }
|
{ "Hard time making up your mind?" }
|
||||||
};
|
};
|
||||||
|
|
||||||
int slot = 0;
|
|
||||||
int device = 0;
|
|
||||||
|
|
||||||
int SdSlotCount = 3;
|
int SdSlotCount = 3;
|
||||||
char SdSlots[3][10] = {
|
char SdSlots[3][10] = {
|
||||||
{ "Slot A" }, { "Slot B" }, { "Wii SD"}
|
{ "Slot A" }, { "Slot B" }, { "Wii SD"}
|
||||||
@ -564,55 +553,67 @@ enum SLOTS {
|
|||||||
int ChosenSlot = 0;
|
int ChosenSlot = 0;
|
||||||
int ChosenDevice = 1;
|
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 StateManager() {
|
||||||
int menu = 0;
|
enum SAVE_MENU {
|
||||||
|
SAVE_SAVE, SAVE_LOAD,
|
||||||
|
SAVE_DEVICE, SAVE_SLOT,
|
||||||
|
SAVE_EXIT
|
||||||
|
};
|
||||||
|
int ChosenMenu = 0;
|
||||||
int quit = 0;
|
int quit = 0;
|
||||||
short j;
|
short j;
|
||||||
int redraw = 1;
|
int redraw = 1;
|
||||||
//int i;
|
|
||||||
|
|
||||||
line = 0;
|
line = 0;
|
||||||
scrollerx = 320 - MARGIN;
|
scrollerx = 320 - MARGIN;
|
||||||
|
|
||||||
while ( quit == 0 )
|
while ( quit == 0 ) {
|
||||||
{
|
|
||||||
|
|
||||||
if ( redraw ) {
|
if ( redraw ) {
|
||||||
sprintf(mcmenu[0], (slot == 0) ? "Use: SLOT A" : "Use: SLOT B");
|
sprintf(mcmenu[SAVE_SLOT], "%s: %s", ChosenDevice ? "SDCard" : "MemCard",
|
||||||
sprintf(mcmenu[1], (device == 0) ? "Device: MCARD" : "Device: SDCARD");
|
SdSlots[ChosenSlot]);
|
||||||
DrawMenu(&mcmenu[0], mccount, menu);
|
sprintf(mcmenu[SAVE_DEVICE], "Device: %s", ChosenDevice ? "SDCard" : "MemCard");
|
||||||
|
DrawMenu(mcmenu, mccount, ChosenMenu);
|
||||||
|
redraw = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
redraw = 0;
|
|
||||||
|
|
||||||
j = PAD_ButtonsDown(0);
|
j = PAD_ButtonsDown(0);
|
||||||
|
|
||||||
if ( j & PAD_BUTTON_DOWN ) {
|
if ( j & PAD_BUTTON_DOWN ) {
|
||||||
menu++;
|
ChosenMenu++;
|
||||||
redraw = 1;
|
redraw = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( j & PAD_BUTTON_UP ) {
|
if ( j & PAD_BUTTON_UP ) {
|
||||||
menu--;
|
ChosenMenu--;
|
||||||
redraw = 1;
|
redraw = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( j & PAD_BUTTON_A ) {
|
if ( j & PAD_BUTTON_A ) {
|
||||||
redraw = 1;
|
redraw = 1;
|
||||||
switch( menu ) {
|
switch( ChosenMenu ) {
|
||||||
case 0 :
|
case SAVE_SAVE:
|
||||||
slot ^= 1;
|
ManageState(0, ChosenSlot, ChosenDevice); //Save
|
||||||
break;
|
break;
|
||||||
case 1 :
|
case SAVE_LOAD:
|
||||||
device ^= 1;
|
ManageState(1, ChosenSlot, ChosenDevice); //Load
|
||||||
break;
|
break;
|
||||||
case 2 :
|
case SAVE_DEVICE:
|
||||||
ManageState(0, slot, device); //Save
|
ChosenDevice ^= 1;
|
||||||
break;
|
break;
|
||||||
case 3 :
|
case SAVE_SLOT:
|
||||||
ManageState(1, slot, device); //Load
|
ChosenSlot++;
|
||||||
|
if (ChosenSlot >= SdSlotCount)
|
||||||
|
ChosenSlot = 0;
|
||||||
break;
|
break;
|
||||||
case 4 :
|
case SAVE_EXIT:
|
||||||
quit = 1;//return 0 ;
|
quit = 1;//return 0 ;
|
||||||
break;
|
break;
|
||||||
default:
|
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 ( j & PAD_BUTTON_B ) quit = 1;
|
||||||
|
|
||||||
if ( menu < 0 )
|
if ( ChosenMenu < 0 )
|
||||||
menu = mccount - 1;
|
ChosenMenu = mccount - 1;
|
||||||
|
|
||||||
if ( menu == mccount )
|
if ( ChosenMenu == mccount )
|
||||||
menu = 0;
|
ChosenMenu = 0;
|
||||||
|
|
||||||
scroller(SCROLLY, &sgmtext[0], 2);
|
scroller(SCROLLY, &sgmtext[0], 2);
|
||||||
VIDEO_WaitVSync();
|
VIDEO_WaitVSync();
|
||||||
@ -908,6 +933,7 @@ int MediaSelect() {
|
|||||||
quit = 1;
|
quit = 1;
|
||||||
#else
|
#else
|
||||||
UseSDCARD = 0; //DVD
|
UseSDCARD = 0; //DVD
|
||||||
|
UseFrontSDCARD = 0;
|
||||||
OpenDVD();
|
OpenDVD();
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -11,8 +11,12 @@
|
|||||||
#include "../../types.h"
|
#include "../../types.h"
|
||||||
#include "../../state.h"
|
#include "../../state.h"
|
||||||
#include "saveicon.h"
|
#include "saveicon.h"
|
||||||
|
#ifdef HW_RVL
|
||||||
#define SAVEDIR "fceu\\saves"
|
#include "wiisd/tff.h"
|
||||||
|
#include "wiisd/integer.h"
|
||||||
|
#endif
|
||||||
|
#define FCEUDIR "fceu"
|
||||||
|
#define SAVEDIR "saves"
|
||||||
|
|
||||||
/*** External functions ***/
|
/*** External functions ***/
|
||||||
extern void FCEUPPU_SaveState(void);
|
extern void FCEUPPU_SaveState(void);
|
||||||
@ -39,7 +43,9 @@ int sboffset; /*** Used as a basic fileptr ***/
|
|||||||
int mcversion = 0x981211;
|
int mcversion = 0x981211;
|
||||||
|
|
||||||
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN(32);
|
static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN(32);
|
||||||
|
extern FILINFO finfo;
|
||||||
|
extern int ChosenSlot;
|
||||||
|
extern int ChosenDevice;
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Memory based file functions
|
* Memory based file functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -479,15 +485,15 @@ void MCManage(int mode, int slot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SD_Manage(int mode, int slot) {
|
void SD_Manage(int mode, int slot) {
|
||||||
|
|
||||||
sd_file *handle;
|
|
||||||
char path[1024];
|
char path[1024];
|
||||||
char msg[128];
|
char msg[128];
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int filesize = 0;
|
int filesize = 0;
|
||||||
int len = 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...");
|
if (mode == 0) ShowAction ("Saving STATE to SD...");
|
||||||
else ShowAction ("Loading STATE from SD...");
|
else ShowAction ("Loading STATE from SD...");
|
||||||
@ -527,10 +533,114 @@ void SD_Manage(int mode, int slot){
|
|||||||
GCFCEUSS_Load();
|
GCFCEUSS_Load();
|
||||||
return ;
|
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) {
|
void ManageState(int mode, int slot, int device) {
|
||||||
|
|
||||||
if (device == 0) {
|
if (device == 0) {
|
||||||
MCManage(mode, slot);
|
MCManage(mode, slot);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user