Skip to content

Commit

Permalink
GameController: Add support for linear triggers. (XInput only)
Browse files Browse the repository at this point in the history
  • Loading branch information
longjunyu2 committed Aug 5, 2024
1 parent 8b9af62 commit edef9b5
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class ExternalController {
private String name;
private String id;
private int deviceId = -1;
private byte triggerMode = TRIGGER_AS_BOTH;
private byte triggerMode = TRIGGER_AS_AXIS;
private final ArrayList<ExternalControllerBinding> controllerBindings = new ArrayList<>();
public final GamepadState state = new GamepadState();

Expand Down Expand Up @@ -148,13 +148,17 @@ private void processJoystickInput(MotionEvent event, int historyPos) {
}

private void processTriggerButton(MotionEvent event) {
state.setPressed(IDX_BUTTON_L2, event.getAxisValue(MotionEvent.AXIS_LTRIGGER) == 1.0f || event.getAxisValue(MotionEvent.AXIS_BRAKE) == 1.0f);
state.setPressed(IDX_BUTTON_R2, event.getAxisValue(MotionEvent.AXIS_RTRIGGER) == 1.0f || event.getAxisValue(MotionEvent.AXIS_GAS) == 1.0f);
float l = event.getAxisValue(MotionEvent.AXIS_LTRIGGER) == 0f ? event.getAxisValue(MotionEvent.AXIS_BRAKE) : event.getAxisValue(MotionEvent.AXIS_LTRIGGER);
float r = event.getAxisValue(MotionEvent.AXIS_RTRIGGER) == 0f ? event.getAxisValue(MotionEvent.AXIS_GAS) : event.getAxisValue(MotionEvent.AXIS_RTRIGGER);
state.triggerL = l;
state.triggerR = r;
state.setPressed(IDX_BUTTON_L2, l == 1.0f);
state.setPressed(IDX_BUTTON_R2, r == 1.0f);
}

public boolean updateStateFromMotionEvent(MotionEvent event) {
if (isJoystickDevice(event)) {
if (triggerMode != TRIGGER_AS_BUTTON)
if (triggerMode == TRIGGER_AS_AXIS)
processTriggerButton(event);
int historySize = event.getHistorySize();
for (int i = 0; i < historySize; i++) processJoystickInput(event, i);
Expand All @@ -169,9 +173,20 @@ public boolean updateStateFromKeyEvent(KeyEvent event) {
int keyCode = event.getKeyCode();
int buttonIdx = getButtonIdxByKeyCode(keyCode);
if (buttonIdx != -1) {
if (triggerMode != TRIGGER_AS_AXIS || (buttonIdx != IDX_BUTTON_L2 && buttonIdx != IDX_BUTTON_R2)) {
if (buttonIdx == IDX_BUTTON_L2) {
if (triggerMode == TRIGGER_AS_BUTTON) {
state.triggerL = pressed ? 1.0f : 0f;
state.setPressed(buttonIdx, pressed);
} else
return true;
} else if (buttonIdx == IDX_BUTTON_R2) {
if (triggerMode == TRIGGER_AS_BUTTON) {
state.triggerR = pressed ? 1.0f : 0f;
state.setPressed(buttonIdx, pressed);
} else
return true;
} else
state.setPressed(buttonIdx, pressed);
}
return true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.winlator.inputcontrols;

import android.util.Log;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
Expand All @@ -9,6 +11,8 @@ public class GamepadState {
public float thumbLY = 0;
public float thumbRX = 0;
public float thumbRY = 0;
public float triggerL = 0;
public float triggerR = 0;
public final boolean[] dpad = new boolean[4];
public short buttons = 0;

Expand All @@ -32,6 +36,8 @@ public void writeTo(ByteBuffer buffer) {
buffer.putShort((short)(thumbLY * Short.MAX_VALUE));
buffer.putShort((short)(thumbRX * Short.MAX_VALUE));
buffer.putShort((short)(thumbRY * Short.MAX_VALUE));
buffer.put((byte)(triggerL * 255));
buffer.put((byte)(triggerR * 255));
}

public void setPressed(int buttonIdx, boolean pressed) {
Expand Down Expand Up @@ -59,6 +65,8 @@ public void copy(GamepadState other) {
this.thumbLY = other.thumbLY;
this.thumbRX = other.thumbRX;
this.thumbRY = other.thumbRY;
this.triggerL = other.triggerL;
this.triggerR = other.triggerR;
this.buttons = other.buttons;
System.arraycopy(other.dpad, 0, this.dpad, 0, 4);
}
Expand Down
9 changes: 7 additions & 2 deletions app/src/main/java/com/winlator/widget/InputControlsView.java
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,13 @@ public void handleInputEvent(Binding binding, boolean isActionDown, float offset
GamepadState state = profile.getGamepadState();

int buttonIdx = binding.ordinal() - Binding.GAMEPAD_BUTTON_A.ordinal();
if (buttonIdx <= 11) {
state.setPressed(buttonIdx, isActionDown);
if (buttonIdx <= ExternalController.IDX_BUTTON_R2) {
if (buttonIdx == ExternalController.IDX_BUTTON_L2)
state.triggerL = isActionDown ? 1.0f : 0f;
else if (buttonIdx == ExternalController.IDX_BUTTON_R2)
state.triggerR = isActionDown ? 1.0f : 0f;
else
state.setPressed(buttonIdx, isActionDown);
}
else if (binding == Binding.GAMEPAD_LEFT_THUMB_UP || binding == Binding.GAMEPAD_LEFT_THUMB_DOWN) {
state.thumbLY = isActionDown ? offset : 0;
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/winlator/winhandler/WinHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ private void handleRequest(byte requestCode, final int port) {
case RequestCodes.INIT: {
initReceived = true;
preferences = PreferenceManager.getDefaultSharedPreferences(activity.getBaseContext());
triggerMode = (byte) preferences.getInt("trigger_mode", ExternalController.TRIGGER_AS_BOTH);
triggerMode = (byte) preferences.getInt("trigger_mode", ExternalController.TRIGGER_AS_AXIS);

synchronized (actions) {
actions.notify();
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/layout/settings_fragment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:enabled="false"
android:visibility="gone"
android:text="@string/install_wine" />
</LinearLayout>

Expand Down Expand Up @@ -270,6 +271,7 @@

<RadioButton
android:id="@+id/RBTriggerAsBoth"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
Expand Down

0 comments on commit edef9b5

Please sign in to comment.