Mercurial > spc_convert
diff demo/save_state.c @ 0:e38dacceb958
initial import
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 21 Oct 2011 05:53:11 -0700 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/demo/save_state.c Fri Oct 21 05:53:11 2011 -0700 1.3 @@ -0,0 +1,107 @@ 1.4 +/* Loads "test.spc", skips 5 seconds, saves exact emulator state to "state.bin", 1.5 +hen records 5 seconds to "first.wav". When run again, loads this state back into 1.6 +emulator and records 5 seconds to "second.wav". These two wave files should 1.7 +be identical. 1.8 + 1.9 +Usage: save_state [test.spc] 1.10 +*/ 1.11 + 1.12 +#include "snes_spc/spc.h" 1.13 + 1.14 +#include "wave_writer.h" 1.15 +#include "demo_util.h" /* error(), load_file() */ 1.16 + 1.17 +static SNES_SPC* snes_spc; 1.18 + 1.19 +void record_wav( const char* path, int secs ) 1.20 +{ 1.21 + /* Start writing wave file */ 1.22 + wave_open( spc_sample_rate, path ); 1.23 + wave_enable_stereo(); 1.24 + while ( wave_sample_count() < secs * spc_sample_rate * 2 ) 1.25 + { 1.26 + /* Play into buffer */ 1.27 + #define BUF_SIZE 2048 1.28 + short buf [BUF_SIZE]; 1.29 + error( spc_play( snes_spc, BUF_SIZE, buf ) ); 1.30 + 1.31 + wave_write( buf, BUF_SIZE ); 1.32 + } 1.33 + wave_close(); 1.34 +} 1.35 + 1.36 +void state_save( unsigned char** out, void* in, size_t size ) 1.37 +{ 1.38 + memcpy( *out, in, size ); 1.39 + *out += size; 1.40 +} 1.41 + 1.42 +void make_save_state( const char* path ) 1.43 +{ 1.44 + /* Load SPC */ 1.45 + long spc_size; 1.46 + void* spc = load_file( path, &spc_size ); 1.47 + error( spc_load_spc( snes_spc, spc, spc_size ) ); 1.48 + free( spc ); 1.49 + spc_clear_echo( snes_spc ); 1.50 + 1.51 + /* Skip several seconds */ 1.52 + error( spc_play( snes_spc, 5 * spc_sample_rate * 2, 0 ) ); 1.53 + 1.54 + /* Save state to file */ 1.55 + { 1.56 + static unsigned char state [spc_state_size]; /* buffer large enough for data */ 1.57 + unsigned char* out = state; 1.58 + spc_copy_state( snes_spc, &out, state_save ); 1.59 + write_file( "state.bin", state, out - state ); 1.60 + } 1.61 + 1.62 + record_wav( "first.wav", 5 ); 1.63 +} 1.64 + 1.65 +void state_load( unsigned char** in, void* out, size_t size ) 1.66 +{ 1.67 + memcpy( out, *in, size ); 1.68 + *in += size; 1.69 +} 1.70 + 1.71 +void use_save_state() 1.72 +{ 1.73 + /* Load state into memory */ 1.74 + long state_size; 1.75 + unsigned char* state = load_file( "state.bin", &state_size ); 1.76 + 1.77 + /* Load into emulator */ 1.78 + unsigned char* in = state; 1.79 + spc_copy_state( snes_spc, &in, state_load ); 1.80 + assert( in - state <= state_size ); /* be sure it didn't read past end */ 1.81 + 1.82 + record_wav( "second.wav", 5 ); 1.83 +} 1.84 + 1.85 +int file_exists( const char* path ) 1.86 +{ 1.87 + FILE* file = fopen( path, "rb" ); 1.88 + if ( !file ) 1.89 + return 0; 1.90 + 1.91 + fclose( file ); 1.92 + return 1; 1.93 +} 1.94 + 1.95 +int main( int argc, char** argv ) 1.96 +{ 1.97 + snes_spc = spc_new(); 1.98 + if ( !snes_spc ) error( "Out of memory" ); 1.99 + 1.100 + /* Make new state if it doesn't exist, otherwise load it and 1.101 + record to wave file */ 1.102 + if ( !file_exists( "state.bin" ) ) 1.103 + make_save_state( (argc > 1) ? argv [1] : "test.spc" ); 1.104 + else 1.105 + use_save_state(); 1.106 + 1.107 + spc_delete( snes_spc ); 1.108 + 1.109 + return 0; 1.110 +}