FIXED GB audio state loading [blargg]
This commit is contained in:
parent
a5179953ab
commit
79cc82a59f
|
@ -20,6 +20,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../System.h"
|
||||
#include "../NLS.h"
|
||||
|
@ -591,7 +592,8 @@ u8 ZeroTable[256] = {
|
|||
#define GBSAVE_GAME_VERSION_9 9
|
||||
#define GBSAVE_GAME_VERSION_10 10
|
||||
#define GBSAVE_GAME_VERSION_11 11
|
||||
#define GBSAVE_GAME_VERSION GBSAVE_GAME_VERSION_11
|
||||
#define GBSAVE_GAME_VERSION_12 12
|
||||
#define GBSAVE_GAME_VERSION GBSAVE_GAME_VERSION_12
|
||||
|
||||
int inline gbGetValue(int min,int max,int v)
|
||||
{
|
||||
|
@ -3565,6 +3567,7 @@ static bool gbWriteSaveState(gzFile gzFile)
|
|||
utilWriteInt(gzFile, gbWindowLine);
|
||||
utilWriteInt(gzFile, inUseRegister_WY);
|
||||
utilWriteInt(gzFile, gbScreenOn);
|
||||
utilWriteInt(gzFile, 0x12345678); // end marker
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3956,6 +3959,9 @@ static bool gbReadSaveState(gzFile gzFile)
|
|||
|
||||
systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
|
||||
|
||||
if ( version >= 12 && utilReadInt( gzFile ) != 0x12345678 )
|
||||
assert( false ); // fails if something read too much/little from file
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,8 +43,6 @@ extern int soundTicks;
|
|||
extern int SOUND_CLOCK_TICKS;
|
||||
extern u32 soundNextPosition;
|
||||
|
||||
extern int soundDebug;
|
||||
|
||||
extern bool soundEcho;
|
||||
extern bool soundLowPass;
|
||||
extern bool soundReverse;
|
||||
|
@ -71,13 +69,6 @@ void gbSoundEvent(register u16 address, register int data)
|
|||
|
||||
gbMemory[address] = data;
|
||||
|
||||
#ifndef FINAL_VERSION
|
||||
if(soundDebug) {
|
||||
// don't translate. debug only
|
||||
log("Sound event: %08lx %02x\n", address, data);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( gb_apu && address >= NR10 && address <= 0xFF3F )
|
||||
gb_apu->write_register( blip_time(), address, data );
|
||||
}
|
||||
|
@ -198,12 +189,6 @@ void gbSoundReset()
|
|||
soundPaused = 1;
|
||||
soundNextPosition = 0;
|
||||
|
||||
// don't translate
|
||||
#ifndef FINAL_VERSION
|
||||
if(soundDebug) {
|
||||
log("*** Sound Init ***\n");
|
||||
}
|
||||
#endif
|
||||
gbSoundEvent(0xff10, 0x80);
|
||||
gbSoundEvent(0xff11, 0xbf);
|
||||
gbSoundEvent(0xff12, 0xf3);
|
||||
|
@ -229,12 +214,6 @@ void gbSoundReset()
|
|||
else
|
||||
gbSoundEvent(0xff26, 0xf1);
|
||||
|
||||
// don't translate
|
||||
#ifndef FINAL_VERSION
|
||||
if(soundDebug) {
|
||||
log("*** Sound Init Complete ***\n");
|
||||
}
|
||||
#endif
|
||||
int addr = 0xff30;
|
||||
|
||||
while(addr < 0xff40) {
|
||||
|
@ -271,12 +250,18 @@ void gbSoundSetQuality(int quality)
|
|||
}
|
||||
}
|
||||
|
||||
static char dummy_buf [735 * 2];
|
||||
static struct {
|
||||
int version;
|
||||
gb_apu_state_t apu;
|
||||
} state;
|
||||
|
||||
#define SKIP( type, name ) { dummy_buf, sizeof (type) }
|
||||
static char dummy_state [735 * 2];
|
||||
|
||||
// funny expr at end ensures that type matches type of variable
|
||||
#define LOAD( type, name ) { &name, sizeof (name) + (&name - (type*) &name) }
|
||||
#define SKIP( type, name ) { dummy_state, sizeof (type) }
|
||||
|
||||
#define LOAD( type, name ) { &name, sizeof (type) }
|
||||
|
||||
// Old save state support
|
||||
|
||||
static variable_desc gbsound_format [] =
|
||||
{
|
||||
|
@ -362,11 +347,6 @@ static variable_desc gbsound_format3 [] =
|
|||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
void gbSoundSaveGame(gzFile gzFile)
|
||||
{
|
||||
// TODO: implement
|
||||
}
|
||||
|
||||
enum {
|
||||
nr10 = 0,
|
||||
nr11, nr12, nr13, nr14,
|
||||
|
@ -376,9 +356,17 @@ enum {
|
|||
nr50, nr51, nr52
|
||||
};
|
||||
|
||||
void gbSoundReadGame(int version,gzFile gzFile)
|
||||
static void gbSoundReadGameOld(int version,gzFile gzFile)
|
||||
{
|
||||
return; // TODO: apparently GB save states don't work in the main emulator
|
||||
if ( version == 11 )
|
||||
{
|
||||
// Version 11 didn't save any state
|
||||
// TODO: same for version 10?
|
||||
state.apu.regs [nr50] = 0x77; // volume at max
|
||||
state.apu.regs [nr51] = 0xFF; // channels enabled
|
||||
state.apu.regs [nr52] = 0x80; // power on
|
||||
return;
|
||||
}
|
||||
|
||||
// Load state
|
||||
utilReadData( gzFile, gbsound_format );
|
||||
|
@ -395,9 +383,7 @@ void gbSoundReadGame(int version,gzFile gzFile)
|
|||
gbSoundSetQuality( quality );
|
||||
|
||||
// Convert to format Gb_Apu uses
|
||||
reset_apu();
|
||||
gb_apu_state_t s;
|
||||
gb_apu->save_state( &s ); // use fresh values for anything not restored
|
||||
gb_apu_state_t& s = state.apu;
|
||||
|
||||
// Only some registers are properly preserved
|
||||
static int const regs_to_copy [] = {
|
||||
|
@ -407,6 +393,64 @@ void gbSoundReadGame(int version,gzFile gzFile)
|
|||
s.regs [regs_to_copy [i]] = gbMemory [0xFF10 + regs_to_copy [i]];
|
||||
|
||||
memcpy( &s.regs [0x20], &gbMemory [0xFF30], 0x10 ); // wave
|
||||
|
||||
gb_apu->load_state( s );
|
||||
}
|
||||
|
||||
// New state format
|
||||
|
||||
static variable_desc gb_state [] =
|
||||
{
|
||||
LOAD( int, state.version ), // room_for_expansion will be used by later versions
|
||||
|
||||
// APU
|
||||
LOAD( u8 [0x40], state.apu.regs ), // last values written to registers and wave RAM (both banks)
|
||||
LOAD( int, state.apu.frame_time ), // clocks until next frame sequencer action
|
||||
LOAD( int, state.apu.frame_phase ), // next step frame sequencer will run
|
||||
|
||||
LOAD( int, state.apu.sweep_freq ), // sweep's internal frequency register
|
||||
LOAD( int, state.apu.sweep_delay ), // clocks until next sweep action
|
||||
LOAD( int, state.apu.sweep_enabled ),
|
||||
LOAD( int, state.apu.sweep_neg ), // obscure internal flag
|
||||
LOAD( int, state.apu.noise_divider ),
|
||||
LOAD( int, state.apu.wave_buf ), // last read byte of wave RAM
|
||||
|
||||
LOAD( int [4], state.apu.delay ), // clocks until next channel action
|
||||
LOAD( int [4], state.apu.length_ctr ),
|
||||
LOAD( int [4], state.apu.phase ), // square/wave phase, noise LFSR
|
||||
LOAD( int [4], state.apu.enabled ), // internal enabled flag
|
||||
|
||||
LOAD( int [3], state.apu.env_delay ), // clocks until next envelope action
|
||||
LOAD( int [3], state.apu.env_volume ),
|
||||
LOAD( int [3], state.apu.env_enabled ),
|
||||
|
||||
SKIP( int [13], room_for_expansion ),
|
||||
|
||||
// Emulator
|
||||
SKIP( int [16], room_for_expansion ),
|
||||
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
void gbSoundSaveGame( gzFile out )
|
||||
{
|
||||
gb_apu->save_state( &state.apu );
|
||||
|
||||
// Be sure areas for expansion get written as zero
|
||||
memset( dummy_state, 0, sizeof dummy_state );
|
||||
|
||||
state.version = 1;
|
||||
utilWriteData( out, gb_state );
|
||||
}
|
||||
|
||||
void gbSoundReadGame( int version, gzFile in )
|
||||
{
|
||||
// Prepare APU and default state
|
||||
reset_apu();
|
||||
gb_apu->save_state( &state.apu );
|
||||
|
||||
if ( version > 11 )
|
||||
utilReadData( in, gb_state );
|
||||
else
|
||||
gbSoundReadGameOld( version, in );
|
||||
|
||||
gb_apu->load_state( state.apu );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue