From 3e2e40d262700f5ca04f9bfa82f6f9633bc13bb8 Mon Sep 17 00:00:00 2001 From: Steve Fosdick Date: Fri, 20 Oct 2023 20:02:12 +0100 Subject: [PATCH] Tricky's Joystick re-vamp. See: https://stardot.org.uk/forums/viewtopic.php?p=405729#p405729 --- b-em.cfg | 88 ++++++++++- mkcross.sh | 2 +- src/Makefile.am | 2 +- src/adc.c | 2 +- src/b-em.h | 3 +- src/b-em.vcxproj | 14 +- src/gui-allegro.c | 66 ++++++-- src/gui-allegro.h | 4 + src/joystick.c | 375 ++++++++++++++++++++++++---------------------- src/joystick.h | 10 +- src/main.c | 6 +- src/model.h | 4 + src/sysvia.c | 14 ++ 13 files changed, 388 insertions(+), 202 deletions(-) diff --git a/b-em.cfg b/b-em.cfg index 163dfdfe..ae8e2a83 100644 --- a/b-em.cfg +++ b/b-em.cfg @@ -452,8 +452,81 @@ music2000_out3_alsa_raw_enabled=false music2000_out1_alsa_raw_device=default music2000_out2_alsa_raw_device=default music2000_out3_alsa_raw_device=default + +[joymap default] +stick0axis0adc=1 +stick0axis1adc=2 +stick1axis0adc=3 +stick1axis1adc=4 +button0btn=0 +button1btn=1 +button2btn=2 +button3btn=3 + +[joymap default Player 1] +stick0axis0adc=1 +stick0axis1adc=2 +button0btn=0 +button1btn=2 + +[joymap default Player 2] +stick0axis0adc=3 +stick0axis1adc=4 +button0btn=1 +button1btn=3 [joymap X Box One Standard] -joystick=Microsoft X-Box One S pad +stick0axis0adc=1 +stick0axis1adc=2 +stick1axis0adc=3 +stick1axis1adc=4 +button0btn=0 +button1btn=1 +button2btn=2 +button3btn=3 + +[joymap XInput Joystick 1] +stick0axis0adc=1 +stick0axis1adc=2 +stick1axis0adc=3 +stick1axis1adc=4 +button0btn=0 +button1btn=1 +button2btn=2 +button3btn=3 +button8key=Escape + +[joymap XInput Joystick 1 ZX/:] +stick0axis0nkey=A +stick0axis0pkey=S +stick0axis1nkey=/ +stick0axis1pkey=: +button0key=Return +button1key=Shift +button8key=Escape + +[joymap XInput Joystick 1 Missile Command] +stick0axis0adc=1 +stick0axis1adc=2 +button2btn=3 +button3btn=4 +button1btn=2 +button0btn=0 +button8key=Escape +button9key=2 + +[joymap X Box One Standard Player 1] +stick0axis0adc=1 +stick0axis1adc=2 +button0btn=0 +button1btn=2 + +[joymap X Box One Standard Player 2] +stick0axis0adc=3 +stick0axis1adc=4 +button0btn=1 +button1btn=3 + +[joymap X Box One Standard AS] stick0axis0adc=1 stick0axis0nkey=A stick0axis0pkey=S @@ -462,3 +535,16 @@ stick1axis0adc=0 stick1axis1adc=3 stick2axis0adc=4 stick2axis1adc=0 +button0btn=0 +button1btn=1 +button2btn=2 +button3btn=3 + +[joymap X Box One Standard Player 1 AS] +stick0axis0adc=1 +stick0axis0nkey=A +stick0axis0pkey=S +stick0axis1adc=2 +button0btn=0 +button1btn=2 + diff --git a/mkcross.sh b/mkcross.sh index a137a8e5..ff9552ce 100755 --- a/mkcross.sh +++ b/mkcross.sh @@ -34,7 +34,7 @@ buildit() { export CXX="$2-g++" export WINDRES="$2-windres" cd $dir - make -j2 -e -f ../src/Makefile.win b-em.exe + make -j4 -e -f ../src/Makefile.win b-em.exe zip -q -r b-em-$VERSION-$1.zip *.exe b-em.cfg *.dll $dirs } diff --git a/src/Makefile.am b/src/Makefile.am index 15297326..23d05df2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,7 +14,7 @@ amrefresh: # INCLUDE_DEBUGGER - include the cpu_debug implementation # USE_MEMORY_POINTER - do not assume Co Pro memory starts at address 0 -b_em_CFLAGS = $(allegro_CFLAGS) -DBEM -DINCLUDE_DEBUGGER -DUSE_MEMORY_POINTER -DMODET -DMODE32 -DBEEBEM +b_em_CFLAGS = $(allegro_CFLAGS) -DBEM -DINCLUDE_DEBUGGER -DUSE_MEMORY_POINTER -DMODET -DMODE32 -DBEEBEM -DM68K # workaround for Win32 Allegro, which has `allegro-config' missing if OS_WIN diff --git a/src/adc.c b/src/adc.c index 3eb3b96b..50bc3d92 100644 --- a/src/adc.c +++ b/src/adc.c @@ -40,7 +40,7 @@ void adc_write(uint16_t addr, uint8_t val) void adc_poll() { - uint32_t val = (uint32_t)(joyaxes[adc_status & 3] * -32760.0) + 32760; + uint32_t val = (uint32_t)(joyaxes[adc_status & 3] * -32760.0 + 32760); // putting the ) after the .0 makes the numbers 32k+ ONLY in VS if (val > 0xFFFF) val = 0xFFFF; adc_status =(adc_status & 0xF) | 0x40; /*Not busy, conversion complete*/ diff --git a/src/b-em.h b/src/b-em.h index 25d6c43c..91483956 100644 --- a/src/b-em.h +++ b/src/b-em.h @@ -55,8 +55,9 @@ extern ALLEGRO_PATH *find_cfg_file(const char *name, const char *ext); extern ALLEGRO_PATH *find_cfg_dest(const char *name, const char *ext); extern bool is_relative_filename(const char *fn); -extern int joybutton[2]; +extern int joybutton[4]; extern float joyaxes[4]; +extern bool tricky_sega_adapter; void setquit(void); diff --git a/src/b-em.vcxproj b/src/b-em.vcxproj index 29b2645e..b877fd09 100644 --- a/src/b-em.vcxproj +++ b/src/b-em.vcxproj @@ -14,21 +14,21 @@ {28E2DE55-0A88-47FA-92DC-3F96D72608F9} Win32Proj bem - 10.0.17763.0 + 10.0 Application true Unicode - v141 + v142 Application false true Unicode - v141 + v142 @@ -68,9 +68,10 @@ Level4 Disabled - VERSION="vsX";USE_MEMORY_POINTER;BEM;MODET;MODE32;BEEBEM;WIN32;INCLUDE_DEBUGGER;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS=1;VERSION="vsX";USE_MEMORY_POINTER;BEM;MODET;MODE32;BEEBEM;WIN32;INCLUDE_DEBUGGER;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) UNICODE;_UNICODE;%(UndefinePreprocessorDefinitions) ..\packages\Allegro.5.2.6\build\native\include;%(AdditionalIncludeDirectories) + 4456;4459;4113;4100;4389;4146;4245;4996;4706;4701;4244;4018;4702;4703;4005;4201;4127;4098;4267;4047;4024;4716;4458 Windows @@ -87,10 +88,11 @@ MaxSpeed true true - VERSION="vsX";USE_MEMORY_POINTER;BEM;WIN32;MODET;MODE32;BEEBEM;INCLUDE_DEBUGGER;_WINDOWS;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS=1;VERSION="vsX";USE_MEMORY_POINTER;BEM;WIN32;MODET;MODE32;BEEBEM;INCLUDE_DEBUGGER;_WINDOWS;%(PreprocessorDefinitions) UNICODE;_UNICODE;%(UndefinePreprocessorDefinitions) MultiThreadedDLL ..\packages\Allegro.5.2.6\build\native\include;%(AdditionalIncludeDirectories) + 4456;4459;4113;4100;4389;4146;4245;4996;4706;4701;4244;4018;4702;4703;4005;4201;4127;4098;4267;4047;4024;4716;4458 Windows @@ -364,4 +366,4 @@ - \ No newline at end of file + diff --git a/src/gui-allegro.c b/src/gui-allegro.c index 8974dfdd..e4140314 100644 --- a/src/gui-allegro.c +++ b/src/gui-allegro.c @@ -492,6 +492,40 @@ static ALLEGRO_MENU *create_keyboard_menu(void) return menu; } +static ALLEGRO_MENU *create_joystick_menu(int joystick) +{ + ALLEGRO_MENU *menu = al_create_menu(); + int i; + + for (i = 0; i < joystick_count; i++) if (joystick_names[i]) + add_checkbox_item(menu, joystick_names[i], menu_id_num(IDM_JOYSTICK + joystick, i), i == joystick_index[joystick]); + return menu; +} + +static ALLEGRO_MENU *create_joymap_menu(int joystick) +{ + ALLEGRO_MENU *menu = al_create_menu(); + int i; + + for (i = 0; i < joymap_count; i++) + add_checkbox_item(menu, joymaps[i].name, menu_id_num(IDM_JOYMAP + joystick, i), i == joymap_index[joystick]); + return menu; +} + +static ALLEGRO_MENU *create_joysticks_menu(void) +{ + ALLEGRO_MENU *menu = al_create_menu(); + add_checkbox_item(menu, "Tricky SEGA Adapter", IDM_TRIACK_SEGA_ADAPTER, autopause); + al_append_menu_item(menu, "Joystick", 0, 0, NULL, create_joystick_menu(0)); + al_append_menu_item(menu, "Joystick Map", 0, 0, NULL, create_joymap_menu(0)); + if (joystick_count > 1) { + al_append_menu_item(menu, "Joystick 2", 0, 0, NULL, create_joystick_menu(1)); + al_append_menu_item(menu, "Joystick 2 Map", 0, 0, NULL, create_joymap_menu(1)); + } + return menu; +} + + static const char *jim_sizes[] = { "None (disabled)", @@ -510,16 +544,6 @@ static ALLEGRO_MENU *create_jim_menu(void) return menu; } -static ALLEGRO_MENU *create_joymap_menu(void) -{ - ALLEGRO_MENU *menu = al_create_menu(); - int i; - - for (i = 0; i < joymap_count; i++) - add_checkbox_item(menu, joymaps[i].name, menu_id_num(IDM_JOYMAP, i), i == joymap_num); - return menu; -} - static ALLEGRO_MENU *create_settings_menu(void) { ALLEGRO_MENU *menu = al_create_menu(); @@ -532,8 +556,8 @@ static ALLEGRO_MENU *create_settings_menu(void) al_append_menu_item(menu, "Jim Memory", 0, 0, NULL, create_jim_menu()); add_checkbox_item(menu, "Auto-Pause", IDM_AUTO_PAUSE, autopause); add_checkbox_item(menu, "Mouse (AMX)", IDM_MOUSE_AMX, mouse_amx); - if (joymap_count > 0) - al_append_menu_item(menu, "Joystick Map", 0, 0, NULL, create_joymap_menu()); + if (joystick_count > 0) + al_append_menu_item(menu, "Joysticks", 0, 0, NULL, create_joysticks_menu()); return menu; } @@ -1503,7 +1527,23 @@ void gui_allegro_event(ALLEGRO_EVENT *event) case IDM_MOUSE_AMX: mouse_amx = !mouse_amx; break; + case IDM_TRIACK_SEGA_ADAPTER: + tricky_sega_adapter = !tricky_sega_adapter; + remap_joystick(0); + remap_joystick(1); + break; + case IDM_JOYSTICK: + change_joystick(0, radio_event_with_deselect(event, joystick_index[0])); + break; + case IDM_JOYSTICK2: + change_joystick(1, radio_event_with_deselect(event, joystick_index[1])); + break; case IDM_JOYMAP: - joystick_change_joymap(radio_event_simple(event, joymap_num)); + joymap_index[0] = radio_event_simple(event, joymap_index[0]); + remap_joystick(0); + case IDM_JOYMAP2: + joymap_index[1] = radio_event_simple(event, joymap_index[1]); + remap_joystick(1); + break; } } diff --git a/src/gui-allegro.h b/src/gui-allegro.h index abd7e75a..3222c726 100644 --- a/src/gui-allegro.h +++ b/src/gui-allegro.h @@ -100,7 +100,11 @@ typedef enum { IDM_JIM_SIZE, IDM_AUTO_PAUSE, IDM_MOUSE_AMX, + IDM_TRIACK_SEGA_ADAPTER, IDM_JOYMAP, + IDM_JOYMAP2, + IDM_JOYSTICK, + IDM_JOYSTICK2, IDM_SPEED, IDM_DEBUGGER, IDM_DEBUG_TUBE, diff --git a/src/joystick.c b/src/joystick.c index 6161ae1f..0ce05e55 100644 --- a/src/joystick.c +++ b/src/joystick.c @@ -29,7 +29,6 @@ typedef struct { } js_btn_map_t; typedef struct { - const char *js_name; ALLEGRO_JOYSTICK *js_id; int num_stick; js_stick_t *js_sticks; @@ -39,11 +38,15 @@ typedef struct { static joystick_map_t *joystick_map; static joystick_map_t *joystick_end; -static int num_joystick; - joymap_t *joymaps; + int joymap_count; -int joymap_num; +int joymap_index[2] = {0, 0}; + +int joystick_count; +int joystick_index[2] = {-1, -1}; +const char ** joystick_names; + static void *js_malloc(size_t size) { @@ -55,161 +58,56 @@ static void *js_malloc(size_t size) exit(1); } -static void alloc_joystick(joystick_map_t *jsptr, ALLEGRO_JOYSTICK *js) -{ - int num_stick, stick_num, num_axes, num_butn; - js_stick_t *stick; - js_axis_map_t *axis; - - jsptr->num_stick = num_stick = al_get_joystick_num_sticks(js); - jsptr->js_sticks = stick = js_malloc(jsptr->num_stick * sizeof(js_axis_map_t)); - for (stick_num = 0; stick_num < jsptr->num_stick; stick_num++) { - stick->num_axes = num_axes = al_get_joystick_num_axes(js, stick_num); - stick->axes_map = axis = js_malloc(num_axes * sizeof(js_axis_map_t)); - stick++; - } - jsptr->num_butn = num_butn = al_get_joystick_num_buttons(js); - jsptr->js_btns = js_malloc(jsptr->num_butn * sizeof(js_btn_map_t)); -} - -static int default_chan(int stick, int axis) -{ - switch(stick) { - case 0: - switch(axis) { - case 0: return 1; - case 1: return 2; - } - break; - case 1: - switch(axis) { - case 0: return 3; - case 1: return 4; - } - break; - } - return 0; -} +static const char hori_fighting_stick_allegro_name[64] = {-26, -91, -109, -26, -107, -92, -26, -91, -105, -26, -111, -82, -25, -119, -91, -28, -100, -96, -26, -75, -95, -30, -127, -91, -26, -123, -112, -30, -127, -92, -25, -119, -112, -30, -127, -81, -27, -115, -107, -30, -127, -126, -26, -107, -74, -25, -115, -78, -26, -67, -87, -30, -127, -82, -30, -72, -79, 48, -31, -74, -87, -25, -104, 0}; +static const char hori_fighting_stick_display_name[20] = "Hori fighting stick"; -static void reset_joystick(joystick_map_t *jsptr, int js_num) +static void clear_joystick_map(int joystick) { - int stick_num, axis_num, butn_num; - js_stick_t *stick; + joystick_map_t *jsptr = &joystick_map[joystick_index[joystick]]; + js_stick_t *stick = jsptr->js_sticks; js_axis_map_t *axis; - js_btn_map_t *butn; + js_btn_map_t *butn = jsptr->js_btns; + int stick_num, axis_num, butn_num; + if (-1 == joystick_index[joystick]) return; - stick = jsptr->js_sticks; for (stick_num = 0; stick_num < jsptr->num_stick; stick_num++) { axis = stick->axes_map; for (axis_num = 0; axis_num < stick->num_axes; axis_num++) { - if (num_joystick == 1) - axis->js_adc_chan = default_chan(js_num, axis_num); - else - axis->js_adc_chan = default_chan(stick_num, axis_num); - axis->js_scale = 1.0; + axis->js_scale = 1; + axis->js_adc_chan = 0; axis->js_nkey = 0; axis->js_pkey = 0; axis++; } stick++; } - butn = jsptr->js_btns; + for (butn_num = 0; butn_num < jsptr->num_butn; butn_num++) { - if (num_joystick == 1) - butn->js_button = butn_num & 1; - else if (js_num == 0) - butn->js_button = 1; - else if (js_num == 1) - butn->js_button = 2; - else - butn->js_button = 0; - butn->js_key = 0; + butn->js_button = 0; + butn->js_key = 0; butn++; } } -static void init_joysticks(void) -{ - int js_num; - joystick_map_t *jsptr; - ALLEGRO_JOYSTICK *js; - - jsptr = joystick_map = js_malloc(num_joystick * sizeof(joystick_map_t)); - for (js_num = 0; js_num < num_joystick; js_num++) { - if ((js = al_get_joystick(js_num))) { - jsptr->js_id = js; - jsptr->js_name = al_get_joystick_name(js); - log_debug("joystick: found joystick '%s'", jsptr->js_name); - alloc_joystick(jsptr, js); - reset_joystick(jsptr, js_num); - } - else { - jsptr->js_name = NULL; - jsptr->js_id = NULL; - jsptr->js_sticks = NULL; - jsptr->js_btns = NULL; - } - jsptr++; - } - joystick_end = jsptr; -} - -static int cmp_joymap(const void *va, const void *vb) -{ - const joymap_t *ja = va; - const joymap_t *jb = vb; - return strcmp(ja->name, jb->name); -} - -static void read_joymaps(void) -{ - const char *sect, *name; - ALLEGRO_CONFIG_SECTION *siter; - int num_jm, jm_num; - - if (bem_cfg) { - num_jm = 0; - for (sect = al_get_first_config_section(bem_cfg, &siter); sect; sect = al_get_next_config_section(&siter)) - if (strncasecmp(sect, "joymap", 6) == 0) - num_jm++; - if (num_jm == 0) - log_debug("joystick: no joymaps found"); - else { - joymap_count = num_jm; - joymaps = js_malloc(num_jm * sizeof(joymap_t)); - jm_num = 0; - for (sect = al_get_first_config_section(bem_cfg, &siter); sect; sect = al_get_next_config_section(&siter)) { - if (strncasecmp(sect, "joymap", 6) == 0) { - joymaps[jm_num].sect = sect; - for (name = sect + 6; isspace(*name); name++) - ; - joymaps[jm_num++].name = name; - log_debug("joystick: found joymap %s", name); - } - } - qsort(joymaps, num_jm, sizeof(joymap_t), cmp_joymap); - } - } -} - static const char rebuke[] = "joystick: invalid %s %s at section %s, key %s"; -static void apply_axes(const char *sect, joystick_map_t *jsptr) +static void apply_axes_map(int joystick) { int stick_num, axis_num; - js_stick_t *stick; + joystick_map_t *jsptr = &joystick_map[joystick_index[joystick]]; + joymap_t *joymap = &joymaps[joymap_index[joystick]]; + js_stick_t *stick = jsptr->js_sticks; js_axis_map_t *axis; const char *value; - int adc_chan, key_num; float scale; char key[50]; + int adc_chan, key_num; - stick = jsptr->js_sticks; for (stick_num = 0; stick_num < jsptr->num_stick; stick_num++) { axis = stick->axes_map; for (axis_num = 0; axis_num < stick->num_axes; axis_num++) { snprintf(key, sizeof key, "stick%daxis%dadc", stick_num, axis_num); - if ((value = al_get_config_value(bem_cfg, sect, key))) { + if ((value = al_get_config_value(bem_cfg, joymap->sect, key))) { if ((adc_chan = atoi(value)) >= 0 && adc_chan <= 4) { axis->js_adc_chan = adc_chan; if (adc_chan) @@ -218,34 +116,34 @@ static void apply_axes(const char *sect, joystick_map_t *jsptr) log_debug("joystick: mapped stick %d axis %d to 'not action'", stick_num, axis_num); } else - log_warn(rebuke, "BBC ADC channel", value, sect, key); + log_warn(rebuke, "BBC ADC channel", value, joymap->sect, key); } snprintf(key, sizeof key, "stick%daxis%dscale", stick_num, axis_num); - if ((value = al_get_config_value(bem_cfg, sect, key))) { + if ((value = al_get_config_value(bem_cfg, joymap->sect, key))) { if ((scale = atof(value)) != 0.0) { axis->js_scale = scale; log_debug("joystick: scaling for stick %d axis %d set to %g", stick_num, axis_num, scale); } else - log_warn(rebuke, "scale", value, sect, key); + log_warn(rebuke, "scale", value, joymap->sect, key); } snprintf(key, sizeof key, "stick%daxis%dnkey", stick_num, axis_num); - if ((value = al_get_config_value(bem_cfg, sect, key))) { + if ((value = al_get_config_value(bem_cfg, joymap->sect, key))) { if ((key_num = keydef_lookup_name(value))) { axis->js_nkey = key_num; log_debug("joysticK: mapped stick %d axis %d negative direction to key %d", stick_num, axis_num, key_num); } else - log_warn(rebuke, "negative direction key", value, sect, key); + log_warn(rebuke, "negative direction key", value, joymap->sect, key); } snprintf(key, sizeof key, "stick%daxis%dpkey", stick_num, axis_num); - if ((value = al_get_config_value(bem_cfg, sect, key))) { + if ((value = al_get_config_value(bem_cfg, joymap->sect, key))) { if ((key_num = keydef_lookup_name(value))) { axis->js_pkey = key_num; log_debug("joysticK: mapped stick %d axis %d positive negative direction to key %d", stick_num, axis_num, key_num); } else - log_warn(rebuke, "positive direction key", value, sect, key); + log_warn(rebuke, "positive direction key", value, joymap->sect, key); } axis++; } @@ -253,73 +151,181 @@ static void apply_axes(const char *sect, joystick_map_t *jsptr) } } -static void apply_buttons(const char *sect, joystick_map_t *jsptr) +static void apply_button_map(int joystick) { - int butn_num; - js_btn_map_t *butn; + joystick_map_t *jsptr = &joystick_map[joystick_index[joystick]]; + joymap_t *joymap = &joymaps[joymap_index[joystick]]; + int butn_num, key_num, btn_mask = 1 + 2 * tricky_sega_adapter; + js_btn_map_t *butn = jsptr->js_btns; const char *value; - int bbcbno, key_num; char key[50]; - - butn = jsptr->js_btns; + for (butn_num = 0; butn_num < jsptr->num_butn; butn_num++) { snprintf(key, sizeof key, "button%dbtn", butn_num); - if ((value = al_get_config_value(bem_cfg, sect, key))) { - if ((bbcbno = atoi(value)) >= 1 && bbcbno <= 2) - butn->js_button = bbcbno; - else - log_warn(rebuke, "button", value, sect, key); - } + if ((value = al_get_config_value(bem_cfg, joymap->sect, key))) + butn->js_button = (atoi(value) & btn_mask) + 1; snprintf(key, sizeof key, "button%dkey", butn_num); - if ((value = al_get_config_value(bem_cfg, sect, key))) { + if ((value = al_get_config_value(bem_cfg, joymap->sect, key))) { if ((key_num = keydef_lookup_name(value))) butn->js_key = key_num; else - log_warn(rebuke, "key", value, sect, key); + log_warn(rebuke, "key", value, joymap->sect, key); } butn++; } } -void joystick_change_joymap(int mapno) +void remap_joystick(int joystick) +{ + if (-1 == joystick_index[joystick]) return; + clear_joystick_map(joystick); + apply_axes_map(joystick); + apply_button_map(joystick); +} + +static void alloc_joystick(joystick_map_t *jsptr, ALLEGRO_JOYSTICK *js) +{ + int stick_num; + js_stick_t *stick; + jsptr->num_stick = al_get_joystick_num_sticks(js); + jsptr->js_sticks = stick = js_malloc(jsptr->num_stick * sizeof(js_axis_map_t)); + for (stick_num = 0; stick_num < jsptr->num_stick; stick_num++) { + stick->num_axes = al_get_joystick_num_axes(js, stick_num); + stick->axes_map = js_malloc(stick->num_axes * sizeof(js_axis_map_t)); + stick++; + } + jsptr->num_butn = al_get_joystick_num_buttons(js); + jsptr->js_btns = js_malloc(jsptr->num_butn * sizeof(js_btn_map_t)); +} + +static void free_joysticks() +{ + while (joystick_map != joystick_end--) + { + int j; + free(joystick_end->js_btns); + for (j = 0; j < joystick_end->num_stick; ++j) + free(joystick_end->js_sticks[j].axes_map); + free(joystick_end->js_sticks); + } + free(joystick_map); + joystick_map = joystick_end = NULL; +} + +static void init_joysticks(void) +{ + int js_num, js_used = 0; + joystick_map_t *jsptr; + ALLEGRO_JOYSTICK *js; + + jsptr = joystick_map = js_malloc(joystick_count * sizeof(joystick_map_t)); + joystick_names = js_malloc(joystick_count * sizeof(joystick_names[0])); + for (js_num = 0; js_num < joystick_count; js_num++) { + if ((js = al_get_joystick(js_num)) && al_get_joystick_active(js)) { + jsptr->js_id = js; + joystick_names[js_num] = al_get_joystick_name(js); + if (!strncmp(joystick_names[js_num], hori_fighting_stick_allegro_name, 63)) // name seems t be meaningless! + joystick_names[js_num] = hori_fighting_stick_display_name; + log_debug("joystick: found joystick '%s'", joystick_names[js_num]); + alloc_joystick(jsptr, js); + if (js_used < 2) joystick_index[js_used++] = js_num; + } + else { + joystick_names[js_num] = NULL; + jsptr->js_id = NULL; + jsptr->js_sticks = NULL; + jsptr->js_btns = NULL; + jsptr->num_butn = jsptr->num_stick = 0; + } + jsptr++; + } + joystick_end = jsptr; + change_joystick(0, joystick_index[0]); + change_joystick(1, joystick_index[1]); +} + +//static int cmp_joymap(const void *va, const void *vb) +//{ +// const joymap_t *ja = va; +// const joymap_t *jb = vb; +// return strcmp(ja->name, jb->name); +//} + +static void read_joymaps(void) { - joystick_map_t *js; const char *sect, *name; - int js_num; - - if (mapno < joymap_count) { - log_debug("joystick: changing to joymap #%d, %s", mapno, joymaps[mapno].name); - sect = joymaps[mapno].sect; - js = joystick_map; - if ((name = al_get_config_value(bem_cfg, sect, "joystick"))) { - while (!js->js_name || strcasecmp(name, js->js_name)) { - if (++js == joystick_end) { - js = joystick_map; - if (js->js_name) - log_warn("joystick: joystick '%s' not found, applying map to first joystick '%s'", name, js->js_name); - break; + ALLEGRO_CONFIG_SECTION *siter; + int num_jm, jm_num; + + if (bem_cfg) { + num_jm = 0; + for (sect = al_get_first_config_section(bem_cfg, &siter); sect; sect = al_get_next_config_section(&siter)) + if (strncasecmp(sect, "joymap", 6) == 0) + num_jm++; + if (num_jm == 0) + log_debug("joystick: no joymaps found"); + else { + joymap_count = num_jm; + joymaps = js_malloc(num_jm * sizeof(joymap_t)); + jm_num = 0; + for (sect = al_get_first_config_section(bem_cfg, &siter); sect; sect = al_get_next_config_section(&siter)) { + if (strncasecmp(sect, "joymap", 6) == 0) { + joymaps[jm_num].sect = sect; + for (name = sect + 6; isspace(*name); name++) + ; + joymaps[jm_num++].name = name; + log_debug("joystick: found joymap %s", name); } } +// qsort(joymaps, num_jm, sizeof(joymap_t), cmp_joymap); + } + } +} + +void change_joystick(int joystick, int index) +{ + int i; + char name[] = {'P', 'l', 'a', 'y', 'e', 'r', ' ', '1' + joystick, '\0'}; + if (-1 != joystick_index[joystick] && -1 == index) // removing joystick + clear_joystick_map(joystick); + joystick_index[joystick] = index; + if (-1 == joystick_index[joystick]) { + if (-1 != joystick_index[joystick ^ 1]) + change_joystick(joystick ^ 1, joystick_index[joystick ^ 1]); + return; + } + + joymap_index[joystick] = (joystick_index[joystick ^ 1] >= 0) ? 1 + joystick : 0; + if (joymap_index[joystick] > joymap_count) // expect first three joymaps to be single player, player 1 aplayer 2 ("default" in provided .cfg) + joymap_index[joystick] = joymap_count - 1; + for (i = 0; i < joymap_count; ++i) + if (strstr(joymaps[i].name, joystick_names[index])) { // partial match + joymap_index[joystick] = i; + break; } - if (js->js_name) { - js_num = js - joystick_map; - reset_joystick(js, js_num); - apply_axes(sect, js); - apply_buttons(sect, js); - joymap_num = mapno; + for (i = 0; i < joymap_count; ++i) + if (!strcmp(joystick_names[index], joymaps[i].name)) { // exact match + joymap_index[joystick] = i; + break; + } + if (joystick_index[joystick ^ 1] >= 0) { // two players + for (i = 0; i < joymap_count; ++i) { + if (!strncmp(joystick_names[index], joymaps[i].name, strlen(joystick_names[index])) && strcmp(name, joymaps[i].name + strlen(joystick_names[index]) + 2)) { // exact match + joymap_index[joystick] = i; + break; + } } } - else - log_warn("joystick: attempt to change to invalid joymap no #%d", mapno); + remap_joystick(joystick); + remap_joystick(joystick ^ 1); } void joystick_init(ALLEGRO_EVENT_QUEUE *queue) { if (al_install_joystick()) { - if ((num_joystick = al_get_num_joysticks()) > 0) { - init_joysticks(); + if ((joystick_count = al_get_num_joysticks()) > 0) { read_joymaps(); - joystick_change_joymap(get_config_int("joystick", "joymap", 0)); + init_joysticks(); al_register_event_source(queue, al_get_joystick_event_source()); } else @@ -329,6 +335,25 @@ void joystick_init(ALLEGRO_EVENT_QUEUE *queue) log_warn("joystick: unable to install joystick driver"); } +void joystick_rescan_sticks() +{ + ALLEGRO_JOYSTICK * ids[2] = {-1 == joystick_index[0] ? NULL : joystick_map[joystick_index[0]].js_id, -1 == joystick_index[1] ? NULL : joystick_map[joystick_index[1]].js_id}; + int j; + if (!al_reconfigure_joysticks()) return; + free_joysticks(); + init_joysticks(); + joystick_index[0] = joystick_index[1] = -1; + for (j = 0; j < joystick_count; ++j) + { + if (joystick_map[j].js_id == ids[0]) + joystick_index[0] = j; + if (joystick_map[j].js_id == ids[1]) + joystick_index[1] = j; + } + remap_joystick(0); + remap_joystick(1); +} + void joystick_axis(ALLEGRO_EVENT *event) { joystick_map_t *js; diff --git a/src/joystick.h b/src/joystick.h index c3409609..8d8b7bd7 100644 --- a/src/joystick.h +++ b/src/joystick.h @@ -8,12 +8,18 @@ typedef struct { extern joymap_t *joymaps; extern int joymap_count; -extern int joymap_num; +extern int joymap_index[2]; + +extern int joystick_count; +extern int joystick_index[2]; +extern const char ** joystick_names; void joystick_init(ALLEGRO_EVENT_QUEUE *queue); -void joystick_change_joymap(int mapno); void joystick_axis(ALLEGRO_EVENT *event); void joystick_button_down(ALLEGRO_EVENT *event); void joystick_button_up(ALLEGRO_EVENT *event); +void remap_joystick(int joystick); +void change_joystick(int joystick, int index); +void joystick_rescan_sticks(); #endif diff --git a/src/main.c b/src/main.c index 190c828c..f5f917e4 100644 --- a/src/main.c +++ b/src/main.c @@ -72,9 +72,10 @@ bool quitting = false; bool keydefining = false; bool autopause = false; int autoboot=0; -int joybutton[2]; +int joybutton[4]; float joyaxes[4]; int emuspeed = 4; +bool tricky_sega_adapter = false; static ALLEGRO_TIMER *timer; ALLEGRO_EVENT_QUEUE *queue; @@ -540,6 +541,9 @@ void main_run() case ALLEGRO_EVENT_JOYSTICK_BUTTON_UP: joystick_button_up(&event); break; + case ALLEGRO_EVENT_JOYSTICK_CONFIGURATION: + joystick_rescan_sticks(); + break; case ALLEGRO_EVENT_DISPLAY_CLOSE: log_debug("main: event display close - quitting"); quitting = true; diff --git a/src/model.h b/src/model.h index d96b22b7..7d3ce0ce 100644 --- a/src/model.h +++ b/src/model.h @@ -55,7 +55,11 @@ typedef struct int speed_multiplier; } TUBE; +#ifdef M68K +#define NUM_TUBES 14 +#else #define NUM_TUBES 13 +#endif extern TUBE tubes[NUM_TUBES]; extern int curmodel, curtube, oldmodel, selecttube; diff --git a/src/sysvia.c b/src/sysvia.c index b1ce2ab3..ef808282 100644 --- a/src/sysvia.c +++ b/src/sysvia.c @@ -136,6 +136,20 @@ uint8_t sysvia_read_portB() if (i2c_clock) temp |= 0x20; if (i2c_data) temp |= 0x10; } + else if (tricky_sega_adapter) + { + temp |= 0xF0; + if ((sysvia.pcr & 0xE0) == 0xC0) // CB2 Low Output + { + if (joybutton[2]) temp &= ~0x10; + if (joybutton[3]) temp &= ~0x20; + } + else // assuming high, could do a better job! + { + if (joybutton[0]) temp &= ~0x10; + if (joybutton[1]) temp &= ~0x20; + } + } else { temp |= 0xF0;