Commit 282c4e8a authored by Andre Leiradella's avatar Andre Leiradella
Browse files

added auto-configuration to the core; games from the bob's stuff collection...

added auto-configuration to the core; games from the bob's stuff collection were added to the game database
parent 5e5dd844
...@@ -31,11 +31,11 @@ The only core option available on the frontend is: ...@@ -31,11 +31,11 @@ The only core option available on the frontend is:
* Tape Fast Load (enabled|disabled): Instantly loads files if enabled, or disabled it to see the moving horizontal lines while the game loads * Tape Fast Load (enabled|disabled): Instantly loads files if enabled, or disabled it to see the moving horizontal lines while the game loads
* 8K-16K Contents (ROM shadow|RAM|dK'tronics 4K Graphics ROM + 4K RAM): Selects the contents of memory addresses between 8192 and 16383, a shadow copy of the ROM, 8K of RAM, or [dK'tronics 4K ROM plus 4K of RAM](http://www.fruitcake.plus.com/Sinclair/ZX81/Chroma/ChromaInterface_Software_CharacterSetROM.htm) * 8K-16K Contents (ROM shadow|RAM|dK'tronics 4K Graphics ROM + 4K RAM): Selects the contents of memory addresses between 8192 and 16383, a shadow copy of the ROM, 8K of RAM, or [dK'tronics 4K ROM plus 4K of RAM](http://www.fruitcake.plus.com/Sinclair/ZX81/Chroma/ChromaInterface_Software_CharacterSetROM.htm)
* High Resolution (none|WRX): Enables WRX high resolution * High Resolution (auto|none|WRX): Enables WRX high resolution
* Emulate Chroma 81 (disabled|enabled): Enable the [Chroma 81](http://www.fruitcake.plus.com/Sinclair/ZX81/Chroma/ChromaInterface.htm) interface * Emulate Chroma 81 (auto|disabled|enabled): Enable the [Chroma 81](http://www.fruitcake.plus.com/Sinclair/ZX81/Chroma/ChromaInterface.htm) interface
* Video Presets (clean|tv|noisy): Change how the video is emulated (if Chroma 81 is enabled, the video is set to "clean" regardless of this option) * Video Presets (clean|tv|noisy): Change how the video is emulated (if Chroma 81 is enabled, the video is set to "clean" regardless of this option)
* Sound emulation (none|Zon X-81): Enables sound emulation * Sound emulation (auto|none|Zon X-81): Enables sound emulation
* Joypad Up, Down, Left, Right and Fire mappings (default|new line|shift|space|.|0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z): Maps a joypad button to a keyboard key, defaults are the cursor keys and 0 to fire * Joypad button mappings (up, down, left, right, a, b, x, y, l, r, l2, r2): (auto|default|new line|shift|space|.|0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z): Maps a joypad button to a keyboard key, defaults are the cursor keys for the directional pad and '0' to all the other buttons
* Transparent Keyboard Overlay (enabled|disabled): If the keyboard overlay is transparent or opaque * Transparent Keyboard Overlay (enabled|disabled): If the keyboard overlay is transparent or opaque
* Time to Release Key in ms (500|1000|100|300): How many milliseconds to wait before releasing the key pressed using the keyboard overlay * Time to Release Key in ms (500|1000|100|300): How many milliseconds to wait before releasing the key pressed using the keyboard overlay
...@@ -49,7 +49,7 @@ The `p` and the `tzx` formats are supported. ...@@ -49,7 +49,7 @@ The `p` and the `tzx` formats are supported.
## Save States ## Save States
Save states are supported, but are likely to change when more machines are emulated. Save states are supported, but the format is likely to change when more machines are emulated.
## Setup ## Setup
...@@ -57,6 +57,14 @@ Save states are supported, but are likely to change when more machines are emula ...@@ -57,6 +57,14 @@ Save states are supported, but are likely to change when more machines are emula
1. Copy the resulting `81_libretro.dll` or `81_libretro.so` into the `cores` folder of your libretro frontend 1. Copy the resulting `81_libretro.dll` or `81_libretro.so` into the `cores` folder of your libretro frontend
1. Profit! 1. Profit!
## Game Database
Since configuring the core for each game can be a tedious task, **81-libretro** now features auto-configuration. Games support auto-configuration are listed in the `src/gamedb/gamedb.json` file, along with some information and the configuration required to play them.
Currently, there's no way to change the auto-configuration settings short of recompiling the core after making the changes. If you feel the provided auto-configuration could be better or has bugs, please open an issue and I'll take a look.
The core comes with auto-configuration for all homebrew games from [Bob's Stuff](http://www.bobs-stuff.co.uk/zx81.html). If you want to add an auto-configuration for a missing game, please submit a push request with changes only to the `gamedb.json` file.
## Thanks ## Thanks
Erik Olofsen for help with: Erik Olofsen for help with:
...@@ -66,6 +74,8 @@ Erik Olofsen for help with: ...@@ -66,6 +74,8 @@ Erik Olofsen for help with:
* `tzx` support * `tzx` support
* Zon X-81 sound emulation * Zon X-81 sound emulation
See also the `colorized` subfolder.
## Versions ## Versions
Versions that are being used to build and test **81-libretro**: Versions that are being used to build and test **81-libretro**:
......
...@@ -39,6 +39,7 @@ SOURCES_C += $(CORE_DIR)/src/keybovl.c ...@@ -39,6 +39,7 @@ SOURCES_C += $(CORE_DIR)/src/keybovl.c
SOURCES_C += $(CORE_DIR)/src/eo.c SOURCES_C += $(CORE_DIR)/src/eo.c
SOURCES_C += $(CORE_DIR)/src/kbds/zx81kbd.c SOURCES_C += $(CORE_DIR)/src/kbds/zx81kbd.c
SOURCES_C += $(CORE_DIR)/src/version.c SOURCES_C += $(CORE_DIR)/src/version.c
SOURCES_C += $(CORE_DIR)/src/gamedb/sha1.c
SOURCES_CXX += $(CORE_DIR)/src/compat.cpp SOURCES_CXX += $(CORE_DIR)/src/compat.cpp
ROMS += $(CORE_DIR)/bin/ROM/zx81.rom ROMS += $(CORE_DIR)/bin/ROM/zx81.rom
......
...@@ -4,7 +4,7 @@ else ...@@ -4,7 +4,7 @@ else
TARGET = 81_libretro$(SOEXT) TARGET = 81_libretro$(SOEXT)
endif endif
DEFINES += DEFINES += SHA1_REMOVE_MAIN=1
CFLAGS += -Wall CFLAGS += -Wall
CXXFLAGS += -Wall CXXFLAGS += -Wall
LDFLAGS += LDFLAGS +=
......
#include <coreopt.h> #include <coreopt.h>
#include <string.h> #include <string.h>
#include <stdlib.h>
#include <stdint.h>
int coreopt( retro_environment_t env_cb, const struct retro_variable* vars, const char* opt_name, const char** opt_value ) #include <libretro.h>
#include <gamedb/db.inl>
static int getindex( const char* options, const char* value )
{
const char* option = options;
size_t opt_len = strlen( value );
for ( ;; )
{
option = strstr( option, value );
if ( !option )
{
break;
}
if ( ( option == options || option[ -1 ] == '|' ) && ( option[ opt_len ] == 0 || option[ opt_len ] == '|' ) )
{
int pipes = 0;
while ( option > options )
{
pipes += *--option == '|';
}
return pipes;
}
option += opt_len;
}
return -1;
}
static int coreopt_env( retro_environment_t env_cb, const char* options, const char* opt_name, const char** opt_value )
{
struct retro_variable user_opt;
user_opt.key = opt_name;
user_opt.value = NULL;
if ( env_cb( RETRO_ENVIRONMENT_GET_VARIABLE, &user_opt ) && user_opt.value )
{
*opt_value = user_opt.value;
return getindex( options, user_opt.value );
}
return -1;
}
static int compare_hashes( const void* e1, const void* e2 )
{
const overrides_t* o1 = (const overrides_t*)e1;
const overrides_t* o2 = (const overrides_t*)e2;
const uint32_t* s1 = o1->sha1;
const uint32_t* s2 = o2->sha1;
const uint32_t* end1 = s1 + sizeof( o1->sha1 ) / sizeof( o1->sha1[ 1 ] ) - 1;
while ( s1 < end1 )
{
if ( *s1 < *s2 )
{
return -1;
}
else if ( *s1 > *s2 )
{
return 1;
}
s1++, s2++;
}
if ( *s1 < *s2 )
{
return -1;
}
else if ( *s1 > *s2 )
{
return 1;
}
else
{
return 0;
}
}
static int compare_vars( const void* e1, const void* e2 )
{
const struct retro_variable* v1 = (struct retro_variable*)e1;
const struct retro_variable* v2 = (struct retro_variable*)e2;
return strcmp( v1->key, v2->key );
}
static int coreopt_auto( uint32_t* sha1, const char* options, const char* opt_name, const char** opt_value )
{
overrides_t key;
memcpy( &key.sha1, sha1, sizeof( key.sha1 ) );
overrides_t* overrides = bsearch( &key, s_overrides, sizeof( s_overrides ) / sizeof( s_overrides[ 0 ] ), sizeof( s_overrides[ 0 ] ), compare_hashes );
if ( overrides )
{
struct retro_variable key;
key.key = opt_name;
struct retro_variable* var = bsearch( &key, overrides->vars, sizeof( overrides->vars ) / sizeof( overrides->vars[ 0 ] ), sizeof( overrides->vars[ 0 ] ), compare_vars );
if ( var )
{
*opt_value = var->value;
return getindex( options, var->value );
}
}
return -1;
}
int coreopt( retro_environment_t env_cb, const struct retro_variable* vars, uint32_t* sha1, const char* opt_name, const char** opt_value )
{ {
const struct retro_variable* var = vars; const struct retro_variable* var = vars;
...@@ -15,55 +138,35 @@ int coreopt( retro_environment_t env_cb, const struct retro_variable* vars, cons ...@@ -15,55 +138,35 @@ int coreopt( retro_environment_t env_cb, const struct retro_variable* vars, cons
++var; ++var;
} }
int index = -1;
const char* value;
if ( var->key ) if ( var->key )
{ {
const char* first_opt = strchr( var->value, ';' ); const char* options = strchr( var->value, ';' );
if ( first_opt ) if ( options )
{ {
while ( *++first_opt == ' ' ) /* do nothing */; while ( *++options == ' ' ) /* do nothing */;
struct retro_variable user_opt; index = coreopt_env( env_cb, options, opt_name, &value );
user_opt.key = var->key; if ( !strcmp( value, "auto" ) && sha1 )
user_opt.value = NULL;
if ( env_cb( RETRO_ENVIRONMENT_GET_VARIABLE, &user_opt ) && user_opt.value )
{ {
const char* option = first_opt; int index2 = coreopt_auto( sha1, options, opt_name, &value );
size_t opt_len = strlen( user_opt.value );
if ( index2 != -1 )
for ( ;; )
{ {
option = strstr( option, user_opt.value ); index = index2;
if ( !option )
{
break;
}
if ( ( option == first_opt || option[ -1 ] == '|' ) && ( option[ opt_len ] == 0 || option[ opt_len ] == '|' ) )
{
int pipes = 0;
while ( option > first_opt )
{
pipes += *--option == '|';
}
if ( opt_value )
{
*opt_value = user_opt.value;
}
return pipes;
}
option += opt_len;
} }
} }
} }
} }
return -1; if ( opt_value )
{
*opt_value = value;
}
return index;
} }
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#define COREOPT_H #define COREOPT_H
#include <libretro.h> #include <libretro.h>
#include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
...@@ -11,7 +12,7 @@ extern "C" { ...@@ -11,7 +12,7 @@ extern "C" {
* retro_variable. Returns -1 if the option wasn't found in the list or if * retro_variable. Returns -1 if the option wasn't found in the list or if
* opt_name is not a valid option. * opt_name is not a valid option.
*/ */
int coreopt( retro_environment_t env_cb, const struct retro_variable* vars, const char* opt_name, const char** opt_value ); int coreopt( retro_environment_t env_cb, const struct retro_variable* vars, uint32_t* sha1, const char* opt_name, const char** opt_value );
#ifdef __cplusplus #ifdef __cplusplus
} }
......
#include <stdint.h>
#include <libretro.h>
typedef struct
{
uint32_t sha1[ 5 ];
struct retro_variable vars[ 15 ];
}
overrides_t;
static overrides_t s_overrides[] =
{
{
/* Virus, 2010, Bob Smith, http://www.bobs-stuff.co.uk/zx81.html*/
{ 0x0f7a62faU, 0x0d575d59U, 0x5857aafdU, 0xefc78b33U, 0xa207be91U },
{
{ "81_chroma_81", "disabled" },
{ "81_highres", "none" },
{ "81_joypad_a", "0" },
{ "81_joypad_b", "default" },
{ "81_joypad_down", "6" },
{ "81_joypad_l", "c" },
{ "81_joypad_l2", "q" },
{ "81_joypad_left", "5" },
{ "81_joypad_r", "r" },
{ "81_joypad_r2", "p" },
{ "81_joypad_right", "8" },
{ "81_joypad_up", "7" },
{ "81_joypad_x", "default" },
{ "81_joypad_y", "s" },
{ "81_sound", "none" },
},
},
{
/* Impact!, 2012, Bob Smith, http://www.bobs-stuff.co.uk/zx81.html*/
{ 0x11c5fe8dU, 0x44763d94U, 0xa3eedf59U, 0x7b6daf04U, 0x38364e22U },
{
{ "81_chroma_81", "disabled" },
{ "81_highres", "none" },
{ "81_joypad_a", "0" },
{ "81_joypad_b", "h" },
{ "81_joypad_down", "6" },
{ "81_joypad_l", "default" },
{ "81_joypad_l2", "default" },
{ "81_joypad_left", "5" },
{ "81_joypad_r", "default" },
{ "81_joypad_r2", "default" },
{ "81_joypad_right", "8" },
{ "81_joypad_up", "7" },
{ "81_joypad_x", "default" },
{ "81_joypad_y", "s" },
{ "81_sound", "none" },
},
},
{
/* U-Bend, 2015, Bob Smith, http://www.bobs-stuff.co.uk/zx81.html*/
{ 0x17c49e4aU, 0xc9179ed0U, 0xd08c18c6U, 0x71f3db53U, 0x43bad3ccU },
{
{ "81_chroma_81", "enabled" },
{ "81_highres", "none" },
{ "81_joypad_a", "l" },
{ "81_joypad_b", "default" },
{ "81_joypad_down", "m" },
{ "81_joypad_l", "c" },
{ "81_joypad_l2", "default" },
{ "81_joypad_left", "z" },
{ "81_joypad_r", "default" },
{ "81_joypad_r2", "default" },
{ "81_joypad_right", "x" },
{ "81_joypad_up", "k" },
{ "81_joypad_x", "default" },
{ "81_joypad_y", "p" },
{ "81_sound", "none" },
},
},
{
/* Ant Attack, 2013, Bob Smith, http://www.bobs-stuff.co.uk/zx81.html*/
{ 0x1b4fc9ebU, 0x5cd3373aU, 0x9986fcd3U, 0x95d0117cU, 0x6b3c4718U },
{
{ "81_chroma_81", "disabled" },
{ "81_highres", "none" },
{ "81_joypad_a", "c" },
{ "81_joypad_b", "default" },
{ "81_joypad_down", "default" },
{ "81_joypad_l", "f" },
{ "81_joypad_l2", "g" },
{ "81_joypad_left", "z" },
{ "81_joypad_r", "s" },
{ "81_joypad_r2", "d" },
{ "81_joypad_right", "x" },
{ "81_joypad_up", "v" },
{ "81_joypad_x", "g" },
{ "81_joypad_y", "b" },
{ "81_sound", "none" },
},
},
{
/* Pandemic, 2014, Bob Smith, http://www.bobs-stuff.co.uk/zx81.html*/
{ 0x28afa426U, 0xe660186aU, 0x1c1c56d7U, 0x4251b604U, 0xe25bb2a1U },
{
{ "81_chroma_81", "disabled" },
{ "81_highres", "none" },
{ "81_joypad_a", "l" },
{ "81_joypad_b", "default" },
{ "81_joypad_down", "m" },
{ "81_joypad_l", "c" },
{ "81_joypad_l2", "m" },
{ "81_joypad_left", "z" },
{ "81_joypad_r", "default" },
{ "81_joypad_r2", "p" },
{ "81_joypad_right", "x" },
{ "81_joypad_up", "k" },
{ "81_joypad_x", "r" },
{ "81_joypad_y", "s" },
{ "81_sound", "none" },
},
},
{
/* Boulder Logic, 2011, Bob Smith, http://www.bobs-stuff.co.uk/zx81.html*/
{ 0x3c74569eU, 0xf70327ecU, 0xf17db982U, 0xef92b455U, 0x7c17b538U },
{
{ "81_chroma_81", "disabled" },
{ "81_highres", "none" },
{ "81_joypad_a", "0" },
{ "81_joypad_b", "p" },
{ "81_joypad_down", "6" },
{ "81_joypad_l", "l" },
{ "81_joypad_l2", "q" },
{ "81_joypad_left", "5" },
{ "81_joypad_r", "r" },
{ "81_joypad_r2", "p" },
{ "81_joypad_right", "8" },
{ "81_joypad_up", "7" },
{ "81_joypad_x", "c" },
{ "81_joypad_y", "s" },
{ "81_sound", "none" },
},
},
{
/* Miner Man, 2011, Bob Smith, http://www.bobs-stuff.co.uk/zx81.html*/
{ 0x54db0c53U, 0x05f89a62U, 0x9a19e5e1U, 0x07f34e65U, 0xd2bfbd93U },
{
{ "81_chroma_81", "disabled" },
{ "81_highres", "none" },
{ "81_joypad_a", "default" },
{ "81_joypad_b", "default" },
{ "81_joypad_down", "6" },
{ "81_joypad_l", "l" },
{ "81_joypad_l2", "q" },
{ "81_joypad_left", "5" },
{ "81_joypad_r", "r" },
{ "81_joypad_r2", "p" },
{ "81_joypad_right", "8" },
{ "81_joypad_up", "7" },
{ "81_joypad_x", "c" },
{ "81_joypad_y", "s" },
{ "81_sound", "none" },
},
},
{
/* Noir Shapes, 2012, Bob Smith, http://www.bobs-stuff.co.uk/zx81.html*/
{ 0x5642ddd9U, 0x4d1c6649U, 0xbc2e01caU, 0x112b7d76U, 0xf376c826U },
{
{ "81_chroma_81", "disabled" },
{ "81_highres", "none" },
{ "81_joypad_a", "0" },
{ "81_joypad_b", "default" },
{ "81_joypad_down", "6" },
{ "81_joypad_l", "l" },
{ "81_joypad_l2", "q" },
{ "81_joypad_left", "5" },
{ "81_joypad_r", "r" },
{ "81_joypad_r2", "default" },
{ "81_joypad_right", "8" },
{ "81_joypad_up", "7" },
{ "81_joypad_x", "c" },
{ "81_joypad_y", "s" },
{ "81_sound", "none" },
},
},
{
/* ZXagon, 2014, Bob Smith, http://www.bobs-stuff.co.uk/zx81.html*/
{ 0x59dae098U, 0x079f00c3U, 0xe72ec464U, 0x7ccbd2edU, 0x99b979f1U },
{
{ "81_chroma_81", "disabled" },
{ "81_highres", "none" },
{ "81_joypad_a", "default" },
{ "81_joypad_b", "default" },
{ "81_joypad_down", "default" },
{ "81_joypad_l", "default" },
{ "81_joypad_l2", "default" },
{ "81_joypad_left", "z" },
{ "81_joypad_r", "default" },
{ "81_joypad_r2", "default" },
{ "81_joypad_right", "x" },
{ "81_joypad_up", "default" },
{ "81_joypad_x", "default" },
{ "81_joypad_y", "s" },
{ "81_sound", "none" },
},
},
{
/* Rebound, 2014, Bob Smith, http://www.bobs-stuff.co.uk/zx81.html*/
{ 0x6abc2d4dU, 0xe5bb40aaU, 0xc8f3703eU, 0x5c33a9ceU, 0x3a31be75U },
{
{ "81_chroma_81", "enabled" },
{ "81_highres", "none" },
{ "81_joypad_a", "l" },
{ "81_joypad_b", "default" },
{ "81_joypad_down", "default" },
{ "81_joypad_l", "default" },
{ "81_joypad_l2", "default" },
{ "81_joypad_left", "z" },
{ "81_joypad_r", "default" },
{ "81_joypad_r2", "p" },
{ "81_joypad_right", "x" },
{ "81_joypad_up", "default" },
{ "81_joypad_x", "default" },
{ "81_joypad_y", "s" },
{ "81_sound", "none" },
},
},
{
/* One Little Ghost, 2012, Bob Smith, http://www.bobs-stuff.co.uk/zx81.html*/
{ 0x7bd65421U, 0x239915daU, 0xd4137206U, 0xc0c7572fU, 0x31c6ac5aU },
{
{ "81_chroma_81", "disabled" },
{ "81_highres", "none" },
{ "81_joypad_a", "default" },
{ "81_joypad_b", "default" },
{ "81_joypad_down", "5" },
{ "81_joypad_l", "default" },
{ "81_joypad_l2", "default" },
{ "81_joypad_left", "7" },
{ "81_joypad_r", "default" },
{ "81_joypad_r2", "default" },
{ "81_joypad_right", "6" },
{ "81_joypad_up", "8" },
{ "81_joypad_x", "default" },
{ "81_joypad_y", "p" },
{ "81_sound", "none" },
},
},
{
/* Domin8tr1s, 2010, Bob Smith, http://www.bobs-stuff.co.uk/zx81.html*/
{ 0x8e8ee9c4U, 0xfc589f38U, 0x6596ef3bU, 0x3e8fab9bU, 0x9ee799efU },
{
{ "81_chroma_81", "disabled" },
{ "81_highres", "none" },
{ "81_joypad_a", "0" },
{ "81_joypad_b", "6" },
{ "81_joypad_down", "default" },
{ "81_joypad_l", "s" },
{ "81_joypad_l2", "w" },
{ "81_joypad_left", "5" },
{ "81_joypad_r", "i" },
{ "81_joypad_r2", "h" },
{ "81_joypad_right", "8" },
{ "81_joypad_up", "default" },
{ "81_joypad_x", "default" },
{ "81_joypad_y", "n" },
{ "81_sound", "none" },
},
},
{
/* CroZXy Road, 2015, Bob Smith, http://www.bobs-stuff.co.uk/zx81.html*/
{ 0x98ef4e7aU, 0x24f87c9dU, 0x253da0dcU, 0x68698850U, 0xdcd2752fU },
{
{ "81_chroma_81", "disabled" },
{ "81_highres", "none" },
{ "81_joypad_a", "default" },
{ "81_joypad_b", "default" },
{ "81_joypad_down", "6" },
{ "81_joypad_l", "default" },
{ "81_joypad_l2", "m" },
{ "81_joypad_left", "5" },
{ "81_joypad_r", "default" },
{ "81_joypad_r2", "default" },
{ "81_joypad_right", "8" },
{ "81_joypad_up", "7" },
{ "81_joypad_x", "default" },
{ "81_joypad_y", "p" },
{ "81_sound", "none" },
},
},
{
/* Quack!, 2014, Bob Smith, http://www.bobs-stuff.co.uk/zx81.html*/
{ 0xd7e40348U, 0xcc9181d2U, 0x033c63e1U, 0x7e8fe075U, 0x89e90c64U },
{
{ "81_chroma_81", "disabled" },
{ "81_highres", "none" },
{ "81_joypad_a", "0" },
{ "81_joypad_b", "default" },
{ "81_joypad_down", "6" },
{ "81_joypad_l", "default" },
{ "81_joypad_l2", "default" },
{ "81_joypad_left", "5" },
{ "81_joypad_r", "default" },
{ "81_joypad_r2", "default" },
{ "81_joypad_right", "8" },
{ "81_joypad_up", "7" },
{ "81_joypad_x", "default" },
{ "81_joypad_y", "default" },
{ "81_sound", "none" },
},
},
};
local json = require 'dkjson'