This commit is contained in:
OBattler
2025-07-04 05:26:46 +02:00
4 changed files with 198 additions and 33 deletions

View File

@@ -15,7 +15,7 @@
*
* Copyright 2016-2022 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2021 RichardG.
* Copyright 2021 RichardG.
* Copyright 2021-2025 Jasmine Iwanek.
*/
#include <stdio.h>
@@ -90,11 +90,18 @@ static const struct {
} joysticks[] = {
{ &joystick_none },
{ &joystick_2axis_2button },
{ &joystick_2button_gamepad },
{ &joystick_2button_flight_yoke },
{ &joystick_2axis_4button },
{ &joystick_4button_gamepad },
{ &joystick_4button_flight_yoke },
{ &joystick_2axis_6button },
{ &joystick_2axis_8button },
{ &joystick_3axis_2button },
{ &joystick_2button_yoke_throttle },
{ &joystick_3axis_4button },
{ &joystick_win95_steering_wheel }, // Temp
{ &joystick_4button_yoke_throttle },
{ &joystick_4axis_4button },
{ &joystick_ch_flightstick_pro },
{ &joystick_ch_flightstick_pro_ch_pedals },

View File

@@ -8,13 +8,14 @@
*
* Implementation of a standard joystick.
*
*
*
* Authors: Miran Grca, <mgrca8@gmail.com>
* Sarah Walker, <https://pcem-emulator.co.uk/>
* Miran Grca, <mgrca8@gmail.com>
* Jasmine Iwanek, <jriwanek@gmail.com>
*
* Copyright 2016-2018 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2021-2025 Jasmine Iwanek.
*
* 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
@@ -147,6 +148,37 @@ joystick_standard_read_axis_4button(UNUSED(void *priv), int axis)
}
}
static int
joystick_standard_read_axis_with_pov(UNUSED(void *priv), int axis)
{
if (!JOYSTICK_PRESENT(0, 0))
return AXIS_NOT_PRESENT;
switch (axis) {
case 0: // X-axis
return joystick_state[0][0].axis[0];
case 1: // Y-axis
return joystick_state[0][0].axis[1];
case 2: // POV Hat (mapped to the 3rd logical axis, index 2)
if (joystick_state[0][0].pov[0] == -1)
return 32767; // Centered/No input (as per tm_fcs_rcs_read_axis example)
if (joystick_state[0][0].pov[0] > 315 || joystick_state[0][0].pov[0] < 45)
return -32768; // Up
if (joystick_state[0][0].pov[0] >= 45 && joystick_state[0][0].pov[0] < 135)
return -16384; // Up-Right (example value, matches tm_fcs_rcs_read_axis)
if (joystick_state[0][0].pov[0] >= 135 && joystick_state[0][0].pov[0] < 225)
return 0; // Right/Left (example, matches tm_fcs_rcs_read_axis)
if (joystick_state[0][0].pov[0] >= 225 && joystick_state[0][0].pov[0] < 315)
return 16384; // Down-Left (example value, matches tm_fcs_rcs_read_axis)
return 0; // Fallback
case 3: // This case might be used for a Z-axis if present, or can return 0 if not.
// For gamepads with only X/Y and POV, this will likely be unused or return 0.
return 0;
default:
return 0;
}
}
static int
joystick_standard_read_axis_3axis(UNUSED(void *priv), int axis)
{
@@ -257,6 +289,42 @@ const joystick_if_t joystick_2axis_2button = {
.pov_names = { NULL }
};
const joystick_if_t joystick_2button_gamepad = {
.name = "2-button gamepad(s)",
.internal_name = "2button_gamepad",
.init = joystick_standard_init,
.close = joystick_standard_close,
.read = joystick_standard_read,
.write = joystick_standard_write,
.read_axis = joystick_standard_read_axis,
.a0_over = joystick_standard_a0_over,
.axis_count = 2,
.button_count = 2,
.pov_count = 0,
.max_joysticks = 2,
.axis_names = { "X axis", "Y axis" },
.button_names = { "Button 1", "Button 2" },
.pov_names = { NULL }
};
const joystick_if_t joystick_2button_flight_yoke = {
.name = "2-button flight yoke",
.internal_name = "2button_flight_yoke",
.init = joystick_standard_init,
.close = joystick_standard_close,
.read = joystick_standard_read,
.write = joystick_standard_write,
.read_axis = joystick_standard_read_axis,
.a0_over = joystick_standard_a0_over,
.axis_count = 2,
.button_count = 2,
.pov_count = 0,
.max_joysticks = 2,
.axis_names = { "Roll axis", "Pitch axis" },
.button_names = { "Trigger", "Button 2" },
.pov_names = { NULL }
};
const joystick_if_t joystick_2axis_4button = {
.name = "2-axis, 4-button joystick",
.internal_name = "2axis_4button",
@@ -275,6 +343,42 @@ const joystick_if_t joystick_2axis_4button = {
.pov_names = { NULL }
};
const joystick_if_t joystick_4button_gamepad = {
.name = "4-button gamepad",
.internal_name = "4button_gamepad",
.init = joystick_standard_init,
.close = joystick_standard_close,
.read = joystick_standard_read_4button,
.write = joystick_standard_write,
.read_axis = joystick_standard_read_axis_4button,
.a0_over = joystick_standard_a0_over,
.axis_count = 2,
.button_count = 4,
.pov_count = 0,
.max_joysticks = 1,
.axis_names = { "X axis", "Y axis" },
.button_names = { "Button 1", "Button 2", "Button 3", "Button 4" },
.pov_names = { NULL }
};
const joystick_if_t joystick_4button_flight_yoke = {
.name = "4-button flight yoke",
.internal_name = "4button_flight_yoke",
.init = joystick_standard_init,
.close = joystick_standard_close,
.read = joystick_standard_read_4button,
.write = joystick_standard_write,
.read_axis = joystick_standard_read_axis_4button,
.a0_over = joystick_standard_a0_over,
.axis_count = 2,
.button_count = 4,
.pov_count = 0,
.max_joysticks = 1,
.axis_names = { "Roll axis", "Pitch axis" },
.button_names = { "Trigger", "Button 2", "Button 3", "Button 4" },
.pov_names = { NULL }
};
const joystick_if_t joystick_3axis_2button = {
.name = "3-axis, 2-button joystick",
.internal_name = "3axis_2button",
@@ -293,6 +397,24 @@ const joystick_if_t joystick_3axis_2button = {
.pov_names = { NULL }
};
const joystick_if_t joystick_2button_yoke_throttle = {
.name = "2-button flight yoke with throttle",
.internal_name = "2button_yoke_throttle",
.init = joystick_standard_init,
.close = joystick_standard_close,
.read = joystick_standard_read,
.write = joystick_standard_write,
.read_axis = joystick_standard_read_axis_3axis,
.a0_over = joystick_standard_a0_over,
.axis_count = 3,
.button_count = 2,
.pov_count = 0,
.max_joysticks = 1,
.axis_names = { "Roll axis", "Pitch axis", "Throttle axis" },
.button_names = { "Trigger", "Button 2" },
.pov_names = { NULL }
};
const joystick_if_t joystick_3axis_4button = {
.name = "3-axis, 4-button joystick",
.internal_name = "3axis_4button",
@@ -311,6 +433,42 @@ const joystick_if_t joystick_3axis_4button = {
.pov_names = { NULL }
};
const joystick_if_t joystick_4button_yoke_throttle = {
.name = "4-button flight yoke with throttle",
.internal_name = "4button_yoke_throttle",
.init = joystick_standard_init,
.close = joystick_standard_close,
.read = joystick_standard_read_4button,
.write = joystick_standard_write,
.read_axis = joystick_standard_read_axis_3axis,
.a0_over = joystick_standard_a0_over,
.axis_count = 3,
.button_count = 4,
.pov_count = 0,
.max_joysticks = 1,
.axis_names = { "Roll axis", "Pitch axis", "Throttle axis" },
.button_names = { "Button 1", "Button 2", "Button 3", "Button 4" },
.pov_names = { NULL }
};
const joystick_if_t joystick_win95_steering_wheel = {
.name = "Win95 Steering Wheel (3-axis, 4-button)",
.internal_name = "win95_steering_wheel",
.init = joystick_standard_init,
.close = joystick_standard_close,
.read = joystick_standard_read_4button,
.write = joystick_standard_write,
.read_axis = joystick_standard_read_axis_3axis,
.a0_over = joystick_standard_a0_over,
.axis_count = 3,
.button_count = 4,
.pov_count = 0,
.max_joysticks = 1,
.axis_names = { "Steering axis", "Accelerator axis", "Brake axis" },
.button_names = { "Button 1", "Button 2", "Button 3", "Button 4" },
.pov_names = { NULL }
};
const joystick_if_t joystick_4axis_4button = {
.name = "4-axis, 4-button joystick",
.internal_name = "4axis_4button",

View File

@@ -15,7 +15,7 @@
*
* Copyright 2016-2022 Miran Grca.
* Copyright 2008-2018 Sarah Walker.
* Copyright 2021 RichardG.
* Copyright 2021 RichardG.
* Copyright 2021-2025 Jasmine Iwanek.
*/
#ifndef EMU_GAMEPORT_H
@@ -52,6 +52,26 @@
#define GAMEPORT_8ADDR 0x080000
#define GAMEPORT_SIO 0x1000000
typedef struct joystick_if_t {
const char *name;
const char *internal_name;
void *(*init)(void);
void (*close)(void *priv);
uint8_t (*read)(void *priv);
void (*write)(void *priv);
int (*read_axis)(void *priv, int axis);
void (*a0_over)(void *priv);
int axis_count;
int button_count;
int pov_count;
int max_joysticks;
const char *axis_names[MAX_JOY_AXES];
const char *button_names[MAX_JOY_BUTTONS];
const char *pov_names[MAX_JOY_POVS];
} joystick_if_t;
typedef struct plat_joystick_t {
char name[260];
@@ -90,26 +110,6 @@ typedef struct joystick_t {
int pov_mapping[MAX_JOY_POVS][2];
} joystick_t;
typedef struct joystick_if_t {
const char *name;
const char *internal_name;
void *(*init)(void);
void (*close)(void *priv);
uint8_t (*read)(void *priv);
void (*write)(void *priv);
int (*read_axis)(void *priv, int axis);
void (*a0_over)(void *priv);
int axis_count;
int button_count;
int pov_count;
int max_joysticks;
const char *axis_names[MAX_JOY_AXES];
const char *button_names[MAX_JOY_BUTTONS];
const char *pov_names[MAX_JOY_POVS];
} joystick_if_t;
extern device_t game_ports[GAMEPORT_MAX];
#ifdef __cplusplus
@@ -171,9 +171,16 @@ 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_2button_gamepad;
extern const joystick_if_t joystick_2button_flight_yoke;
extern const joystick_if_t joystick_2axis_4button;
extern const joystick_if_t joystick_4button_gamepad;
extern const joystick_if_t joystick_4button_flight_yoke;
extern const joystick_if_t joystick_3axis_2button;
extern const joystick_if_t joystick_2button_yoke_throttle;
extern const joystick_if_t joystick_3axis_4button;
extern const joystick_if_t joystick_4button_yoke_throttle;
extern const joystick_if_t joystick_win95_steering_wheel;
extern const joystick_if_t joystick_4axis_4button;
extern const joystick_if_t joystick_2axis_6button;
extern const joystick_if_t joystick_2axis_8button;
@@ -186,14 +193,6 @@ extern const joystick_if_t joystick_sw_pad;
extern const joystick_if_t joystick_tm_fcs;
extern const joystick_if_t joystick_tm_fcs_rcs;
extern int gameport_available(int);
extern int gameport_has_config(int);
extern const char *gameport_get_internal_name(int);
extern int gampeport_get_from_internal_name(char *);
#ifdef EMU_DEVICE_H
extern const device_t *gameport_getdevice(int);
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -222,6 +222,7 @@ joystick_get_capabilities(raw_joystick_t *rawjoy, plat_joystick_t *joy)
UINT size = 0;
PHIDP_BUTTON_CAPS btn_caps = NULL;
PHIDP_VALUE_CAPS val_caps = NULL;
HIDP_CAPS caps;
/* Get preparsed data (HID data format) */
GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, NULL, &size);
@@ -229,7 +230,6 @@ joystick_get_capabilities(raw_joystick_t *rawjoy, plat_joystick_t *joy)
if (GetRawInputDeviceInfoW(rawjoy->hdevice, RIDI_PREPARSEDDATA, rawjoy->data, &size) <= 0)
fatal("joystick_get_capabilities: Failed to get preparsed data.\n");
HIDP_CAPS caps;
HidP_GetCaps(rawjoy->data, &caps);
/* Buttons */
@@ -356,6 +356,7 @@ end_loop:
free(info);
}
free(deviceList);
joystick_log("joystick_init: joysticks_present=%i\n", joysticks_present);
/* Initialize the RawInput (joystick and gamepad) module. */