2021-12-13 22:45:37 +01:00
|
|
|
// Lifted from wx-sdl2-joystick.c in PCem
|
|
|
|
|
|
|
|
|
|
#include <SDL2/SDL.h>
|
|
|
|
|
|
2021-12-16 12:53:04 +01:00
|
|
|
#include <algorithm>
|
|
|
|
|
|
2021-12-13 22:45:37 +01:00
|
|
|
extern "C" {
|
|
|
|
|
#include <86box/device.h>
|
|
|
|
|
#include <86box/gameport.h>
|
|
|
|
|
|
2022-11-19 08:49:04 -05:00
|
|
|
int joysticks_present;
|
|
|
|
|
joystick_t joystick_state[MAX_JOYSTICKS];
|
|
|
|
|
plat_joystick_t plat_joystick_state[MAX_PLAT_JOYSTICKS];
|
2021-12-13 22:45:37 +01:00
|
|
|
static SDL_Joystick *sdl_joy[MAX_PLAT_JOYSTICKS];
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-14 16:33:53 +06:00
|
|
|
#include <algorithm>
|
|
|
|
|
|
2021-12-15 00:50:46 +02:00
|
|
|
#ifndef M_PI
|
2022-11-19 08:49:04 -05:00
|
|
|
# define M_PI 3.14159265358979323846
|
2021-12-15 00:50:46 +02:00
|
|
|
#endif
|
|
|
|
|
|
2022-11-19 08:49:04 -05:00
|
|
|
void
|
|
|
|
|
joystick_init()
|
|
|
|
|
{
|
2021-12-13 22:45:37 +01:00
|
|
|
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
joysticks_present = SDL_NumJoysticks();
|
|
|
|
|
|
|
|
|
|
memset(sdl_joy, 0, sizeof(sdl_joy));
|
2022-11-19 08:49:04 -05:00
|
|
|
for (int c = 0; c < joysticks_present; c++) {
|
2021-12-13 22:45:37 +01:00
|
|
|
sdl_joy[c] = SDL_JoystickOpen(c);
|
|
|
|
|
|
2022-11-19 08:49:04 -05:00
|
|
|
if (sdl_joy[c]) {
|
2021-12-13 22:45:37 +01:00
|
|
|
int d;
|
|
|
|
|
|
|
|
|
|
strncpy(plat_joystick_state[c].name, SDL_JoystickNameForIndex(c), 64);
|
2022-11-19 08:49:04 -05:00
|
|
|
plat_joystick_state[c].nr_axes = SDL_JoystickNumAxes(sdl_joy[c]);
|
2021-12-13 22:45:37 +01:00
|
|
|
plat_joystick_state[c].nr_buttons = SDL_JoystickNumButtons(sdl_joy[c]);
|
2022-11-19 08:49:04 -05:00
|
|
|
plat_joystick_state[c].nr_povs = SDL_JoystickNumHats(sdl_joy[c]);
|
2021-12-13 22:45:37 +01:00
|
|
|
|
2022-11-19 08:49:04 -05:00
|
|
|
for (d = 0; d < std::min(plat_joystick_state[c].nr_axes, 8); d++) {
|
2021-12-13 22:45:37 +01:00
|
|
|
sprintf(plat_joystick_state[c].axis[d].name, "Axis %i", d);
|
|
|
|
|
plat_joystick_state[c].axis[d].id = d;
|
|
|
|
|
}
|
2022-11-19 08:49:04 -05:00
|
|
|
for (d = 0; d < std::min(plat_joystick_state[c].nr_buttons, 8); d++) {
|
2021-12-13 22:45:37 +01:00
|
|
|
sprintf(plat_joystick_state[c].button[d].name, "Button %i", d);
|
|
|
|
|
plat_joystick_state[c].button[d].id = d;
|
|
|
|
|
}
|
2022-11-19 08:49:04 -05:00
|
|
|
for (d = 0; d < std::min(plat_joystick_state[c].nr_povs, 4); d++) {
|
2021-12-13 22:45:37 +01:00
|
|
|
sprintf(plat_joystick_state[c].pov[d].name, "POV %i", d);
|
|
|
|
|
plat_joystick_state[c].pov[d].id = d;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-19 08:49:04 -05:00
|
|
|
void
|
|
|
|
|
joystick_close()
|
2021-12-13 22:45:37 +01:00
|
|
|
{
|
|
|
|
|
int c;
|
|
|
|
|
|
2022-11-19 08:49:04 -05:00
|
|
|
for (c = 0; c < joysticks_present; c++) {
|
2021-12-13 22:45:37 +01:00
|
|
|
if (sdl_joy[c])
|
|
|
|
|
SDL_JoystickClose(sdl_joy[c]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-19 08:49:04 -05:00
|
|
|
static int
|
|
|
|
|
joystick_get_axis(int joystick_nr, int mapping)
|
2021-12-13 22:45:37 +01:00
|
|
|
{
|
2022-11-19 08:49:04 -05:00
|
|
|
if (mapping & POV_X) {
|
|
|
|
|
switch (plat_joystick_state[joystick_nr].p[mapping & 3]) {
|
|
|
|
|
case SDL_HAT_LEFTUP:
|
|
|
|
|
case SDL_HAT_LEFT:
|
|
|
|
|
case SDL_HAT_LEFTDOWN:
|
|
|
|
|
return -32767;
|
|
|
|
|
|
|
|
|
|
case SDL_HAT_RIGHTUP:
|
|
|
|
|
case SDL_HAT_RIGHT:
|
|
|
|
|
case SDL_HAT_RIGHTDOWN:
|
|
|
|
|
return 32767;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
2021-12-13 22:45:37 +01:00
|
|
|
}
|
2022-11-19 08:49:04 -05:00
|
|
|
} else if (mapping & POV_Y) {
|
|
|
|
|
switch (plat_joystick_state[joystick_nr].p[mapping & 3]) {
|
|
|
|
|
case SDL_HAT_LEFTUP:
|
|
|
|
|
case SDL_HAT_UP:
|
|
|
|
|
case SDL_HAT_RIGHTUP:
|
|
|
|
|
return -32767;
|
|
|
|
|
|
|
|
|
|
case SDL_HAT_LEFTDOWN:
|
|
|
|
|
case SDL_HAT_DOWN:
|
|
|
|
|
case SDL_HAT_RIGHTDOWN:
|
|
|
|
|
return 32767;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
2021-12-13 22:45:37 +01:00
|
|
|
}
|
2022-11-19 08:49:04 -05:00
|
|
|
} else
|
2021-12-13 22:45:37 +01:00
|
|
|
return plat_joystick_state[joystick_nr].a[plat_joystick_state[joystick_nr].axis[mapping].id];
|
|
|
|
|
}
|
2022-11-19 08:49:04 -05:00
|
|
|
void
|
|
|
|
|
joystick_process()
|
2021-12-13 22:45:37 +01:00
|
|
|
{
|
2023-05-29 01:30:51 -04:00
|
|
|
int c;
|
|
|
|
|
int d;
|
2021-12-13 22:45:37 +01:00
|
|
|
|
2022-11-19 08:49:04 -05:00
|
|
|
if (!joystick_type)
|
|
|
|
|
return;
|
2022-07-10 14:31:49 +02:00
|
|
|
|
2021-12-13 22:45:37 +01:00
|
|
|
SDL_JoystickUpdate();
|
2022-11-19 08:49:04 -05:00
|
|
|
for (c = 0; c < joysticks_present; c++) {
|
2021-12-13 22:45:37 +01:00
|
|
|
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 < 16; b++)
|
|
|
|
|
plat_joystick_state[c].b[b] = SDL_JoystickGetButton(sdl_joy[c], b);
|
|
|
|
|
|
|
|
|
|
for (b = 0; b < 4; 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);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-19 08:49:04 -05:00
|
|
|
for (c = 0; c < joystick_get_max_joysticks(joystick_type); c++) {
|
|
|
|
|
if (joystick_state[c].plat_joystick_nr) {
|
2021-12-13 22:45:37 +01:00
|
|
|
int joystick_nr = joystick_state[c].plat_joystick_nr - 1;
|
|
|
|
|
|
|
|
|
|
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
|
|
|
|
joystick_state[c].axis[d] = joystick_get_axis(joystick_nr, joystick_state[c].axis_mapping[d]);
|
|
|
|
|
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
|
|
|
|
joystick_state[c].button[d] = plat_joystick_state[joystick_nr].b[joystick_state[c].button_mapping[d]];
|
2022-11-19 08:49:04 -05:00
|
|
|
for (d = 0; d < joystick_get_pov_count(joystick_type); d++) {
|
|
|
|
|
int x, y;
|
2021-12-13 22:45:37 +01:00
|
|
|
double angle, magnitude;
|
|
|
|
|
|
|
|
|
|
x = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][0]);
|
|
|
|
|
y = joystick_get_axis(joystick_nr, joystick_state[c].pov_mapping[d][1]);
|
|
|
|
|
|
2022-11-19 08:49:04 -05:00
|
|
|
angle = (atan2((double) y, (double) x) * 360.0) / (2 * M_PI);
|
|
|
|
|
magnitude = sqrt((double) x * (double) x + (double) y * (double) y);
|
2021-12-13 22:45:37 +01:00
|
|
|
|
|
|
|
|
if (magnitude < 16384)
|
|
|
|
|
joystick_state[c].pov[d] = -1;
|
|
|
|
|
else
|
2022-11-19 08:49:04 -05:00
|
|
|
joystick_state[c].pov[d] = ((int) angle + 90 + 360) % 360;
|
2021-12-13 22:45:37 +01:00
|
|
|
}
|
2022-11-19 08:49:04 -05:00
|
|
|
} else {
|
2021-12-13 22:45:37 +01:00
|
|
|
for (d = 0; d < joystick_get_axis_count(joystick_type); d++)
|
|
|
|
|
joystick_state[c].axis[d] = 0;
|
|
|
|
|
for (d = 0; d < joystick_get_button_count(joystick_type); d++)
|
|
|
|
|
joystick_state[c].button[d] = 0;
|
|
|
|
|
for (d = 0; d < joystick_get_pov_count(joystick_type); d++)
|
|
|
|
|
joystick_state[c].pov[d] = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|