mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-19 02:53:05 +00:00
Send the initial number of connected gamepads during launch to fix some games like L4D2
This commit is contained in:
parent
8d4c86e113
commit
fb54bd5c78
@ -294,6 +294,16 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
if (prefConfig.videoFormat == PreferenceConfiguration.FORCE_H265_ON && !decoderRenderer.isHevcSupported()) {
|
||||
Toast.makeText(this, "No H.265 decoder found.\nFalling back to H.264.", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
int gamepadMask = ControllerHandler.getAttachedControllerMask(this);
|
||||
if (!prefConfig.multiController && gamepadMask != 0) {
|
||||
// If any gamepads are present in non-MC mode, set only gamepad 1.
|
||||
gamepadMask = 1;
|
||||
}
|
||||
if (prefConfig.onscreenController) {
|
||||
// If we're using OSC, always set at least gamepad 1.
|
||||
gamepadMask |= 1;
|
||||
}
|
||||
|
||||
StreamConfiguration config = new StreamConfiguration.Builder()
|
||||
.setResolution(prefConfig.width, prefConfig.height)
|
||||
@ -307,6 +317,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
.setHevcBitratePercentageMultiplier(75)
|
||||
.setHevcSupported(decoderRenderer.isHevcSupported())
|
||||
.setEnableHdr(willStreamHdr)
|
||||
.setAttachedGamepadMask(gamepadMask)
|
||||
.setAudioConfiguration(prefConfig.enable51Surround ?
|
||||
MoonBridge.AUDIO_CONFIGURATION_51_SURROUND :
|
||||
MoonBridge.AUDIO_CONFIGURATION_STEREO)
|
||||
|
@ -2,6 +2,8 @@ package com.limelight.binding.input;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.hardware.usb.UsbDevice;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.os.SystemClock;
|
||||
import android.util.SparseArray;
|
||||
import android.view.InputDevice;
|
||||
@ -12,6 +14,7 @@ import android.widget.Toast;
|
||||
|
||||
import com.limelight.LimeLog;
|
||||
import com.limelight.binding.input.driver.UsbDriverListener;
|
||||
import com.limelight.binding.input.driver.UsbDriverService;
|
||||
import com.limelight.nvstream.NvConnection;
|
||||
import com.limelight.nvstream.input.ControllerPacket;
|
||||
import com.limelight.nvstream.input.MouseButtonPacket;
|
||||
@ -48,7 +51,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
private boolean hasGameController;
|
||||
|
||||
private final boolean multiControllerEnabled;
|
||||
private short currentControllers;
|
||||
private short currentControllers, initialControllers;
|
||||
|
||||
public ControllerHandler(Context activityContext, NvConnection conn, GameGestures gestures, boolean multiControllerEnabled, int deadzonePercentage) {
|
||||
this.activityContext = activityContext;
|
||||
@ -102,6 +105,12 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
// consume these. Instead, let's ignore them since that's probably the
|
||||
// most likely case.
|
||||
defaultContext.ignoreBack = true;
|
||||
|
||||
// Get the initially attached set of gamepads. As each gamepad receives
|
||||
// its initial InputEvent, we will move these from this set onto the
|
||||
// currentControllers set which will allow them to properly unplug
|
||||
// if they are removed.
|
||||
initialControllers = getAttachedControllerMask(activityContext);
|
||||
}
|
||||
|
||||
private static InputDevice.MotionRange getMotionRangeForJoystickAxis(InputDevice dev, int axis) {
|
||||
@ -139,8 +148,47 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
onInputDeviceAdded(deviceId);
|
||||
}
|
||||
|
||||
public static short getAttachedControllerMask(Context context) {
|
||||
int count = 0;
|
||||
short mask = 0;
|
||||
|
||||
// Count all input devices that are gamepads
|
||||
InputManager im = (InputManager) context.getSystemService(Context.INPUT_SERVICE);
|
||||
for (int id : im.getInputDeviceIds()) {
|
||||
InputDevice dev = im.getInputDevice(id);
|
||||
if (dev == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((dev.getSources() & InputDevice.SOURCE_JOYSTICK) != 0) {
|
||||
LimeLog.info("Counting InputDevice: "+dev.getName());
|
||||
mask |= 1 << count++;
|
||||
}
|
||||
}
|
||||
|
||||
// Count all USB devices that match our drivers
|
||||
UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
|
||||
for (UsbDevice dev : usbManager.getDeviceList().values()) {
|
||||
if (UsbDriverService.shouldClaimDevice(dev)) {
|
||||
LimeLog.info("Counting UsbDevice: "+dev.getDeviceName());
|
||||
mask |= 1 << count++;
|
||||
}
|
||||
}
|
||||
|
||||
LimeLog.info("Enumerated "+count+" gamepads");
|
||||
return mask;
|
||||
}
|
||||
|
||||
private void releaseControllerNumber(GenericControllerContext context) {
|
||||
// If this device sent data as a gamepad, zero the values before removing
|
||||
// If we reserved a controller number, remove that reservation
|
||||
if (context.reservedControllerNumber) {
|
||||
LimeLog.info("Controller number "+context.controllerNumber+" is now available");
|
||||
currentControllers &= ~(1 << context.controllerNumber);
|
||||
}
|
||||
|
||||
// If this device sent data as a gamepad, zero the values before removing.
|
||||
// We must do this after clearing the currentControllers entry so this
|
||||
// causes the device to be removed on the server PC.
|
||||
if (context.assignedControllerNumber) {
|
||||
conn.sendControllerInput(context.controllerNumber, getActiveControllerMask(),
|
||||
(short) 0,
|
||||
@ -148,12 +196,6 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
(short) 0, (short) 0,
|
||||
(short) 0, (short) 0);
|
||||
}
|
||||
|
||||
// If we reserved a controller number, remove that reservation
|
||||
if (context.reservedControllerNumber) {
|
||||
LimeLog.info("Controller number "+context.controllerNumber+" is now available");
|
||||
currentControllers &= ~(1 << context.controllerNumber);
|
||||
}
|
||||
}
|
||||
|
||||
// Called before sending input but after we've determined that this
|
||||
@ -181,6 +223,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
if ((currentControllers & (1 << i)) == 0) {
|
||||
// Found an unused controller value
|
||||
currentControllers |= (1 << i);
|
||||
|
||||
// Take this value out of the initial gamepad set
|
||||
initialControllers &= ~(1 << i);
|
||||
|
||||
context.controllerNumber = i;
|
||||
context.reservedControllerNumber = true;
|
||||
break;
|
||||
@ -201,6 +247,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
if ((currentControllers & (1 << i)) == 0) {
|
||||
// Found an unused controller value
|
||||
currentControllers |= (1 << i);
|
||||
|
||||
// Take this value out of the initial gamepad set
|
||||
initialControllers &= ~(1 << i);
|
||||
|
||||
context.controllerNumber = i;
|
||||
context.reservedControllerNumber = true;
|
||||
break;
|
||||
@ -473,7 +523,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
|
||||
private short getActiveControllerMask() {
|
||||
if (multiControllerEnabled) {
|
||||
return currentControllers;
|
||||
return (short)(currentControllers | initialControllers);
|
||||
}
|
||||
else {
|
||||
// Only Player 1 is active with multi-controller disabled
|
||||
|
@ -157,7 +157,7 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isRecognizedInputDevice(UsbDevice device) {
|
||||
private static boolean isRecognizedInputDevice(UsbDevice device) {
|
||||
// On KitKat and later, we can determine if this VID and PID combo
|
||||
// matches an existing input device and defer to the built-in controller
|
||||
// support in that case. Prior to KitKat, we'll always return true to be safe.
|
||||
@ -182,7 +182,7 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldClaimDevice(UsbDevice device) {
|
||||
public static boolean shouldClaimDevice(UsbDevice device) {
|
||||
// We always bind to XB1 controllers but only bind to XB360 controllers
|
||||
// if we know the kernel isn't already driving this device.
|
||||
return XboxOneController.canClaimDevice(device) ||
|
||||
|
Loading…
x
Reference in New Issue
Block a user