mirror of https://github.com/mgba-emu/mgba.git
SDL: Add ability to control gyro sensor with left analog stick (currently hardcoded)
This commit is contained in:
parent
7fa043cb50
commit
b97be4b461
|
@ -66,6 +66,10 @@ InputController::~InputController() {
|
||||||
GBAInputMapDeinit(&m_inputMap);
|
GBAInputMapDeinit(&m_inputMap);
|
||||||
|
|
||||||
#ifdef BUILD_SDL
|
#ifdef BUILD_SDL
|
||||||
|
if (m_playerAttached) {
|
||||||
|
GBASDLDetachPlayer(&s_sdlEvents, &m_sdlPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
--s_sdlInited;
|
--s_sdlInited;
|
||||||
if (s_sdlInited == 0) {
|
if (s_sdlInited == 0) {
|
||||||
GBASDLDeinitEvents(&s_sdlEvents);
|
GBASDLDeinitEvents(&s_sdlEvents);
|
||||||
|
|
|
@ -134,6 +134,7 @@ int main(int argc, char** argv) {
|
||||||
GBAConfigFreeOpts(&opts);
|
GBAConfigFreeOpts(&opts);
|
||||||
GBAConfigDeinit(&config);
|
GBAConfigDeinit(&config);
|
||||||
free(context.debugger);
|
free(context.debugger);
|
||||||
|
GBASDLDetachPlayer(&renderer.events, &renderer.player);
|
||||||
GBAInputMapDeinit(&inputMap);
|
GBAInputMapDeinit(&inputMap);
|
||||||
|
|
||||||
GBASDLDeinit(&renderer);
|
GBASDLDeinit(&renderer);
|
||||||
|
|
|
@ -20,9 +20,12 @@
|
||||||
#define GUI_MOD KMOD_CTRL
|
#define GUI_MOD KMOD_CTRL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define GYRO_STEPS 100
|
||||||
|
|
||||||
static void _GBASDLSetRumble(struct GBARumble* rumble, int enable);
|
static void _GBASDLSetRumble(struct GBARumble* rumble, int enable);
|
||||||
static int32_t _GBASDLReadTiltX(struct GBARotationSource* rumble);
|
static int32_t _GBASDLReadTiltX(struct GBARotationSource* rumble);
|
||||||
static int32_t _GBASDLReadTiltY(struct GBARotationSource* rumble);
|
static int32_t _GBASDLReadTiltY(struct GBARotationSource* rumble);
|
||||||
|
static int32_t _GBASDLReadGyroZ(struct GBARotationSource* rumble);
|
||||||
static void _GBASDLRotationSample(struct GBARotationSource* source);
|
static void _GBASDLRotationSample(struct GBARotationSource* source);
|
||||||
|
|
||||||
bool GBASDLInitEvents(struct GBASDLEvents* context) {
|
bool GBASDLInitEvents(struct GBASDLEvents* context) {
|
||||||
|
@ -151,10 +154,15 @@ bool GBASDLAttachPlayer(struct GBASDLEvents* events, struct GBASDLPlayer* player
|
||||||
|
|
||||||
player->rotation.d.readTiltX = _GBASDLReadTiltX;
|
player->rotation.d.readTiltX = _GBASDLReadTiltX;
|
||||||
player->rotation.d.readTiltY = _GBASDLReadTiltY;
|
player->rotation.d.readTiltY = _GBASDLReadTiltY;
|
||||||
player->rotation.d.readGyroZ = 0;
|
player->rotation.d.readGyroZ = _GBASDLReadGyroZ;
|
||||||
player->rotation.d.sample = _GBASDLRotationSample;
|
player->rotation.d.sample = _GBASDLRotationSample;
|
||||||
player->rotation.axisX = 2;
|
player->rotation.axisX = 2;
|
||||||
player->rotation.axisY = 3;
|
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;
|
player->rotation.p = player;
|
||||||
|
|
||||||
if (events->playersAttached >= MAX_PLAYERS) {
|
if (events->playersAttached >= MAX_PLAYERS) {
|
||||||
|
@ -215,6 +223,11 @@ bool GBASDLAttachPlayer(struct GBASDLEvents* events, struct GBASDLPlayer* player
|
||||||
return true;
|
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) {
|
void GBASDLPlayerLoadConfig(struct GBASDLPlayer* context, const struct Configuration* config) {
|
||||||
GBAInputMapLoad(context->bindings, SDL_BINDING_KEY, config);
|
GBAInputMapLoad(context->bindings, SDL_BINDING_KEY, config);
|
||||||
if (context->joystick) {
|
if (context->joystick) {
|
||||||
|
@ -472,7 +485,34 @@ static int32_t _GBASDLReadTiltY(struct GBARotationSource* source) {
|
||||||
struct GBASDLRotation* rotation = (struct GBASDLRotation*) source;
|
struct GBASDLRotation* rotation = (struct GBASDLRotation*) source;
|
||||||
return _readTilt(rotation->p, rotation->axisY);
|
return _readTilt(rotation->p, rotation->axisY);
|
||||||
}
|
}
|
||||||
static void _GBASDLRotationSample(struct GBARotationSource* source) {
|
|
||||||
UNUSED(source);
|
static int32_t _GBASDLReadGyroZ(struct GBARotationSource* source) {
|
||||||
SDL_JoystickUpdate();
|
struct GBASDLRotation* rotation = (struct GBASDLRotation*) source;
|
||||||
|
float z = rotation->zDelta;
|
||||||
|
return z * rotation->gyroSensitivity;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _GBASDLRotationSample(struct GBARotationSource* 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#define SDL_EVENTS_H
|
#define SDL_EVENTS_H
|
||||||
|
|
||||||
#include "util/common.h"
|
#include "util/common.h"
|
||||||
|
#include "util/circle-buffer.h"
|
||||||
|
|
||||||
#include "gba/supervisor/thread.h"
|
#include "gba/supervisor/thread.h"
|
||||||
|
|
||||||
|
@ -51,8 +52,19 @@ struct GBASDLPlayer {
|
||||||
struct GBASDLRotation {
|
struct GBASDLRotation {
|
||||||
struct GBARotationSource d;
|
struct GBARotationSource d;
|
||||||
struct GBASDLPlayer* p;
|
struct GBASDLPlayer* p;
|
||||||
|
|
||||||
|
// Tilt
|
||||||
int axisX;
|
int axisX;
|
||||||
int axisY;
|
int axisY;
|
||||||
|
|
||||||
|
// Gyro
|
||||||
|
int gyroX;
|
||||||
|
int gyroY;
|
||||||
|
float gyroSensitivity;
|
||||||
|
struct CircleBuffer zHistory;
|
||||||
|
int oldX;
|
||||||
|
int oldY;
|
||||||
|
float zDelta;
|
||||||
} rotation;
|
} rotation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,6 +72,7 @@ bool GBASDLInitEvents(struct GBASDLEvents*);
|
||||||
void GBASDLDeinitEvents(struct GBASDLEvents*);
|
void GBASDLDeinitEvents(struct GBASDLEvents*);
|
||||||
|
|
||||||
bool GBASDLAttachPlayer(struct GBASDLEvents*, struct GBASDLPlayer*);
|
bool GBASDLAttachPlayer(struct GBASDLEvents*, struct GBASDLPlayer*);
|
||||||
|
void GBASDLDetachPlayer(struct GBASDLEvents*, struct GBASDLPlayer*);
|
||||||
void GBASDLEventsLoadConfig(struct GBASDLEvents*, const struct Configuration*);
|
void GBASDLEventsLoadConfig(struct GBASDLEvents*, const struct Configuration*);
|
||||||
void GBASDLPlayerChangeJoystick(struct GBASDLEvents*, struct GBASDLPlayer*, size_t index);
|
void GBASDLPlayerChangeJoystick(struct GBASDLEvents*, struct GBASDLPlayer*, size_t index);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue