GBA GPIO: Fix gyro read-out start (fixes #3141)

This commit is contained in:
Vicki Pfau 2024-04-05 00:10:09 -07:00
parent e61a324df2
commit 1f2d0d5056
8 changed files with 14 additions and 11 deletions

View File

@ -12,6 +12,7 @@ Emulation fixes:
- GB Video: Implement DMG-style sprite ordering - GB Video: Implement DMG-style sprite ordering
- GBA: Unhandled bkpt should be treated as an undefined exception - GBA: Unhandled bkpt should be treated as an undefined exception
- GBA GPIO: Fix tilt scale and orientation (fixes mgba.io/i/2703) - GBA GPIO: Fix tilt scale and orientation (fixes mgba.io/i/2703)
- GBA GPIO: Fix gyro read-out start (fixes mgba.io/i/3141)
- GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309) - GBA I/O: Fix HALTCNT access behavior (fixes mgba.io/i/2309)
- GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110) - GBA SIO: Fix MULTI mode SIOCNT bit 7 writes on secondary GBAs (fixes mgba.io/i/3110)
- GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722) - GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722)

View File

@ -320,18 +320,20 @@ void _gyroReadPins(struct GBACartridgeHardware* hw) {
return; return;
} }
// Write bit on falling edge
bool doOutput = hw->gyroEdge && !(hw->pinState & 2);
if (hw->pinState & 1) { if (hw->pinState & 1) {
if (gyro->sample) { if (gyro->sample) {
gyro->sample(gyro); gyro->sample(gyro);
} }
int32_t sample = gyro->readGyroZ(gyro); int32_t sample = gyro->readGyroZ(gyro);
// Normalize to ~12 bits, focused on 0x6C0 // Normalize to ~12 bits, focused on 0x700
hw->gyroSample = (sample >> 21) + 0x6C0; // Crop off an extra bit so that we can't go negative hw->gyroSample = (sample >> 21) + 0x700; // Crop off an extra bit so that we can't go negative
doOutput = true;
} }
if (hw->gyroEdge && !(hw->pinState & 2)) { if (doOutput) {
// Write bit on falling edge
unsigned bit = hw->gyroSample >> 15; unsigned bit = hw->gyroSample >> 15;
hw->gyroSample <<= 1; hw->gyroSample <<= 1;
_outputPins(hw, bit << 2); _outputPins(hw, bit << 2);

View File

@ -704,7 +704,7 @@ static int32_t _readTiltY(struct mRotationSource* source) {
static int32_t _readGyroZ(struct mRotationSource* source) { static int32_t _readGyroZ(struct mRotationSource* source) {
struct m3DSRotationSource* rotation = (struct m3DSRotationSource*) source; struct m3DSRotationSource* rotation = (struct m3DSRotationSource*) source;
return rotation->gyro.y << 18L; // Yes, y return rotation->gyro.y << 17L; // Yes, y
} }
static void _startRequestImage(struct mImageSource* source, unsigned w, unsigned h, int colorFormats) { static void _startRequestImage(struct mImageSource* source, unsigned w, unsigned h, int colorFormats) {

View File

@ -1390,7 +1390,7 @@ static void _updateRotation(struct mRotationSource* source) {
tiltY = sensorGetCallback(0, RETRO_SENSOR_ACCELEROMETER_Y) * 2e8f; tiltY = sensorGetCallback(0, RETRO_SENSOR_ACCELEROMETER_Y) * 2e8f;
} }
if (gyroEnabled) { if (gyroEnabled) {
gyroZ = sensorGetCallback(0, RETRO_SENSOR_GYROSCOPE_Z) * -1.1e9f; gyroZ = sensorGetCallback(0, RETRO_SENSOR_GYROSCOPE_Z) * -5.5e8f;
} }
} }

View File

@ -149,7 +149,7 @@ static int32_t _readTiltY(struct mRotationSource* source) {
static int32_t _readGyroZ(struct mRotationSource* source) { static int32_t _readGyroZ(struct mRotationSource* source) {
struct mSceRotationSource* rotation = (struct mSceRotationSource*) source; struct mSceRotationSource* rotation = (struct mSceRotationSource*) source;
return rotation->state.gyro.z * -0x10000000; return rotation->state.gyro.z * -0x8000000;
} }
static void _setRumble(struct mRumble* source, int enable) { static void _setRumble(struct mRumble* source, int enable) {

View File

@ -823,14 +823,14 @@ static void _mSDLRotationSample(struct mRotationSource* source) {
float theta[3]; float theta[3];
int count = SDL_GameControllerGetSensorData(controller, SDL_SENSOR_GYRO, theta, 3); int count = SDL_GameControllerGetSensorData(controller, SDL_SENSOR_GYRO, theta, 3);
if (count >= 0) { if (count >= 0) {
rotation->zDelta = theta[1] / -10.f; rotation->zDelta = theta[1] / -20.f;
} }
return; return;
} }
} }
#endif #endif
if (rotation->gyroZ >= 0) { if (rotation->gyroZ >= 0) {
rotation->zDelta = SDL_JoystickGetAxis(rotation->p->joystick->joystick, rotation->gyroZ) / 1.e5f; rotation->zDelta = SDL_JoystickGetAxis(rotation->p->joystick->joystick, rotation->gyroZ) / 2.e5f;
return; return;
} }

View File

@ -644,7 +644,7 @@ void _sampleRotation(struct mRotationSource* source) {
} }
tiltX = sixaxis.acceleration.x * 3e8f; tiltX = sixaxis.acceleration.x * 3e8f;
tiltY = sixaxis.acceleration.y * -3e8f; tiltY = sixaxis.acceleration.y * -3e8f;
gyroZ = sixaxis.angular_velocity.z * -1.1e9f; gyroZ = sixaxis.angular_velocity.z * -5.5e8f;
} }
int32_t _readTiltX(struct mRotationSource* source) { int32_t _readTiltX(struct mRotationSource* source) {

View File

@ -1731,7 +1731,7 @@ void _sampleRotation(struct mRotationSource* source) {
return; return;
} }
gyroZ = exp.mp.rz - 0x1FA0; gyroZ = exp.mp.rz - 0x1FA0;
gyroZ <<= 18; gyroZ <<= 17;
} }
int32_t _readTiltX(struct mRotationSource* source) { int32_t _readTiltX(struct mRotationSource* source) {