qzdoom-gpl/snes_spc/demo/save_state.c
Randy Heit 3bfcc5c09c - Removed lots of spc_* cvars that are no longer meaningful and changed
spc_amp from a x.4 fixed point number to a normal float.
- Switched SPC playback from the external SNESAPU.DLL to Blargg's LGPL
  snes_spc library. I've compiled it with the fast DSP rather than the
  highly accurate one, since I didn't notice a meaningful difference between
  the two in my limited testing. In short: SPC playback is now built in to
  ZDoom. You don't need to download anything extra to make it work, and it
  also works on Linux as well as Windows (though building with Linux is
  currently untested).
- Fixed: Stereo separation was calculated very wrongly when in 2D sound mode.


SVN r794 (trunk)
2008-03-11 22:17:57 +00:00

107 lines
2.4 KiB
C

/* Loads "test.spc", skips 5 seconds, saves exact emulator state to "state.bin",
hen records 5 seconds to "first.wav". When run again, loads this state back into
emulator and records 5 seconds to "second.wav". These two wave files should
be identical.
Usage: save_state [test.spc]
*/
#include "snes_spc/spc.h"
#include "wave_writer.h"
#include "demo_util.h" /* error(), load_file() */
static SNES_SPC* snes_spc;
void record_wav( const char* path, int secs )
{
/* Start writing wave file */
wave_open( spc_sample_rate, path );
wave_enable_stereo();
while ( wave_sample_count() < secs * spc_sample_rate * 2 )
{
/* Play into buffer */
#define BUF_SIZE 2048
short buf [BUF_SIZE];
error( spc_play( snes_spc, BUF_SIZE, buf ) );
wave_write( buf, BUF_SIZE );
}
wave_close();
}
void state_save( unsigned char** out, void* in, size_t size )
{
memcpy( *out, in, size );
*out += size;
}
void make_save_state( const char* path )
{
/* Load SPC */
long spc_size;
void* spc = load_file( path, &spc_size );
error( spc_load_spc( snes_spc, spc, spc_size ) );
free( spc );
spc_clear_echo( snes_spc );
/* Skip several seconds */
error( spc_play( snes_spc, 5 * spc_sample_rate * 2, 0 ) );
/* Save state to file */
{
static unsigned char state [spc_state_size]; /* buffer large enough for data */
unsigned char* out = state;
spc_copy_state( snes_spc, &out, state_save );
write_file( "state.bin", state, out - state );
}
record_wav( "first.wav", 5 );
}
void state_load( unsigned char** in, void* out, size_t size )
{
memcpy( out, *in, size );
*in += size;
}
void use_save_state()
{
/* Load state into memory */
long state_size;
unsigned char* state = load_file( "state.bin", &state_size );
/* Load into emulator */
unsigned char* in = state;
spc_copy_state( snes_spc, &in, state_load );
assert( in - state <= state_size ); /* be sure it didn't read past end */
record_wav( "second.wav", 5 );
}
int file_exists( const char* path )
{
FILE* file = fopen( path, "rb" );
if ( !file )
return 0;
fclose( file );
return 1;
}
int main( int argc, char** argv )
{
snes_spc = spc_new();
if ( !snes_spc ) error( "Out of memory" );
/* Make new state if it doesn't exist, otherwise load it and
record to wave file */
if ( !file_exists( "state.bin" ) )
make_save_state( (argc > 1) ? argv [1] : "test.spc" );
else
use_save_state();
spc_delete( snes_spc );
return 0;
}