Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions aurora-main/cmake/AuroraSDL3Patches.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,44 @@ static void UpdateDeviceIdentity(SDL_HIDAPI_Device *device)
now = SDL_GetTicks();
]==])

# Classic Controller sticks: the stock path stretches each half-range by learned min/max;
# this posts WPAD's linear value (raw - first-report centre) * unit, times 64.
_aurora_sdl3_replace("${_wii}" "Wii Classic Controller linear sticks (helper)"
[==[static void HandleGamepadControllerButtonData(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick, const WiiButtonData *data)
{
]==]
[==[/* WiiCompiled: axis = (raw - centre) * unit * 64, y inverted; see AuroraSDL3Patches.cmake */
static void PostClassicStickLinear(Uint64 timestamp, SDL_Joystick *joystick, StickCalibrationData *calibration, Uint8 axis, Uint16 data, int unit)
{
int value;

if (!calibration->center) {
// Center on first read
calibration->center = data;
return;
}
value = ((int)data - (int)calibration->center) * unit * 64;
if (axis == SDL_GAMEPAD_AXIS_LEFTY || axis == SDL_GAMEPAD_AXIS_RIGHTY) {
value = -value;
}
SDL_SendJoystickAxis(timestamp, joystick, axis, (Sint16)SDL_clamp(value, SDL_JOYSTICK_AXIS_MIN, SDL_JOYSTICK_AXIS_MAX));
}

static void HandleGamepadControllerButtonData(SDL_DriverWii_Context *ctx, SDL_Joystick *joystick, const WiiButtonData *data)
{
]==])
_aurora_sdl3_replace("${_wii}" "Wii Classic Controller linear sticks (axes)"
[==[ PostStickCalibrated(ctx->timestamp, joystick, &ctx->m_StickCalibrationData[0], SDL_GAMEPAD_AXIS_LEFTX, lx);
PostStickCalibrated(ctx->timestamp, joystick, &ctx->m_StickCalibrationData[1], SDL_GAMEPAD_AXIS_LEFTY, ly);
PostStickCalibrated(ctx->timestamp, joystick, &ctx->m_StickCalibrationData[2], SDL_GAMEPAD_AXIS_RIGHTX, rx);
PostStickCalibrated(ctx->timestamp, joystick, &ctx->m_StickCalibrationData[3], SDL_GAMEPAD_AXIS_RIGHTY, ry);
]==]
[==[ PostClassicStickLinear(ctx->timestamp, joystick, &ctx->m_StickCalibrationData[0], SDL_GAMEPAD_AXIS_LEFTX, lx, 16);
PostClassicStickLinear(ctx->timestamp, joystick, &ctx->m_StickCalibrationData[1], SDL_GAMEPAD_AXIS_LEFTY, ly, 16);
PostClassicStickLinear(ctx->timestamp, joystick, &ctx->m_StickCalibrationData[2], SDL_GAMEPAD_AXIS_RIGHTX, rx, 32);
PostClassicStickLinear(ctx->timestamp, joystick, &ctx->m_StickCalibrationData[3], SDL_GAMEPAD_AXIS_RIGHTY, ry, 32);
]==])

# Wii Remote: decode the accelerometer with the factory calibration from the EEPROM.
_aurora_sdl3_replace("${_wii}" "Wii Remote accelerometer calibration (context fields)"
[==[ StickCalibrationData m_StickCalibrationData[6];
Expand Down
37 changes: 25 additions & 12 deletions runtime/src/wii_remote_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -603,15 +603,30 @@ void FillGraceSample(uint32_t chan, Kind kind, KpadSample& sample) {
sample.hasClassic = kind == Kind::RemoteWithClassic;
}

// SDL's stick axis (-32767..32767, y down) as WPADCLStatus carries it: WPAD
// normalises every Classic Controller stick, whatever the report's resolution,
// to a signed 10-bit value, -512..511 with 0 at the centre and +y up (RVL SDK
// WPAD.h; wut's WPADStatusClassic documents the same range).
// The patched SDL Wii driver posts Classic Controller sticks as WPAD's own
// value times 64 (aurora-main/cmake/AuroraSDL3Patches.cmake), so WPADCLStatus
// is the axis divided back: signed, 0 at the centre, -512..511, +y up.
int16_t ClassicStickRaw(Sint16 axis, bool invert) {
float value = static_cast<float>(axis) / 32767.0f;
if (invert) value = -value;
value = std::clamp(value, -1.0f, 1.0f);
return static_cast<int16_t>(std::clamp(std::lround(value * 512.0f), -512L, 511L));
const long value = invert ? -static_cast<long>(axis) : axis;
return static_cast<int16_t>(std::clamp(std::lround(value / 64.0), -512L, 511L));
}

// KPAD's default Classic Controller stick limits; the game uses the cross clamp.
constexpr float kKpadStickMin = 60.0f;
constexpr float kKpadStickMax = 308.0f;

// KPAD cross clamp: per-axis dead zone and scale, then the unit circle.
void ClassicStickFloat(const int16_t raw[2], float out[2]) {
for (int i = 0; i < 2; ++i) {
const float magnitude = std::fabs(static_cast<float>(raw[i]));
const float scaled = std::clamp((magnitude - kKpadStickMin) / (kKpadStickMax - kKpadStickMin), 0.0f, 1.0f);
out[i] = raw[i] < 0 ? -scaled : scaled;
}
const float length = std::sqrt(out[0] * out[0] + out[1] * out[1]);
if (length > 1.0f) {
out[0] /= length;
out[1] /= length;
}
}

// Samples buttons, accelerometers and the extension of the remote on a port.
Expand Down Expand Up @@ -697,14 +712,12 @@ bool ReadKpadSample(uint32_t chan, KpadSample& sample) {
const Sint16 ly = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTY);
const Sint16 rx = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX);
const Sint16 ry = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY);
sample.clLStick[0] = std::clamp(static_cast<float>(lx) / 32767.0f, -1.0f, 1.0f);
sample.clLStick[1] = std::clamp(-static_cast<float>(ly) / 32767.0f, -1.0f, 1.0f);
sample.clRStick[0] = std::clamp(static_cast<float>(rx) / 32767.0f, -1.0f, 1.0f);
sample.clRStick[1] = std::clamp(-static_cast<float>(ry) / 32767.0f, -1.0f, 1.0f);
sample.clLStickRaw[0] = ClassicStickRaw(lx, false);
sample.clLStickRaw[1] = ClassicStickRaw(ly, true);
sample.clRStickRaw[0] = ClassicStickRaw(rx, false);
sample.clRStickRaw[1] = ClassicStickRaw(ry, true);
ClassicStickFloat(sample.clLStickRaw, sample.clLStick);
ClassicStickFloat(sample.clRStickRaw, sample.clRStick);
// Only the full-press click of L/R reaches SDL; report it as a full pull.
sample.clTriggerL = (sample.clHold & kClL) ? 255 : 0;
sample.clTriggerR = (sample.clHold & kClR) ? 255 : 0;
Expand Down
Loading