Skip to content

Commit

Permalink
Merge pull request #359 from libertyernie/pocketnes_interop_2
Browse files Browse the repository at this point in the history
Allow loading/saving of PocketNES ROMs/SRAM
  • Loading branch information
askotx committed Aug 31, 2017
2 parents e41ae64 + 2a11670 commit da54d31
Show file tree
Hide file tree
Showing 18 changed files with 11,505 additions and 3 deletions.
3 changes: 2 additions & 1 deletion Makefile.gc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ BUILD := build_gc
SOURCES := source source/images source/sounds source/fonts source/lang \
source/gui source/utils source/utils/unzip source/utils/sz \
source/fceultra source/fceultra/boards source/fceultra/input \
source/fceultra/utils source/fceultra/mbshare source/utils/vm
source/fceultra/utils source/fceultra/mbshare source/utils/vm \
source/pocketnes source/pocketnes/minilzo
INCLUDES := source

#---------------------------------------------------------------------------------
Expand Down
3 changes: 2 additions & 1 deletion Makefile.wii
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ BUILD := build_wii
SOURCES := source source/images source/sounds source/fonts source/lang \
source/gui source/utils source/utils/sz source/utils/unzip \
source/fceultra source/fceultra/boards source/fceultra/input \
source/fceultra/utils source/fceultra/mbshare
source/fceultra/utils source/fceultra/mbshare \
source/pocketnes source/pocketnes/minilzo
INCLUDES := source

#---------------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions source/fceugx.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ struct SGCSettings
int AutoSave;
int LoadMethod; // For ROMS: Auto, SD, DVD, USB, Network (SMB)
int SaveMethod; // For SRAM, Freeze, Prefs: Auto, SD, USB, SMB
int AppendAuto; // 0 - no, 1 - yes
char LoadFolder[MAXPATHLEN]; // Path to game files
char LastFileLoaded[MAXPATHLEN]; //Last file loaded filename
char SaveFolder[MAXPATHLEN]; // Path to save files
Expand Down
126 changes: 126 additions & 0 deletions source/fceuram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "menu.h"
#include "filebrowser.h"
#include "fileop.h"
#include "pocketnes/goombasav.h"

static u32 WiiFCEU_GameSave(CartInfo *LocalHWInfo, int operation)
{
Expand Down Expand Up @@ -74,6 +75,75 @@ bool SaveRAM (char * filepath, bool silent)
else if(GameInfo->type == GIT_VSUNI)
datasize = WiiFCEU_GameSave(&UNIFCart, 0);

if (datasize)
{
// Check to see if this is a PocketNES save file
FILE* file = fopen(filepath, "rb");
if (file)
{
uint32 tag;
fread(&tag, sizeof(uint32), 1, file);
fclose(file);

if (goomba_is_sram(&tag))
{
void* gba_data = malloc(GOOMBA_COLOR_SRAM_SIZE);

file = fopen(filepath, "rb");
fread(gba_data, 1, GOOMBA_COLOR_SRAM_SIZE, file);
fclose(file);

void* cleaned = goomba_cleanup(gba_data);
if (!cleaned) {
ErrorPrompt(goomba_last_error());
} else if (cleaned != gba_data) {
memcpy(gba_data, cleaned, GOOMBA_COLOR_SRAM_SIZE);
free(cleaned);
}

// Look for just one save file. If there aren't any, or there is more than one, don't read any data.
const stateheader* sh1 = NULL;
const stateheader* sh2 = NULL;

const stateheader* sh = stateheader_first(gba_data);
while (sh && stateheader_plausible(sh)) {
if (little_endian_conv_16(sh->type) != GOOMBA_SRAMSAVE) {}
else if (sh1 == NULL) {
sh1 = sh;
}
else {
sh2 = sh;
break;
}
sh = stateheader_advance(sh);
}

if (sh1 == NULL)
{
ErrorPrompt("PocketNES save file has no SRAM.");
datasize = 0;
}
else if (sh2 != NULL)
{
ErrorPrompt("PocketNES save file has more than one SRAM.");
datasize = 0;
}
else
{
char* newdata = goomba_new_sav(gba_data, sh1, savebuffer, datasize);
if (!newdata) {
ErrorPrompt(goomba_last_error());
datasize = 0;
} else {
memcpy(savebuffer, newdata, GOOMBA_COLOR_SRAM_SIZE);
datasize = GOOMBA_COLOR_SRAM_SIZE;
free(newdata);
}
}
}
}
}

if (datasize)
{
offset = SaveFile(filepath, datasize, silent);
Expand Down Expand Up @@ -121,6 +191,59 @@ bool LoadRAM (char * filepath, bool silent)

offset = LoadFile(filepath, silent);

// Check to see if this is a PocketNES save file
if (goomba_is_sram(savebuffer))
{
void* cleaned = goomba_cleanup(savebuffer);
if (!cleaned) {
ErrorPrompt(goomba_last_error());
} else if (cleaned != savebuffer) {
memcpy(savebuffer, cleaned, GOOMBA_COLOR_SRAM_SIZE);
free(cleaned);
}

// Look for just one save file. If there aren't any, or there is more than one, don't read any data.
const stateheader* sh1 = NULL;
const stateheader* sh2 = NULL;

const stateheader* sh = stateheader_first(savebuffer);
while (sh && stateheader_plausible(sh)) {
if (little_endian_conv_16(sh->type) != GOOMBA_SRAMSAVE) { }
else if (sh1 == NULL) {
sh1 = sh;
}
else {
sh2 = sh;
break;
}
sh = stateheader_advance(sh);
}

if (sh1 == NULL)
{
ErrorPrompt("PocketNES save file has no SRAM.");
offset = 0;
}
else if (sh2 != NULL)
{
ErrorPrompt("PocketNES save file has more than one SRAM.");
offset = 0;
}
else
{
goomba_size_t len;
void* extracted = goomba_extract(savebuffer, sh1, &len);
if (!extracted)
ErrorPrompt(goomba_last_error());
else
{
memcpy(savebuffer, extracted, len);
offset = len;
free(extracted);
}
}
}

if (offset > 0)
{
if(GameInfo->type == GIT_CART)
Expand Down Expand Up @@ -154,6 +277,9 @@ LoadRAMAuto (bool silent)
if (LoadRAM(filepath, silent))
return true;

if (!GCSettings.AppendAuto)
return false;

// look for file with no number or Auto appended
if(!MakeFilePath(filepath2, FILE_RAM, romFilename, -1))
return false;
Expand Down
35 changes: 34 additions & 1 deletion source/filebrowser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
#include "fceuram.h"
#include "fceustate.h"
#include "patch.h"
#include "pocketnes/goombasav.h"
#include "pocketnes/pocketnesrom.h"

BROWSERINFO browser;
BROWSERENTRY * browserList = NULL; // list of files/folders in browser
Expand Down Expand Up @@ -280,7 +282,10 @@ bool MakeFilePath(char filepath[], int type, char * filename, int filenum)
if(filenum == -1)
sprintf(file, "%s.%s", filename, ext);
else if(filenum == 0)
sprintf(file, "%s Auto.%s", filename, ext);
if (GCSettings.AppendAuto <= 0)
sprintf(file, "%s.%s", filename, ext);
else
sprintf(file, "%s Auto.%s", filename, ext);
else
sprintf(file, "%s %i.%s", filename, filenum, ext);
}
Expand Down Expand Up @@ -353,6 +358,12 @@ static bool IsValidROM()

if (p != NULL)
{
if(strcasecmp(p, ".gba") == 0)
{
// File will be checked for GBA ROMs later.
return true;
}

char * zippedFilename = NULL;

if(stricmp(p, ".zip") == 0 && !inSz)
Expand Down Expand Up @@ -480,6 +491,28 @@ int BrowserLoadFile()
goto done;

filesize = LoadFile ((char *)nesrom, filepath, browserList[browser.selIndex].length, NOTSILENT);

// check nesrom for PocketNES embedded roms
const char *ext = strrchr(filepath, '.');
if (ext != NULL && strcmp(ext, ".gba") == 0)
{
const pocketnes_romheader* rom1 = pocketnes_first_rom(nesrom, filesize);
const pocketnes_romheader* rom2 = NULL;
if (rom1 != NULL) {
rom2 = pocketnes_next_rom(nesrom, filesize, rom1);
}

if (rom1 == NULL)
ErrorPrompt("No NES ROMs found in this file.");
else if (rom2 != NULL)
ErrorPrompt("More than one NES ROM found in this file. Only files with one ROM are supported.");
else
{
const void* rom = rom1 + 1;
filesize = little_endian_conv_32(rom1->filesize);
memcpy(nesrom, rom, filesize);
}
}
}
else
{
Expand Down
1 change: 1 addition & 0 deletions source/fileop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,7 @@ static bool ParseDirEntries()
if( stricmp(ext, "nes") != 0 && stricmp(ext, "fds") != 0 &&
stricmp(ext, "nsf") != 0 && stricmp(ext, "unf") != 0 &&
stricmp(ext, "nez") != 0 && stricmp(ext, "unif") != 0 &&
stricmp(ext, "gba") != 0 &&
stricmp(ext, "zip") != 0 && stricmp(ext, "7z") != 0)
continue;
}
Expand Down
10 changes: 10 additions & 0 deletions source/menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3549,6 +3549,7 @@ static int MenuSettingsFile()
sprintf(options.name[i++], "Screenshots Folder");
sprintf(options.name[i++], "Auto Load");
sprintf(options.name[i++], "Auto Save");
sprintf(options.name[i++], "Append Auto to .SAV Files");
options.length = i;

for(i=0; i < options.length; i++)
Expand Down Expand Up @@ -3634,6 +3635,12 @@ static int MenuSettingsFile()
if (GCSettings.AutoSave > 3)
GCSettings.AutoSave = 0;
break;

case 8:
GCSettings.AppendAuto++;
if (GCSettings.AppendAuto > 1)
GCSettings.AppendAuto = 0;
break;
}

if(ret >= 0 || firstRun)
Expand Down Expand Up @@ -3706,6 +3713,9 @@ static int MenuSettingsFile()
else if (GCSettings.AutoSave == 2) sprintf (options.value[7],"State");
else if (GCSettings.AutoSave == 3) sprintf (options.value[7],"Both");

if (GCSettings.AppendAuto == 0) sprintf (options.value[8], "Off");
else if (GCSettings.AppendAuto == 1) sprintf (options.value[8], "On");

optionBrowser.TriggerUpdate();
}

Expand Down
Loading

0 comments on commit da54d31

Please sign in to comment.