From f246587a9d8eec1da3f7a83c35182ed0862b4afd Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Wed, 8 May 2013 16:31:32 -0700 Subject: [PATCH] Add support for (my) joystick --- CMakeLists.txt | 6 +- src/main.c | 64 ++------------------ src/sdl/main.c | 63 ++------------------ src/sdl/sdl-events.c | 137 +++++++++++++++++++++++++++++++++++++++++++ src/sdl/sdl-events.h | 13 ++++ 5 files changed, 165 insertions(+), 118 deletions(-) create mode 100644 src/sdl/sdl-events.c create mode 100644 src/sdl/sdl-events.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a8509009d..badcf54b0 100644 --- a/CMakeLists.txt +++ b/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}) diff --git a/src/main.c b/src/main.c index 9fca7beab..d70fcea7d 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,7 @@ #include "gba-thread.h" #include "gba.h" #include "renderers/video-glsl.h" +#include "sdl-events.h" #include #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 @@ static int _GBASDLInit() { 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 @@ static void _GBASDLRunloop(struct GBAThread* context, struct GBAVideoGLSLRendere 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 _GBASDLRunloop(struct GBAThread* context, struct GBAVideoGLSLRendere } 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); - } -} diff --git a/src/sdl/main.c b/src/sdl/main.c index ee798d3f0..4cad51df6 100644 --- a/src/sdl/main.c +++ b/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 @@ -25,7 +26,6 @@ struct GLSoftwareRenderer { 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, @@ -83,6 +83,8 @@ static int _GBASDLInit(struct GLSoftwareRenderer* renderer) { 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); @@ -129,16 +131,7 @@ static void _GBASDLRunloop(struct GBAThread* context, struct GLSoftwareRenderer* 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 _GBASDLRunloop(struct GBAThread* context, struct GLSoftwareRenderer* 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); - } -} diff --git a/src/sdl/sdl-events.c b/src/sdl/sdl-events.c new file mode 100644 index 000000000..440c4efe3 --- /dev/null +++ b/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); + } +} diff --git a/src/sdl/sdl-events.h b/src/sdl/sdl-events.h new file mode 100644 index 000000000..a9e718560 --- /dev/null +++ b/src/sdl/sdl-events.h @@ -0,0 +1,13 @@ +#ifndef SDL_EVENTS_H +#define SDL_EVENTS_H + +#include "gba-thread.h" + +#include + +int GBASDLInitEvents(void); +void GBASDLDeinitEvents(void); + +void GBASDLHandleEvent(struct GBAThread* context, const union SDL_Event* event); + +#endif