mirror of https://github.com/mgba-emu/mgba.git
GBA: Implement tilt sensor
This commit is contained in:
parent
c9b8254971
commit
c141063101
|
@ -364,6 +364,60 @@ void _lightReadPins(struct GBACartridgeGPIO* gpio) {
|
||||||
|
|
||||||
void GBAGPIOInitTilt(struct GBACartridgeGPIO* gpio) {
|
void GBAGPIOInitTilt(struct GBACartridgeGPIO* gpio) {
|
||||||
gpio->gpioDevices |= GPIO_TILT;
|
gpio->gpioDevices |= GPIO_TILT;
|
||||||
|
gpio->tiltX = 0xFFF;
|
||||||
|
gpio->tiltY = 0xFFF;
|
||||||
|
gpio->tiltState = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GBAGPIOTiltWrite(struct GBACartridgeGPIO* gpio, uint32_t address, uint8_t value) {
|
||||||
|
switch (address) {
|
||||||
|
case 0x8000:
|
||||||
|
if (value == 0x55) {
|
||||||
|
gpio->tiltState = 1;
|
||||||
|
} else {
|
||||||
|
GBALog(0, GBA_LOG_GAME_ERROR, "Tilt sensor wrote wrong byte to %04x: %02x", address, value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x8100:
|
||||||
|
if (value == 0xAA && gpio->tiltState == 1) {
|
||||||
|
gpio->tiltState = 0;
|
||||||
|
struct GBARotationSource* rotationSource = gpio->p->rotationSource;
|
||||||
|
if (!rotationSource || !rotationSource->readTiltX || !rotationSource->readTiltY) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (rotationSource->sample) {
|
||||||
|
rotationSource->sample(rotationSource);
|
||||||
|
}
|
||||||
|
int32_t x = rotationSource->readTiltX(rotationSource);
|
||||||
|
int32_t y = rotationSource->readTiltY(rotationSource);
|
||||||
|
// Normalize to ~12 bits, focused on 0x3A0
|
||||||
|
gpio->tiltX = (x >> 21) + 0x3A0; // Crop off an extra bit so that we can't go negative
|
||||||
|
gpio->tiltY = (y >> 21) + 0x3A0;
|
||||||
|
} else {
|
||||||
|
GBALog(0, GBA_LOG_GAME_ERROR, "Tilt sensor wrote wrong byte to %04x: %02x", address, value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
GBALog(0, GBA_LOG_GAME_ERROR, "Invalid tilt sensor write to %04x: %02x", address, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t GBAGPIOTiltRead(struct GBACartridgeGPIO* gpio, uint32_t address) {
|
||||||
|
switch (address) {
|
||||||
|
case 0x8200:
|
||||||
|
return gpio->tiltX & 0xFF;
|
||||||
|
case 0x8300:
|
||||||
|
return ((gpio->tiltX >> 8) & 0xF) | 0x80;
|
||||||
|
case 0x8400:
|
||||||
|
return gpio->tiltY & 0xFF;
|
||||||
|
case 0x8500:
|
||||||
|
return (gpio->tiltY >> 8) & 0xF;
|
||||||
|
default:
|
||||||
|
GBALog(0, GBA_LOG_GAME_ERROR, "Invalid tilt sensor read from %04x", address);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
// == Serialization
|
// == Serialization
|
||||||
|
|
|
@ -107,6 +107,10 @@ struct GBACartridgeGPIO {
|
||||||
unsigned lightCounter : 12;
|
unsigned lightCounter : 12;
|
||||||
uint8_t lightSample;
|
uint8_t lightSample;
|
||||||
bool lightEdge;
|
bool lightEdge;
|
||||||
|
|
||||||
|
uint16_t tiltX;
|
||||||
|
uint16_t tiltY;
|
||||||
|
int tiltState;
|
||||||
};
|
};
|
||||||
|
|
||||||
void GBAGPIOInit(struct GBACartridgeGPIO* gpio, uint16_t* gpioBase);
|
void GBAGPIOInit(struct GBACartridgeGPIO* gpio, uint16_t* gpioBase);
|
||||||
|
@ -118,6 +122,9 @@ void GBAGPIOInitRumble(struct GBACartridgeGPIO* gpio);
|
||||||
void GBAGPIOInitLightSensor(struct GBACartridgeGPIO* gpio);
|
void GBAGPIOInitLightSensor(struct GBACartridgeGPIO* gpio);
|
||||||
void GBAGPIOInitTilt(struct GBACartridgeGPIO* gpio);
|
void GBAGPIOInitTilt(struct GBACartridgeGPIO* gpio);
|
||||||
|
|
||||||
|
void GBAGPIOTiltWrite(struct GBACartridgeGPIO* gpio, uint32_t address, uint8_t value);
|
||||||
|
uint8_t GBAGPIOTiltRead(struct GBACartridgeGPIO* gpio, uint32_t address);
|
||||||
|
|
||||||
struct GBASerializedState;
|
struct GBASerializedState;
|
||||||
void GBAGPIOSerialize(struct GBACartridgeGPIO* gpio, struct GBASerializedState* state);
|
void GBAGPIOSerialize(struct GBACartridgeGPIO* gpio, struct GBASerializedState* state);
|
||||||
void GBAGPIODeserialize(struct GBACartridgeGPIO* gpio, struct GBASerializedState* state);
|
void GBAGPIODeserialize(struct GBACartridgeGPIO* gpio, struct GBASerializedState* state);
|
||||||
|
|
|
@ -449,8 +449,7 @@ int8_t GBALoad8(struct ARMCore* cpu, uint32_t address, int* cycleCounter) {
|
||||||
} else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
|
} else if (memory->savedata.type == SAVEDATA_FLASH512 || memory->savedata.type == SAVEDATA_FLASH1M) {
|
||||||
value = GBASavedataReadFlash(&memory->savedata, address);
|
value = GBASavedataReadFlash(&memory->savedata, address);
|
||||||
} else if (memory->gpio.gpioDevices & GPIO_TILT) {
|
} else if (memory->gpio.gpioDevices & GPIO_TILT) {
|
||||||
GBALog(gba, GBA_LOG_STUB, "Unimplemented tilt sensor read: 0x%08X", address);
|
value = GBAGPIOTiltRead(&memory->gpio, address & OFFSET_MASK);
|
||||||
value = 0xFF;
|
|
||||||
} else {
|
} else {
|
||||||
GBALog(gba, GBA_LOG_GAME_ERROR, "Reading from non-existent SRAM: 0x%08X", address);
|
GBALog(gba, GBA_LOG_GAME_ERROR, "Reading from non-existent SRAM: 0x%08X", address);
|
||||||
value = 0xFF;
|
value = 0xFF;
|
||||||
|
@ -667,7 +666,7 @@ void GBAStore8(struct ARMCore* cpu, uint32_t address, int8_t value, int* cycleCo
|
||||||
} else if (memory->savedata.type == SAVEDATA_SRAM) {
|
} else if (memory->savedata.type == SAVEDATA_SRAM) {
|
||||||
memory->savedata.data[address & (SIZE_CART_SRAM - 1)] = value;
|
memory->savedata.data[address & (SIZE_CART_SRAM - 1)] = value;
|
||||||
} else if (memory->gpio.gpioDevices & GPIO_TILT) {
|
} else if (memory->gpio.gpioDevices & GPIO_TILT) {
|
||||||
GBALog(gba, GBA_LOG_STUB, "Unimplemented tilt sensor write: 0x%08X", address);
|
GBAGPIOTiltWrite(&memory->gpio, address & OFFSET_MASK, value);
|
||||||
} else {
|
} else {
|
||||||
GBALog(gba, GBA_LOG_GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
|
GBALog(gba, GBA_LOG_GAME_ERROR, "Writing to non-existent SRAM: 0x%08X", address);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue