Assorted Joystick fixes

Implemented use of DirectInput sliders.  They were previously lumped in with axis and then not read or used at all.

Lots of use of joystick_type == 7 or joystick_type != 7 to detect if the joystick_type was none.  Changed this to a define.

The text to enumerate the types of joysticks was contained in a numbered LPARAM sheet.  Switched to using the name listed in the joystick struct.

Joysticks with more than 32 buttons would overflow the plat_joystick_state button array.  Added overflow checks.

Added a 4 axis 4 button joystick type that Win98 can pick up as a generic 4 axis 4 button controller.
This commit is contained in:
horkthane
2020-01-16 19:23:54 -05:00
parent 9b80d4b151
commit 3a8b89af63
20 changed files with 151 additions and 51 deletions

View File

@@ -607,7 +607,7 @@ load_input_devices(void)
else
mouse_type = 0;
joystick_type = config_get_int(cat, "joystick_type", 7);
joystick_type = config_get_int(cat, "joystick_type", JOYSTICK_TYPE_NONE);
for (c=0; c<joystick_get_max_joysticks(joystick_type); c++) {
sprintf(temp, "joystick_%i_nr", c);
@@ -1266,7 +1266,7 @@ config_load(void)
gfxcard = video_get_video_from_internal_name("cga");
vid_api = plat_vidapi("default");
time_sync = TIME_SYNC_ENABLED;
joystick_type = 7;
joystick_type = JOYSTICK_TYPE_NONE;
hdc_current = hdc_get_from_internal_name("none");
serial_enabled[0] = 1;
serial_enabled[1] = 1;
@@ -1488,7 +1488,7 @@ save_input_devices(void)
config_set_string(cat, "mouse_type", mouse_get_internal_name(mouse_type));
if (joystick_type == 7) {
if (joystick_type == JOYSTICK_TYPE_NONE) {
config_delete_var(cat, "joystick_type");
for (c = 0; c < 16; c++) {

View File

@@ -90,6 +90,7 @@ static const joystick_if_t *joystick_list[] = {
&joystick_standard_4button,
&joystick_standard_6button,
&joystick_standard_8button,
&joystick_4axis_4button,
&joystick_ch_flightstick_pro,
&joystick_sw_pad,
&joystick_tm_fcs,
@@ -265,7 +266,7 @@ gameport_init(const device_t *info)
{
gameport_t *p = NULL;
if (joystick_type == 7) {
if (joystick_type == JOYSTICK_TYPE_NONE) {
p = NULL;
return(p);
}
@@ -284,7 +285,7 @@ gameport_201_init(const device_t *info)
{
gameport_t *p;
if (joystick_type == 7) {
if (joystick_type == JOYSTICK_TYPE_NONE) {
p = NULL;
return(p);
}

View File

@@ -45,8 +45,10 @@
#define POV_X 0x80000000
#define POV_Y 0x40000000
#define SLIDER 0x20000000
#define AXIS_NOT_PRESENT -99999
#define JOYSTICK_TYPE_NONE 8
#define JOYSTICK_PRESENT(n) (joystick_state[n].plat_joystick_nr != 0)
@@ -57,6 +59,7 @@ typedef struct {
int a[8];
int b[32];
int p[4];
int s[2];
struct {
char name[260];
@@ -73,9 +76,16 @@ typedef struct {
int id;
} pov[4];
struct
{
char name[260];
int id;
} slider[2];
int nr_axes;
int nr_buttons;
int nr_povs;
int nr_sliders;
} plat_joystick_t;
typedef struct {

View File

@@ -144,6 +144,27 @@ static int joystick_standard_read_axis_4button(void *p, int axis)
return 0;
}
}
static int joystick_standard_read_axis_4axis(void *p, int axis)
{
if (!JOYSTICK_PRESENT(0))
return AXIS_NOT_PRESENT;
switch (axis)
{
case 0:
return joystick_state[0].axis[0];
case 1:
return joystick_state[0].axis[1];
case 2:
return joystick_state[0].axis[2];
case 3:
return joystick_state[0].axis[3];
default:
return 0;
}
}
static int joystick_standard_read_axis_6button(void *p, int axis)
{
if (!JOYSTICK_PRESENT(0))
@@ -227,6 +248,22 @@ const joystick_if_t joystick_standard_4button =
{"X axis", "Y axis"},
{"Button 1", "Button 2", "Button 3", "Button 4"}
};
const joystick_if_t joystick_4axis_4button =
{
"4-axis 4-button joystick",
joystick_standard_init,
joystick_standard_close,
joystick_standard_read_4button,
joystick_standard_write,
joystick_standard_read_axis_4axis,
joystick_standard_a0_over,
4,
4,
0,
1,
{"X axis", "Y axis", "Z axis", "zX axis"},
{"Button 1", "Button 2", "Button 3", "Button 4"}
};
const joystick_if_t joystick_standard_6button =
{
"Standard 6-button joystick",

View File

@@ -37,5 +37,6 @@
extern const joystick_if_t joystick_standard;
extern const joystick_if_t joystick_standard_4button;
extern const joystick_if_t joystick_4axis_4button;
extern const joystick_if_t joystick_standard_6button;
extern const joystick_if_t joystick_standard_8button;

View File

@@ -2508,7 +2508,7 @@ machine_amstrad_init(const machine_t *model, int type)
mouse_set_poll(ms_poll, ams);
}
if (joystick_type != 7)
if (joystick_type != JOYSTICK_TYPE_NONE)
device_add(&gameport_device);
}

View File

@@ -72,7 +72,7 @@ machine_at_common_init_ex(const machine_t *model, int type)
else if (type == 0)
device_add(&at_nvr_device);
if (joystick_type != 7)
if (joystick_type != JOYSTICK_TYPE_NONE)
device_add(&gameport_device);
}

View File

@@ -615,7 +615,7 @@ europc_boot(const device_t *info)
mouse_bus_set_irq(sys->mouse, 2);
/* Configure the port for (Bus Mouse Compatible) Mouse. */
b |= 0x01;
} else if (joystick_type != 7)
} else if (joystick_type != JOYSTICK_TYPE_NONE)
b |= 0x02; /* enable port as joysticks */
sys->nvr.regs[MRTC_CONF_C] = b;

View File

@@ -892,7 +892,7 @@ machine_olim24_init(const machine_t *model)
keyboard_set_table(scancode_xt);
if (joystick_type != 7)
if (joystick_type != JOYSTICK_TYPE_NONE)
device_add(&gameport_device);
/* FIXME: make sure this is correct?? */

View File

@@ -525,7 +525,7 @@ ps1_common_init(const machine_t *model)
device_add(&keyboard_ps2_ps1_device);
/* Audio uses ports 200h and 202-207h, so only initialize gameport on 201h. */
if (joystick_type != 7)
if (joystick_type != JOYSTICK_TYPE_NONE)
device_add(&gameport_201_device);
}

View File

@@ -1527,7 +1527,7 @@ machine_tandy1k_init(const machine_t *model, int type)
device_add(&eep_1000sl2_device);
}
if (joystick_type != 7)
if (joystick_type != JOYSTICK_TYPE_NONE)
device_add(&gameport_device);
eep_data_out = 0x0000;

View File

@@ -26,7 +26,7 @@ machine_xt_common_init(const machine_t *model)
device_add(&fdc_xt_device);
nmi_init();
if (joystick_type != 7)
if (joystick_type != JOYSTICK_TYPE_NONE)
device_add(&gameport_device);
}

View File

@@ -55,7 +55,7 @@ machine_xt_compaq_init(const machine_t *model)
device_add(&keyboard_xt_compaq_device);
device_add(&fdc_xt_device);
nmi_init();
if (joystick_type != 7)
if (joystick_type != JOYSTICK_TYPE_NONE)
device_add(&gameport_device);
lpt1_remove();

View File

@@ -171,7 +171,7 @@ machine_xt_lxt3_init(const machine_t *model)
device_add(&keyboard_xt_lxt3_device);
device_add(&fdc_xt_device);
nmi_init();
if (joystick_type != 7)
if (joystick_type != JOYSTICK_TYPE_NONE)
device_add(&gameport_device);
laserxt_init(1);

View File

@@ -175,7 +175,7 @@ machine_xt_xi8088_init(const machine_t *model)
nmi_init();
device_add(&ibmat_nvr_device);
pic2_init();
if (joystick_type != 7)
if (joystick_type != JOYSTICK_TYPE_NONE)
device_add(&gameport_device);
return ret;

View File

@@ -767,7 +767,7 @@ pc_reset_hard_init(void)
/* Reset and reconfigure the Network Card layer. */
network_reset();
if (joystick_type != 7)
if (joystick_type != JOYSTICK_TYPE_NONE)
gameport_update_joystick_type();
ui_sb_update_panes();

View File

@@ -82,10 +82,10 @@ BOOL CALLBACK DIEnumDeviceObjectsCallback(
plat_joystick_t *state = (plat_joystick_t *)pvRef;
if (lpddoi->guidType == GUID_XAxis || lpddoi->guidType == GUID_YAxis || lpddoi->guidType == GUID_ZAxis ||
lpddoi->guidType == GUID_RxAxis || lpddoi->guidType == GUID_RyAxis || lpddoi->guidType == GUID_RzAxis ||
lpddoi->guidType == GUID_Slider)
lpddoi->guidType == GUID_RxAxis || lpddoi->guidType == GUID_RyAxis || lpddoi->guidType == GUID_RzAxis)
{
memcpy(state->axis[state->nr_axes].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1);
if (state->nr_axes < 8)
{memcpy(state->axis[state->nr_axes].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1);
joystick_log("Axis %i : %s %x %x\n", state->nr_axes, state->axis[state->nr_axes].name, lpddoi->dwOfs, lpddoi->dwType);
if (lpddoi->guidType == GUID_XAxis)
state->axis[state->nr_axes].id = 0;
@@ -101,18 +101,35 @@ BOOL CALLBACK DIEnumDeviceObjectsCallback(
state->axis[state->nr_axes].id = 5;
state->nr_axes++;
}
}
else if (lpddoi->guidType == GUID_Button)
{
if (state->nr_buttons < 32)
{
memcpy(state->button[state->nr_buttons].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1);
joystick_log("Button %i : %s %x %x\n", state->nr_buttons, state->button[state->nr_buttons].name, lpddoi->dwOfs, lpddoi->dwType);
state->nr_buttons++;
}
}
else if (lpddoi->guidType == GUID_POV)
{
if (state->nr_povs < 4)
{
memcpy(state->pov[state->nr_povs].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1);
joystick_log("POV %i : %s %x %x\n", state->nr_povs, state->pov[state->nr_povs].name, lpddoi->dwOfs, lpddoi->dwType);
state->nr_povs++;
}
}
else if (lpddoi->guidType == GUID_Slider)
{
if (state->nr_sliders < 2)
{
memcpy(state->slider[state->nr_sliders].name, lpddoi->tszName, strlen(lpddoi->tszName) + 1);
state->slider[state->nr_sliders].id = state->nr_sliders | SLIDER;
joystick_log("Slider %i : %s %x %x\n", state->nr_sliders, state->slider[state->nr_sliders].name, lpddoi->dwOfs, lpddoi->dwType);
state->nr_sliders++;
}
}
return DIENUM_CONTINUE;
}
@@ -186,6 +203,10 @@ void joystick_init()
joy_axis_range.diph.dwObj = DIJOFS_RY;
lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph);
joy_axis_range.diph.dwObj = DIJOFS_RZ;
lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph);
joy_axis_range.diph.dwObj = DIJOFS_SLIDER(0);
lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph);
joy_axis_range.diph.dwObj = DIJOFS_SLIDER(1);
lpdi_joystick[c]->SetProperty(DIPROP_RANGE, &joy_axis_range.diph);
if (FAILED(lpdi_joystick[c]->Acquire()))
@@ -226,6 +247,10 @@ static int joystick_get_axis(int joystick_nr, int mapping)
return 0;
else
return -cos((2*M_PI * (double)pov) / 36000.0) * 32767;
}
else if (mapping & SLIDER)
{
return plat_joystick_state[joystick_nr].s[mapping & 3];
}
else
return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id];
@@ -235,7 +260,7 @@ void joystick_process(void)
{
int c, d;
if (joystick_type == 7) return;
if (joystick_type == JOYSTICK_TYPE_NONE) return;
for (c = 0; c < joysticks_present; c++)
{
@@ -260,6 +285,8 @@ void joystick_process(void)
plat_joystick_state[c].a[3] = joystate.lRx;
plat_joystick_state[c].a[4] = joystate.lRy;
plat_joystick_state[c].a[5] = joystate.lRz;
plat_joystick_state[c].s[0] = joystate.rglSlider[0];
plat_joystick_state[c].s[1] = joystate.rglSlider[1];
for (b = 0; b < 16; b++)
plat_joystick_state[c].b[b] = joystate.rgbButtons[b] & 0x80;

View File

@@ -216,7 +216,7 @@ void joystick_process(void)
{
int c, d;
if (joystick_type == 7) return;
if (joystick_type == JOYSTICK_TYPE_NONE) return;
joystick_poll();

View File

@@ -58,6 +58,10 @@ static void rebuild_axis_button_selections(HWND hdlg)
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
sprintf(s, "%s (Y axis)", plat_joystick_state[joystick-1].pov[d].name);
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)s);
}
for (d = 0; d < plat_joystick_state[joystick - 1].nr_sliders; d++)
{
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)(LPCSTR)plat_joystick_state[joystick - 1].slider[d].name);
}
SendMessage(h, CB_SETCURSEL, sel, 0);
EnableWindow(h, TRUE);
@@ -122,15 +126,23 @@ static int get_axis(HWND hdlg, int id)
HWND h = GetDlgItem(hdlg, id);
int axis_sel = SendMessage(h, CB_GETCURSEL, 0, 0);
int nr_axes = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr-1].nr_axes;
int nr_povs = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_povs;
int nr_sliders = plat_joystick_state[joystick_state[joystick_nr].plat_joystick_nr - 1].nr_sliders;
if (axis_sel < nr_axes)
return axis_sel;
axis_sel -= nr_axes;
if (axis_sel < nr_povs * 2)
{
if (axis_sel & 1)
return POV_Y | (axis_sel >> 1);
else
return POV_X | (axis_sel >> 1);
}
axis_sel -= nr_povs;
return SLIDER | (axis_sel >> 1);
}
static int get_pov(HWND hdlg, int id)
@@ -163,6 +175,7 @@ joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
int joystick;
int nr_axes;
int nr_povs;
int nr_sliders;
int mapping;
switch (message)
@@ -186,6 +199,8 @@ joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
nr_axes = plat_joystick_state[joystick-1].nr_axes;
nr_povs = plat_joystick_state[joystick-1].nr_povs;
nr_sliders = plat_joystick_state[joystick - 1].nr_sliders;
for (c = 0; c < joystick_get_axis_count(joystick_config_type); c++)
{
int mapping = joystick_state[joystick_nr].axis_mapping[c];
@@ -195,6 +210,8 @@ joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3)*2, 0);
else if (mapping & POV_Y)
SendMessage(h, CB_SETCURSEL, nr_axes + (mapping & 3)*2 + 1, 0);
else if (mapping & SLIDER)
SendMessage(h, CB_SETCURSEL, nr_axes + nr_povs * 2 + (mapping & 3), 0);
else
SendMessage(h, CB_SETCURSEL, mapping, 0);
id += 2;

View File

@@ -971,6 +971,7 @@ static BOOL CALLBACK
win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
{
wchar_t str[128];
char *joy_name;
HWND h;
int c, d;
@@ -1000,9 +1001,15 @@ win_settings_input_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam)
h = GetDlgItem(hdlg, IDC_COMBO_JOYSTICK);
c = 0;
while (joystick_get_name(c)) {
SendMessage(h, CB_ADDSTRING, 0, win_get_string(2105 + c));
joy_name = joystick_get_name(c);
while (joy_name)
{
mbstowcs(str, joy_name, strlen(joy_name) + 1);
SendMessage(h, CB_ADDSTRING, 0, (LPARAM)str);
// SendMessage(h, CB_ADDSTRING, 0, win_get_string(2105 + c));
c++;
joy_name = joystick_get_name(c);
}
EnableWindow(h, TRUE);
SendMessage(h, CB_SETCURSEL, temp_joystick, 0);