diff --git a/config.c b/config.c index 1f7ffa5..27771e8 100644 --- a/config.c +++ b/config.c @@ -106,7 +106,6 @@ static char config_filename[CONFIG_FILE_NAME_LENGTH] = ""; /* Specific XML tags */ static const char *tag_root = "cabrio-config"; static const char *tag_emulators = "emulators"; -static const char *tag_emulator = "emulator"; static const char *tag_emulator_executable = "executable"; static const char *tag_game_list = "game-list"; static const char *tag_games = "games"; @@ -152,6 +151,7 @@ static const char *tag_theme_sounds_sound = "sound"; static const char *tag_theme_sounds_sound_file = "sound-file"; static const char *tag_theme_snap = "snap"; static const char *tag_theme_snap_fix_ar = "fix-aspect-ratio"; +static const char *tag_theme_snap_platform_icons = "platform-icons"; static const char *tag_theme_hints = "hints"; static const char *tag_theme_hints_pulse = "pulse"; static const char *tag_theme_hints_image_back = "back-image"; @@ -202,6 +202,8 @@ static const char *tag_directory = "directory"; static const char *tag_color = "color"; static const char *tag_match = "match"; static const char *tag_category = "category"; +static const char *tag_emulator = "emulator"; +static const char *tag_default = "default"; /* Common values */ static const char *config_empty = ""; @@ -438,9 +440,15 @@ int config_read_emulator( xmlNode *node, struct config_emulator *emulator ) { else if( strcmp( (char*)node->name, tag_directory ) == 0 ) { strncpy( emulator->directory, (char*)xmlNodeGetContent(node), CONFIG_FILE_NAME_LENGTH ); } + else if( strcmp( (char*)node->name, tag_platform ) == 0 ) { + emulator->platform = config_platform( (char*)xmlNodeGetContent(node) ); + } else if( strcmp( (char*)node->name, tag_params ) == 0 ) { config_read_emulator_params( node->children, emulator ); } + else if( strcmp( (char*)node->name, tag_default ) == 0 ) { + config_read_boolean( (char*)node->name, (char*)xmlNodeGetContent(node), &emulator->is_default ); + } else { fprintf( stderr, warn_skip, tag_emulator, node->name ); } @@ -738,6 +746,9 @@ int config_read_game( xmlNode *node, struct config_game *game, const char *game_ else if( strcmp( (char*)node->name, tag_game_video ) == 0 ) { strncpy( game->video, (char*)xmlNodeGetContent(node), CONFIG_FILE_NAME_LENGTH ); } + else if( strcmp( (char*)node->name, tag_emulator ) == 0 ) { + strncpy( game->emulator, (char*)xmlNodeGetContent(node), CONFIG_NAME_LENGTH ); + } else { fprintf( stderr, warn_skip, tag_game, node->name ); } @@ -1083,6 +1094,9 @@ int config_read_snap( xmlNode *node, struct config_snap *snap ) { else if( strcmp( (char*)node->name, tag_auto_hide ) == 0 ) { config_read_boolean( (char*)node->name, (char*)xmlNodeGetContent(node), &snap->auto_hide ); } + else if( strcmp( (char*)node->name, tag_theme_snap_platform_icons ) == 0 ) { + config_read_boolean( (char*)node->name, (char*)xmlNodeGetContent(node), &snap->platform_icons ); + } else { fprintf( stderr, warn_skip, tag_theme_snap, node->name ); } @@ -2220,6 +2234,7 @@ int config_new( void ) { default_theme.snap.size = 1.0; default_theme.snap.fix_aspect_ratio = 1; default_theme.snap.auto_hide = 1; + default_theme.snap.platform_icons = 1; default_theme.hints.offset1 = -2.0; default_theme.hints.offset2 = -1.2; diff --git a/emulator.c b/emulator.c index e56313b..9404fd5 100644 --- a/emulator.c +++ b/emulator.c @@ -1,5 +1,6 @@ #include #include +#include #ifdef __unix__ #include #endif @@ -52,11 +53,11 @@ int resume_all( void ) { return -7; if( game_list_resume() != 0 ) return -8; + sound_resume(); if( snap_resume() != 0 ) return -9; if( game_sel_resume() != 0 ) return -10; - sound_resume(); return 0; } @@ -66,7 +67,6 @@ int emulator_exec( struct game *game ) { struct config_param *param = NULL; int i = 0; int count = 0; - const struct config *config = config_get(); char current_dir[CONFIG_FILE_NAME_LENGTH]; #ifdef __WIN32__ PROCESS_INFORMATION pi; @@ -74,8 +74,8 @@ int emulator_exec( struct game *game ) { char cmdline[CONFIG_MAX_CMD_LENGTH]; #endif - if( config->emulators && config->emulators->executable ) { - param = config->emulators->params; + if( game->emulator && game->emulator->executable ) { + param = game->emulator->params; while( param ) { if( param->name && *param->name && count < CONFIG_MAX_PARAMS - 2 ) params[count++] = param->name; @@ -106,16 +106,16 @@ int emulator_exec( struct game *game ) { } /* If emulator provided a directory, go to it. */ - if( config->emulators->directory[0] ) { + if( game->emulator->directory[0] ) { getcwd( current_dir, CONFIG_FILE_NAME_LENGTH-1 ); - chdir( config->emulators->directory ); + chdir( game->emulator->directory ); } #ifdef __unix__ /* Terminate param list */ params[count] = NULL; - printf( "Executing: %s", config->emulators->executable ); + printf( "Executing: %s", game->emulator->executable ); for( i = 0 ; i < count ; i++ ) { printf( " %s", params[i] ); } @@ -123,10 +123,13 @@ int emulator_exec( struct game *game ) { pid_t pid = fork(); if (pid == 0) { - execvp( config->emulators->executable, params ); + if( execvp( game->emulator->executable, params ) != 0 ) { + fprintf( stderr, "Error: Couldn't execute emulator '%s': %s\n", game->emulator->executable, strerror(errno) ); + exit( 1 ); + } } else if (pid < 0) { - fprintf(stderr, "Warning: failed to fork\n"); + fprintf(stderr, "Error: failed to fork\n"); return -1; } wait( NULL ); @@ -136,7 +139,7 @@ int emulator_exec( struct game *game ) { memset( &si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(si); - snprintf( cmdline, CONFIG_MAX_CMD_LENGTH, "\"%s\"", config->emulators->executable ); + snprintf( cmdline, CONFIG_MAX_CMD_LENGTH, "\"%s\"", game->emulator->executable ); for( i = 0 ; i < count ; i++ ) { if( strlen(cmdline) + strlen(params[i]) + 4 <= CONFIG_MAX_CMD_LENGTH ) { strcat( cmdline, " \"" ); @@ -163,7 +166,7 @@ int emulator_exec( struct game *game ) { } #endif - if( config->emulators->directory[0] ) + if( game->emulator->directory[0] ) chdir( current_dir ); return 0; @@ -187,3 +190,47 @@ int emulator_run( struct game *game ) { return ret; } + +struct config_emulator *emulator_get_by_name( const char *name ) { + struct config_emulator *e = config_get()->emulators; + + if( name && name[0] ) { + while( e ) { + if( strcasecmp( e->name, name ) == 0 ) + break; + e = e->next; + } + } + + return e; +} + +struct config_emulator *emulator_get_by_platform( const char *platform ) { + struct config_emulator *e = config_get()->emulators; + + if( platform && platform[0] ) { + while( e ) { + if( e->platform && e->platform->name && strcasecmp( e->platform->name, platform ) == 0 ) + break; + e = e->next; + } + } + + return e; +} + +struct config_emulator *emulator_get_default( void ) { + struct config_emulator *e = config_get()->emulators; + + while( e ) { + if( e->is_default ) + break; + e = e->next; + } + + if( !e ) + e = config_get()->emulators; + + return e; +} + diff --git a/game.c b/game.c index 8c99afb..9fc0ee5 100644 --- a/game.c +++ b/game.c @@ -7,6 +7,7 @@ #include "sdl_ogl.h" #include "font.h" #include "media.h" +#include "emulator.h" #include "location.h" #include "lookup.h" @@ -188,6 +189,23 @@ int game_list_create( void ) { game->platform = platform_get( NULL ); } + if( config_game->emulator && config_game->emulator[0] ) { + game->emulator = emulator_get_by_name( config_game->emulator ); + if( !game->emulator ) + fprintf( stderr, "Warning: Emulator '%s' defined for game '%s' not found\n", config_game->emulator, game->name ); + } + if( !game->emulator && config_game->platform ) { + game->emulator = emulator_get_by_platform( config_game->platform->name ); + } + if( !game->emulator ) { + game->emulator = emulator_get_default(); + } + if( !game->emulator ) { + fprintf( stderr, "Warning: No emulator found for game '%s'\n", game->name ); + free( game ); + continue; + } + /* Add game categories. */ game->categories = NULL; while( config_game_category ) { diff --git a/include/config.h b/include/config.h index e668dd7..e76a6e1 100644 --- a/include/config.h +++ b/include/config.h @@ -38,6 +38,11 @@ struct config_param { char value[CONFIG_PARAM_LENGTH]; }; +struct config_platform { + struct config_platform *next; + char name[CONFIG_NAME_LENGTH]; +}; + struct config_emulator { struct config_emulator *next; int id; @@ -45,12 +50,9 @@ struct config_emulator { char display_name[CONFIG_NAME_LENGTH]; char executable[CONFIG_FILE_NAME_LENGTH]; char directory[CONFIG_FILE_NAME_LENGTH]; + int is_default; struct config_param *params; -}; - -struct config_platform { - struct config_platform *next; - char name[CONFIG_NAME_LENGTH]; + struct config_platform *platform; }; struct config_lookup { @@ -94,6 +96,7 @@ struct config_game { char name[CONFIG_NAME_LENGTH]; char rom_image[CONFIG_FILE_NAME_LENGTH]; char video[CONFIG_FILE_NAME_LENGTH]; + char emulator[CONFIG_NAME_LENGTH]; struct config_game_category *categories; struct config_param *params; struct config_platform *platform; @@ -160,6 +163,7 @@ struct config_snap { float size; int fix_aspect_ratio; int auto_hide; + int platform_icons; }; struct config_hints { diff --git a/include/emulator.h b/include/emulator.h index d0deb81..e209776 100644 --- a/include/emulator.h +++ b/include/emulator.h @@ -2,8 +2,12 @@ #define _EMULATOR_H_ 1 #include "game.h" +#include "config.h" int emulator_run( struct game *game ); +struct config_emulator *emulator_get_by_name( const char *name ); +struct config_emulator *emulator_get_by_platform( const char *platform ); +struct config_emulator *emulator_get_default( void ); #endif diff --git a/include/game.h b/include/game.h index 22f51fc..a87734e 100644 --- a/include/game.h +++ b/include/game.h @@ -28,6 +28,7 @@ struct game { struct texture *texture; struct config_param *params; struct game_media *media; + struct config_emulator *emulator; char *name; char *rom_path; }; diff --git a/snap.c b/snap.c index 0657c63..3f7dc63 100644 --- a/snap.c +++ b/snap.c @@ -212,7 +212,7 @@ void snap_draw( void ) { glTexCoord2f(1.0, 0.0); glVertex3f( xsize, ysize, 0.0); glEnd(); - if( platform_count() > 1 && platform_texture ) { + if( config->platform_icons && platform_count() > 1 && platform_texture ) { GLfloat platform_xsize = platform_texture->width; GLfloat platform_ysize = platform_texture->height;