all repos — mgba @ b97be4b461101be20a4522ee939fa277b53fd0bf

mGBA Game Boy Advance Emulator

SDL: Add ability to control gyro sensor with left analog stick (currently hardcoded)
Jeffrey Pfau jeffrey@endrift.com
Mon, 20 Apr 2015 22:15:57 -0700
commit

b97be4b461101be20a4522ee939fa277b53fd0bf

parent

7fa043cb501644b6bab6c66758a597805eff9d84

M src/platform/qt/InputController.cppsrc/platform/qt/InputController.cpp

@@ -66,6 +66,10 @@ InputController::~InputController() {

GBAInputMapDeinit(&m_inputMap); #ifdef BUILD_SDL + if (m_playerAttached) { + GBASDLDetachPlayer(&s_sdlEvents, &m_sdlPlayer); + } + --s_sdlInited; if (s_sdlInited == 0) { GBASDLDeinitEvents(&s_sdlEvents);
M src/platform/sdl/main.csrc/platform/sdl/main.c

@@ -134,6 +134,7 @@ freeArguments(&args);

GBAConfigFreeOpts(&opts); GBAConfigDeinit(&config); free(context.debugger); + GBASDLDetachPlayer(&renderer.events, &renderer.player); GBAInputMapDeinit(&inputMap); GBASDLDeinit(&renderer);
M src/platform/sdl/sdl-events.csrc/platform/sdl/sdl-events.c

@@ -20,9 +20,12 @@ #else

#define GUI_MOD KMOD_CTRL #endif +#define GYRO_STEPS 100 + static void _GBASDLSetRumble(struct GBARumble* rumble, int enable); static int32_t _GBASDLReadTiltX(struct GBARotationSource* rumble); static int32_t _GBASDLReadTiltY(struct GBARotationSource* rumble); +static int32_t _GBASDLReadGyroZ(struct GBARotationSource* rumble); static void _GBASDLRotationSample(struct GBARotationSource* source); bool GBASDLInitEvents(struct GBASDLEvents* context) {

@@ -151,10 +154,15 @@ #endif

player->rotation.d.readTiltX = _GBASDLReadTiltX; player->rotation.d.readTiltY = _GBASDLReadTiltY; - player->rotation.d.readGyroZ = 0; + player->rotation.d.readGyroZ = _GBASDLReadGyroZ; player->rotation.d.sample = _GBASDLRotationSample; player->rotation.axisX = 2; player->rotation.axisY = 3; + player->rotation.gyroSensitivity = 2.2e9f; + player->rotation.gyroX = 0; + player->rotation.gyroY = 1; + player->rotation.zDelta = 0; + CircleBufferInit(&player->rotation.zHistory, sizeof(float) * GYRO_STEPS); player->rotation.p = player; if (events->playersAttached >= MAX_PLAYERS) {

@@ -213,6 +221,11 @@ }

++events->playersAttached; return true; +} + +void GBASDLDetachPlayer(struct GBASDLEvents* events, struct GBASDLPlayer* player) { + events->joysticksClaimed[player->playerId] = SIZE_MAX; + CircleBufferDeinit(&player->rotation.zHistory); } void GBASDLPlayerLoadConfig(struct GBASDLPlayer* context, const struct Configuration* config) {

@@ -472,7 +485,34 @@ static int32_t _GBASDLReadTiltY(struct GBARotationSource* source) {

struct GBASDLRotation* rotation = (struct GBASDLRotation*) source; return _readTilt(rotation->p, rotation->axisY); } + +static int32_t _GBASDLReadGyroZ(struct GBARotationSource* source) { + struct GBASDLRotation* rotation = (struct GBASDLRotation*) source; + float z = rotation->zDelta; + return z * rotation->gyroSensitivity; +} + static void _GBASDLRotationSample(struct GBARotationSource* source) { - UNUSED(source); + struct GBASDLRotation* rotation = (struct GBASDLRotation*) source; SDL_JoystickUpdate(); + + int x = SDL_JoystickGetAxis(rotation->p->joystick, rotation->gyroX); + int y = SDL_JoystickGetAxis(rotation->p->joystick, rotation->gyroY); + float theta = atan2f(y, x) - atan2f(rotation->oldY, rotation->oldX); + if (isnan(theta)) { + theta = 0.0f; + } else if (theta > M_PI) { + theta -= 2.0f * M_PI; + } else if (theta < -M_PI) { + theta += 2.0f * M_PI; + } + rotation->oldX = x; + rotation->oldY = y; + + float oldZ = 0; + if (CircleBufferSize(&rotation->zHistory) == GYRO_STEPS * sizeof(float)) { + CircleBufferRead32(&rotation->zHistory, (int32_t*) &oldZ); + } + CircleBufferWrite32(&rotation->zHistory, *(int32_t*) &theta); + rotation->zDelta += theta - oldZ; }
M src/platform/sdl/sdl-events.hsrc/platform/sdl/sdl-events.h

@@ -7,6 +7,7 @@ #ifndef SDL_EVENTS_H

#define SDL_EVENTS_H #include "util/common.h" +#include "util/circle-buffer.h" #include "gba/supervisor/thread.h"

@@ -51,8 +52,19 @@

struct GBASDLRotation { struct GBARotationSource d; struct GBASDLPlayer* p; + + // Tilt int axisX; int axisY; + + // Gyro + int gyroX; + int gyroY; + float gyroSensitivity; + struct CircleBuffer zHistory; + int oldX; + int oldY; + float zDelta; } rotation; };

@@ -60,6 +72,7 @@ bool GBASDLInitEvents(struct GBASDLEvents*);

void GBASDLDeinitEvents(struct GBASDLEvents*); bool GBASDLAttachPlayer(struct GBASDLEvents*, struct GBASDLPlayer*); +void GBASDLDetachPlayer(struct GBASDLEvents*, struct GBASDLPlayer*); void GBASDLEventsLoadConfig(struct GBASDLEvents*, const struct Configuration*); void GBASDLPlayerChangeJoystick(struct GBASDLEvents*, struct GBASDLPlayer*, size_t index);