mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-10-21 15:56:57 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0762a6213 | ||
|
|
04efec101e | ||
|
|
a6c69012cc | ||
|
|
0045c54d8e | ||
|
|
45436c006f | ||
|
|
cc183c0da8 | ||
|
|
523f1df98b | ||
|
|
5843dff278 | ||
|
|
7f24f47978 | ||
|
|
b1f9fd459e | ||
|
|
48988eb785 |
No files matched your search
@@ -1,6 +1,7 @@
|
|||||||
# Moonlight Android
|
# Moonlight Android
|
||||||
|
|
||||||
[](https://ci.appveyor.com/project/cgutman/moonlight-android/branch/master)
|
[](https://ci.appveyor.com/project/cgutman/moonlight-android/branch/master)
|
||||||
|
[](https://hosted.weblate.org/projects/moonlight/moonlight-android/)
|
||||||
|
|
||||||
[Moonlight for Android](https://moonlight-stream.org) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield.
|
[Moonlight for Android](https://moonlight-stream.org) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield.
|
||||||
|
|
||||||
@@ -9,7 +10,7 @@ whether in your own home or over the internet.
|
|||||||
|
|
||||||
Moonlight also has a [PC client](https://github.com/moonlight-stream/moonlight-qt) and [iOS/tvOS client](https://github.com/moonlight-stream/moonlight-ios).
|
Moonlight also has a [PC client](https://github.com/moonlight-stream/moonlight-qt) and [iOS/tvOS client](https://github.com/moonlight-stream/moonlight-ios).
|
||||||
|
|
||||||
Check out [the Moonlight wiki](https://github.com/moonlight-stream/moonlight-docs/wiki) for more detailed project information, setup guide, or troubleshooting steps.
|
You can follow development on our [Discord server](https://moonlight-stream.org/discord) and help translate Moonlight into your language on [Weblate](https://hosted.weblate.org/projects/moonlight/moonlight-android/).
|
||||||
|
|
||||||
## Downloads
|
## Downloads
|
||||||
* [Google Play Store](https://play.google.com/store/apps/details?id=com.limelight)
|
* [Google Play Store](https://play.google.com/store/apps/details?id=com.limelight)
|
||||||
|
|||||||
+4
-2
@@ -1,14 +1,16 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
|
ndkVersion "22.0.7026061"
|
||||||
|
|
||||||
compileSdkVersion 30
|
compileSdkVersion 30
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
|
|
||||||
versionName "9.8.3"
|
versionName "9.8.4"
|
||||||
versionCode = 254
|
versionCode = 255
|
||||||
}
|
}
|
||||||
|
|
||||||
flavorDimensions "root"
|
flavorDimensions "root"
|
||||||
|
|||||||
@@ -1000,6 +1000,26 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We cannot simply use modifierFlags for all key event processing, because
|
||||||
|
// some IMEs will not generate real key events for pressing Shift. Instead
|
||||||
|
// they will simply send key events with isShiftPressed() returning true,
|
||||||
|
// and we will need to send the modifier flag ourselves.
|
||||||
|
private byte getModifierState(KeyEvent event) {
|
||||||
|
// Start with the global modifier state to ensure we cover the case
|
||||||
|
// detailed in https://github.com/moonlight-stream/moonlight-android/issues/840
|
||||||
|
byte modifier = getModifierState();
|
||||||
|
if (event.isShiftPressed()) {
|
||||||
|
modifier |= KeyboardPacket.MODIFIER_SHIFT;
|
||||||
|
}
|
||||||
|
if (event.isCtrlPressed()) {
|
||||||
|
modifier |= KeyboardPacket.MODIFIER_CTRL;
|
||||||
|
}
|
||||||
|
if (event.isAltPressed()) {
|
||||||
|
modifier |= KeyboardPacket.MODIFIER_ALT;
|
||||||
|
}
|
||||||
|
return modifier;
|
||||||
|
}
|
||||||
|
|
||||||
private byte getModifierState() {
|
private byte getModifierState() {
|
||||||
return (byte) modifierFlags;
|
return (byte) modifierFlags;
|
||||||
}
|
}
|
||||||
@@ -1065,10 +1085,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte modifiers = getModifierState();
|
byte modifiers = getModifierState(event);
|
||||||
if (KeyboardTranslator.needsShift(event.getKeyCode())) {
|
if (KeyboardTranslator.needsShift(event.getKeyCode())) {
|
||||||
modifiers |= KeyboardPacket.MODIFIER_SHIFT;
|
modifiers |= KeyboardPacket.MODIFIER_SHIFT;
|
||||||
conn.sendKeyboardInput((short) 0x8010, KeyboardPacket.KEY_DOWN, modifiers);
|
|
||||||
}
|
}
|
||||||
conn.sendKeyboardInput(translated, KeyboardPacket.KEY_DOWN, modifiers);
|
conn.sendKeyboardInput(translated, KeyboardPacket.KEY_DOWN, modifiers);
|
||||||
}
|
}
|
||||||
@@ -1129,14 +1148,11 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte modifiers = getModifierState();
|
byte modifiers = getModifierState(event);
|
||||||
if (KeyboardTranslator.needsShift(event.getKeyCode())) {
|
if (KeyboardTranslator.needsShift(event.getKeyCode())) {
|
||||||
modifiers |= KeyboardPacket.MODIFIER_SHIFT;
|
modifiers |= KeyboardPacket.MODIFIER_SHIFT;
|
||||||
}
|
}
|
||||||
conn.sendKeyboardInput(translated, KeyboardPacket.KEY_UP, modifiers);
|
conn.sendKeyboardInput(translated, KeyboardPacket.KEY_UP, modifiers);
|
||||||
if (KeyboardTranslator.needsShift(event.getKeyCode())) {
|
|
||||||
conn.sendKeyboardInput((short) 0x8010, KeyboardPacket.KEY_UP, getModifierState());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public class Xbox360Controller extends AbstractXboxController {
|
|||||||
0x0f0d, // Hori
|
0x0f0d, // Hori
|
||||||
0x1038, // SteelSeries
|
0x1038, // SteelSeries
|
||||||
0x11c9, // Nacon
|
0x11c9, // Nacon
|
||||||
|
0x1209, // Ardwiino
|
||||||
0x12ab, // Unknown
|
0x12ab, // Unknown
|
||||||
0x1430, // RedOctane
|
0x1430, // RedOctane
|
||||||
0x146b, // BigBen
|
0x146b, // BigBen
|
||||||
@@ -34,7 +35,9 @@ public class Xbox360Controller extends AbstractXboxController {
|
|||||||
0x162e, // Joytech
|
0x162e, // Joytech
|
||||||
0x1689, // Razer Onza
|
0x1689, // Razer Onza
|
||||||
0x1bad, // Harmonix
|
0x1bad, // Harmonix
|
||||||
|
0x20d6, // PowerA
|
||||||
0x24c6, // PowerA
|
0x24c6, // PowerA
|
||||||
|
0x2f24, // GameSir
|
||||||
};
|
};
|
||||||
|
|
||||||
public static boolean canClaimDevice(UsbDevice device) {
|
public static boolean canClaimDevice(UsbDevice device) {
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ public class XboxOneController extends AbstractXboxController {
|
|||||||
0x0e6f, // Unknown
|
0x0e6f, // Unknown
|
||||||
0x0f0d, // Hori
|
0x0f0d, // Hori
|
||||||
0x1532, // Razer Wildcat
|
0x1532, // Razer Wildcat
|
||||||
|
0x20d6, // PowerA
|
||||||
0x24c6, // PowerA
|
0x24c6, // PowerA
|
||||||
|
0x2e24, // Hyperkin
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final byte[] FW2015_INIT = {0x05, 0x20, 0x00, 0x01, 0x00};
|
private static final byte[] FW2015_INIT = {0x05, 0x20, 0x00, 0x01, 0x00};
|
||||||
|
|||||||
@@ -147,6 +147,9 @@ public class RelativeTouchContext implements TouchContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void startDragTimer() {
|
private synchronized void startDragTimer() {
|
||||||
|
// Cancel any existing drag timers
|
||||||
|
cancelDragTimer();
|
||||||
|
|
||||||
dragTimer = new Timer(true);
|
dragTimer = new Timer(true);
|
||||||
dragTimer.schedule(new TimerTask() {
|
dragTimer.schedule(new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -177,6 +177,15 @@ public class DigitalButton extends VirtualControllerElement {
|
|||||||
listener.onClick();
|
listener.onClick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timerLongClick != null) {
|
||||||
|
timerLongClick.cancel();
|
||||||
|
timerLongClick = null;
|
||||||
|
}
|
||||||
|
if (longClickTimerTask != null) {
|
||||||
|
longClickTimerTask.cancel();
|
||||||
|
longClickTimerTask = null;
|
||||||
|
}
|
||||||
|
|
||||||
timerLongClick = new Timer();
|
timerLongClick = new Timer();
|
||||||
longClickTimerTask = new TimerLongClickTimerTask();
|
longClickTimerTask = new TimerLongClickTimerTask();
|
||||||
timerLongClick.schedule(longClickTimerTask, timerLongClickTimeout);
|
timerLongClick.schedule(longClickTimerTask, timerLongClickTimeout);
|
||||||
@@ -200,9 +209,11 @@ public class DigitalButton extends VirtualControllerElement {
|
|||||||
// We may be called for a release without a prior click
|
// We may be called for a release without a prior click
|
||||||
if (timerLongClick != null) {
|
if (timerLongClick != null) {
|
||||||
timerLongClick.cancel();
|
timerLongClick.cancel();
|
||||||
|
timerLongClick = null;
|
||||||
}
|
}
|
||||||
if (longClickTimerTask != null) {
|
if (longClickTimerTask != null) {
|
||||||
longClickTimerTask.cancel();
|
longClickTimerTask.cancel();
|
||||||
|
longClickTimerTask = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -5,7 +5,7 @@ buildscript {
|
|||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:4.1.2'
|
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
- Fixed typing upper-case letters with the software keyboard
|
||||||
|
- Improved device compatibility with the built-in USB Xbox gamepad driver
|
||||||
Reference in new issue
Block a user