Skip to content

Commit

Permalink
Initial SDL game controller integration
Browse files Browse the repository at this point in the history
  • Loading branch information
fragglet committed Nov 28, 2024
1 parent 1e4820d commit 44cd2da
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/sdl/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ AM_CFLAGS=-I$(srcdir)/.. @CFLAGS@ @SDL_CFLAGS@

noinst_LIBRARIES = libsdlsopwith.a libsdlsopmain.a

libsdlsopwith_a_SOURCES = video.c pcsound.c timer.c
libsdlsopwith_a_SOURCES = video.c pcsound.c timer.c controller.c
libsdlsopmain_a_SOURCES = main.c

110 changes: 110 additions & 0 deletions src/sdl/controller.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//
// Copyright(C) 2024 Simon Howard
//
// You can redistribute and/or modify this program under the terms of the
// GNU General Public License version 2 as published by the Free Software
// Foundation, or any later version. This program is distributed WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.
//
//
// SDL game controller
//

#include <SDL.h>

#include "sw.h"
#include "video.h"

int controller_bindings[NUM_KEYS] = {
SDL_CONTROLLER_BUTTON_INVALID, // KEY_UNKNOWN
SDL_CONTROLLER_BUTTON_DPAD_DOWN, // KEY_PULLUP
SDL_CONTROLLER_BUTTON_DPAD_UP, // KEY_PULLDOWN
SDL_CONTROLLER_BUTTON_A, // KEY_FLIP
SDL_CONTROLLER_BUTTON_LEFTSHOULDER, // KEY_BOMB
SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, // KEY_FIRE
SDL_CONTROLLER_BUTTON_START, // KEY_HOME
SDL_CONTROLLER_BUTTON_INVALID, // KEY_MISSILE
SDL_CONTROLLER_BUTTON_INVALID, // KEY_STARBURST
SDL_CONTROLLER_BUTTON_Y, // KEY_ACCEL
SDL_CONTROLLER_BUTTON_B, // KEY_DECEL
SDL_CONTROLLER_BUTTON_INVALID, // KEY_SOUND
};

static int button_to_key[SDL_CONTROLLER_BUTTON_MAX];

static SDL_GameController *controller = NULL;
static SDL_JoystickID controller_id;

static void RecalculateButtonMapping(void)
{
int i;

for (i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++) {
button_to_key[i] = KEY_UNKNOWN;
}
for (i = 0; i < NUM_KEYS; i++) {
int button = controller_bindings[i];
if (button != SDL_CONTROLLER_BUTTON_INVALID) {
button_to_key[button] = i;
}
}
}

void Vid_ControllerButtonDown(SDL_ControllerButtonEvent *event)
{
int gamekey;

if (controller != NULL && event->which != controller_id) {
return;
}
if (event->button >= SDL_CONTROLLER_BUTTON_MAX) {
return;
}
gamekey = button_to_key[event->button];
if (gamekey != KEY_UNKNOWN) {
keysdown[gamekey] |= KEYDOWN_GAMEPAD | KEYDOWN_WAS_PRESSED;
}
}

void Vid_ControllerButtonUp(SDL_ControllerButtonEvent *event)
{
int gamekey;

if (controller != NULL && event->which != controller_id) {
return;
}
if (event->button >= SDL_CONTROLLER_BUTTON_MAX) {
return;
}
gamekey = button_to_key[event->button];
if (gamekey != KEY_UNKNOWN) {
keysdown[gamekey] &= ~KEYDOWN_GAMEPAD;
}
}

void Vid_ControllerAdded(SDL_ControllerDeviceEvent *event)
{
if (controller != NULL) {
return;
}
controller = SDL_GameControllerOpen(event->which);
controller_id = SDL_JoystickInstanceID(
SDL_GameControllerGetJoystick(controller));
}

void Vid_ControllerRemoved(SDL_ControllerDeviceEvent *event)
{
if (controller == NULL || event->which != controller_id) {
return;
}
SDL_GameControllerClose(controller);
controller = NULL;
}

void Vid_ControllerInit(void)
{
SDL_Init(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
// SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt");
RecalculateButtonMapping();
}
24 changes: 24 additions & 0 deletions src/sdl/video.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@

#define INPUT_BUFFER_LEN 32

void Vid_ControllerButtonDown(SDL_ControllerButtonEvent *event);
void Vid_ControllerButtonUp(SDL_ControllerButtonEvent *event);
void Vid_ControllerAdded(SDL_ControllerDeviceEvent *event);
void Vid_ControllerRemoved(SDL_ControllerDeviceEvent *event);
void Vid_ControllerInit(void);

struct palette {
char name[13]; // Up to 12 characters will display correctly on the menu
SDL_Color color[4];
Expand Down Expand Up @@ -537,6 +543,8 @@ void Vid_Init(void)

atexit(Vid_Shutdown);

Vid_ControllerInit();

SDL_LockSurface(screenbuf);
}

Expand Down Expand Up @@ -863,6 +871,22 @@ static void GetEvents(void)
case SDL_FINGERMOTION:
FingerMove(&event.tfinger);
break;

case SDL_CONTROLLERBUTTONDOWN:
Vid_ControllerButtonDown(&event.cbutton);
break;

case SDL_CONTROLLERBUTTONUP:
Vid_ControllerButtonUp(&event.cbutton);
break;

case SDL_CONTROLLERDEVICEADDED:
Vid_ControllerAdded(&event.cdevice);
break;

case SDL_CONTROLLERDEVICEREMOVED:
Vid_ControllerRemoved(&event.cdevice);
break;
}
}

Expand Down
1 change: 1 addition & 0 deletions src/video.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ enum gamekey {
#define KEYDOWN_KEYBOARD (1 << 0)
#define KEYDOWN_WAS_PRESSED (1 << 1)
#define KEYDOWN_TOUCH (1 << 2)
#define KEYDOWN_GAMEPAD (1 << 3)

extern int keysdown[NUM_KEYS];
extern int keybindings[NUM_KEYS];
Expand Down

0 comments on commit 44cd2da

Please sign in to comment.