From b09a060ae6ec695a1dba0cbea3b91c63428ca9af Mon Sep 17 00:00:00 2001 From: retro-wertz Date: Sat, 15 Dec 2018 10:23:43 +0800 Subject: [PATCH] Wii related updates for save state fixes/workarounds (#246) * Wii: Fix uninitialized save state size causing load state problems - Issue origially from Wii and possibly affects similar devices where retroarch and the core are one program. The problem was that the serialize size was not reset when you change game, causing the last serialized size to be carried over to the next game loaded causing save state issues due to change in size. Initializing this variable during retro_init() seems enough for most of the games. - In this same observation, also initialized some variables in a similar way. - also exluded a variable used for sound state that was added for smooth sound after load state which causes similar loading issues as well. - default sample rate has been lowered to 32K as well as to minimize some stuttering for these devices, while maintaining 48K sample rate for others. - Some comments are added to modified section as necessary. * Add workaround for save state issue in Wii with expansion audio - Some mappers are not loading states as well. Seems to affect those that are using expansion audio. some of these mappers(bandai, mmc5, namco106), the state variables has to be expanded so that it will load states fine with big endian while others (vrc6, vrc7 sunsoft), some variables that were added for smoother audio during load state has been removed. - This does not guarantee though that other mappers might not have similar incompatibilities after loading a state but so far, some of the most common roms in each mapper has been tested to load fine. * FDS: Expand state variables for big endian compatibility * FDS: Change OSD label from Disk 0 to Disk 1... when switching disks - Minor osd label change that now shows Disk 1 of (# of disks) instead of just Disk 0 Side nth. --- src/boards/69.c | 5 ++++ src/boards/bandai.c | 23 +++++++++++++--- src/boards/mmc5.c | 48 +++++++++++++++++++++++++++------ src/boards/n106.c | 30 ++++++++++++++++++--- src/boards/vrc6.c | 4 +++ src/boards/vrc7.c | 6 +++++ src/drivers/libretro/libretro.c | 26 +++++++++++++----- src/fds.c | 16 ++++++++--- src/sound.c | 7 +++++ 9 files changed, 141 insertions(+), 24 deletions(-) diff --git a/src/boards/69.c b/src/boards/69.c index 672f924..2a7093b 100644 --- a/src/boards/69.c +++ b/src/boards/69.c @@ -113,6 +113,9 @@ static SFORMAT SStateRegs[] = { { &sndcmd, 1, "SCMD" }, { sreg, 14, "SREG" }, + +/* Ignoring these sound state files for Wii since it causes states unable to load */ +#ifndef GEKKO { &dcount[0], 4 | FCEUSTATE_RLSB, "DCT0" }, { &dcount[1], 4 | FCEUSTATE_RLSB, "DCT1" }, { &dcount[2], 4 | FCEUSTATE_RLSB, "DCT2" }, @@ -122,6 +125,8 @@ static SFORMAT SStateRegs[] = { &CAYBC[0], 4 | FCEUSTATE_RLSB, "BC00" }, { &CAYBC[1], 4 | FCEUSTATE_RLSB, "BC01" }, { &CAYBC[2], 4 | FCEUSTATE_RLSB, "BC02" }, +#endif + { 0 } }; diff --git a/src/boards/bandai.c b/src/boards/bandai.c index 9d3ca99..375d2b0 100644 --- a/src/boards/bandai.c +++ b/src/boards/bandai.c @@ -31,12 +31,29 @@ static int16 IRQCount, IRQLatch; static uint8 *WRAM = NULL; static uint32 WRAMSIZE; +/* TODO: Clean this up. State variables are expanded for + * big-endian compatibility when saving and loading states */ static SFORMAT StateRegs[] = { - { reg, 16, "REGS" }, + { ®[0], 1, "REG0" }, + { ®[1], 1, "REG1" }, + { ®[2], 1, "REG2" }, + { ®[3], 1, "REG3" }, + { ®[4], 1, "REG4" }, + { ®[5], 1, "REG5" }, + { ®[6], 1, "REG6" }, + { ®[7], 1, "REG7" }, + { ®[8], 1, "REG8" }, + { ®[9], 1, "REG9" }, + { ®[10], 1, "REGA" }, + { ®[11], 1, "REGB" }, + { ®[12], 1, "REGC" }, + { ®[13], 1, "REGD" }, + { ®[14], 1, "REGE" }, + { ®[15], 1, "REGF" }, { &IRQa, 1, "IRQA" }, - { &IRQCount, 2, "IRQC" }, - { &IRQLatch, 2, "IRQL" }, /* need for Famicom Jump II - Saikyou no 7 Nin (J) [!] */ + { &IRQCount, 2 | FCEUSTATE_RLSB, "IRQC" }, + { &IRQLatch, 2 | FCEUSTATE_RLSB, "IRQL" }, /* need for Famicom Jump II - Saikyou no 7 Nin (J) [!] */ { 0 } }; diff --git a/src/boards/mmc5.c b/src/boards/mmc5.c index 27952c6..0ef1681 100644 --- a/src/boards/mmc5.c +++ b/src/boards/mmc5.c @@ -751,12 +751,31 @@ static void GenMMC5Reset(void) { FCEU_CheatAddRAM(1, 0x5c00, ExRAM); } +/* TODO: Clean this up. State variables are expanded for + * big-endian compatibility when saving and loading states */ static SFORMAT MMC5_StateRegs[] = { - { PRGBanks, 4, "PRGB" }, - { CHRBanksA, 16, "CHRA" }, - { CHRBanksB, 8, "CHRB" }, + { &PRGBanks[0], 1, "PRG1" }, + { &PRGBanks[1], 1, "PRG2" }, + { &PRGBanks[2], 1, "PRG3" }, + { &PRGBanks[3], 1, "PRG4" }, + + { &CHRBanksA[0], 2 | FCEUSTATE_RLSB, "CRA1" }, + { &CHRBanksA[1], 2 | FCEUSTATE_RLSB, "CRA2" }, + { &CHRBanksA[2], 2 | FCEUSTATE_RLSB, "CRA3" }, + { &CHRBanksA[3], 2 | FCEUSTATE_RLSB, "CRA4" }, + { &CHRBanksA[4], 2 | FCEUSTATE_RLSB, "CRA5" }, + { &CHRBanksA[5], 2 | FCEUSTATE_RLSB, "CRA6" }, + { &CHRBanksA[6], 2 | FCEUSTATE_RLSB, "CRA7" }, + { &CHRBanksA[7], 2 | FCEUSTATE_RLSB, "CRA8" }, + + { &CHRBanksB[0], 2 | FCEUSTATE_RLSB, "CRB1" }, + { &CHRBanksB[1], 2 | FCEUSTATE_RLSB, "CRB2" }, + { &CHRBanksB[2], 2 | FCEUSTATE_RLSB, "CRB3" }, + { &CHRBanksB[3], 2 | FCEUSTATE_RLSB, "CRB4" }, + { &WRAMPage, 1, "WRMP" }, - { WRAMMaskEnable, 2, "WRME" }, + { &WRAMMaskEnable[0], 1, "WRM1" }, + { &WRAMMaskEnable[1], 1, "WRM2" }, { &mmc5ABMode, 1, "ABMD" }, { &IRQScanline, 1, "IRQS" }, { &IRQEnable, 1, "IRQE" }, @@ -770,13 +789,25 @@ static SFORMAT MMC5_StateRegs[] = { { &MMC5LineCounter, 1, "LCTR" }, { &mmc5psize, 1, "PSIZ" }, { &mmc5vsize, 1, "VSIZ" }, - { mul, 2, "MUL2" }, - { MMC5ROMWrProtect, 4, "WRPR" }, - { MMC5MemIn, 5, "MEMI" }, + + { &mul[0], 1, "MUL1" }, + { &mul[1], 1, "MUL2" }, + + { &MMC5ROMWrProtect[0], 1, "WRP1" }, + { &MMC5ROMWrProtect[1], 1, "WRP2" }, + { &MMC5ROMWrProtect[2], 1, "WRP3" }, + { &MMC5ROMWrProtect[3], 1, "WRP4" }, + + { &MMC5MemIn[0], 1, "MMI1" }, + { &MMC5MemIn[1], 1, "MMI2" }, + { &MMC5MemIn[2], 1, "MMI3" }, + { &MMC5MemIn[3], 1, "MMI4" }, + { &MMC5MemIn[4], 1, "MMI5" }, { &MMC5Sound.wl[0], 2 | FCEUSTATE_RLSB, "SDW0" }, { &MMC5Sound.wl[1], 2 | FCEUSTATE_RLSB, "SDW1" }, - { MMC5Sound.env, 2, "SDEV" }, + { &MMC5Sound.env[0], 1, "SEV1" }, + { &MMC5Sound.env[1], 1, "SEV2" }, { &MMC5Sound.enable, 1, "SDEN" }, { &MMC5Sound.running, 1, "SDRU" }, { &MMC5Sound.raw, 1, "SDRW" }, @@ -790,6 +821,7 @@ static SFORMAT MMC5_StateRegs[] = { { &MMC5Sound.BC[2], 4 | FCEUSTATE_RLSB, "BC02" }, { &MMC5Sound.vcount[0], 4 | FCEUSTATE_RLSB, "VCT0" }, { &MMC5Sound.vcount[1], 4 | FCEUSTATE_RLSB, "VCT1" }, + { 0 } }; diff --git a/src/boards/n106.c b/src/boards/n106.c index e5e8473..b1d6618 100644 --- a/src/boards/n106.c +++ b/src/boards/n106.c @@ -53,10 +53,34 @@ static int is210; /* Lesser mapper. */ static uint8 PRG[3]; static uint8 CHR[8]; +/* TODO: Clean this up. State variables are expanded for + * big-endian compatibility when saving and loading states */ static SFORMAT N106_StateRegs[] = { - { PRG, 3, "PRG" }, - { CHR, 8, "CHR" }, - { NTAPage, 4, "NTA" }, + { &PRG[0], 1, "PRG1" }, + { &PRG[1], 1, "PRG2" }, + { &PRG[2], 1, "PRG3" }, + + { &CHR[0], 1, "CHR1" }, + { &CHR[1], 1, "CHR2" }, + { &CHR[2], 1, "CHR3" }, + { &CHR[3], 1, "CHR4" }, + { &CHR[4], 1, "CHR5" }, + { &CHR[5], 1, "CHR6" }, + { &CHR[6], 1, "CHR7" }, + { &CHR[7], 1, "CHR8" }, + + { &NTAPage[0], 1, "NTA1" }, + { &NTAPage[1], 1, "NTA2" }, + { &NTAPage[2], 1, "NTA3" }, + { &NTAPage[3], 1, "NTA4" }, + + { &IRQCount, 2 | FCEUSTATE_RLSB, "IRQC" }, + { &IRQa, 1, "IRQA" }, + + { &dopol, 1, "GORF" }, + { &gorfus, 1, "DOPO" }, + { &gorko, 1, "GORK" }, + { 0 } }; diff --git a/src/boards/vrc6.c b/src/boards/vrc6.c index b40261c..0574cef 100644 --- a/src/boards/vrc6.c +++ b/src/boards/vrc6.c @@ -56,6 +56,9 @@ static SFORMAT SStateRegs[] = { { vpsg1, 8, "PSG1" }, { vpsg2, 4, "PSG2" }, + +/* Ignoring these sound state files for Wii since it causes states unable to load */ +#ifndef GEKKO /* rw - 2018-11-28 Added */ { &cvbc[0], 4 | FCEUSTATE_RLSB, "BC01" }, { &cvbc[1], 4 | FCEUSTATE_RLSB, "BC02" }, @@ -67,6 +70,7 @@ static SFORMAT SStateRegs[] = { &vcount[1], 4 | FCEUSTATE_RLSB, "VCT1" }, { &vcount[2], 4 | FCEUSTATE_RLSB, "VCT2" }, { &phaseacc, 4 | FCEUSTATE_RLSB, "ACCU" }, +#endif { 0 } }; diff --git a/src/boards/vrc7.c b/src/boards/vrc7.c index 9a30f1f..2d77fa2 100644 --- a/src/boards/vrc7.c +++ b/src/boards/vrc7.c @@ -174,7 +174,10 @@ static void VRC7IRQHook(int a) { static void StateRestore(int version) { Sync(); + +#ifndef GEKKO OPLL_forceRefresh(VRC7Sound); +#endif } void Mapper85_Init(CartInfo *info) { @@ -193,6 +196,8 @@ void Mapper85_Init(CartInfo *info) { VRC7_ESI(); AddExState(&StateRegs, ~0, 0, 0); +/* Ignoring these sound state files for Wii since it causes states unable to load */ +#ifndef GEKKO /* Sound states */ AddExState(&VRC7Sound->adr, sizeof(VRC7Sound->adr), 0, "ADDR"); AddExState(&VRC7Sound->out, sizeof(VRC7Sound->out), 0, "OUT0"); @@ -214,6 +219,7 @@ void Mapper85_Init(CartInfo *info) { AddExState(&VRC7Sound->key_status, sizeof(VRC7Sound->key_status), 0, "KET"); AddExState(&VRC7Sound->mask, sizeof(VRC7Sound->mask), 0, "MASK"); AddExState((uint8 *)VRC7Sound->slot, sizeof(VRC7Sound->slot), 0, "SLOT"); +#endif } void NSFVRC7_Init(void) { diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 33d57b1..4862585 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -98,10 +98,10 @@ static uint16_t retro_palette[256]; static uint16_t* fceu_video_out; /* Some timing-related variables. */ -unsigned sndsamplerate = 48000; -unsigned sndquality = 0; -unsigned sndvolume = 150; -unsigned swapDuty = 0; +static unsigned sndsamplerate; +static unsigned sndquality; +static unsigned sndvolume; +unsigned swapDuty; static int32_t *sound = 0; static uint32_t JSReturn = 0; @@ -110,6 +110,8 @@ static uint32_t MouseData[MAX_PORTS][3] = { {0} }; static uint32_t fc_MouseData[3] = {0}; static uint32_t current_palette = 0; +static unsigned serialize_size; + int PPUViewScanline=0; int PPUViewer=0; @@ -836,6 +838,20 @@ void retro_init(void) if(environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &rgb565)) log_cb.log(RETRO_LOG_INFO, "Frontend supports RGB565 - will use that instead of XRGB1555.\n"); #endif + + /* initialize some of the default variables */ +#ifdef GEKKO + sndsamplerate = 32000; +#else + sndsamplerate = 48000; +#endif + sndquality = 0; + sndvolume = 150; + swapDuty = 0; + + /* Wii: initialize this or else last variable is passed through + * when loading another rom causing save state size change. */ + serialize_size = 0; } static void retro_set_custom_palette(void) @@ -1550,8 +1566,6 @@ void retro_run(void) retro_run_blit(gfx); } -static unsigned serialize_size = 0; - size_t retro_serialize_size(void) { if (serialize_size == 0) diff --git a/src/fds.c b/src/fds.c index 0cfc215..c783009 100644 --- a/src/fds.c +++ b/src/fds.c @@ -142,10 +142,12 @@ static void FDSInit(void) { void FCEU_FDSInsert(int oride) { if (InDisk == 255) { - FCEU_DispMessage("Disk %d Side %s Inserted", SelectDisk >> 1, (SelectDisk & 1) ? "B" : "A"); + FCEU_DispMessage("Disk %d of %d Side %s Inserted", + 1 + (SelectDisk >> 1), (TotalSides + 1) >> 1, (SelectDisk & 1) ? "B" : "A"); InDisk = SelectDisk; } else { - FCEU_DispMessage("Disk %d Side %s Ejected", SelectDisk >> 1, (SelectDisk & 1) ? "B" : "A"); + FCEU_DispMessage("Disk %d of %d Side %s Ejected", + 1 + (SelectDisk >> 1), (TotalSides + 1) >> 1, (SelectDisk & 1) ? "B" : "A"); InDisk = 255; } } @@ -160,7 +162,8 @@ void FCEU_FDSSelect(void) { return; } SelectDisk = ((SelectDisk + 1) % TotalSides) & 3; - FCEU_DispMessage("Disk %d Side %s Selected", SelectDisk >> 1, (SelectDisk & 1) ? "B" : "A"); + FCEU_DispMessage("Disk %d of %d Side %s Selected", + 1 + (SelectDisk >> 1), (TotalSides + 1) >> 1, (SelectDisk & 1) ? "B" : "A"); } static void FP_FASTAPASS(1) FDSFix(int a) { @@ -702,7 +705,12 @@ int FDSLoad(const char *name, FCEUFILE *fp) { AddExState(diskdata[x], 65500, 0, temp); } - AddExState(FDSRegs, sizeof(FDSRegs), 0, "FREG"); + AddExState(&FDSRegs[0], 1, 0, "REG1"); + AddExState(&FDSRegs[1], 1, 0, "REG2"); + AddExState(&FDSRegs[2], 1, 0, "REG3"); + AddExState(&FDSRegs[3], 1, 0, "REG4"); + AddExState(&FDSRegs[4], 1, 0, "REG5"); + AddExState(&FDSRegs[5], 1, 0, "REG6"); AddExState(&IRQCount, 4, 1, "IRQC"); AddExState(&IRQLatch, 4, 1, "IQL1"); AddExState(&IRQa, 1, 0, "IRQA"); diff --git a/src/sound.c b/src/sound.c index 4eed69f..6454f13 100644 --- a/src/sound.c +++ b/src/sound.c @@ -1224,8 +1224,15 @@ SFORMAT FCEUSND_STATEINFO[] = { { &sexyfilter_acc2, sizeof(sexyfilter_acc2) | FCEUSTATE_RLSB, "FAC2" }, { &lq_tcout, sizeof(lq_tcout) | FCEUSTATE_RLSB, "TCOU"}, +/* 2018-12-14 - Wii and possibly other big-endian platforms are having + * issues loading states with this. Increasing it only helps a few games. + * Disabling this state variable for Wii/WiiU/GC for now. */ +/* TODO: fix this for better runahead feature for big-endian */ +#ifndef GEKKO /* wave buffer is used for filtering, only need first 17 values from it */ { &Wave, 32 * sizeof(int32), "WAVE"}, +#endif + { 0 } };