view 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 source
1 /* Loads "test.spc", skips 5 seconds, saves exact emulator state to "state.bin",
2 hen records 5 seconds to "first.wav". When run again, loads this state back into
3 emulator and records 5 seconds to "second.wav". These two wave files should
4 be identical.
6 Usage: save_state [test.spc]
7 */
9 #include "snes_spc/spc.h"
11 #include "wave_writer.h"
12 #include "demo_util.h" /* error(), load_file() */
14 static SNES_SPC* snes_spc;
16 void record_wav( const char* path, int secs )
17 {
18 /* Start writing wave file */
19 wave_open( spc_sample_rate, path );
20 wave_enable_stereo();
21 while ( wave_sample_count() < secs * spc_sample_rate * 2 )
22 {
23 /* Play into buffer */
24 #define BUF_SIZE 2048
25 short buf [BUF_SIZE];
26 error( spc_play( snes_spc, BUF_SIZE, buf ) );
28 wave_write( buf, BUF_SIZE );
29 }
30 wave_close();
31 }
33 void state_save( unsigned char** out, void* in, size_t size )
34 {
35 memcpy( *out, in, size );
36 *out += size;
37 }
39 void make_save_state( const char* path )
40 {
41 /* Load SPC */
42 long spc_size;
43 void* spc = load_file( path, &spc_size );
44 error( spc_load_spc( snes_spc, spc, spc_size ) );
45 free( spc );
46 spc_clear_echo( snes_spc );
48 /* Skip several seconds */
49 error( spc_play( snes_spc, 5 * spc_sample_rate * 2, 0 ) );
51 /* Save state to file */
52 {
53 static unsigned char state [spc_state_size]; /* buffer large enough for data */
54 unsigned char* out = state;
55 spc_copy_state( snes_spc, &out, state_save );
56 write_file( "state.bin", state, out - state );
57 }
59 record_wav( "first.wav", 5 );
60 }
62 void state_load( unsigned char** in, void* out, size_t size )
63 {
64 memcpy( out, *in, size );
65 *in += size;
66 }
68 void use_save_state()
69 {
70 /* Load state into memory */
71 long state_size;
72 unsigned char* state = load_file( "state.bin", &state_size );
74 /* Load into emulator */
75 unsigned char* in = state;
76 spc_copy_state( snes_spc, &in, state_load );
77 assert( in - state <= state_size ); /* be sure it didn't read past end */
79 record_wav( "second.wav", 5 );
80 }
82 int file_exists( const char* path )
83 {
84 FILE* file = fopen( path, "rb" );
85 if ( !file )
86 return 0;
88 fclose( file );
89 return 1;
90 }
92 int main( int argc, char** argv )
93 {
94 snes_spc = spc_new();
95 if ( !snes_spc ) error( "Out of memory" );
97 /* Make new state if it doesn't exist, otherwise load it and
98 record to wave file */
99 if ( !file_exists( "state.bin" ) )
100 make_save_state( (argc > 1) ? argv [1] : "test.spc" );
101 else
102 use_save_state();
104 spc_delete( snes_spc );
106 return 0;
107 }