Merge pull request #4168 from lemondrops/joystick

Fixes and enhancements to joystick support
This commit is contained in:
Miran Grča
2024-02-18 16:39:51 +01:00
committed by GitHub
17 changed files with 210 additions and 292 deletions

View File

@@ -31,10 +31,6 @@
#include <86box/timer.h>
#include <86box/isapnp.h>
#include <86box/gameport.h>
#include <86box/joystick_ch_flightstick_pro.h>
#include <86box/joystick_standard.h>
#include <86box/joystick_sw_pad.h>
#include <86box/joystick_tm_fcs.h>
#include <86box/plat_unused.h>
typedef struct g_axis_t {

View File

@@ -43,7 +43,6 @@
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/gameport.h>
#include <86box/joystick_standard.h>
#include <86box/plat_unused.h>
static void *

View File

@@ -43,7 +43,6 @@
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/gameport.h>
#include <86box/joystick_standard.h>
#include <86box/plat_unused.h>
static void *

View File

@@ -64,7 +64,6 @@
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/gameport.h>
#include <86box/joystick_sw_pad.h>
#include <86box/plat_unused.h>
typedef struct sw_data {

View File

@@ -43,7 +43,6 @@
#include <86box/device.h>
#include <86box/timer.h>
#include <86box/gameport.h>
#include <86box/joystick_standard.h>
#include <86box/plat_unused.h>
static void *

View File

@@ -24,6 +24,10 @@
#define MAX_PLAT_JOYSTICKS 8
#define MAX_JOYSTICKS 4
#define MAX_JOY_AXES 16
#define MAX_JOY_BUTTONS 32
#define MAX_JOY_POVS 4
#define JS_TYPE_NONE 0
#define JS_TYPE_2AXIS_4BUTTON 1
#define JS_TYPE_2AXIS_6BUTTON 2
@@ -36,7 +40,6 @@
#define POV_X 0x80000000
#define POV_Y 0x40000000
#define SLIDER 0x20000000
#define AXIS_NOT_PRESENT -99999
@@ -47,46 +50,39 @@
typedef struct plat_joystick_t {
char name[260];
int a[8];
int b[32];
int p[4];
int s[2];
int a[MAX_JOY_AXES];
int b[MAX_JOY_BUTTONS];
int p[MAX_JOY_POVS];
struct {
char name[260];
int id;
} axis[8];
} axis[MAX_JOY_AXES];
struct {
char name[260];
int id;
} button[32];
} button[MAX_JOY_BUTTONS];
struct {
char name[260];
int id;
} pov[4];
struct {
char name[260];
int id;
} slider[2];
} pov[MAX_JOY_POVS];
int nr_axes;
int nr_buttons;
int nr_povs;
int nr_sliders;
} plat_joystick_t;
typedef struct joystick_t {
int axis[8];
int button[32];
int pov[4];
int axis[MAX_JOY_AXES];
int button[MAX_JOY_BUTTONS];
int pov[MAX_JOY_POVS];
int plat_joystick_nr;
int axis_mapping[8];
int button_mapping[32];
int pov_mapping[4][2];
int axis_mapping[MAX_JOY_AXES];
int button_mapping[MAX_JOY_BUTTONS];
int pov_mapping[MAX_JOY_POVS][2];
} joystick_t;
typedef struct joystick_if_t {
@@ -104,9 +100,9 @@ typedef struct joystick_if_t {
int button_count;
int pov_count;
int max_joysticks;
const char *axis_names[8];
const char *button_names[32];
const char *pov_names[4];
const char *axis_names[MAX_JOY_AXES];
const char *button_names[MAX_JOY_BUTTONS];
const char *pov_names[MAX_JOY_POVS];
} joystick_if_t;
#ifdef __cplusplus
@@ -158,6 +154,19 @@ extern void gameport_update_joystick_type(void);
extern void gameport_remap(void *priv, uint16_t address);
extern void *gameport_add(const device_t *gameport_type);
extern const joystick_if_t joystick_2axis_2button;
extern const joystick_if_t joystick_2axis_4button;
extern const joystick_if_t joystick_3axis_2button;
extern const joystick_if_t joystick_3axis_4button;
extern const joystick_if_t joystick_4axis_4button;
extern const joystick_if_t joystick_2axis_6button;
extern const joystick_if_t joystick_2axis_8button;
extern const joystick_if_t joystick_ch_flightstick_pro;
extern const joystick_if_t joystick_sw_pad;
extern const joystick_if_t joystick_tm_fcs;
#ifdef __cplusplus
}
#endif

View File

@@ -1,43 +0,0 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Definitions for the Flight Stick Pro driver.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <https://pcem-emulator.co.uk/>
*
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#ifndef EMU_JOYSTICK_CH_FLIGHTSTICK_PRO_H
#define EMU_JOYSTICK_CH_FLIGHTSTICK_PRO_H
extern const joystick_if_t joystick_ch_flightstick_pro;
#endif /*EMU_JOYSTICK_CH_FLIGHTSTICK_PRO_H*/

View File

@@ -1,49 +0,0 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Definitions for the joystick driver.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <https://pcem-emulator.co.uk/>
*
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#ifndef EMU_JOYSTICK_STANDARD_H
#define EMU_JOYSTICK_STANDARD_H
extern const joystick_if_t joystick_2axis_2button;
extern const joystick_if_t joystick_2axis_4button;
extern const joystick_if_t joystick_3axis_2button;
extern const joystick_if_t joystick_3axis_4button;
extern const joystick_if_t joystick_4axis_4button;
extern const joystick_if_t joystick_2axis_6button;
extern const joystick_if_t joystick_2axis_8button;
#endif /*EMU_JOYSTICK_STANDARD_H*/

View File

@@ -1,43 +0,0 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Definitions for the Sidewinder Pro driver.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <https://pcem-emulator.co.uk/>
*
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#ifndef EMU_JOYSTICK_SW_PAD_H
#define EMU_JOYSTICK_SW_PAD_H
extern const joystick_if_t joystick_sw_pad;
#endif /*EMU_JOYSTICK_SW_PAD_H*/

View File

@@ -1,43 +0,0 @@
/*
* 86Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus.
*
* This file is part of the 86Box distribution.
*
* Definitions for the Flight Control System driver.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <https://pcem-emulator.co.uk/>
*
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the:
*
* Free Software Foundation, Inc.
* 59 Temple Place - Suite 330
* Boston, MA 02111-1307
* USA.
*/
#ifndef EMU_JOYSTICK_TM_FCS_H
#define EMU_JOYSTICK_TM_FCS_H
extern const joystick_if_t joystick_tm_fcs;
#endif /*EMU_JOYSTICK_TM_FCS_H*/

View File

@@ -118,19 +118,12 @@ JoystickConfiguration::on_comboBoxDevice_currentIndexChanged(int index)
Models::AddEntry(model, QString("%1 (Y axis)").arg(plat_joystick_state[joystick].pov[d].name), 0);
}
for (int d = 0; d < plat_joystick_state[joystick].nr_sliders; d++) {
Models::AddEntry(model, plat_joystick_state[joystick].slider[d].name, 0);
}
int nr_axes = plat_joystick_state[joystick].nr_axes;
int nr_povs = plat_joystick_state[joystick].nr_povs;
int mapping = joystick_state[joystick_nr].axis_mapping[c];
if (mapping & POV_X)
cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2);
else if (mapping & POV_Y)
cbox->setCurrentIndex(nr_axes + (mapping & 3) * 2 + 1);
else if (mapping & SLIDER)
cbox->setCurrentIndex(nr_axes + nr_povs * 2 + (mapping & 3));
else
cbox->setCurrentIndex(mapping);

View File

@@ -137,22 +137,16 @@ get_axis(JoystickConfiguration &jc, int axis, int joystick_nr)
{
int axis_sel = jc.selectedAxis(axis);
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;
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);
if (axis_sel & 1)
return POV_Y | (axis_sel >> 1);
else
return POV_X | (axis_sel >> 1);
}
static int

View File

@@ -36,19 +36,19 @@ joystick_init()
int d;
strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64);
plat_joystick_state[c].nr_axes = SDL_JoystickNumAxes(sdl_joy[c]);
plat_joystick_state[c].nr_buttons = SDL_JoystickNumButtons(sdl_joy[c]);
plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]);
plat_joystick_state[c].nr_axes = std::min(SDL_JoystickNumAxes(sdl_joy[c]), MAX_JOY_AXES);
plat_joystick_state[c].nr_buttons = std::min(SDL_JoystickNumButtons(sdl_joy[c]), MAX_JOY_BUTTONS);
plat_joystick_state[c].nr_povs = std::min(SDL_JoystickNumHats(sdl_joy[c]), MAX_JOY_POVS);
for (d = 0; d < std::min(plat_joystick_state[c].nr_axes, 8); d++) {
for (d = 0; d < plat_joystick_state[c].nr_axes; d++) {
snprintf(plat_joystick_state[c].axis[d].name, sizeof(plat_joystick_state[c].axis[d].name), "Axis %i", d);
plat_joystick_state[c].axis[d].id = d;
}
for (d = 0; d < std::min(plat_joystick_state[c].nr_buttons, 8); d++) {
for (d = 0; d < plat_joystick_state[c].nr_buttons; d++) {
snprintf(plat_joystick_state[c].button[d].name, sizeof(plat_joystick_state[c].button[d].name), "Button %i", d);
plat_joystick_state[c].button[d].id = d;
}
for (d = 0; d < std::min(plat_joystick_state[c].nr_povs, 4); d++) {
for (d = 0; d < plat_joystick_state[c].nr_povs; d++) {
snprintf(plat_joystick_state[c].pov[d].name, sizeof(plat_joystick_state[c].pov[d].name), "POV %i", d);
plat_joystick_state[c].pov[d].id = d;
}
@@ -116,17 +116,13 @@ joystick_process()
for (c = 0; c < joysticks_present; c++) {
int b;
plat_joystick_state[c].a[0] = SDL_JoystickGetAxis(sdl_joy[c], 0);
plat_joystick_state[c].a[1] = SDL_JoystickGetAxis(sdl_joy[c], 1);
plat_joystick_state[c].a[2] = SDL_JoystickGetAxis(sdl_joy[c], 2);
plat_joystick_state[c].a[3] = SDL_JoystickGetAxis(sdl_joy[c], 3);
plat_joystick_state[c].a[4] = SDL_JoystickGetAxis(sdl_joy[c], 4);
plat_joystick_state[c].a[5] = SDL_JoystickGetAxis(sdl_joy[c], 5);
for (b = 0; b < plat_joystick_state[c].nr_axes; b++)
plat_joystick_state[c].a[b] = SDL_JoystickGetAxis(sdl_joy[c], b);
for (b = 0; b < 16; b++)
for (b = 0; b < plat_joystick_state[c].nr_buttons; b++)
plat_joystick_state[c].b[b] = SDL_JoystickGetButton(sdl_joy[c], b);
for (b = 0; b < 4; b++)
for (b = 0; b < plat_joystick_state[c].nr_povs; b++)
plat_joystick_state[c].p[b] = SDL_JoystickGetHat(sdl_joy[c], b);
// pclog("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present);
}

View File

@@ -35,6 +35,29 @@
#include <86box/gameport.h>
#include <86box/win.h>
/* These are defined in hidusage.h in the Windows SDK, but not in mingw-w64. */
#ifndef HID_USAGE_SIMULATION_AILERON
# define HID_USAGE_SIMULATION_AILERON ((USAGE) 0xb0)
#endif
#ifndef HID_USAGE_SIMULATION_ELEVATOR
# define HID_USAGE_SIMULATION_ELEVATOR ((USAGE) 0xb8)
#endif
#ifndef HID_USAGE_SIMULATION_ACCELLERATOR
# define HID_USAGE_SIMULATION_ACCELLERATOR ((USAGE) 0xc4)
#endif
#ifndef HID_USAGE_SIMULATION_BRAKE
# define HID_USAGE_SIMULATION_BRAKE ((USAGE) 0xc5)
#endif
#ifndef HID_USAGE_SIMULATION_CLUTCH
# define HID_USAGE_SIMULATION_CLUTCH ((USAGE) 0xc6)
#endif
#ifndef HID_USAGE_SIMULATION_SHIFTER
# define HID_USAGE_SIMULATION_SHIFTER ((USAGE) 0xc7)
#endif
#ifndef HID_USAGE_SIMULATION_STEERING
# define HID_USAGE_SIMULATION_STEERING ((USAGE) 0xc8)
#endif
#ifdef ENABLE_JOYSTICK_LOG
int joystick_do_log = ENABLE_JOYSTICK_LOG;
@@ -65,14 +88,14 @@ typedef struct {
USHORT bitsize;
LONG max;
LONG min;
} axis[8];
} axis[MAX_JOY_AXES];
struct raw_pov_t {
USAGE usage;
USHORT link;
LONG max;
LONG min;
} pov[4];
} pov[MAX_JOY_POVS];
} raw_joystick_t;
plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS];
@@ -85,7 +108,7 @@ raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS];
void
joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage)
{
if (joy->nr_buttons >= 32)
if (joy->nr_buttons >= MAX_JOY_BUTTONS)
return;
if (usage < 1 || usage > 128)
return;
@@ -98,7 +121,7 @@ joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage)
void
joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop)
{
if (joy->nr_axes >= 8)
if (joy->nr_axes >= MAX_JOY_AXES)
return;
switch (prop->Range.UsageMin) {
@@ -120,6 +143,42 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS
case HID_USAGE_GENERIC_RZ:
sprintf(joy->axis[joy->nr_axes].name, "RZ");
break;
case HID_USAGE_GENERIC_SLIDER:
sprintf(joy->axis[joy->nr_axes].name, "Slider");
break;
case HID_USAGE_GENERIC_DIAL:
sprintf(joy->axis[joy->nr_axes].name, "Dial");
break;
case HID_USAGE_GENERIC_WHEEL:
sprintf(joy->axis[joy->nr_axes].name, "Wheel");
break;
case HID_USAGE_SIMULATION_AILERON:
sprintf(joy->axis[joy->nr_axes].name, "Aileron");
break;
case HID_USAGE_SIMULATION_ELEVATOR:
sprintf(joy->axis[joy->nr_axes].name, "Elevator");
break;
case HID_USAGE_SIMULATION_RUDDER:
sprintf(joy->axis[joy->nr_axes].name, "Rudder");
break;
case HID_USAGE_SIMULATION_THROTTLE:
sprintf(joy->axis[joy->nr_axes].name, "Throttle");
break;
case HID_USAGE_SIMULATION_ACCELLERATOR:
sprintf(joy->axis[joy->nr_axes].name, "Accelerator");
break;
case HID_USAGE_SIMULATION_BRAKE:
sprintf(joy->axis[joy->nr_axes].name, "Brake");
break;
case HID_USAGE_SIMULATION_CLUTCH:
sprintf(joy->axis[joy->nr_axes].name, "Clutch");
break;
case HID_USAGE_SIMULATION_SHIFTER:
sprintf(joy->axis[joy->nr_axes].name, "Shifter");
break;
case HID_USAGE_SIMULATION_STEERING:
sprintf(joy->axis[joy->nr_axes].name, "Steering");
break;
default:
return;
}
@@ -147,7 +206,7 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS
void
joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop)
{
if (joy->nr_povs >= 4)
if (joy->nr_povs >= MAX_JOY_POVS)
return;
sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs + 1);
@@ -367,10 +426,10 @@ win_joystick_handle(PRAWINPUT raw)
/* Read axes */
for (int a = 0; a < plat_joystick_state[j].nr_axes; a++) {
struct raw_axis_t *axis = &raw_joystick_state[j].axis[a];
ULONG uvalue = 0;
LONG value = 0;
LONG center = (axis->max - axis->min + 1) / 2;
const struct raw_axis_t *axis = &raw_joystick_state[j].axis[a];
ULONG uvalue = 0;
LONG value = 0;
LONG center = (axis->max - axis->min + 1) / 2;
r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, axis->link, axis->usage, &uvalue,
raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid);
@@ -395,14 +454,16 @@ win_joystick_handle(PRAWINPUT raw)
}
plat_joystick_state[j].a[a] = value;
// joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]);
#if 0
joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]);
#endif
}
/* read povs */
for (int p = 0; p < plat_joystick_state[j].nr_povs; p++) {
struct raw_pov_t *pov = &raw_joystick_state[j].pov[p];
ULONG uvalue = 0;
LONG value = -1;
const struct raw_pov_t *pov = &raw_joystick_state[j].pov[p];
ULONG uvalue = 0;
LONG value = -1;
r = HidP_GetUsageValue(HidP_Input, HID_USAGE_PAGE_GENERIC, pov->link, pov->usage, &uvalue,
raw_joystick_state[j].data, (PCHAR) raw->data.hid.bRawData, raw->data.hid.dwSizeHid);
@@ -415,9 +476,13 @@ win_joystick_handle(PRAWINPUT raw)
plat_joystick_state[j].p[p] = value;
// joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]);
#if 0
joystick_log("%s %-3d ", plat_joystick_state[j].pov[p].name, plat_joystick_state[j].p[p]);
#endif
}
// joystick_log("\n");
#if 0
joystick_log("\n");
#endif
}
static int

View File

@@ -36,6 +36,7 @@
plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS];
joystick_t joystick_state[MAX_JOYSTICKS];
int joysticks_present = 0;
int has_slider = 0;
static LPDIRECTINPUT8 lpdi;
static LPDIRECTINPUTDEVICE8 lpdi_joystick[2] = { NULL, NULL };
@@ -83,7 +84,7 @@ 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) {
if (state->nr_axes < 8) {
if (state->nr_axes < MAX_JOY_AXES) {
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)
@@ -98,27 +99,24 @@ DIEnumDeviceObjectsCallback(
state->axis[state->nr_axes].id = 4;
else if (lpddoi->guidType == GUID_RzAxis)
state->axis[state->nr_axes].id = 5;
else if (lpddoi->guidType == GUID_Slider) {
state->axis[state->nr_axes].id = 6 + has_slider;
has_slider++;
}
state->nr_axes++;
}
} else if (lpddoi->guidType == GUID_Button) {
if (state->nr_buttons < 32) {
if (state->nr_buttons < MAX_JOY_BUTTONS) {
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) {
if (state->nr_povs < MAX_JOY_POVS) {
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;
@@ -170,6 +168,7 @@ joystick_init()
joystick_log(" Buttons = %i\n", devcaps.dwButtons);
joystick_log(" POVs = %i\n", devcaps.dwPOVs);
has_slider = 0;
lpdi_joystick[c]->EnumObjects(DIEnumDeviceObjectsCallback, &plat_joystick_state[c], DIDFT_ALL);
if (FAILED(lpdi_joystick[c]->SetCooperativeLevel(hwndMain, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
@@ -234,8 +233,6 @@ 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];
}
@@ -269,13 +266,13 @@ 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];
plat_joystick_state[c].a[6] = joystate.rglSlider[0];
plat_joystick_state[c].a[7] = joystate.rglSlider[1];
for (b = 0; b < 16; b++)
for (b = 0; b < MAX_JOY_BUTTONS; b++)
plat_joystick_state[c].b[b] = joystate.rgbButtons[b] & 0x80;
for (b = 0; b < 4; b++)
for (b = 0; b < MAX_JOY_POVS; b++)
plat_joystick_state[c].p[b] = joystate.rgdwPOV[b];
// joystick_log("joystick %i - x=%i y=%i b[0]=%i b[1]=%i %i\n", c, joystick_state[c].x, joystick_state[c].y, joystick_state[c].b[0], joystick_state[c].b[1], joysticks_present);
}

View File

@@ -35,6 +35,29 @@
#include <86box/gameport.h>
#include <86box/win.h>
/* These are defined in hidusage.h in the Windows SDK, but not in mingw-w64. */
#ifndef HID_USAGE_SIMULATION_AILERON
# define HID_USAGE_SIMULATION_AILERON ((USAGE) 0xb0)
#endif
#ifndef HID_USAGE_SIMULATION_ELEVATOR
# define HID_USAGE_SIMULATION_ELEVATOR ((USAGE) 0xb8)
#endif
#ifndef HID_USAGE_SIMULATION_ACCELLERATOR
# define HID_USAGE_SIMULATION_ACCELLERATOR ((USAGE) 0xc4)
#endif
#ifndef HID_USAGE_SIMULATION_BRAKE
# define HID_USAGE_SIMULATION_BRAKE ((USAGE) 0xc5)
#endif
#ifndef HID_USAGE_SIMULATION_CLUTCH
# define HID_USAGE_SIMULATION_CLUTCH ((USAGE) 0xc6)
#endif
#ifndef HID_USAGE_SIMULATION_SHIFTER
# define HID_USAGE_SIMULATION_SHIFTER ((USAGE) 0xc7)
#endif
#ifndef HID_USAGE_SIMULATION_STEERING
# define HID_USAGE_SIMULATION_STEERING ((USAGE) 0xc8)
#endif
#ifdef ENABLE_JOYSTICK_LOG
int joystick_do_log = ENABLE_JOYSTICK_LOG;
@@ -65,14 +88,14 @@ typedef struct {
USHORT bitsize;
LONG max;
LONG min;
} axis[8];
} axis[MAX_JOY_AXES];
struct raw_pov_t {
USAGE usage;
USHORT link;
LONG max;
LONG min;
} pov[4];
} pov[MAX_JOY_POVS];
} raw_joystick_t;
plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS];
@@ -85,7 +108,7 @@ raw_joystick_t raw_joystick_state[MAX_PLAT_JOYSTICKS];
void
joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage)
{
if (joy->nr_buttons >= 32)
if (joy->nr_buttons >= MAX_JOY_BUTTONS)
return;
if (usage < 1 || usage > 128)
return;
@@ -98,7 +121,7 @@ joystick_add_button(raw_joystick_t *rawjoy, plat_joystick_t *joy, USAGE usage)
void
joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop)
{
if (joy->nr_axes >= 8)
if (joy->nr_axes >= MAX_JOY_AXES)
return;
switch (prop->Range.UsageMin) {
@@ -120,6 +143,42 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS
case HID_USAGE_GENERIC_RZ:
sprintf(joy->axis[joy->nr_axes].name, "RZ");
break;
case HID_USAGE_GENERIC_SLIDER:
sprintf(joy->axis[joy->nr_axes].name, "Slider");
break;
case HID_USAGE_GENERIC_DIAL:
sprintf(joy->axis[joy->nr_axes].name, "Dial");
break;
case HID_USAGE_GENERIC_WHEEL:
sprintf(joy->axis[joy->nr_axes].name, "Wheel");
break;
case HID_USAGE_SIMULATION_AILERON:
sprintf(joy->axis[joy->nr_axes].name, "Aileron");
break;
case HID_USAGE_SIMULATION_ELEVATOR:
sprintf(joy->axis[joy->nr_axes].name, "Elevator");
break;
case HID_USAGE_SIMULATION_RUDDER:
sprintf(joy->axis[joy->nr_axes].name, "Rudder");
break;
case HID_USAGE_SIMULATION_THROTTLE:
sprintf(joy->axis[joy->nr_axes].name, "Throttle");
break;
case HID_USAGE_SIMULATION_ACCELLERATOR:
sprintf(joy->axis[joy->nr_axes].name, "Accelerator");
break;
case HID_USAGE_SIMULATION_BRAKE:
sprintf(joy->axis[joy->nr_axes].name, "Brake");
break;
case HID_USAGE_SIMULATION_CLUTCH:
sprintf(joy->axis[joy->nr_axes].name, "Clutch");
break;
case HID_USAGE_SIMULATION_SHIFTER:
sprintf(joy->axis[joy->nr_axes].name, "Shifter");
break;
case HID_USAGE_SIMULATION_STEERING:
sprintf(joy->axis[joy->nr_axes].name, "Steering");
break;
default:
return;
}
@@ -147,7 +206,7 @@ joystick_add_axis(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS
void
joystick_add_pov(raw_joystick_t *rawjoy, plat_joystick_t *joy, PHIDP_VALUE_CAPS prop)
{
if (joy->nr_povs >= 4)
if (joy->nr_povs >= MAX_JOY_POVS)
return;
sprintf(joy->pov[joy->nr_povs].name, "POV %d", joy->nr_povs + 1);
@@ -395,7 +454,9 @@ win_joystick_handle(PRAWINPUT raw)
}
plat_joystick_state[j].a[a] = value;
// joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]);
#if 0
joystick_log("%s %-06d ", plat_joystick_state[j].axis[a].name, plat_joystick_state[j].a[a]);
#endif
}
/* read povs */

View File

@@ -54,9 +54,6 @@ rebuild_axis_button_selections(HWND hdlg)
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);
} else
@@ -111,21 +108,15 @@ 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;
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);
if (axis_sel & 1)
return POV_Y | (axis_sel >> 1);
else
return POV_X | (axis_sel >> 1);
}
static int
@@ -188,8 +179,6 @@ joystickconfig_dlgproc(HWND hdlg, UINT message, WPARAM wParam, UNUSED(LPARAM lPa
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;