浏览代码

Add gamepad support

master
Nathaniel Walizer 11 个月前
父节点
当前提交
58abae105f
共有 1 个文件被更改,包括 70 次插入10 次删除
  1. +70
    -10
      src/sdl_input.c

+ 70
- 10
src/sdl_input.c 查看文件

@@ -3,27 +3,50 @@
#include "input.h"


static int filter(void*, SDL_Event* event) {
static SDL_GameController* sdl_find_gamepad() {
int i = SDL_NumJoysticks() - 1;
for ( ; i >= 0 && !SDL_IsGameController(i); --i);
return (i < 0 ? NULL : SDL_GameControllerOpen(i));
}

static void sdl_lose_gamepad(void* data) {
SDL_GameController* gamepad = (SDL_GameController*)data;
if (NULL != gamepad) SDL_GameControllerClose(gamepad);
}

static int sdl_match_gamepad(SDL_JoystickID id, void* data) {
SDL_GameController* gamepad = (SDL_GameController*)data;
return ( SDL_JoystickInstanceID(
SDL_GameControllerGetJoystick(gamepad))
== id);
}

static int sdl_event_filter(void*, SDL_Event* event) {
return ( SDL_QUIT == event->type ||
SDL_KEYDOWN == event->type ||
SDL_KEYUP == event->type
SDL_KEYUP == event->type ||
SDL_CONTROLLERDEVICEADDED == event->type ||
SDL_CONTROLLERDEVICEREMOVED == event->type
);
}


static int sdl_input_init(nes_Input_Reader*) {
int status = SDL_Init(SDL_INIT_EVENTS);
static int sdl_input_init(nes_Input_Reader* reader) {
int status = SDL_Init(SDL_INIT_EVENTS |
SDL_INIT_GAMECONTROLLER);

if (status == 0) {
SDL_SetEventFilter(filter, NULL);
reader->data = sdl_find_gamepad();
SDL_SetEventFilter(sdl_event_filter, NULL);
}

return status;
}

static void sdl_input_done(nes_Input_Reader*) {}
static void sdl_input_done(nes_Input_Reader* input) {
sdl_lose_gamepad(input->data);
}

static const int keycodes[nes_controller_num_buttons] = {
static const int sdl_keycodes[nes_controller_num_buttons] = {
SDLK_a,
SDLK_s,
SDLK_q,
@@ -36,11 +59,23 @@ static const int keycodes[nes_controller_num_buttons] = {

static int button_index(int keycode) {
int index = nes_controller_num_buttons - 1;
for ( ; index > 0 && keycode != keycodes[index]; --index);
for ( ; index > 0 && keycode != sdl_keycodes[index]; --index);
return index;
}

static int sdl_input_update(nes_Input_Reader*, nes_input* input) {
static const int sdl_gamepad_buttons[nes_controller_num_buttons] = {
SDL_CONTROLLER_BUTTON_A,
SDL_CONTROLLER_BUTTON_B,
SDL_CONTROLLER_BUTTON_BACK,
SDL_CONTROLLER_BUTTON_START,
SDL_CONTROLLER_BUTTON_DPAD_UP,
SDL_CONTROLLER_BUTTON_DPAD_DOWN,
SDL_CONTROLLER_BUTTON_DPAD_LEFT,
SDL_CONTROLLER_BUTTON_DPAD_RIGHT,
};

static int sdl_input_update(nes_Input_Reader* reader,
nes_input* input) {
int status = 0;

SDL_Event event = {0};
@@ -58,6 +93,31 @@ static int sdl_input_update(nes_Input_Reader*, nes_input* input) {
} else {
input->controllers[0].buttons &= ~mask;
}

} else if (SDL_CONTROLLERDEVICEADDED == event.type) {
if (NULL == reader->data) {
reader->data = sdl_find_gamepad();
}

} else if (SDL_CONTROLLERDEVICEREMOVED == event.type) {
if (sdl_match_gamepad(event.cdevice.which,
reader->data)) {
sdl_lose_gamepad(reader->data);
reader->data = sdl_find_gamepad();
}
}
}

if (NULL != reader->data) {
SDL_GameController* gamepad = (SDL_GameController*)reader->data;

for (int b = 0; b < nes_controller_num_buttons; ++b) {
if (SDL_GameControllerGetButton(
gamepad, sdl_gamepad_buttons[b])) {
input->controllers[0].buttons |= (1 << b);
} else {
input->controllers[0].buttons &= ~(1 << b);
}
}
}



正在加载...
取消
保存