Skip to content

Commit

Permalink
feat: add shortcuts
Browse files Browse the repository at this point in the history
  • Loading branch information
qiin committed Feb 23, 2024
1 parent d215051 commit 9a73652
Show file tree
Hide file tree
Showing 34 changed files with 27,699 additions and 72 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"java.configuration.updateBuildConfiguration": "interactive"
}
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/232a8tadrrn8jv0k/branch/master?svg=true)](https://ci.appveyor.com/project/cgutman/moonlight-android/branch/master)
[![Translation Status](https://hosted.weblate.org/widgets/moonlight/-/moonlight-android/svg-badge.svg)](https://hosted.weblate.org/projects/moonlight/moonlight-android/)
[![follow us](http://pub.idqqimg.com/wpa/images/group.png)](https://qm.qq.com/cgi-bin/qm/qr?k=NTCPcYeTZWcqM_VFRtAxRaJFHYUC2UWp&noverify=0)


[Moonlight for Android](https://moonlight-stream.org) is an open source client for NVIDIA GameStream and [Sunshine](https://github.com/LizardByte/Sunshine).

Expand Down
8 changes: 5 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
apply plugin: 'com.android.application'

android {
ndkVersion "23.2.8568313"
ndkVersion "25.2.9519653"

compileSdk 34

namespace 'com.limelight'

defaultConfig {
minSdk 16
minSdk 22
targetSdk 34

versionName "12.0.2"
Expand Down Expand Up @@ -119,7 +119,7 @@ android {
// is to please change the applicationId before you publish.
//
// TL;DR: Leave the following line alone!
applicationIdSuffix ".unofficial"
applicationIdSuffix ".qiin"
resValue "string", "app_label", "Moonlight"
resValue "string", "app_label_root", "Moonlight (Root)"

Expand All @@ -144,4 +144,6 @@ dependencies {
// 3.5.8 requires minSdk 19, uses StandardCharsets.UTF_8 internally
implementation 'org.jmdns:jmdns:3.5.7'
implementation 'com.github.cgutman:ShieldControllerExtensions:1.0.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.github.ZeyuKeithFu:KeyboardHeaderLayout:v1.0'
}
85 changes: 75 additions & 10 deletions app/src/main/java/com/limelight/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.view.inputmethod.InputMethodManager;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Toast;

import java.io.ByteArrayInputStream;
import java.lang.reflect.InvocationTargetException;
Expand Down Expand Up @@ -147,6 +148,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
private TextView notificationOverlayView;
private int requestedNotificationOverlayVisibility = View.GONE;
private TextView performanceOverlayView;
private int requestedPerformanceOverlayVisibility = View.GONE;

private MediaCodecDecoderRenderer decoderRenderer;
private boolean reportedCrash;
Expand Down Expand Up @@ -241,6 +243,25 @@ else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
}
}

// hotkeys funcs
findViewById(R.id.btnWin).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
sendKeys(new short[]{KeyboardTranslator.VK_LWIN});
}
});

findViewById(R.id.btnEsc).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
sendKeys(new short[]{KeyboardTranslator.VK_ESCAPE});
}
});

findViewById(R.id.btnHDR).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
sendKeys(new short[]{KeyboardTranslator.VK_LWIN, KeyboardTranslator.VK_MENU, KeyboardTranslator.VK_B});
}
});

// Listen for non-touch events on the game surface
streamView = findViewById(R.id.surfaceView);
streamView.setOnGenericMotionListener(this);
Expand Down Expand Up @@ -374,11 +395,6 @@ public boolean onCapturedPointer(View view, MotionEvent motionEvent) {
}
}

// Check if the user has enabled performance stats overlay
if (prefConfig.enablePerfOverlay) {
performanceOverlayView.setVisibility(View.VISIBLE);
}

decoderRenderer = new MediaCodecDecoderRenderer(
this,
prefConfig,
Expand Down Expand Up @@ -639,10 +655,7 @@ public void onConfigurationChanged(Configuration newConfig) {
virtualController.show();
}

if (prefConfig.enablePerfOverlay) {
performanceOverlayView.setVisibility(View.VISIBLE);
}

performanceOverlayView.setVisibility(requestedPerformanceOverlayVisibility);
notificationOverlayView.setVisibility(requestedNotificationOverlayVisibility);

// Enable sensors again after exiting PiP
Expand Down Expand Up @@ -2697,6 +2710,11 @@ public void run() {
});
}

@Override
public boolean isPerfOverlayVisible() {
return requestedPerformanceOverlayVisibility == View.VISIBLE;
}

@Override
public void onUsbPermissionPromptStarting() {
// Disable PiP auto-enter while the USB permission prompt is on-screen. This prevents
Expand Down Expand Up @@ -2745,4 +2763,51 @@ public void onBackPressed() {
// menu when the activity would be closed.
showGameMenu(null);
}

public void togglePerformanceOverlay() {
if (requestedPerformanceOverlayVisibility == View.VISIBLE) {
requestedPerformanceOverlayVisibility = View.GONE;
} else {
requestedPerformanceOverlayVisibility = View.VISIBLE;
}
performanceOverlayView.setVisibility(requestedPerformanceOverlayVisibility);
}

private static byte getModifier(short key) {
switch (key) {
case KeyboardTranslator.VK_LSHIFT:
return KeyboardPacket.MODIFIER_SHIFT;
case KeyboardTranslator.VK_LCONTROL:
return KeyboardPacket.MODIFIER_CTRL;
case KeyboardTranslator.VK_LWIN:
return KeyboardPacket.MODIFIER_META;

default:
return 0;
}
}

private void sendKeys(short[] keys) {
final byte[] modifier = {(byte) 0};

for (short key : keys) {
conn.sendKeyboardInput(key, KeyboardPacket.KEY_DOWN, modifier[0], (byte) 0);

// Apply the modifier of the pressed key, e.g. CTRL first issues a CTRL event (without
// modifier) and then sends the following keys with the CTRL modifier applied
modifier[0] |= getModifier(key);
}

new Handler().postDelayed((() -> {

for (int pos = keys.length - 1; pos >= 0; pos--) {
short key = keys[pos];

// Remove the keys modifier before releasing the key
modifier[0] &= ~getModifier(key);

conn.sendKeyboardInput(key, KeyboardPacket.KEY_UP, modifier[0], (byte) 0);
}
}), 25);
}
}
1 change: 1 addition & 0 deletions app/src/main/java/com/limelight/GameMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ private void showMenu() {
options.addAll(device.getGameMenuOptions());
}

options.add(new MenuOption(getString(R.string.game_menu_toggle_performance_overlay), () -> game.togglePerformanceOverlay()));
options.add(new MenuOption(getString(R.string.game_menu_send_keys), () -> showSpecialKeysMenu()));
options.add(new MenuOption(getString(R.string.game_menu_disconnect), () -> game.disconnect()));
options.add(new MenuOption(getString(R.string.game_menu_cancel), null));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class KeyboardTranslator implements InputManager.InputDeviceListener {
public static final int VK_0 = 48;
public static final int VK_9 = 57;
public static final int VK_A = 65;
public static final int VK_B = 66;
public static final int VK_C = 67;
public static final int VK_D = 68;
public static final int VK_G = 71;
Expand All @@ -41,6 +42,7 @@ public class KeyboardTranslator implements InputManager.InputDeviceListener {
public static final int VK_F11 = 122;
public static final int VK_END = 35;
public static final int VK_HOME = 36;
public static final int VK_MENU = 18;
public static final int VK_NUM_LOCK = 144;
public static final int VK_PAGE_UP = 33;
public static final int VK_PAGE_DOWN = 34;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1424,7 +1424,7 @@ public int submitDecodeUnit(byte[] decodeUnitData, int decodeUnitLength, int dec

// Flip stats windows roughly every second
if (SystemClock.uptimeMillis() >= activeWindowVideoStats.measurementStartTimestamp + 1000) {
if (prefs.enablePerfOverlay) {
if (perfListener.isPerfOverlayVisible()) {
VideoStats lastTwo = new VideoStats();
lastTwo.add(lastWindowVideoStats);
lastTwo.add(activeWindowVideoStats);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

public interface PerfOverlayListener {
void onPerfUpdate(final String text);
boolean isPerfOverlayVisible();
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ public enum AnalogStickForScrolling {
private static final String LEGACY_DISABLE_FRAME_DROP_PREF_STRING = "checkbox_disable_frame_drop";
private static final String ENABLE_HDR_PREF_STRING = "checkbox_enable_hdr";
private static final String ENABLE_PIP_PREF_STRING = "checkbox_enable_pip";
private static final String ENABLE_PERF_OVERLAY_STRING = "checkbox_enable_perf_overlay";
private static final String BIND_ALL_USB_STRING = "checkbox_usb_bind_all";
private static final String MOUSE_EMULATION_STRING = "checkbox_mouse_emulation";
private static final String ANALOG_SCROLLING_PREF_STRING = "analog_scrolling";
Expand Down Expand Up @@ -85,7 +84,6 @@ public enum AnalogStickForScrolling {
private static final boolean ONLY_L3_R3_DEFAULT = false;
private static final boolean DEFAULT_ENABLE_HDR = false;
private static final boolean DEFAULT_ENABLE_PIP = false;
private static final boolean DEFAULT_ENABLE_PERF_OVERLAY = false;
private static final boolean DEFAULT_BIND_ALL_USB = false;
private static final boolean DEFAULT_MOUSE_EMULATION = true;
private static final String DEFAULT_ANALOG_STICK_FOR_SCROLLING = "right";
Expand Down Expand Up @@ -132,7 +130,6 @@ public enum AnalogStickForScrolling {
public boolean onlyL3R3;
public boolean enableHdr;
public boolean enablePip;
public boolean enablePerfOverlay;
public boolean enableLatencyToast;
public boolean bindAllUsb;
public boolean mouseEmulation;
Expand Down Expand Up @@ -579,7 +576,6 @@ else if (audioConfig.equals("51")) {
config.onlyL3R3 = prefs.getBoolean(ONLY_L3_R3_PREF_STRING, ONLY_L3_R3_DEFAULT);
config.enableHdr = prefs.getBoolean(ENABLE_HDR_PREF_STRING, DEFAULT_ENABLE_HDR) && !isShieldAtvFirmwareWithBrokenHdr();
config.enablePip = prefs.getBoolean(ENABLE_PIP_PREF_STRING, DEFAULT_ENABLE_PIP);
config.enablePerfOverlay = prefs.getBoolean(ENABLE_PERF_OVERLAY_STRING, DEFAULT_ENABLE_PERF_OVERLAY);
config.bindAllUsb = prefs.getBoolean(BIND_ALL_USB_STRING, DEFAULT_BIND_ALL_USB);
config.mouseEmulation = prefs.getBoolean(MOUSE_EMULATION_STRING, DEFAULT_MOUSE_EMULATION);
config.mouseNavButtons = prefs.getBoolean(MOUSE_NAV_BUTTONS_STRING, DEFAULT_MOUSE_NAV_BUTTONS);
Expand Down
Loading

0 comments on commit 9a73652

Please sign in to comment.