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 f9e3fbb0..e886dfd5 100644
--- a/src/gui-allegro.c
+++ b/src/gui-allegro.c
@@ -494,6 +494,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)",
@@ -512,16 +546,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();
@@ -534,8 +558,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;
}
@@ -1505,7 +1529,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 f4a20150..eb86147f 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/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;