Retransmit OSC gamepad packets every 100 ms to recover from dropped events in GFE

This commit is contained in:
Cameron Gutman 2018-11-30 21:17:12 -08:00
parent 4930087c4d
commit 6993051529
3 changed files with 23 additions and 15 deletions

View File

@ -406,6 +406,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
(FrameLayout)streamView.getParent(),
this);
virtualController.refreshLayout();
virtualController.show();
}
if (prefConfig.usbDriver) {
@ -692,6 +693,10 @@ public class Game extends Activity implements SurfaceHolder.Callback,
SpinnerDialog.closeDialogs(this);
Dialog.closeDialogs();
if (virtualController != null) {
virtualController.hide();
}
if (conn != null) {
int videoFormat = decoderRenderer.getActiveVideoFormat();

View File

@ -339,15 +339,6 @@ public class AnalogStick extends VirtualControllerElement {
stick_state = STICK_STATE.NO_MOVEMENT;
notifyOnRevoke();
// HACK: We can sometimes generate back-to-back controller events
// that cause GFE to drop newer data. Dropping zeroing events would
// be disastrous because we may not get a follow-up joystick event to
// correct the dropped zeroing packet. Delay 5 ms when raising the
// analog stick to ensure this doesn't happen.
try {
Thread.sleep(5);
} catch (InterruptedException e) {}
// not longer pressed reset analog stick
notifyOnMovement(0, 0);
}

View File

@ -17,6 +17,8 @@ import com.limelight.nvstream.NvConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class VirtualController {
public class ControllerInputContext {
@ -42,6 +44,8 @@ public class VirtualController {
private FrameLayout frame_layout = null;
private RelativeLayout relative_layout = null;
private Timer retransmitTimer;
ControllerMode currentMode = ControllerMode.Active;
ControllerInputContext inputContext = new ControllerInputContext();
@ -88,11 +92,24 @@ public class VirtualController {
}
public void hide() {
retransmitTimer.cancel();
relative_layout.setVisibility(View.INVISIBLE);
}
public void show() {
relative_layout.setVisibility(View.VISIBLE);
// HACK: GFE sometimes discards gamepad packets when they are received
// very shortly after another. This can be critical if an axis zeroing packet
// is lost and causes an analog stick to get stuck. To avoid this, we send
// a gamepad input packet every 100 ms to ensure any loss can be recovered.
retransmitTimer = new Timer("OSC timer", true);
retransmitTimer.schedule(new TimerTask() {
@Override
public void run() {
sendControllerInputContext();
}
}, 100, 100);
}
public void removeElements() {
@ -149,18 +166,13 @@ public class VirtualController {
return inputContext;
}
public void sendControllerInputContext() {
sendControllerInputPacket();
}
private void sendControllerInputPacket() {
void sendControllerInputContext() {
try {
_DBG("INPUT_MAP + " + inputContext.inputMap);
_DBG("LEFT_TRIGGER " + inputContext.leftTrigger);
_DBG("RIGHT_TRIGGER " + inputContext.rightTrigger);
_DBG("LEFT STICK X: " + inputContext.leftStickX + " Y: " + inputContext.leftStickY);
_DBG("RIGHT STICK X: " + inputContext.rightStickX + " Y: " + inputContext.rightStickY);
_DBG("RIGHT STICK X: " + inputContext.rightStickX + " Y: " + inputContext.rightStickY);
if (connection != null) {
connection.sendControllerInput(