Add support for (my) joystick
Jeffrey Pfau jeffrey@endrift.com
Wed, 08 May 2013 16:31:32 -0700
5 files changed,
165 insertions(+),
118 deletions(-)
M
CMakeLists.txt
→
CMakeLists.txt
@@ -13,8 +13,12 @@ include_directories(${CMAKE_SOURCE_DIR}/src/debugger)
include_directories(${CMAKE_SOURCE_DIR}/third-party/linenoise) find_package(SDL 1.2 REQUIRED) +file(GLOB SDL_SRC ${CMAKE_SOURCE_DIR}/src/sdl/sdl-*.c) +include_directories(${CMAKE_SOURCE_DIR}/src/sdl) + find_package(OpenGL REQUIRED) + include_directories(${SDL_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR}) -add_executable(gbac ${ARM_SRC} ${GBA_SRC} ${DEBUGGER_SRC} ${RENDERER_SRC} ${THIRD_PARTY} ${CMAKE_SOURCE_DIR}/src/main.c) +add_executable(gbac ${ARM_SRC} ${GBA_SRC} ${DEBUGGER_SRC} ${RENDERER_SRC} ${THIRD_PARTY} ${SDL_SRC} ${CMAKE_SOURCE_DIR}/src/main.c) target_link_libraries(gbac m pthread ${SDL_LIBRARY} ${OPENGL_LIBRARY})
M
src/main.c
→
src/main.c
@@ -2,6 +2,7 @@ #include "debugger.h"
#include "gba-thread.h" #include "gba.h" #include "renderers/video-glsl.h" +#include "sdl-events.h" #include <SDL.h> #ifdef __APPLE__@@ -19,8 +20,6 @@
static int _GBASDLInit(void); static void _GBASDLDeinit(void); static void _GBASDLRunloop(struct GBAThread* context, struct GBAVideoGLSLRenderer* renderer); -static void _GBASDLHandleKeypress(struct GBAThread* context, const struct SDL_KeyboardEvent* event); - int main(int argc, char** argv) { const char* fname = "test.rom";@@ -59,6 +58,8 @@ if (SDL_Init(SDL_INIT_VIDEO) < 0) {
return 0; } + GBASDLInitEvents(); + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);@@ -85,16 +86,7 @@
SDL_GL_SwapBuffers(); while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - // FIXME: this isn't thread-safe - context->debugger->state = DEBUGGER_EXITING; - break; - case SDL_KEYDOWN: - case SDL_KEYUP: - _GBASDLHandleKeypress(context, &event.key); - break; - } + GBASDLHandleEvent(context, &event); } pthread_mutex_lock(&renderer->mutex); pthread_cond_broadcast(&renderer->downCond);@@ -107,52 +99,6 @@ }
} static void _GBASDLDeinit() { + GBASDLDeinitEvents(); SDL_Quit(); } - -static void _GBASDLHandleKeypress(struct GBAThread* context, const struct SDL_KeyboardEvent* event) { - enum GBAKey key = 0; - switch (event->keysym.sym) { - case SDLK_z: - key = GBA_KEY_A; - break; - case SDLK_x: - key = GBA_KEY_B; - break; - case SDLK_a: - key = GBA_KEY_L; - break; - case SDLK_s: - key = GBA_KEY_R; - break; - case SDLK_RETURN: - key = GBA_KEY_START; - break; - case SDLK_BACKSPACE: - key = GBA_KEY_SELECT; - break; - case SDLK_UP: - key = GBA_KEY_UP; - break; - case SDLK_DOWN: - key = GBA_KEY_DOWN; - break; - case SDLK_LEFT: - key = GBA_KEY_LEFT; - break; - case SDLK_RIGHT: - key = GBA_KEY_RIGHT; - break; - case SDLK_TAB: - context->renderer->turbo = !context->renderer->turbo; - return; - default: - return; - } - - if (event->type == SDL_KEYDOWN) { - context->activeKeys |= 1 << key; - } else { - context->activeKeys &= ~(1 << key); - } -}
M
src/sdl/main.c
→
src/sdl/main.c
@@ -1,6 +1,7 @@
#include "debugger.h" #include "gba-thread.h" #include "gba.h" +#include "sdl-events.h" #include "renderers/video-software.h" #include <SDL.h>@@ -25,7 +26,6 @@
static int _GBASDLInit(struct GLSoftwareRenderer* renderer); static void _GBASDLDeinit(struct GLSoftwareRenderer* renderer); static void _GBASDLRunloop(struct GBAThread* context, struct GLSoftwareRenderer* renderer); -static void _GBASDLHandleKeypress(struct GBAThread* context, const struct SDL_KeyboardEvent* event); static const GLint _glVertices[] = { 0, 0,@@ -82,6 +82,8 @@ static int _GBASDLInit(struct GLSoftwareRenderer* renderer) {
if (SDL_Init(SDL_INIT_VIDEO) < 0) { return 0; } + + GBASDLInitEvents(); SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);@@ -129,16 +131,7 @@
SDL_GL_SwapBuffers(); while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - // FIXME: this isn't thread-safe - context->debugger->state = DEBUGGER_EXITING; - break; - case SDL_KEYDOWN: - case SDL_KEYUP: - _GBASDLHandleKeypress(context, &event.key); - break; - } + GBASDLHandleEvent(context, &event); } pthread_mutex_lock(&renderer->d.mutex); pthread_cond_broadcast(&renderer->d.downCond);@@ -163,52 +156,6 @@
static void _GBASDLDeinit(struct GLSoftwareRenderer* renderer) { free(renderer->d.outputBuffer); + GBASDLDeinitEvents(); SDL_Quit(); } - -static void _GBASDLHandleKeypress(struct GBAThread* context, const struct SDL_KeyboardEvent* event) { - enum GBAKey key = 0; - switch (event->keysym.sym) { - case SDLK_z: - key = GBA_KEY_A; - break; - case SDLK_x: - key = GBA_KEY_B; - break; - case SDLK_a: - key = GBA_KEY_L; - break; - case SDLK_s: - key = GBA_KEY_R; - break; - case SDLK_RETURN: - key = GBA_KEY_START; - break; - case SDLK_BACKSPACE: - key = GBA_KEY_SELECT; - break; - case SDLK_UP: - key = GBA_KEY_UP; - break; - case SDLK_DOWN: - key = GBA_KEY_DOWN; - break; - case SDLK_LEFT: - key = GBA_KEY_LEFT; - break; - case SDLK_RIGHT: - key = GBA_KEY_RIGHT; - break; - case SDLK_TAB: - context->renderer->turbo = !context->renderer->turbo; - return; - default: - return; - } - - if (event->type == SDL_KEYDOWN) { - context->activeKeys |= 1 << key; - } else { - context->activeKeys &= ~(1 << key); - } -}
A
src/sdl/sdl-events.c
@@ -0,0 +1,137 @@
+#include "sdl-events.h" + +#include "debugger.h" +#include "gba-io.h" +#include "gba-video.h" + +int GBASDLInitEvents() { + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) { + return 0; + } + SDL_JoystickEventState(SDL_ENABLE); + SDL_JoystickOpen(0); + return 1; +} + +void GBASDLDeinitEvents() { + SDL_QuitSubSystem(SDL_INIT_JOYSTICK); +} + +static void _GBASDLHandleKeypress(struct GBAThread* context, const struct SDL_KeyboardEvent* event) { + enum GBAKey key = 0; + switch (event->keysym.sym) { + case SDLK_z: + key = GBA_KEY_A; + break; + case SDLK_x: + key = GBA_KEY_B; + break; + case SDLK_a: + key = GBA_KEY_L; + break; + case SDLK_s: + key = GBA_KEY_R; + break; + case SDLK_RETURN: + key = GBA_KEY_START; + break; + case SDLK_BACKSPACE: + key = GBA_KEY_SELECT; + break; + case SDLK_UP: + key = GBA_KEY_UP; + break; + case SDLK_DOWN: + key = GBA_KEY_DOWN; + break; + case SDLK_LEFT: + key = GBA_KEY_LEFT; + break; + case SDLK_RIGHT: + key = GBA_KEY_RIGHT; + break; + case SDLK_TAB: + context->renderer->turbo = !context->renderer->turbo; + return; + default: + return; + } + + if (event->type == SDL_KEYDOWN) { + context->activeKeys |= 1 << key; + } else { + context->activeKeys &= ~(1 << key); + } +} + +static void _GBASDLHandleJoyButton(struct GBAThread* context, const struct SDL_JoyButtonEvent* event) { + enum GBAKey key = 0; + // Sorry, hardcoded to my gamepad for now + switch (event->button) { + case 2: + key = GBA_KEY_A; + break; + case 1: + key = GBA_KEY_B; + break; + case 6: + key = GBA_KEY_L; + break; + case 7: + key = GBA_KEY_R; + break; + case 8: + key = GBA_KEY_START; + break; + case 9: + key = GBA_KEY_SELECT; + break; + default: + return; + } + + if (event->type == SDL_JOYBUTTONDOWN) { + context->activeKeys |= 1 << key; + } else { + context->activeKeys &= ~(1 << key); + } +} + +static void _GBASDLHandleJoyHat(struct GBAThread* context, const struct SDL_JoyHatEvent* event) { + enum GBAKey key = 0; + + if (event->value & SDL_HAT_UP) { + key |= 1 << GBA_KEY_UP; + } + if (event->value & SDL_HAT_LEFT) { + key |= 1 << GBA_KEY_LEFT; + } + if (event->value & SDL_HAT_DOWN) { + key |= 1 << GBA_KEY_DOWN; + } + if (event->value & SDL_HAT_RIGHT) { + key |= 1 << GBA_KEY_RIGHT; + } + + context->activeKeys &= ~((1 << GBA_KEY_UP) | (1 << GBA_KEY_LEFT) | (1 << GBA_KEY_DOWN) | (1 << GBA_KEY_RIGHT)); + context->activeKeys |= key; +} + +void GBASDLHandleEvent(struct GBAThread* context, const union SDL_Event* event) { + switch (event->type) { + case SDL_QUIT: + // FIXME: this isn't thread-safe + context->debugger->state = DEBUGGER_EXITING; + break; + case SDL_KEYDOWN: + case SDL_KEYUP: + _GBASDLHandleKeypress(context, &event->key); + break; + case SDL_JOYBUTTONDOWN: + case SDL_JOYBUTTONUP: + _GBASDLHandleJoyButton(context, &event->jbutton); + break; + case SDL_JOYHATMOTION: + _GBASDLHandleJoyHat(context, &event->jhat); + } +}
A
src/sdl/sdl-events.h
@@ -0,0 +1,13 @@
+#ifndef SDL_EVENTS_H +#define SDL_EVENTS_H + +#include "gba-thread.h" + +#include <SDL.h> + +int GBASDLInitEvents(void); +void GBASDLDeinitEvents(void); + +void GBASDLHandleEvent(struct GBAThread* context, const union SDL_Event* event); + +#endif