Compare commits

...

2 Commits

Author SHA1 Message Date
patchzyy c3cc0840eb merge main 2026-10-18 14:09:28 +02:00
patchzyy 3d4b29d9b9 Fix soft-drift 2026-10-18 11:34:19 +02:00
2 changed files with 63 additions and 12 deletions
+38
View File
@@ -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];
+25 -12
View File
@@ -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.
@@ -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;