Update GBA-Slot Analog Address Map
This commit is contained in:
parent
2db26fb4e3
commit
43cab27a55
|
@ -27,40 +27,58 @@
|
||||||
#define ANGLE_TO_SHORT 10430.37835047f
|
#define ANGLE_TO_SHORT 10430.37835047f
|
||||||
/* (float) 0x1000 */
|
/* (float) 0x1000 */
|
||||||
#define FLOAT_TO_FIXED 4096.0f
|
#define FLOAT_TO_FIXED 4096.0f
|
||||||
|
/* Open-Bus Value (mask) */
|
||||||
|
#define OPEN_BUS 0xAFFF
|
||||||
|
|
||||||
static u16 state[4];
|
static u16 analog_x, analog_y, analog_magnitude, analog_angle;
|
||||||
|
|
||||||
class Slot2_Analog : public ISlot2Interface {
|
class Slot2_Analog : public ISlot2Interface {
|
||||||
public:
|
public:
|
||||||
Slot2Info const* info() override {
|
Slot2Info const* info() override {
|
||||||
static Slot2InfoSimple info("Analog Stick", "Analog Stick input for Modded SM64DS", 0x09);
|
static Slot2InfoSimple info("Analog Stick", "Analog Stick Input", 0x09);
|
||||||
return &info;
|
return &info;
|
||||||
}
|
}
|
||||||
|
|
||||||
void connect() override {
|
void connect() override {
|
||||||
std::memset(state, 0, sizeof(state));
|
analog_x = analog_y = 0;
|
||||||
}
|
analog_magnitude = analog_angle = 0;
|
||||||
|
|
||||||
u8 readByte(u8 PROCNUM, u32 addr) override {
|
|
||||||
if ((addr & 0xFFFFFFF8) != 0x09000000)
|
|
||||||
return 0xFF;
|
|
||||||
else if ((addr & 1) == 0)
|
|
||||||
return (u8) state[(addr & 6) >> 1];
|
|
||||||
else
|
|
||||||
return (u8) (state[(addr & 6) >> 1] >> 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 readWord(u8 PROCNUM, u32 addr) override {
|
u16 readWord(u8 PROCNUM, u32 addr) override {
|
||||||
if ((addr & 0xFFFFFFF8) != 0x09000000)
|
if ((addr & 0xFF000000) != 0x09000000) return OPEN_BUS;
|
||||||
return 0xFFFF;
|
switch ((addr >> 8) & 0xFFFF) {
|
||||||
return state[(addr & 6) >> 1];
|
case 0: // Generic
|
||||||
|
switch (addr & 0xFF) {
|
||||||
|
// 0x00 and 0x01 are reserved to match the output
|
||||||
|
// of any physical device made for this purpose.
|
||||||
|
// 0x02 through 0x07 are reserved for future DeSmuME use
|
||||||
|
case 0x08: return analog_x;
|
||||||
|
case 0x0A: return analog_y;
|
||||||
|
default: return OPEN_BUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1: // AM64DS
|
||||||
|
// Matches the layout of values used in SM64DS
|
||||||
|
switch (addr & 0xFF) {
|
||||||
|
case 0x00: return analog_magnitude;
|
||||||
|
case 0x02: return analog_x;
|
||||||
|
case 0x04: return analog_y;
|
||||||
|
case 0x06: return analog_angle;
|
||||||
|
default: return OPEN_BUS;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// Available for future game-specific interfaces
|
||||||
|
return OPEN_BUS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 readByte(u8 PROCNUM, u32 addr) override {
|
||||||
|
return (readWord(PROCNUM, addr & ~((u32) 1)) >> ((addr & 1) * 8)) & 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 readLong(u8 PROCNUM, u32 addr) override {
|
u32 readLong(u8 PROCNUM, u32 addr) override {
|
||||||
if ((addr & 0xFFFFFFF8) != 0x09000000)
|
return (u32) readWord(PROCNUM, addr) | ((u32) readWord(PROCNUM, addr | 2) << 16);
|
||||||
return 0xFFFFFFFF;
|
|
||||||
int i = (addr & 4) >> 1;
|
|
||||||
return ((u32) state[i]) | ((u32) state[i + 1] << 16);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,8 +93,8 @@ void analog_setValue(float x, float y) {
|
||||||
mag = 1.0f;
|
mag = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
state[0] = static_cast<u16>(std::lround(mag * FLOAT_TO_FIXED));
|
analog_x = static_cast<u16>(std::lround(x * FLOAT_TO_FIXED));
|
||||||
state[1] = static_cast<u16>(std::lround( x * FLOAT_TO_FIXED));
|
analog_y = static_cast<u16>(std::lround(y * FLOAT_TO_FIXED));
|
||||||
state[2] = static_cast<u16>(std::lround( y * FLOAT_TO_FIXED));
|
analog_magnitude = static_cast<u16>(std::lround(mag * FLOAT_TO_FIXED));
|
||||||
state[3] = static_cast<u16>(std::lround(ang * ANGLE_TO_SHORT));
|
analog_angle = static_cast<u16>(std::lround(ang * ANGLE_TO_SHORT));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue