some controls for star wars trilogy wip

This commit is contained in:
izzy2lost
2026-01-12 16:06:57 -05:00
parent 856620d696
commit 2d70aaccb3
6 changed files with 137 additions and 42 deletions
@@ -121,20 +121,20 @@ InputAnalogJoyLeft = KEY_LEFT
InputAnalogJoyRight = KEY_RIGHT
InputAnalogJoyUp = KEY_UP
InputAnalogJoyDown = KEY_DOWN
InputAnalogJoyX = JOY_XAXIS,MOUSE_XAXIS
InputAnalogJoyY = JOY_YAXIS,MOUSE_YAXIS
InputAnalogJoyTrigger = KEY_A,JOY_BUTTON1,MOUSE_LEFT_BUTTON
InputAnalogJoyEvent = KEY_S,JOY_BUTTON2,MOUSE_RIGHT_BUTTON
InputAnalogJoyX = JOY_XAXIS,MOUSE_XAXIS_INV
InputAnalogJoyY = JOY_YAXIS,MOUSE_YAXIS_INV
InputAnalogJoyTrigger = KEY_A,KEY_W,JOY1_BUTTON1,MOUSE_LEFT_BUTTON
InputAnalogJoyEvent = KEY_S,KEY_X,JOY1_BUTTON2,MOUSE_RIGHT_BUTTON
InputAnalogJoyTrigger2 = KEY_D,JOY_BUTTON2
InputAnalogJoyEvent2 = NONE
InputGunLeft = KEY_LEFT
InputGunRight = KEY_RIGHT
InputGunUp = KEY_UP
InputGunDown = KEY_DOWN
InputGunX = MOUSE_XAXIS,JOY1_XAXIS
InputGunY = MOUSE_YAXIS,JOY1_YAXIS
InputTrigger = KEY_A,JOY1_BUTTON1,MOUSE_LEFT_BUTTON
InputOffscreen = KEY_S,JOY1_BUTTON2,MOUSE_RIGHT_BUTTON
InputGunX = MOUSE_XAXIS,JOY1_RXAXIS,JOY1_XAXIS
InputGunY = MOUSE_YAXIS,JOY1_RYAXIS,JOY1_YAXIS
InputTrigger = KEY_A,JOY1_RZAXIS_POS,JOY1_BUTTON1,MOUSE_LEFT_BUTTON
InputOffscreen = KEY_S,JOY1_ZAXIS_POS,JOY1_BUTTON2,MOUSE_RIGHT_BUTTON
InputAutoTrigger = 1
InputGunLeft2 = NONE
InputGunRight2 = NONE
@@ -149,18 +149,18 @@ InputAnalogGunLeft = KEY_LEFT
InputAnalogGunRight = KEY_RIGHT
InputAnalogGunUp = KEY_UP
InputAnalogGunDown = KEY_DOWN
InputAnalogGunX = MOUSE_XAXIS,JOY1_XAXIS
InputAnalogGunY = MOUSE_YAXIS,JOY1_YAXIS
InputAnalogTriggerLeft = KEY_A,JOY1_BUTTON1,MOUSE_LEFT_BUTTON
InputAnalogTriggerRight = KEY_S,JOY1_BUTTON2,MOUSE_RIGHT_BUTTON
InputAnalogGunX = MOUSE_XAXIS,JOY1_RXAXIS,JOY1_XAXIS
InputAnalogGunY = MOUSE_YAXIS,JOY1_RYAXIS,JOY1_YAXIS
InputAnalogTriggerLeft = KEY_A,JOY1_RZAXIS_POS,JOY1_BUTTON1,MOUSE_LEFT_BUTTON
InputAnalogTriggerRight = KEY_S,JOY1_ZAXIS_POS,JOY1_BUTTON2,MOUSE_RIGHT_BUTTON
InputAnalogGunLeft2 = NONE
InputAnalogGunRight2 = NONE
InputAnalogGunUp2 = NONE
InputAnalogGunDown2 = NONE
InputAnalogGunX2 = NONE
InputAnalogGunY2 = NONE
InputAnalogTriggerLeft2 = NONE
InputAnalogTriggerRight2 = NONE
InputAnalogGunX2 = JOY2_RXAXIS,JOY2_XAXIS
InputAnalogGunY2 = JOY2_RYAXIS,JOY2_YAXIS
InputAnalogTriggerLeft2 = JOY2_RZAXIS_POS,JOY2_BUTTON1
InputAnalogTriggerRight2 = JOY2_ZAXIS_POS,JOY2_BUTTON2
InputSkiLeft = KEY_LEFT
InputSkiRight = KEY_RIGHT
InputSkiUp = KEY_UP
@@ -197,4 +197,10 @@ InputFishingCast = KEY_Z,JOY1_BUTTON1
InputFishingSelect = KEY_X,JOY1_BUTTON2
InputFishingTension = KEY_T,JOY1_ZAXIS_NEG
[ lamachin ]
InputAnalogGunLeft = JOY1_XAXIS_NEG
InputAnalogGunRight = JOY1_XAXIS_POS
InputAnalogGunUp = JOY1_YAXIS_NEG
InputAnalogGunDown = JOY1_YAXIS_POS
@@ -14,7 +14,7 @@ AndroidInputSystem::AndroidInputSystem()
m_mouseDetails.isAbsolute = true;
std::memset(&m_virtualJoyDetails, 0, sizeof(m_virtualJoyDetails));
std::strncpy(m_virtualJoyDetails.name, "Touch Wheel", MAX_NAME_LENGTH);
std::strncpy(m_virtualJoyDetails.name, "Touch Controls", MAX_NAME_LENGTH);
m_virtualJoyDetails.name[MAX_NAME_LENGTH] = '\0';
m_virtualJoyDetails.numAxes = 6;
m_virtualJoyDetails.numPOVs = 0;
@@ -58,12 +58,7 @@ void AndroidInputSystem::SetVirtualWheelEnabled(bool enabled)
m_wheelFinger = 0;
m_virtualJoyX.store(0, std::memory_order_relaxed);
m_virtualJoyY = 0;
if (enabled && !m_virtualAnalogGunEnabled)
{
m_virtualJoyDetails.hasAxis[AXIS_Y] = false;
std::strncpy(m_virtualJoyDetails.name, "Touch Wheel", MAX_NAME_LENGTH);
m_virtualJoyDetails.name[MAX_NAME_LENGTH] = '\0';
}
UpdateVirtualJoystickDescriptor();
}
void AndroidInputSystem::SetVirtualShifterMode(bool shift4, bool shiftUpDown)
@@ -78,14 +73,17 @@ void AndroidInputSystem::SetVirtualAnalogGunEnabled(bool enabled)
if (m_virtualAnalogGunEnabled == enabled)
return;
m_virtualAnalogGunEnabled = enabled;
m_virtualJoyDetails.hasAxis[AXIS_Y] = enabled;
if (enabled && !m_virtualWheelEnabled)
std::strncpy(m_virtualJoyDetails.name, "Touch Gun", MAX_NAME_LENGTH);
else if (!enabled && m_virtualWheelEnabled)
std::strncpy(m_virtualJoyDetails.name, "Touch Wheel", MAX_NAME_LENGTH);
else
std::strncpy(m_virtualJoyDetails.name, "Touch Controls", MAX_NAME_LENGTH);
m_virtualJoyDetails.name[MAX_NAME_LENGTH] = '\0';
UpdateVirtualJoystickDescriptor();
m_virtualJoyX.store(0, std::memory_order_relaxed);
m_virtualJoyY = 0;
}
void AndroidInputSystem::SetVirtualAnalogJoystickEnabled(bool enabled)
{
if (m_virtualAnalogJoystickEnabled == enabled)
return;
m_virtualAnalogJoystickEnabled = enabled;
UpdateVirtualJoystickDescriptor();
m_virtualJoyX.store(0, std::memory_order_relaxed);
m_virtualJoyY = 0;
}
@@ -97,7 +95,7 @@ bool AndroidInputSystem::UseVirtualWheel() const
bool AndroidInputSystem::UseVirtualJoystick() const
{
return m_controllers.empty() && (m_virtualWheelEnabled || m_virtualAnalogGunEnabled);
return m_controllers.empty() && (m_virtualWheelEnabled || m_virtualAnalogGunEnabled || m_virtualAnalogJoystickEnabled);
}
void AndroidInputSystem::SetVirtualSteerFromEncoded(float encodedX)
@@ -106,6 +104,27 @@ void AndroidInputSystem::SetVirtualSteerFromEncoded(float encodedX)
SetVirtualSteerFromSteer((encodedX - 0.5f) * 2.0f);
}
void AndroidInputSystem::UpdateVirtualJoystickDescriptor()
{
const bool wheel = m_virtualWheelEnabled;
const bool gun = m_virtualAnalogGunEnabled;
const bool stick = m_virtualAnalogJoystickEnabled;
const int enabledCount = (wheel ? 1 : 0) + (gun ? 1 : 0) + (stick ? 1 : 0);
m_virtualJoyDetails.hasAxis[AXIS_Y] = gun || stick;
const char* name = "Touch Controls";
if (enabledCount <= 1)
{
if (wheel) name = "Touch Wheel";
else if (gun) name = "Touch Gun";
else if (stick) name = "Touch Stick";
}
std::strncpy(m_virtualJoyDetails.name, name, MAX_NAME_LENGTH);
m_virtualJoyDetails.name[MAX_NAME_LENGTH] = '\0';
}
void AndroidInputSystem::SetVirtualSteerFromSteer(float steer)
{
steer = std::clamp(steer, -1.0f, 1.0f);
@@ -137,6 +156,33 @@ void AndroidInputSystem::SetVirtualJoyFromNormalized(float x, float y)
m_virtualJoyY = (int)std::lround(sy * 32767.0f);
}
void AndroidInputSystem::SetVirtualStickFromNormalized(float x, float y)
{
float sx = std::clamp((x - 0.5f) * 2.0f, -1.0f, 1.0f);
float sy = std::clamp((y - 0.5f) * 2.0f, -1.0f, 1.0f);
// Apply a circular deadzone + a mild curve so the center is less twitchy.
const float mag = std::sqrt(sx * sx + sy * sy);
constexpr float deadzone = 0.18f;
if (mag < deadzone)
{
m_virtualJoyX.store(0, std::memory_order_relaxed);
m_virtualJoyY = 0;
return;
}
float scaled = (mag - deadzone) / (1.0f - deadzone);
scaled = std::clamp(scaled, 0.0f, 1.0f);
scaled *= scaled;
const float invMag = 1.0f / mag;
sx = sx * invMag * scaled;
sy = sy * invMag * scaled;
m_virtualJoyX.store((int)std::lround(sx * 32767.0f), std::memory_order_relaxed);
m_virtualJoyY = (int)std::lround(sy * 32767.0f);
}
void AndroidInputSystem::ApplyConfig(const Util::Config::Node& config)
{
auto get = [&](const char* key, const char* fallback) -> std::string {
@@ -460,6 +506,15 @@ void AndroidInputSystem::HandleTouch(const SDL_TouchFingerEvent& tf, bool down)
// Virtual fighting stick: 8-way directional based on encoded x/y in [0..1], keyed by a fixed fingerId.
if (tf.fingerId == 1114)
{
if (m_virtualAnalogJoystickEnabled || m_virtualAnalogGunEnabled)
{
if (down)
SetVirtualStickFromNormalized(x, y);
else
SetVirtualStickFromNormalized(0.5f, 0.5f);
return;
}
auto releaseHeld = [&]() {
auto it = m_fingerHeldDir.find(tf.fingerId);
if (it != m_fingerHeldDir.end())
@@ -648,8 +703,6 @@ void AndroidInputSystem::HandleTouch(const SDL_TouchFingerEvent& tf, bool down)
m_gunFingerActive = true;
m_gunFinger = tf.fingerId;
SetMousePosFromNormalized(x, y);
if (m_virtualAnalogGunEnabled)
SetVirtualJoyFromNormalized(x, y);
SetMouseButton(0, true); // left = trigger (held)
}
}
@@ -779,8 +832,6 @@ void AndroidInputSystem::HandleTouchMotion(const SDL_TouchFingerEvent& tf)
if (m_gunFingerActive && tf.fingerId == m_gunFinger)
{
SetMousePosFromNormalized(tf.x, tf.y);
if (m_virtualAnalogGunEnabled)
SetVirtualJoyFromNormalized(tf.x, tf.y);
}
return;
}
@@ -830,8 +881,11 @@ int AndroidInputSystem::GetMouseAxisValue(int mseNum, int axisNum)
return 0;
// For analog-gun games, prefer the virtual joystick (JOY1_XAXIS/JOY1_YAXIS).
// Keep the virtual mouse centered so MOUSE_XAXIS/MOUSE_YAXIS mappings don't override JOY mappings.
if (m_virtualAnalogGunEnabled && (axisNum == AXIS_X || axisNum == AXIS_Y))
// Keep the virtual mouse centered unless the user is actively aiming via touch.
// This lets:
// - touch aim drive MOUSE_* mappings while held, and
// - physical controller aim drive JOY* mappings when not touching.
if (m_virtualAnalogGunEnabled && (axisNum == AXIS_X || axisNum == AXIS_Y) && !m_gunFingerActive)
{
const unsigned extent = (axisNum == AXIS_X) ? m_dispW : m_dispH;
const unsigned origin = (axisNum == AXIS_X) ? m_dispX : m_dispY;
@@ -25,6 +25,7 @@ public:
void SetVirtualWheelEnabled(bool enabled);
void SetVirtualShifterMode(bool shift4, bool shiftUpDown);
void SetVirtualAnalogGunEnabled(bool enabled);
void SetVirtualAnalogJoystickEnabled(bool enabled);
void SetGyroSteer(float steer); // [-1..1]
// Called from the SDL event loop (main thread).
@@ -88,6 +89,8 @@ private:
void SetVirtualSteerFromEncoded(float encodedX);
void SetVirtualSteerFromSteer(float steer);
void SetVirtualJoyFromNormalized(float x, float y);
void SetVirtualStickFromNormalized(float x, float y);
void UpdateVirtualJoystickDescriptor();
void SetKey(SDL_Scancode sc, bool down);
void PulseKey(SDL_Scancode sc, uint32_t durationMs);
@@ -186,6 +189,7 @@ private:
int m_lastVirtualGear = -1;
bool m_virtualAnalogGunEnabled = false;
bool m_virtualAnalogJoystickEnabled = false;
MouseDetails m_mouseDetails{};
int m_mouseX = 0;
+4 -1
View File
@@ -463,7 +463,8 @@ struct Super3Host {
const bool gunGame =
(game.inputs & (Game::INPUT_GUN1 | Game::INPUT_GUN2 | Game::INPUT_ANALOG_GUN1 | Game::INPUT_ANALOG_GUN2)) != 0;
inputSystem.SetGunTouchEnabled(gunGame);
const bool analogJoystickGame = (game.inputs & Game::INPUT_ANALOG_JOYSTICK) != 0;
inputSystem.SetGunTouchEnabled(gunGame || analogJoystickGame);
const bool analogGunGame = (game.inputs & (Game::INPUT_ANALOG_GUN1 | Game::INPUT_ANALOG_GUN2)) != 0;
inputSystem.SetVirtualAnalogGunEnabled(analogGunGame);
@@ -471,6 +472,8 @@ struct Super3Host {
const bool vehicleGame = (game.inputs & (Game::INPUT_VEHICLE | Game::INPUT_HARLEY)) != 0;
inputSystem.SetVirtualWheelEnabled(vehicleGame);
inputSystem.SetVirtualAnalogJoystickEnabled(analogJoystickGame);
const bool shift4 = (game.inputs & Game::INPUT_SHIFT4) != 0;
const bool shiftUpDown = (game.inputs & Game::INPUT_SHIFTUPDOWN) != 0;
inputSystem.SetVirtualShifterMode(shift4, shiftUpDown);
@@ -57,6 +57,25 @@ object AssetInstaller {
"InputGearShiftN = KEY_T" to "InputGearShiftN = KEY_6",
"InputAutoTrigger = 0" to "InputAutoTrigger = 1",
"InputAutoTrigger2 = 0" to "InputAutoTrigger2 = 1",
// Star Wars Trilogy: correct mouse inversion + allow using the pedal touch zone as Trigger/Event.
"InputAnalogJoyX = JOY_XAXIS,MOUSE_XAXIS" to "InputAnalogJoyX = JOY_XAXIS,MOUSE_XAXIS_INV",
"InputAnalogJoyY = JOY_YAXIS,MOUSE_YAXIS" to "InputAnalogJoyY = JOY_YAXIS,MOUSE_YAXIS_INV",
"InputAnalogJoyTrigger = KEY_A,JOY_BUTTON1,MOUSE_LEFT_BUTTON" to "InputAnalogJoyTrigger = KEY_A,KEY_W,JOY1_BUTTON1,MOUSE_LEFT_BUTTON",
"InputAnalogJoyEvent = KEY_S,JOY_BUTTON2,MOUSE_RIGHT_BUTTON" to "InputAnalogJoyEvent = KEY_S,KEY_X,JOY1_BUTTON2,MOUSE_RIGHT_BUTTON",
// Gun games: include right stick + trigger axes in default mappings.
"InputGunX = MOUSE_XAXIS,JOY1_XAXIS" to "InputGunX = MOUSE_XAXIS,JOY1_RXAXIS,JOY1_XAXIS",
"InputGunY = MOUSE_YAXIS,JOY1_YAXIS" to "InputGunY = MOUSE_YAXIS,JOY1_RYAXIS,JOY1_YAXIS",
"InputTrigger = KEY_A,JOY1_BUTTON1,MOUSE_LEFT_BUTTON" to "InputTrigger = KEY_A,JOY1_RZAXIS_POS,JOY1_BUTTON1,MOUSE_LEFT_BUTTON",
"InputOffscreen = KEY_S,JOY1_BUTTON2,MOUSE_RIGHT_BUTTON" to "InputOffscreen = KEY_S,JOY1_ZAXIS_POS,JOY1_BUTTON2,MOUSE_RIGHT_BUTTON",
// Analog-gun games: include right stick + trigger axes, and set P2 defaults if still unmapped.
"InputAnalogGunX = MOUSE_XAXIS,JOY1_XAXIS" to "InputAnalogGunX = MOUSE_XAXIS,JOY1_RXAXIS,JOY1_XAXIS",
"InputAnalogGunY = MOUSE_YAXIS,JOY1_YAXIS" to "InputAnalogGunY = MOUSE_YAXIS,JOY1_RYAXIS,JOY1_YAXIS",
"InputAnalogTriggerLeft = KEY_A,JOY1_BUTTON1,MOUSE_LEFT_BUTTON" to "InputAnalogTriggerLeft = KEY_A,JOY1_RZAXIS_POS,JOY1_BUTTON1,MOUSE_LEFT_BUTTON",
"InputAnalogTriggerRight = KEY_S,JOY1_BUTTON2,MOUSE_RIGHT_BUTTON" to "InputAnalogTriggerRight = KEY_S,JOY1_ZAXIS_POS,JOY1_BUTTON2,MOUSE_RIGHT_BUTTON",
"InputAnalogGunX2 = NONE" to "InputAnalogGunX2 = JOY2_RXAXIS,JOY2_XAXIS",
"InputAnalogGunY2 = NONE" to "InputAnalogGunY2 = JOY2_RYAXIS,JOY2_YAXIS",
"InputAnalogTriggerLeft2 = NONE" to "InputAnalogTriggerLeft2 = JOY2_RZAXIS_POS,JOY2_BUTTON1",
"InputAnalogTriggerRight2 = NONE" to "InputAnalogTriggerRight2 = JOY2_ZAXIS_POS,JOY2_BUTTON2",
)
val updated =
lines.map { line ->
@@ -212,8 +212,17 @@ class Super3Activity : SDLActivity() {
gamesXml.isNotBlank() &&
GameInputsIndex.hasAnyInputType(gamesXml, game, setOf("spikeout"))
val needsAimStickAndButtons =
game.isNotBlank() &&
gamesXml.isNotBlank() &&
(
game == "lamachin" ||
GameInputsIndex.hasAnyInputType(gamesXml, game, setOf("analog_joystick"))
)
val showFightButtons = isFighting || isSpikeout || isSoccer || isTwinJoysticks || isFishing || isSki
val showFightStick = showFightButtons || isMagTruck
val showFightStick = showFightButtons || isMagTruck || needsAimStickAndButtons
val showExtraButtons = showFightButtons || needsAimStickAndButtons
val shifterEnabled = getSharedPreferences("super3_prefs", MODE_PRIVATE)
.getBoolean("overlay_shifter_enabled", false)
@@ -238,7 +247,7 @@ class Super3Activity : SDLActivity() {
if (showFightStick) View.VISIBLE else View.GONE
overlay.findViewById<View>(R.id.overlay_fight_buttons)?.visibility =
if (showFightButtons) View.VISIBLE else View.GONE
if (showExtraButtons) View.VISIBLE else View.GONE
overlay.findViewById<View>(R.id.overlay_vo_row)?.visibility =
if (isTwinJoysticks) View.VISIBLE else View.GONE
@@ -335,7 +344,7 @@ class Super3Activity : SDLActivity() {
bindMomentary(R.id.overlay_reload, fingerId = 1109, x = 0.90f, y = 0.90f)
}
if (showFightButtons) {
if (showExtraButtons) {
val baseId =
if (isSpikeout) {
1115