forked from Ports/goldeneye-pc-port
input: implement Wave A controller options + Turok-verbatim labels (v0.5.0)
Port-layer only (port/src/input.c, optionsoverlay.c); zero src/game edits. All new knobs off/neutral at default = byte-identical at defaults. New controller input options (CONTROLLER-INPUT-PLAN Wave A): - Input.PadLookSensX/Y: per-axis right-stick look sensitivity (100 = native) - Input.PadSouthpaw: swap fire<->grenade triggers (applied after edge capture, so edge-detection stays consistent) - Input.PadDeadzoneL/R: per-stick deadzone; legacy Input.PadDeadzone key kept registered (no row) + one-time migration in inputInit() seeds any unset L/R from it (C-init sentinel PAD_DZ_UNSET) before the first configSave - Input.PadLookSmooth: 0-10 per-pad EMA low-pass on the natural-pitch look output (default 0 = off), reset on pad hot-unplug - Input.MouseYScale: pre-existing registered key finally gets an INPUT row Verbiage baseline (Turok PC options menu, user-provided verbatim): Mouse horizontal/vertical sensitivity, X axis/Y axis look sensitivity, Look smoothing, Southpaw, Vibration (was "Rumble strength"), Deadzone (left/right stick). GE keeps one flat INPUT section (D356), so the two Invert-look rows retain their (mouse)/(controller) suffixes. Display baseline (Turok scales): sensitivity + deadzone rows render 0-100 with 50 = default (existing calibratedDefault path); look smoothing renders 0-10 via a new dispMax "N/M" row formatter (alongside the existing N/100 and N/255 special cases). Tested on a real pad (Windows build) - all six options behave as intended.
This commit is contained in:
1 parent
83ece6c370
commit
39d1fd381e
3 files changed
+163
-21
No files matched your search
+68
-14
@@ -520,10 +520,27 @@ static int naturalPitchMode = 1; /* D194/D238: 1 = force GE's own 1.2/SOLITAR
|
||||
* 0 = legacy 1.1/HONEY + D166 digital pulse. */
|
||||
static Uint64 s_lastLookPollCounter = 0; /* D194(b): monotonic clock, gameplay-look drain only */
|
||||
|
||||
/* Gamepad tuning -- defaults reproduce the old hardcoded constants exactly. */
|
||||
static int padDeadzone = STICK_DEADZONE; /* left-stick deadzone, raw 0..32767 */
|
||||
static int padTriggerPct = 23; /* trigger press point, % of travel (~30*256) */
|
||||
static int padLookInvertY = 0; /* 1 = invert right-stick (look) Y */
|
||||
/* Gamepad tuning -- defaults reproduce the old hardcoded constants exactly.
|
||||
* Wave A (v0.5.0 controller/input wave, docs/dev/CONTROLLER-INPUT-PLAN.md):
|
||||
* per-stick deadzone splits the single Input.PadDeadzone into a left (movement)
|
||||
* and a right (look) value (padDeadzone stays registered so old inis load; the
|
||||
* unset L/R values migrate from it once in inputInit). The look knobs
|
||||
* (sens X/Y, smoothing) are feel-only and identity at their defaults. */
|
||||
#define PAD_DZ_UNSET (-1) /* C init for padDeadzoneL/R: "not in ini -> migrate" */
|
||||
static int padDeadzoneL = PAD_DZ_UNSET; /* left (movement) stick deadzone, raw 0..32767 */
|
||||
static int padDeadzoneR = PAD_DZ_UNSET; /* right (look) stick deadzone, raw 0..32767 */
|
||||
static int padDeadzone = STICK_DEADZONE; /* legacy shared deadzone (Input.PadDeadzone) */
|
||||
static int padLookSensX = 100; /* right-stick look: horizontal sensitivity, % (100 = native) */
|
||||
static int padLookSensY = 100; /* right-stick look: vertical (pitch) sensitivity, % */
|
||||
static int padSouthpaw = 0; /* 1 = swap fire (G) / grenade (R) trigger actions */
|
||||
static int padLookSmooth = 0; /* right-stick look low-pass strength, 0-10 (0 = off, 10 = max) */
|
||||
static int padTriggerPct = 23; /* trigger press point, % of travel (~30*256) */
|
||||
static int padLookInvertY = 0; /* 1 = invert right-stick (look) Y */
|
||||
/* Per-pad look-smoothing EMA state (Wave A item 5), one X/Y pair per pad. Reset
|
||||
* on hot-unplug (inputRescanPads) so a smoothed value can't stick after the
|
||||
* stick snaps back; the low-pass otherwise recentres it toward 0 on its own. */
|
||||
static double padSmSX[MAX_PADS] = {0};
|
||||
static double padSmSY[MAX_PADS] = {0};
|
||||
|
||||
/* Smoothed mouse delta carried between polls when mouseSmoothing > 0. */
|
||||
static double mouseSmDX = 0.0, mouseSmDY = 0.0;
|
||||
@@ -848,6 +865,13 @@ int inputInit(void)
|
||||
|
||||
inputMigrateBinds(); /* D380: materialise effective GEPD defaults once */
|
||||
inputRebuildBinds(); /* D214: parse [Bind] now that configLoad() has run */
|
||||
|
||||
/* Wave A: one-time per-stick deadzone migration. Old inis carry a single
|
||||
* Input.PadDeadzone; if the player has not set the new per-stick keys, seed
|
||||
* both from it (the C-init sentinel PAD_DZ_UNSET means "not in the ini").
|
||||
* Runs before any configSave, so the saved L/R values are always valid. */
|
||||
if (padDeadzoneL == PAD_DZ_UNSET) padDeadzoneL = padDeadzone;
|
||||
if (padDeadzoneR == PAD_DZ_UNSET) padDeadzoneR = padDeadzone;
|
||||
if (getenv("GE_BINDPROBE")) inputBindingProbe();
|
||||
|
||||
sysLogPrintf(LOG_INFO, "input: PC bindings, crouch mode %s",
|
||||
@@ -912,9 +936,8 @@ void inputUpdate(void)
|
||||
mouseDY += dy;
|
||||
}
|
||||
|
||||
static int scaleAxis(int v)
|
||||
static int scaleAxis(int v, int dz)
|
||||
{
|
||||
int dz = padDeadzone;
|
||||
if (dz < 0) dz = 0;
|
||||
if (dz > 30000) dz = 30000;
|
||||
if (v > -dz && v < dz) {
|
||||
@@ -1916,8 +1939,8 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
|
||||
current_menu != GE_MENU_INVALID);
|
||||
|
||||
if (padMenuMode) {
|
||||
int px = scaleAxis(lx);
|
||||
int py = -scaleAxis(ly); /* SDL up = negative -> N64 up = positive */
|
||||
int px = scaleAxis(lx, padDeadzoneL);
|
||||
int py = -scaleAxis(ly, padDeadzoneL); /* SDL up = negative -> N64 up = positive */
|
||||
if (px) sx = px;
|
||||
if (py) sy = py;
|
||||
} else if (naturalPitchMode) {
|
||||
@@ -1931,15 +1954,30 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
|
||||
if (lx < -RSTICK_THRESHOLD) button |= GE_CONT_C; /* strafe left */
|
||||
if (lx > RSTICK_THRESHOLD) button |= GE_CONT_F; /* strafe right */
|
||||
|
||||
int rxs = scaleAxis(rx);
|
||||
if (rxs || scaleAxis(ry)) s_aimDevMouse = 0; /* D337: pad aim active */
|
||||
int rys = -scaleAxis(ry); /* SDL up = negative -> N64 up = positive */
|
||||
/* Wave A (v0.5.0): right-stick look -- per-stick deadzone (right),
|
||||
* per-axis sensitivity (% of native, 100 = unchanged, re-clamped to
|
||||
* STICK_MAX), and an optional low-pass. All feel-only, identity at
|
||||
* their defaults (sens 100%, smoothing off). */
|
||||
int rxs = scaleAxis(rx, padDeadzoneR);
|
||||
int rys = -scaleAxis(ry, padDeadzoneR); /* SDL up = negative -> N64 up = positive */
|
||||
if (padLookSensX != 100 && rxs) rxs = rxs * padLookSensX / 100;
|
||||
if (padLookSensY != 100 && rys) rys = rys * padLookSensY / 100;
|
||||
if (rxs > STICK_MAX) rxs = STICK_MAX; else if (rxs < -STICK_MAX) rxs = -STICK_MAX;
|
||||
if (rys > STICK_MAX) rys = STICK_MAX; else if (rys < -STICK_MAX) rys = -STICK_MAX;
|
||||
if (rxs || rys) s_aimDevMouse = 0; /* D337: pad aim active */
|
||||
if (padLookSmooth > 0) {
|
||||
double a = padLookSmooth * 0.09; /* 10 -> 0.9 (heaviest); 0 = off */
|
||||
padSmSX[idx] = padSmSX[idx] * a + (double)rxs * (1.0 - a);
|
||||
padSmSY[idx] = padSmSY[idx] * a + (double)rys * (1.0 - a);
|
||||
rxs = (int)lround(padSmSX[idx]);
|
||||
rys = (int)lround(padSmSY[idx]);
|
||||
}
|
||||
if (padLookInvertY) rys = -rys;
|
||||
if (rxs) sx = rxs;
|
||||
if (rys) sy = rys;
|
||||
} else {
|
||||
int px = scaleAxis(lx);
|
||||
int py = -scaleAxis(ly); /* SDL up = negative -> N64 up = positive */
|
||||
int px = scaleAxis(lx, padDeadzoneL);
|
||||
int py = -scaleAxis(ly, padDeadzoneL); /* SDL up = negative -> N64 up = positive */
|
||||
if (px) sx = px;
|
||||
if (py) sy = py;
|
||||
if (px || py) s_aimDevMouse = 0; /* D337: pad aim active */
|
||||
@@ -1956,6 +1994,14 @@ unsigned inputComputePad(int idx, signed char *stick_x, signed char *stick_y)
|
||||
button |= GE_CONT_G;
|
||||
if (SDL_GameControllerGetAxis(pad, SDL_CONTROLLER_AXIS_TRIGGERLEFT) > trigPt)
|
||||
button |= GE_CONT_R;
|
||||
/* Wave A: southpaw swaps the fire (G) and grenade (R) trigger actions
|
||||
* (right<->left trigger), after the raw edges above are captured. */
|
||||
if (padSouthpaw) {
|
||||
int t = button;
|
||||
button = (t & ~(GE_CONT_G | GE_CONT_R))
|
||||
| ((t & GE_CONT_G) ? GE_CONT_R : 0)
|
||||
| ((t & GE_CONT_R) ? GE_CONT_G : 0);
|
||||
}
|
||||
|
||||
/* Xbox 1.1 Jinx-style gameplay: A=use, X=reload (handled by the
|
||||
* keyboard action gate), B=gadgets, Y=weapons, stick clicks=crouch,
|
||||
@@ -2212,6 +2258,8 @@ void inputRescanPads(void)
|
||||
pads[i] = NULL;
|
||||
}
|
||||
padRumbleOn[i] = 0; /* D401: re-detected by inputOpenPads below */
|
||||
padSmSX[i] = 0.0; /* Wave A: clear the look-smoothing EMA so a stick
|
||||
padSmSY[i] = 0.0; * snap-back after re-plug can't lag from a stale value */
|
||||
}
|
||||
inputOpenPads();
|
||||
sysLogPrintf(LOG_NOTE, "input: rescanned pads (mask=0x%x, %d controller(s))",
|
||||
@@ -2569,7 +2617,13 @@ PD_CONSTRUCTOR static void inputConfigInit(void)
|
||||
configRegisterInt("Input.MouseSensitivity", &mouseSensitivity, 1, 500); /* D238 */
|
||||
configRegisterInt("Input.MouseAimCurve", &aimCurveGamma, 50, 400); /* D194(a), x100 */
|
||||
configRegisterInt("Input.NaturalPitch", &naturalPitchMode, 0, 1); /* D194/D238 */
|
||||
configRegisterInt("Input.PadDeadzone", &padDeadzone, 0, 30000);
|
||||
configRegisterInt("Input.PadDeadzone", &padDeadzone, 0, 30000); /* legacy; Wave A migrates to L/R */
|
||||
configRegisterInt("Input.PadDeadzoneL", &padDeadzoneL, 0, 30000); /* Wave A: left (movement) stick */
|
||||
configRegisterInt("Input.PadDeadzoneR", &padDeadzoneR, 0, 30000); /* Wave A: right (look) stick */
|
||||
configRegisterInt("Input.PadLookSensX", &padLookSensX, 25, 200); /* Wave A: look horizontal sensitivity (%) */
|
||||
configRegisterInt("Input.PadLookSensY", &padLookSensY, 25, 200); /* Wave A: look vertical (pitch) sensitivity (%) */
|
||||
configRegisterInt("Input.PadSouthpaw", &padSouthpaw, 0, 1); /* Wave A: swap fire/grenade triggers */
|
||||
configRegisterInt("Input.PadLookSmooth", &padLookSmooth, 0, 10); /* Wave A: look low-pass strength, 0-10 (0 = off) */
|
||||
configRegisterInt("Input.PadTriggerPct", &padTriggerPct, 1, 99);
|
||||
configRegisterInt("Input.PadLookInvertY", &padLookInvertY, 0, 1);
|
||||
/* D401: global rumble scale (0 = silent .. 1 = full), applied to every
|
||||
|
||||
Reference in new issue
Block a user