diff --git a/cheevos.c b/cheevos.c index 28ab1d2af7..4b97355771 100644 --- a/cheevos.c +++ b/cheevos.c @@ -1321,42 +1321,14 @@ int cheevos_get_by_game_id( const char** json, unsigned game_id ) return 0; } -#define CHEEVOS_EIGHT_MB ( 8 * 1024 * 1024 ) - -int cheevos_get_by_content( const char** json, const void* data, size_t size, unsigned flags ) +static unsigned cheevos_get_game_id( unsigned char* hash ) { MD5_CTX ctx; - char buffer[ 4096 ]; - size_t len; - unsigned char hash[ 16 ]; char request[ 256 ]; + const char* json; char game_id[ 16 ]; int res; - MD5_Init( &ctx ); - MD5_Update( &ctx, data, size ); - - if ( ( flags & CHEEVOS_FLAGS_IS_SNES ) && size < CHEEVOS_EIGHT_MB ) - { - size = CHEEVOS_EIGHT_MB - size; - memset( (void*)buffer, 0, sizeof( buffer ) ); - - while ( size ) - { - len = sizeof( buffer ); - - if ( len > size ) - { - len = size; - } - - MD5_Update( &ctx, (void*)buffer, len ); - size -= len; - } - } - - MD5_Final( hash, &ctx ); - snprintf( request, sizeof( request ), "http://retroachievements.org/dorequest.php?r=gameid&u=%s&m=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", @@ -1369,23 +1341,69 @@ int cheevos_get_by_content( const char** json, const void* data, size_t size, un request[ sizeof( request ) - 1 ] = 0; - *json = cheevos_http_get( request, NULL ); + json = cheevos_http_get( request, NULL ); - if ( !*json ) + if ( !json ) { return -1; } - res = cheevos_get_value( *json, 0xb4960eecU /* GameID */, game_id, sizeof( game_id ) ); - free( (void*)*json ); + res = cheevos_get_value( json, 0xb4960eecU /* GameID */, game_id, sizeof( game_id ) ); + free( (void*)json ); - if ( !res ) + return res ? 0 : strtoul( game_id, NULL, 10 ); +} + +#define CHEEVOS_EIGHT_MB ( 8 * 1024 * 1024 ) + +int cheevos_get_by_content( const char** json, const void* data, size_t size ) +{ + MD5_CTX ctx, saved_ctx; + char buffer[ 4096 ]; + size_t len; + unsigned char hash[ 16 ]; + char request[ 256 ]; + unsigned game_id; + int res; + + MD5_Init( &ctx ); + MD5_Update( &ctx, data, size ); + saved_ctx = ctx; + MD5_Final( hash, &ctx ); + + game_id = cheevos_get_game_id( hash ); + + if ( !game_id ) { - RARCH_LOG( "game id is %s\n", game_id ); - res = cheevos_get_by_game_id( json, strtoul( game_id, NULL, 10 ) ); + /* If the content is a SNES game, continue MD5 with zeroes. */ + size = CHEEVOS_EIGHT_MB - size; + memset( (void*)buffer, 0, sizeof( buffer ) ); + + while ( size ) + { + len = sizeof( buffer ); + + if ( len > size ) + { + len = size; + } + + MD5_Update( &saved_ctx, (void*)buffer, len ); + size -= len; + } + + MD5_Final( hash, &saved_ctx ); + + game_id = cheevos_get_game_id( hash ); + + if ( !game_id ) + { + return -1; + } } - return res; + RARCH_LOG( "cheevos game id is %u\n", game_id ); + return cheevos_get_by_game_id( json, game_id ); } #else /* HAVE_CHEEVOS */ diff --git a/cheevos.h b/cheevos.h index a8dfdc27f0..ce37e89495 100644 --- a/cheevos.h +++ b/cheevos.h @@ -29,17 +29,12 @@ typedef struct } cheevos_config_t; -enum -{ - CHEEVOS_FLAGS_IS_SNES = 1 << 0, /* forces * mb padded with zeroes */ -}; - extern cheevos_config_t cheevos_config; int cheevos_load( const char* json ); void cheevos_test( void ); void cheevos_unload( void ); int cheevos_get_by_game_id( const char** json, unsigned game_id ); -int cheevos_get_by_content( const char** json, const void* data, size_t size, unsigned flags ); +int cheevos_get_by_content( const char** json, const void* data, size_t size ); #endif /* __RARCH_CHEEVOS_H */ diff --git a/content.c b/content.c index aff3bfab2a..1fbd1f51d6 100644 --- a/content.c +++ b/content.c @@ -515,7 +515,7 @@ static bool load_content(const struct retro_subsystem_info *special, { if (*content->elems[0].data) { - if ( cheevos_get_by_content(&json, info->data, info->size, CHEEVOS_FLAGS_IS_SNES) == 0 ) + if ( cheevos_get_by_content(&json, info->data, info->size) == 0 ) { cheevos_load(json); free((void*)json);