From 4ff5f2f63ce92a7858336792becd02ced172f0c6 Mon Sep 17 00:00:00 2001 From: dsbomb Date: Mon, 28 Apr 2008 05:02:18 +0000 Subject: [PATCH] write save states to WiiSD --- source/drivers/gamecube/gcdvd.c | 21 ++-- source/drivers/gamecube/info.c | 104 ++++++++++------ source/drivers/gamecube/memstate.c | 192 +++++++++++++++++++++++------ 3 files changed, 228 insertions(+), 89 deletions(-) diff --git a/source/drivers/gamecube/gcdvd.c b/source/drivers/gamecube/gcdvd.c index 4959dc7..deb833a 100644 --- a/source/drivers/gamecube/gcdvd.c +++ b/source/drivers/gamecube/gcdvd.c @@ -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; diff --git a/source/drivers/gamecube/info.c b/source/drivers/gamecube/info.c index 3d4cc44..9ee93d4 100644 --- a/source/drivers/gamecube/info.c +++ b/source/drivers/gamecube/info.c @@ -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 diff --git a/source/drivers/gamecube/memstate.c b/source/drivers/gamecube/memstate.c index 1bc7e44..ecf2430 100644 --- a/source/drivers/gamecube/memstate.c +++ b/source/drivers/gamecube/memstate.c @@ -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); } }