1.1 --- a/src/dreamcast.c Sat Oct 27 05:47:55 2007 +0000
1.2 +++ b/src/dreamcast.c Wed Oct 31 09:11:14 2007 +0000
1.5 - * $Id: dreamcast.c,v 1.26 2007-10-27 05:47:55 nkeynes Exp $
1.6 + * $Id: dreamcast.c,v 1.27 2007-10-31 09:10:23 nkeynes Exp $
1.7 * Central switchboard for the system. This pulls all the individual modules
1.8 * together into some kind of coherent structure. This is also where you'd
1.9 * add Naomi support, if I ever get a board to play with...
1.10 @@ -220,62 +220,137 @@
1.11 uint32_t module_count;
1.14 +struct chunk_header {
1.15 + char marker[4]; /* Always BLCK */
1.16 + char name[8]; /* Block (module) name */
1.17 + uint32_t block_length;
1.21 + * Check the save state header to ensure that it is a valid, supported
1.23 + * @return the number of blocks following, or 0 if the file is invalid.
1.25 +int dreamcast_read_save_state_header( FILE *f )
1.27 + struct save_state_header header;
1.28 + if( fread( &header, sizeof(header), 1, f ) != 1 ) {
1.31 + if( strncmp( header.magic, DREAMCAST_SAVE_MAGIC, 16 ) != 0 ) {
1.32 + ERROR( "Not a %s save state file", APP_NAME );
1.35 + if( header.version != DREAMCAST_SAVE_VERSION ) {
1.36 + ERROR( "%s save state version not supported", APP_NAME );
1.39 + if( header.module_count > MAX_MODULES ) {
1.40 + ERROR( "%s save state is corrupted (bad module count)", APP_NAME );
1.43 + return header.module_count;
1.46 +int dreamcast_write_chunk_header( const gchar *name, uint32_t length, FILE *f )
1.48 + struct chunk_header head;
1.50 + memcpy( head.marker, "BLCK", 4 );
1.51 + memset( head.name, 0, 8 );
1.52 + memcpy( head.name, name, strlen(name) );
1.53 + head.block_length = length;
1.54 + return fwrite( &head, sizeof(head), 1, f );
1.58 +frame_buffer_t dreamcast_load_preview( const gchar *filename )
1.61 + FILE *f = fopen( filename, "r" );
1.62 + if( f == NULL ) return NULL;
1.64 + int module_count = dreamcast_read_save_state_header(f);
1.65 + if( module_count <= 0 ) {
1.69 + for( i=0; i<module_count; i++ ) {
1.70 + struct chunk_header head;
1.71 + if( fread( &head, sizeof(head), 1, f ) != 1 ) {
1.75 + if( memcmp("BLCK", head.marker, 4) != 0 ) {
1.80 + if( strcmp("PVR2", head.name) == 0 ) {
1.81 + uint32_t buf_count;
1.83 + fread( &buf_count, sizeof(buf_count), 1, f );
1.84 + fread( &has_front, sizeof(has_front), 1, f );
1.85 + if( buf_count != 0 && has_front ) {
1.86 + frame_buffer_t result = read_png_from_stream(f);
1.92 + fseek( f, head.block_length, SEEK_CUR );
1.98 int dreamcast_load_state( const gchar *filename )
1.102 + int module_count;
1.103 int have_read[MAX_MODULES];
1.105 - struct save_state_header header;
1.108 - f = fopen( filename, "r" );
1.109 + FILE *f = fopen( filename, "r" );
1.110 if( f == NULL ) return errno;
1.112 - fread( &header, sizeof(header), 1, f );
1.113 - if( strncmp( header.magic, DREAMCAST_SAVE_MAGIC, 16 ) != 0 ) {
1.114 - ERROR( "Not a %s save state file", APP_NAME );
1.115 + module_count = dreamcast_read_save_state_header(f);
1.116 + if( module_count <= 0 ) {
1.120 - if( header.version != DREAMCAST_SAVE_VERSION ) {
1.121 - ERROR( "%s save state version not supported", APP_NAME );
1.124 - if( header.module_count > MAX_MODULES ) {
1.125 - ERROR( "%s save state is corrupted (bad module count)", APP_NAME );
1.129 for( i=0; i<MAX_MODULES; i++ ) {
1.133 - for( i=0; i<header.module_count; i++ ) {
1.134 - fread(tmp, 4, 1, f );
1.135 - if( strncmp(tmp, "BLCK", 4) != 0 ) {
1.136 + for( i=0; i<module_count; i++ ) {
1.137 + struct chunk_header chunk;
1.138 + fread( &chunk, sizeof(chunk), 1, f );
1.139 + if( strncmp(chunk.marker, "BLCK", 4) != 0 ) {
1.140 ERROR( "%s save state is corrupted (missing block header %d)", APP_NAME, i );
1.143 - len = fread_string(tmp, sizeof(tmp), f );
1.144 - if( len > 64 || len < 1 ) {
1.145 - ERROR( "%s save state is corrupted (bad string)", APP_NAME );
1.150 /* Find the matching module by name */
1.151 for( j=0; j<num_modules; j++ ) {
1.152 - if( strcmp(modules[j]->name,tmp) == 0 ) {
1.153 + if( strcmp(modules[j]->name,chunk.name) == 0 ) {
1.155 if( modules[j]->load == NULL ) {
1.156 ERROR( "%s save state is corrupted (no loader for %s)", APP_NAME, modules[j]->name );
1.159 } else if( modules[j]->load(f) != 0 ) {
1.160 ERROR( "%s save state is corrupted (%s failed)", APP_NAME, modules[j]->name );
1.167 if( j == num_modules ) {
1.169 ERROR( "%s save state contains unrecognized section", APP_NAME );
1.172 @@ -315,9 +390,15 @@
1.173 fwrite( &header, sizeof(header), 1, f );
1.174 for( i=0; i<num_modules; i++ ) {
1.175 if( modules[i]->save != NULL ) {
1.176 - fwrite( "BLCK", 4, 1, f );
1.177 - fwrite_string( modules[i]->name, f );
1.178 + uint32_t blocklen, posn1, posn2;
1.179 + dreamcast_write_chunk_header( modules[i]->name, 0, f );
1.180 + posn1 = ftell(f);
1.181 modules[i]->save(f);
1.182 + posn2 = ftell(f);
1.183 + blocklen = posn2 - posn1;
1.184 + fseek( f, posn1-4, SEEK_SET );
1.185 + fwrite( &blocklen, sizeof(blocklen), 1, f );
1.186 + fseek( f, posn2, SEEK_SET );