Compare commits

...

34 commits

Author SHA1 Message Date
downthecrop
5b72e87a89 Merge branch 'master' of https://github.com/2009scape/2009scape-mobile 2024-06-09 21:52:51 +09:00
downthecrop
cb9ffc52fb Update Jar to e8589 (Music + WorldMap), Set default resolution scale 2024-06-09 21:52:40 +09:00
downthecrop
5270adf48f regession in special character sending 2023-12-17 01:53:40 -08:00
downthecrop
fa697c6a75 Keycode 67 handling 2023-12-17 01:39:06 -08:00
downthecrop
6f969cb7d7 Longpress rc should only be active in touch mode 2023-11-30 02:00:34 -08:00
downthecrop
5330ad05ef Release 2.2 2023-11-30 01:37:49 -08:00
downthecrop
668660e13e I'm guessing this was here for debug.. but why?.. anyway removing it 2023-11-30 01:37:49 -08:00
downthecrop
f97451fc3d Swipe cam for SD + Start init of dragclick/longpress 2023-11-30 01:37:49 -08:00
downthecrop
089c9f6c8c Respect autoenabled virtual mouse 2023-11-07 22:43:41 -08:00
downthecrop
9df7163c22 Link images to the new repo 2023-11-01 22:27:59 -07:00
downthecrop
aed8217b81 SD mode respect mouse speed preferences 2023-11-01 22:25:57 -07:00
Dan G
793d2e4ba1
Slight screenshot tweak 2023-10-29 05:25:04 +09:00
Dan G
2446f3b2be
Merge pull request #15 from dginovker/readme-images
Change Readme images
2023-10-29 04:58:51 +09:00
Dan G
74a0eb9903
Change Readme images 2023-10-29 04:53:47 +09:00
downthecrop
41f2c2e9ae gh-actions doesn't like the newer gradle version 2023-10-18 21:45:35 -07:00
downthecrop
5418099a39 Include GE Data for GroundItems Plugin 2023-10-18 21:45:35 -07:00
downthecrop
e155582ac8 Update to GroundItems 1.1 2023-10-18 21:45:35 -07:00
downthecrop
ce2ad54977 Reverting last two commits 2023-10-18 21:45:35 -07:00
downthecrop
94c395099f Default to 60% resolution scale 2023-10-18 21:45:35 -07:00
downthecrop
0874bce6a6 Upgrade Gradle-Wrapper 2023-10-18 21:45:35 -07:00
downthecrop
c1d8def550 Preferences are now able to save 2023-10-18 21:45:35 -07:00
downthecrop
1f6f4f2b4e Icons are back for SD 2023-10-18 21:45:35 -07:00
downthecrop
2962c55adf Mouse pointer positioning for inse canvas 2023-10-18 21:45:35 -07:00
downthecrop
99d619705c Sliding inset values (mouse doesn't work right) 2023-10-18 21:45:35 -07:00
downthecrop
dd25be1bb8 New basic loading of preferences on launch 2023-10-18 21:45:35 -07:00
downthecrop
1196fc8d86 Start adding a new custom setting to the original pojav launcher settings 2023-10-18 21:45:35 -07:00
downthecrop
496f3ea33a
Merge pull request #12 from 7MXek/patch-1
Update strings.xml
2023-10-12 18:53:21 -07:00
7MXek
c8ec2ede42
Update strings.xml
The application name in my launcher has one too many zeroes. I believe this change should fix that.
2023-10-10 13:20:12 -04:00
downthecrop
ca4bfc4c9f
Merge pull request #10 from 2009scape/readme-link
Client source link
2023-08-10 22:31:12 -07:00
downthecrop
5d8d6ffda5 Client source link 2023-08-10 22:30:26 -07:00
downthecrop
a8b7a59b22
Merge pull request #9 from 2009scape/readme-link
Fix link to releases #8
2023-08-08 17:22:55 -07:00
downthecrop
12c38dc2d4 Fix link to releases #8 2023-08-08 17:21:30 -07:00
downthecrop
a4340bff7e
Merge pull request #6 from 2009scape/readme
README
2023-08-01 23:41:51 -07:00
downthecrop
a1143f6a66 README 2023-08-01 23:40:12 -07:00
32 changed files with 325 additions and 319 deletions

4
.gitignore vendored
View file

@ -2,7 +2,9 @@
/build
/*/build
app_pojavlauncher/src/main/assets/components/jre
app_pojavlauncher/src/main/assets/components/lwjgl3/version
local.properties
.idea/
.DS_Store
app_pojavlauncher/.cxx/
.vs/
.vs/

144
README.md
View file

@ -1,135 +1,23 @@
<H1 align="center">PojavLauncher</H1>
<h1 align="center"">HD Launcher - 2009Scape Mobile 2.1</h1>
<img src="https://github.com/PojavLauncherTeam/PojavLauncher/blob/v3_openjdk/app_pojavlauncher/src/main/assets/pojavlauncher.png" align="left" width="130" height="150" alt="PojavLauncher logo">
<p align="center">
<a href="https://github.com/2009scape/2009Scape-mobile/releases"><img src="https://i.imgur.com/7wtvknj.png" alt="2009scape Mobile Logo"/></a>
<a href="https://github.com/2009scape/2009Scape-mobile/releases"><img src="https://i.imgur.com/o8OwASv.png" alt="2009scape Mobile splash"/></a>
<a href="https://github.com/2009scape/2009Scape-mobile/releases"><img src="https://i.imgur.com/nSC3O2Q.png" alt="2009scape Mobile login screen"/></a>
<a href="https://github.com/2009scape/2009Scape-mobile/releases"><img src="https://i.imgur.com/KUXPn6P.png" alt="2009scape Mobile play screen"/></a>
</p>
[![Android CI](https://github.com/PojavLauncherTeam/PojavLauncher/workflows/Android%20CI/badge.svg)](https://github.com/PojavLauncherTeam/PojavLauncher/actions)
[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/PojavLauncherTeam/PojavLauncher)](https://github.com/PojavLauncherTeam/PojavLauncher/actions)
[![Crowdin](https://badges.crowdin.net/pojavlauncher/localized.svg)](https://crowdin.com/project/pojavlauncher)
[![Discord](https://img.shields.io/discord/724163890803638273.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/6RpEJda)
[![Twitter Follow](https://img.shields.io/twitter/follow/plaunchteam?color=blue&style=flat-square)](https://twitter.com/PLaunchTeam)
---------
* From [Boardwalk](https://github.com/zhuowei/Boardwalk)'s ashes here comes PojavLauncher!
Unoffical, unsupported, and unethical app to run 2009Scape on your Android device. Based on Pojav/Boardwalk.
* PojavLauncher is a launcher that allows you to play Minecraft: Java Edition on your Android device!
# Download
[Releases](https://github.com/2009scape/2009Scape-mobile/releases/)
* It can run almost every version of the Minecraft, allowing you to use .jar only installers to install modloaders such as [Forge](https://files.minecraftforge.net/) and [Fabric](http://fabricmc.net/), mods like [OptiFine](https://optifine.net) and [LabyMod](https://www.labymod.net/en), as well as hack clients like [Wurst](https://www.wurstclient.net/), and much more!
<hr>
* For more details [check out our wiki](https://github.com/PojavLauncherTeam/PojavLauncher/wiki)
## Some notes to start with
- We do not have an official TikTok account. No one from the dev team makes TikTok videos.
- The official Twitter for PojavLauncher is [@PLaunchTeam](https://twitter.com/PLaunchTeam). Any others (most notably @PojavLauncher) are fake, please report them to Twitter's moderation team.
[Controls](https://github.com/2009scape/2009Scape-mobile/wiki/Controls)
## Navigation
- [Introduction](#introduction)
- [Getting PojavLauncher](#getting-pojavlauncher)
- [Building](#building)
- [Current status](#current-status)
- [License](#license)
- [Contributing](#contributing)
- [Credits & Third party components and their licenses](#credits--third-party-components-and-their-licenses-if-available)
Tip: Use [SwiftKey](https://play.google.com/store/apps/details?id=com.touchtype.swiftkey&hl=en_CA&gl=US) keyboard and disable battery optimization to get the best experience
## Introduction
* PojavLauncher is a Minecraft: Java Edition launcher for Android and iOS based on [Boardwalk](https://github.com/zhuowei/Boardwalk).
* This launcher can launch almost all available Minecraft versions ranging from rd-132211 to 1.19 snapshots (including Combat Test versions).
* Modding via Forge and Fabric are also supported.
* This repository contains source code for Android.
* For iOS/iPadOS, check out [PojavLauncher_iOS](https://github.com/PojavLauncherTeam/PojavLauncher_iOS).
## Getting PojavLauncher
You can get PojavLauncher via three methods:
1. You can get the prebuilt app from [stable releases](https://github.com/PojavLauncherTeam/PojavLauncher/releases) or [automatic builds](https://github.com/PojavLauncherTeam/PojavLauncher/actions).
2. You can get it from Google Play by clicking on this badge:
[![Google Play](https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png)](https://play.google.com/store/apps/details?id=net.kdt.pojavlaunch)
3. You can [build](#building) from source.
## Building
If you want to build from source code, follow the steps below.
### Java Runtime Environment (JRE)
- JRE for Android is [here](https://github.com/PojavLauncherTeam/openjdk-multiarch-jdk8u), and the build script is [here](https://github.com/PojavLauncherTeam/android-openjdk-build-multiarch).
- Follow build instruction on build script [README.md](https://github.com/PojavLauncherTeam/android-openjdk-build-multiarch/blob/buildjre8/README.md).
- You can also get [CI auto builds](https://github.com/PojavLauncherTeam/android-openjdk-build-multiarch/actions) if you are lazy or are failing to build it for some reason.
* Either get the `jre8-pojav` artifact from auto builds, or split all artifacts by yourself:</br>
- Get JREs for all of 4 supported architectures (arm, arm64, x86, x86_64) </br>
- Split JRE into parts:</br>
Platform-independent: .jar files, libraries, configs, etc...</br>
Platform-dependent: .so files, etc...</br>
- Create:</br>
A file named `universal.tar.xz` with all platform-independent files</br>
4 files named `bin-<arch>.tar.xz` with all platform-dependent files per-architecture</br>
- Put these in the `assets/components/jre/` folder</br>
- (If needed) update the Version file with the current date</br>
### LWJGL
- **Coming soon**
### The Launcher
- Because languages are auto-added by Crowdin, you need to run the language list generator before building. In the project directory, run:
* On Linux, Mac OS:
```
chmod +x scripts/languagelist_updater.sh
bash scripts/languagelist_updater.sh
```
* On Windows:
```
scripts\languagelist_updater.bat
```
Then, run these commands ~~or build using Android Studio~~.
* Build GLFW stub:
```
./gradlew :jre_lwjgl3glfw:build
```
* Build the launcher
```
./gradlew :app_pojavlauncher:assembleDebug
```
(Replace `gradlew` with `gradlew.bat` if you are building on Windows).
## Current status
- [x] ~~OpenJDK 9 Mobile port: ARM32, ARM64, x86, x86_64.~~ Replaced by JRE8.
- [x] OpenJDK 8 Mobile port: ARM32, ARM64, x86, x86_64
- [x] OpenJDK 17 Mobile port: ARM32, ARM64, x86, x86_64
- [x] Headless mod installer
- [x] Mod installer with GUI. Used `Caciocavallo` project for AWT without X11.
- [x] OpenGL in OpenJDK environment
- [x] OpenAL (works on most devices)
- [x] Support for Minecraft 1.12.2 and below. Used [lwjglx](https://github.com/PojavLauncherTeam/lwjglx), a LWJGL2 compatibility layer for LWJGL3.
- [x] Support for Minecraft 1.13 and above. Used [GLFW stub](https://github.com/PojavLauncherTeam/lwjgl3-glfw-java).
- [x] Support for Minecraft 1.17 (22w13a to be exact) and above. Used [Holy GL4ES](https://github.com/PojavLauncherTeam/gl4es-114-extra)
- [x] Game surface zooming.
- [x] New input pipe rewritten to native code to boost performance.
- [x] Rewritten entire controls system (thanks to @Mathias-Boulay)
- [ ] More to come!
## Known Issues
- Controller mods aren't working.
- Random crashes could happen very often on Android 5.x when loading the game or joining a world.
- With big modpacks textures could be messed up
- Probably more, that's why we have a bug tracker ;)
## License
- PojavLauncher is licensed under [GNU GPLv3](https://github.com/khanhduytran0/PojavLauncher/blob/master/LICENSE).
## Contributing
Contributions are welcome! We welcome any type of contribution, not only code. For example, you can help the wiki shape up. You can help the [translation](https://crowdin.com/project/pojavlauncher) too!
Any code change to this repository (or iOS) should be submitted as a pull request. The description should explain what the code does and give steps to execute it.
## Credits & Third party components and their licenses (if available)
- [Boardwalk](https://github.com/zhuowei/Boardwalk) (JVM Launcher): Unknown License/[Apache License 2.0](https://github.com/zhuowei/Boardwalk/blob/master/LICENSE) or GNU GPLv2.
- Android Support Libraries: [Apache License 2.0](https://android.googlesource.com/platform/prebuilts/maven_repo/android/+/master/NOTICE.txt).
- [GL4ES](https://github.com/PojavLauncherTeam/gl4es): [MIT License](https://github.com/ptitSeb/gl4es/blob/master/LICENSE).<br>
- [OpenJDK](https://github.com/PojavLauncherTeam/openjdk-multiarch-jdk8u): [GNU GPLv2 License](https://openjdk.java.net/legal/gplv2+ce.html).<br>
- [LWJGL3](https://github.com/PojavLauncherTeam/lwjgl3): [BSD-3 License](https://github.com/LWJGL/lwjgl3/blob/master/LICENSE.md).
- [LWJGLX](https://github.com/PojavLauncherTeam/lwjglx) (LWJGL2 API compatibility layer for LWJGL3): unknown license.<br>
- [Mesa 3D Graphics Library](https://gitlab.freedesktop.org/mesa/mesa): [MIT License](https://docs.mesa3d.org/license.html).
- [pro-grade](https://github.com/pro-grade/pro-grade) (Java sandboxing security manager): [Apache License 2.0](https://github.com/pro-grade/pro-grade/blob/master/LICENSE.txt).
- [xHook](https://github.com/iqiyi/xHook) (Used for exit code trapping): [MIT and BSD-style licenses](https://github.com/iqiyi/xHook/blob/master/LICENSE).
- [libepoxy](https://github.com/anholt/libepoxy): [MIT License](https://github.com/anholt/libepoxy/blob/master/COPYING).
- [virglrenderer](https://github.com/PojavLauncherTeam/virglrenderer): [MIT License](https://gitlab.freedesktop.org/virgl/virglrenderer/-/blob/master/COPYING).
- Thanks to [MCHeads](https://mc-heads.net) for providing Minecraft avatars.
Client Source
- https://gitlab.com/downthecrop/rt4-client/-/tree/lwjgl-mobile-callbacks?ref_type=heads

View file

@ -81,9 +81,6 @@ android {
compileSdk = 33
lintOptions {
abortOnError false
}
signingConfigs {
customDebug {
@ -168,6 +165,9 @@ android {
}
buildToolsVersion = '33.0.2'
lint {
abortOnError false
}
}
dependencies {

View file

@ -1 +1 @@
1690945073108
1697690411292

View file

@ -57,13 +57,15 @@ public class AWTCanvasView extends TextureView implements TextureView.SurfaceTex
Surface surface = new Surface(getSurfaceTexture());
Bitmap rgbArrayBitmap = Bitmap.createBitmap(AWT_CANVAS_WIDTH, AWT_CANVAS_HEIGHT, Bitmap.Config.ARGB_8888);
Paint paint = new Paint();
paint.setAntiAlias(false);
paint.setDither(false);
paint.setFilterBitmap(false);
long frameEndNanos;
long frameStartNanos;
long sleepTime;
long sleepMillis;
int sleepNanos;
int[] rgbArray;
// define the frame rate limit
final long frameTimeNanos = (long)(NANOS / 60); // Targeting 60 FPS
long frameDuration;
@ -107,6 +109,9 @@ public class AWTCanvasView extends TextureView implements TextureView.SurfaceTex
private void refreshSize(){
ViewGroup.LayoutParams layoutParams = getLayoutParams();
/** Note: In the future this is a good way to stretch the aspect ratio too. Like for
* 16:9 widescreen in SD mode like mudkip osrs videos */
if(getHeight() < getWidth()){
layoutParams.width = AWT_CANVAS_WIDTH * getHeight() / AWT_CANVAS_HEIGHT;
}else{

View file

@ -1,6 +1,7 @@
package net.kdt.pojavlaunch;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_DISABLE_SWAP_HAND;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_INSET_X;
import static net.kdt.pojavlaunch.utils.MCOptionUtils.getMcScale;
import static org.lwjgl.glfw.CallbackBridge.sendKeyPress;
import static org.lwjgl.glfw.CallbackBridge.sendMouseButton;
@ -156,6 +157,7 @@ public class GLFWGLSurface extends View implements GrabListener {
/** Initialize the view and all its settings */
@SuppressLint("ClickableViewAccessibility")
public void start(){
System.out.println("Hello.. I can see the inset it: "+PREF_INSET_X);
scaleGestureDetector = new ScaleGestureDetector(this.getContext(), new ScaleListener());
if(LauncherPreferences.PREF_USE_ALTERNATE_SURFACE){
SurfaceView surfaceView = new SurfaceView(getContext());
@ -218,30 +220,14 @@ public class GLFWGLSurface extends View implements GrabListener {
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {}
});
this.longPressDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
boolean isDragClicking = false;
longPressDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {
@Override
public void onLongPress(MotionEvent e) {
super.onLongPress(e);
if(!isDragClicking) {
isDragClicking = true;
AWTInputBridge.sendKey((char) AWTInputEvent.VK_F5, AWTInputEvent.VK_F5);
}
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
if(isDragClicking) {
isDragClicking = false;
AWTInputBridge.sendKey((char)AWTInputEvent.VK_F5, AWTInputEvent.VK_F5);
}
return super.onSingleTapUp(e);
CallbackBridge.putMouseEventWithCoords(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, CallbackBridge.mouseX, CallbackBridge.mouseY);
}
});
//this.longPressDetector.setIsLongpressEnabled(true);
((ViewGroup)getParent()).addView(textureView);
}
}
@ -255,7 +241,7 @@ public class GLFWGLSurface extends View implements GrabListener {
@SuppressWarnings("accessibility")
public boolean onTouchEvent(MotionEvent e) {
scaleGestureDetector.onTouchEvent(e);
//longPressDetector.onTouchEvent(e);
longPressDetector.onTouchEvent(e);
// Kinda need to send this back to the layout
if(((ControlLayout)getParent()).getModifiable()) return false;
@ -274,11 +260,10 @@ public class GLFWGLSurface extends View implements GrabListener {
//Getting scaled position from the event
/* Tells if a double tap happened [MOUSE GRAB ONLY]. Doesn't tell where though. */
if(!CallbackBridge.isGrabbing()) {
CallbackBridge.mouseX = (e.getX() * mScaleFactor);
CallbackBridge.mouseY = (e.getY() * mScaleFactor);
CallbackBridge.mouseX = (e.getX() * mScaleFactor);
CallbackBridge.mouseY = (e.getY() * mScaleFactor);
//One android click = one MC click
if(mSingleTapDetector.onTouchEvent(e)){ //
//longPressDetector.onTouchEvent(e);// Touch Mode
CallbackBridge.putMouseEventWithCoords(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, CallbackBridge.mouseX, CallbackBridge.mouseY);
return true;
}
@ -427,6 +412,7 @@ public class GLFWGLSurface extends View implements GrabListener {
// Actualise the pointer count
mLastPointerCount = e.getPointerCount();
longPressDetector.onTouchEvent(e);
return true;
}
@ -480,7 +466,6 @@ public class GLFWGLSurface extends View implements GrabListener {
// Make sure we grabbed the mouse if necessary
updateGrabState(CallbackBridge.isGrabbing());
switch(event.getActionMasked()) {
case MotionEvent.ACTION_HOVER_MOVE:
CallbackBridge.mouseX = (event.getX(mouseCursorIndex) * mScaleFactor);
@ -504,8 +489,8 @@ public class GLFWGLSurface extends View implements GrabListener {
@RequiresApi(26)
@Override
public boolean dispatchCapturedPointerEvent(MotionEvent e) {
CallbackBridge.mouseX += (e.getX()* mScaleFactor);
CallbackBridge.mouseY += (e.getY()* mScaleFactor);
CallbackBridge.mouseX = (e.getX() * mScaleFactor);
CallbackBridge.mouseY = (e.getY() * mScaleFactor);
switch (e.getActionMasked()) {
case MotionEvent.ACTION_MOVE:
@ -644,8 +629,8 @@ public class GLFWGLSurface extends View implements GrabListener {
/** Called when the size need to be set at any point during the surface lifecycle **/
public void refreshSize(){
windowWidth = Tools.getDisplayFriendlyRes(Tools.currentDisplayMetrics.widthPixels, mScaleFactor);
windowHeight = Tools.getDisplayFriendlyRes(Tools.currentDisplayMetrics.heightPixels, mScaleFactor);
windowWidth = Tools.getDisplayFriendlyRes((int) (Tools.currentDisplayMetrics.widthPixels - (PREF_INSET_X*2)), mScaleFactor);
windowHeight = Tools.getDisplayFriendlyRes((int) (Tools.currentDisplayMetrics.heightPixels - (PREF_INSET_X*2)), mScaleFactor);
if(mSurface == null){
Log.w("MGLSurface", "Attempt to refresh size on null surface");
return;

View file

@ -1,9 +1,13 @@
package net.kdt.pojavlaunch;
import static net.kdt.pojavlaunch.MainActivity.fullyExit;
import static net.kdt.pojavlaunch.Tools.currentDisplayMetrics;
import static java.security.AccessController.getContext;
import android.annotation.SuppressLint;
import android.content.ClipboardManager;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
@ -46,7 +50,10 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
private LinearLayout mTouchPad;
private ImageView mMousePointerImageView;
private GestureDetector mGestureDetector;
private GestureDetector longPressDetector;
private boolean cameraMode = false;
float prevX = 0, prevY = 0;
private long lastPress = 0;
private ScaleGestureDetector scaleGestureDetector;
private boolean rcState = false;
@ -89,10 +96,11 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
ViewGroup.LayoutParams params = mMousePointerImageView.getLayoutParams();
params.width = (int) (36 / 100f * LauncherPreferences.PREF_MOUSESCALE);
params.height = (int) (54 / 100f * LauncherPreferences.PREF_MOUSESCALE);
if(LauncherPreferences.PREF_VIRTUAL_MOUSE_START)
toggleVirtualMouse();
});
mTouchPad.setOnTouchListener(new View.OnTouchListener() {
float prevX = 0, prevY = 0;
@Override
public boolean onTouch(View v, MotionEvent event) {
// MotionEvent reports input details from the touch screen
@ -100,21 +108,26 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
// interested in events where the touch position changed.
// int index = event.getActionIndex();
int action = event.getActionMasked();
float mouseSpeed = LauncherPreferences.PREF_MOUSESPEED;
float x = event.getX();
float y = event.getY();
float mouseX, mouseY;
// Scale the mouse speed
mouseX = mMousePointerImageView.getX();
mouseY = mMousePointerImageView.getY();
if (mGestureDetector.onTouchEvent(event)) {
sendScaledMousePosition(mouseX,mouseY);
AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK);
if(rcState) {
clearRC();
}
} else {
if (action == MotionEvent.ACTION_MOVE) { // 2
mouseX = Math.max(0, Math.min(CallbackBridge.physicalWidth, mouseX + x - prevX));
mouseY = Math.max(0, Math.min(CallbackBridge.physicalHeight, mouseY + y - prevY));
mouseX = Math.max(0, Math.min(currentDisplayMetrics.widthPixels, mouseX + (x - prevX) * mouseSpeed));
mouseY = Math.max(0, Math.min(currentDisplayMetrics.heightPixels, mouseY + (y - prevY) * mouseSpeed));
placeMouseAt(mouseX, mouseY);
sendScaledMousePosition(mouseX, mouseY);
}
@ -123,8 +136,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
if (event.getPointerCount() == 2) {
// Right-click event when a second finger touches the screen
// Simulating right-click by sending GLFW_MOUSE_BUTTON_RIGHT event
Log.i("downthecrop","Hi from a rightclick event!");
activateRC();
AWTInputBridge.sendKey((char)AWTInputEvent.VK_F11,AWTInputEvent.VK_F11);
AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK);
}
}
@ -138,11 +150,15 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
mTextureView.setOnTouchListener((v, event) -> {
scaleGestureDetector.onTouchEvent(event);
longPressDetector.onTouchEvent(event);
float x = event.getX();
float y = event.getY();
if (mGestureDetector.onTouchEvent(event)) {
sendScaledMousePosition(x + mTextureView.getX(), y);
AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK);
if(rcState) {
clearRC();
}
return true;
}
@ -153,11 +169,34 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
break;
case MotionEvent.ACTION_MOVE: // 2
sendScaledMousePosition(x + mTextureView.getX(), y);
try {
panCamera(prevX-x, prevY-y);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
break;
}
prevY = y;
prevX = x;
return true;
});
longPressDetector = new GestureDetector(this, new GestureDetector.SimpleOnGestureListener() {
@Override
public void onLongPress(MotionEvent e) {
// Send RightClick
AWTInputBridge.sendKey((char)AWTInputEvent.VK_F11,AWTInputEvent.VK_F11);
AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK);
super.onLongPress(e);
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return super.onSingleTapUp(e);
}
});
try {
placeMouseAt(CallbackBridge.physicalWidth / 2f, CallbackBridge.physicalHeight / 2f);
@ -192,14 +231,28 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
} catch (Throwable th) {
Tools.showError(this, th, true);
}
}
private void panCamera(float dx, float dy) throws InterruptedException {
//Log.i("downthecrop-pan","dx: " +dx + " dy: " + dy);
final float threshold = 8.0f; // adjust this value as needed to control the sensitivity of the panning
getOnBackPressedDispatcher().addCallback(new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
MainActivity.dialogForceClose(JavaGUILauncherActivity.this);
}
});
// Check horizontal panning
if(dx > threshold) {
// Finger moved to the right, pan camera to the right
AWTInputBridge.sendKey((char)AWTInputEvent.VK_RIGHT, AWTInputEvent.VK_RIGHT);
} else if(dx < -threshold) {
AWTInputBridge.sendKey((char)AWTInputEvent.VK_LEFT, AWTInputEvent.VK_LEFT);
}
// Check vertical panning
if(dy > threshold) {
// Finger moved down, pan camera up
AWTInputBridge.sendKey((char)AWTInputEvent.VK_UP, AWTInputEvent.VK_UP);
} else if(dy < -threshold) {
// Finger moved up, pan camera down
AWTInputBridge.sendKey((char)AWTInputEvent.VK_DOWN, AWTInputEvent.VK_DOWN);
}
}
@Override
@ -250,16 +303,17 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
break;
case R.id.camera:
if (!cameraMode) { // Camera Mode On
Log.i("downthecrop", "Hello from the camrea Button");
AWTInputBridge.sendKey((char) AWTInputEvent.VK_F9, AWTInputEvent.VK_F9); // Send F9
cameraMode = true;
findViewById(R.id.camera).setBackground(getResources().getDrawable( R.drawable.control_button_pressed ));
} else { // Camera Mode off
AWTInputBridge.sendKey((char) AWTInputEvent.VK_F8, AWTInputEvent.VK_F8);
cameraMode = false;
findViewById(R.id.camera).setBackground(getResources().getDrawable( R.drawable.control_button_normal ));
}
break;
case R.id.mouseMode:
toggleVirtualMouse(this.getCurrentFocus());
toggleVirtualMouse();
}
lastPress = time;
}
@ -281,11 +335,13 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
private void clearRC(){
rcState = false;
findViewById(R.id.mb2).setBackground(getResources().getDrawable( R.drawable.control_button_normal ));
AWTInputBridge.sendKey((char)AWTInputEvent.VK_F10,AWTInputEvent.VK_F10);
}
private void activateRC(){
rcState = true;
findViewById(R.id.mb2).setBackground(getResources().getDrawable( R.drawable.control_button_pressed ));
AWTInputBridge.sendKey((char)AWTInputEvent.VK_F11,AWTInputEvent.VK_F11);
}
@ -305,8 +361,14 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
mLoggerView.setVisibility(View.VISIBLE);
}
public void toggleVirtualMouse(View v) {
public void toggleVirtualMouse() {
mIsVirtualMouseEnabled = !mIsVirtualMouseEnabled;
ImageView view = findViewById(R.id.mouseModeIco);
if(!mIsVirtualMouseEnabled){
view.setImageResource(R.drawable.touch);
} else{
view.setImageResource(R.drawable.ic_mouse3);
}
mTouchPad.setVisibility(mIsVirtualMouseEnabled ? View.VISIBLE : View.GONE);
Toast.makeText(this,
mIsVirtualMouseEnabled ? R.string.control_mouseon : R.string.control_mouseoff,
@ -324,6 +386,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
Tools.getCacioJavaArgs(javaArgList,runtime.javaVersion == 8);
javaArgList.add("-DconfigFile="+Tools.DIR_DATA + "/config.json");
javaArgList.add("-DpluginDir="+ Tools.DIR_DATA + "/plugins/");
javaArgList.add("-DclientHomeOverride="+gamedir);
javaArgList.add("-jar");
javaArgList.add(Tools.DIR_DATA+"/rt4.jar");

View file

@ -1,6 +1,7 @@
package net.kdt.pojavlaunch;
import static net.kdt.pojavlaunch.Tools.currentDisplayMetrics;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_INSET_X;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_SUSTAINED_PERFORMANCE;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_USE_ALTERNATE_SURFACE;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_VIRTUAL_MOUSE_START;
@ -70,6 +71,7 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
private DrawerLayout drawerLayout;
private ListView navDrawer;
private View mDrawerPullButton;
private View contentFrame;
private GyroControl mGyroControl = null;
public static ControlLayout mControlLayout;
@ -206,6 +208,10 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
mControlLayout = findViewById(R.id.main_control_layout);
touchCharInput = findViewById(R.id.mainTouchCharInput);
mDrawerPullButton = findViewById(R.id.drawer_button);
contentFrame = findViewById(R.id.content_frame);
int inset = (int) PREF_INSET_X;
//touchpad.setPadding(inset,inset,inset,inset);
contentFrame.setPadding(inset,inset,inset,inset);
}
@Override

View file

@ -162,10 +162,11 @@ public final class Tools {
getCacioJavaArgs(javaArgList, runtime.javaVersion == 8);
javaArgList.add("-DconfigFile="+Tools.DIR_DATA + "/config.json");
javaArgList.add("-DpluginDir="+ Tools.DIR_DATA + "/plugins/");
javaArgList.add("-DclientHomeOverride="+gamedir);
javaArgList.add("-DglfwWidth="+CallbackBridge.windowWidth);
javaArgList.add("-DglfwHeight="+CallbackBridge.windowHeight);
javaArgList.add("-DconfigFile="+Tools.DIR_DATA + "/config.json");
javaArgList.add("-cp");
javaArgList.add(getLWJGL3ClassPath()+":"+Tools.DIR_DATA+"/rt4.jar");
javaArgList.add(RT4_MAIN_CLASS);

View file

@ -3,6 +3,7 @@ package net.kdt.pojavlaunch;
import static net.kdt.pojavlaunch.GLFWGLSurface.FINGER_SCROLL_THRESHOLD;
import static net.kdt.pojavlaunch.Tools.currentDisplayMetrics;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.DEFAULT_PREF;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_SCALE_FACTOR;
import android.content.Context;
import android.os.Build;
@ -35,7 +36,7 @@ public class Touchpad extends FrameLayout implements GrabListener{
/* Detect a classic android Tap */
private final GestureDetector mSingleTapDetector = new GestureDetector(getContext(), new SingleTapConfirm());
/* Resolution scaler option, allow downsizing a window */
private final float mScaleFactor = DEFAULT_PREF.getInt("resolutionRatio",100)/100f;
private final float mScaleFactor = PREF_SCALE_FACTOR/100f;
/* Current pointer ID to move the mouse */
private int mCurrentPointerID = -1000;
/* Previous MotionEvent position, not scale */

View file

@ -42,6 +42,7 @@ import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.DIRECTI
import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.DIRECTION_SOUTH_WEST;
import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.DIRECTION_WEST;
import static net.kdt.pojavlaunch.customcontrols.gamepad.GamepadJoystick.isJoystickEvent;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_SCALE_FACTOR;
import static net.kdt.pojavlaunch.utils.MCOptionUtils.getMcScale;
import static org.lwjgl.glfw.CallbackBridge.sendKeyPress;
import static org.lwjgl.glfw.CallbackBridge.sendMouseButton;
@ -51,7 +52,7 @@ import fr.spse.gamepad_remapper.GamepadHandler;
public class Gamepad implements GrabListener, GamepadHandler {
/* Resolution scaler option, allow downsizing a window */
private final float mScaleFactor = LauncherPreferences.DEFAULT_PREF.getInt("resolutionRatio",100)/100f;
private final float mScaleFactor = PREF_SCALE_FACTOR/100f;
/* Sensitivity, adjusted according to screen size */
private final double mSensitivityFactor = (1.4 * (1080f/ currentDisplayMetrics.heightPixels));

View file

@ -23,6 +23,7 @@ import net.kdt.pojavlaunch.utils.KeyEncoder;
*/
public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText {
public static final String TEXT_FILLER = " ";
public static boolean softKeyboardIsActive = false;
public TouchCharInput(@NonNull Context context) {
this(context, null);
}
@ -49,7 +50,7 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText
Log.i("TouchCharInput","New Event (before/after)!: "+ lengthBefore + " : " + lengthAfter);
boolean isBackSpace = (lengthBefore > lengthAfter);
if(isBackSpace) {
KeyEncoder.sendEncodedChar(KeyEncoder.backspaceUnicode,KeyEncoder.backspaceUnicode);
KeyEncoder.sendUnicodeBackspace();
return;
}
char c = text.charAt(text.length()-1);
@ -115,6 +116,7 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText
/** Regain ability to exist, take focus and have some text being input */
public void enable(){
softKeyboardIsActive = true;
setEnabled(true);
setFocusable(true);
setVisibility(VISIBLE);
@ -123,6 +125,7 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText
/** Lose ability to exist, take focus and have some text being input */
public void disable(){
softKeyboardIsActive = false;
clear();
setVisibility(GONE);
clearFocus();

View file

@ -89,6 +89,7 @@ public class CustomSeekBarPreference extends SeekBarPreference {
setValue(progress + mMin);
updateTextViewWithSuffix();
System.out.println("Hello from CustomSeekBar: "+progress);
}
});

View file

@ -38,6 +38,7 @@ public class LauncherPreferences {
public static boolean PREF_DISABLE_GESTURES = false;
public static boolean PREF_DISABLE_SWAP_HAND = false;
public static float PREF_MOUSESPEED = 1f;
public static float PREF_INSET_X = 0f;
public static int PREF_RAM_ALLOCATION;
public static String PREF_DEFAULT_RUNTIME;
public static boolean PREF_SUSTAINED_PERFORMANCE = false;
@ -45,7 +46,7 @@ public class LauncherPreferences {
public static boolean PREF_ARC_CAPES = false;
public static boolean PREF_USE_ALTERNATE_SURFACE = true;
public static boolean PREF_JAVA_SANDBOX = true;
public static int PREF_SCALE_FACTOR = 100;
public static int PREF_SCALE_FACTOR = 60;
public static boolean PREF_ENABLE_GYRO = false;
public static float PREF_GYRO_SENSITIVITY = 1f;
public static int PREF_GYRO_SAMPLE_RATE = 16;
@ -72,6 +73,7 @@ public class LauncherPreferences {
PREF_BUTTONSIZE = DEFAULT_PREF.getInt("buttonscale", 100);
PREF_MOUSESCALE = DEFAULT_PREF.getInt("mousescale", 100);
PREF_MOUSESPEED = ((float)DEFAULT_PREF.getInt("mousespeed",100))/100f;
PREF_INSET_X = DEFAULT_PREF.getInt("xinset", 0)*2;
PREF_HIDE_SIDEBAR = DEFAULT_PREF.getBoolean("hideSidebar", false);
PREF_IGNORE_NOTCH = DEFAULT_PREF.getBoolean("ignoreNotch", false);
PREF_VERTYPE_RELEASE = DEFAULT_PREF.getBoolean("vertype_release", true);
@ -91,7 +93,7 @@ public class LauncherPreferences {
PREF_ARC_CAPES = DEFAULT_PREF.getBoolean("arc_capes",false);
PREF_USE_ALTERNATE_SURFACE = DEFAULT_PREF.getBoolean("alternate_surface", false);
PREF_JAVA_SANDBOX = DEFAULT_PREF.getBoolean("java_sandbox", true);
PREF_SCALE_FACTOR = DEFAULT_PREF.getInt("resolutionRatio", 100);
PREF_SCALE_FACTOR = DEFAULT_PREF.getInt("resolutionRatio", 60);
PREF_ENABLE_GYRO = DEFAULT_PREF.getBoolean("enableGyro", false);
PREF_GYRO_SENSITIVITY = ((float)DEFAULT_PREF.getInt("gyroSensitivity", 100))/100f;
PREF_GYRO_SAMPLE_RATE = DEFAULT_PREF.getInt("gyroSampleRate", 16);

View file

@ -1,6 +1,7 @@
package net.kdt.pojavlaunch.prefs.screens;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_NOTCH_SIZE;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_SCALE_FACTOR;
import android.content.SharedPreferences;
import android.os.Build;

View file

@ -1,112 +1,63 @@
package net.kdt.pojavlaunch.utils;
import net.kdt.pojavlaunch.AWTInputBridge;
import net.kdt.pojavlaunch.customcontrols.keyboard.TouchCharInput;
/*
About Key Events. Because the Android Spec doesn't require
soft keyboards to dispatch key events not all keyboard implementations
across Android will trigger these actions.
Currently we use the following function to translate keycodes for
special character, capital letters, and digits.
keycode 123 (F12) is used as a single digit capslock button which
when sent to the miniclient before a char will act accordingly.
*/
import java.util.HashMap;
import java.util.Map;
public class KeyEncoder {
static String specialChars = "/*!@#$%^&*()\"{}_[+:;=-_]'|\\?/<>,.";
static char modifier = 123;
static char backspaceAndroid = 67;
public static char backspaceUnicode = 8;
private static final Map<Character, Character> specialCharMap = createSpecialCharMap();
private static final char MODIFIER = 123; // F12 key as a modifier for caps lock
private static final char BACKSPACE_ANDROID = 67;
private static final char BACKSPACE_UNICODE = 8;
public static void sendEncodedChar(int keyCode, char iC){
System.out.println(keyCode);
if(keyCode == 75)
AWTInputBridge.sendKey((char)222,222);
else if(keyCode == backspaceAndroid){
AWTInputBridge.sendKey(backspaceUnicode,backspaceUnicode);
} else if(specialChars.contains(""+iC)){
// Send special character to client
char c = iC;
switch(c){
case '!':
c = '1';
break;
case '@':
c = '2';
break;
case '#':
c = '3';
break;
case '$':
c = '4';
break;
case '%':
c = '5';
break;
case '^':
c = '6';
break;
case '&':
c = '7';
break;
case '*':
c = '8';
break;
case '(':
c = '9';
break;
case ')':
c = '0';
break;
case '_':
c = '-';
break;
case '+':
c = '=';
break;
case '{':
c = '[';
break;
case '}':
c = ']';
break;
case ':':
c = ';';
break;
case '"':
c = '\'';
break;
case '<':
c = ',';
break;
case '>':
c = '.';
break;
case '?':
c = '/';
break;
case '|':
c = '\\';
break;
}
if(c != iC){
AWTInputBridge.sendKey(modifier,modifier);
}
AWTInputBridge.sendKey(c,c);
} else if(Character.isDigit(iC)){
AWTInputBridge.sendKey(iC,iC);
} else if (iC == Character.toUpperCase(iC)){
// We send F12 as a modifier to avoid needing to worry about shift.
// Client takes this modifier and does a toUpperCase().
AWTInputBridge.sendKey(modifier,modifier);
AWTInputBridge.sendKey(Character.toUpperCase(iC),Character.toUpperCase(iC));
} else if(iC == Character.toLowerCase(iC)){
AWTInputBridge.sendKey(Character.toUpperCase(iC),Character.toUpperCase(iC));
// Initialize the mapping of special characters to their respective keys
private static Map<Character, Character> createSpecialCharMap() {
Map<Character, Character> map = new HashMap<>();
map.put('!', '1');
map.put('@', '2');
map.put('#', '3');
map.put('$', '4');
map.put('%', '5');
map.put('^', '6');
map.put('&', '7');
map.put('*', '8');
map.put('(', '9');
map.put(')', '0');
map.put('_', '-');
map.put('+', '=');
map.put('{', '[');
map.put('}', ']');
map.put(':', ';');
map.put('"', '\'');
map.put('<', ',');
map.put('>', '.');
map.put('?', '/');
map.put('|', '\\');
return map;
}
public static void sendUnicodeBackspace(){
AWTInputBridge.sendKey(BACKSPACE_UNICODE, BACKSPACE_UNICODE);
}
public static void sendEncodedChar(int keyCode, char c) {
if (keyCode == BACKSPACE_ANDROID && !TouchCharInput.softKeyboardIsActive) {
sendUnicodeBackspace();
} else if (specialCharMap.containsKey(c)) {
AWTInputBridge.sendKey(MODIFIER, MODIFIER);
AWTInputBridge.sendKey(specialCharMap.get(c), specialCharMap.get(c));
} else if (Character.isDigit(c)) {
AWTInputBridge.sendKey(c, c);
} else if (Character.isLowerCase(c)){
AWTInputBridge.sendKey(Character.toUpperCase(c),Character.toUpperCase(c));
} else if (Character.isUpperCase(c)) {
AWTInputBridge.sendKey(MODIFIER, MODIFIER);
AWTInputBridge.sendKey(c, c);
} else {
AWTInputBridge.sendKey(iC,keyCode);
AWTInputBridge.sendKey(c, keyCode);
}
}
}
}

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@color/control_button_pressed_color" />
<item android:drawable="@color/control_button_color" />
<item android:state_pressed="true" android:drawable="@drawable/control_button_pressed" />
<item android:drawable="@drawable/control_button_normal" />
</selector>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#807f7f7f" />
<stroke android:width="2.0dip" android:color="#dd7f7f7f" />
<padding android:left="8.0dip" android:top="0.0dip" android:right="8.0dip" android:bottom="0.0dip" />
</shape>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#dd7f7f7f" />
<stroke android:width="2.0dip" android:color="#dd7f7f7f" />
<padding android:left="8.0dip" android:top="0.0dip" android:right="8.0dip" android:bottom="0.0dip" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 827 B

View file

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="#FFFFFF"
android:alpha="0.8">
<path
android:fillColor="@android:color/white"
android:pathData="M20,5L4,5c-1.1,0 -1.99,0.9 -1.99,2L2,17c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,7c0,-1.1 -0.9,-2 -2,-2zM11,8h2v2h-2L11,8zM11,11h2v2h-2v-2zM8,8h2v2L8,10L8,8zM8,11h2v2L8,13v-2zM7,13L5,13v-2h2v2zM7,10L5,10L5,8h2v2zM16,17L8,17v-2h8v2zM16,13h-2v-2h2v2zM16,10h-2L14,8h2v2zM19,13h-2v-2h2v2zM19,10h-2L17,8h2v2z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B

View file

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M9,11.24V7.5C9,6.12 10.12,5 11.5,5S14,6.12 14,7.5v3.74c1.21,-0.81 2,-2.18 2,-3.74C16,5.01 13.99,3 11.5,3S7,5.01 7,7.5C7,9.06 7.79,10.43 9,11.24zM18.84,15.87l-4.54,-2.26c-0.17,-0.07 -0.35,-0.11 -0.54,-0.11H13v-6C13,6.67 12.33,6 11.5,6S10,6.67 10,7.5v10.74c-3.6,-0.76 -3.54,-0.75 -3.67,-0.75c-0.31,0 -0.59,0.13 -0.79,0.33l-0.79,0.8l4.94,4.94C9.96,23.83 10.34,24 10.75,24h6.79c0.75,0 1.33,-0.55 1.44,-1.28l0.75,-5.27c0.01,-0.07 0.02,-0.14 0.02,-0.2C19.75,16.63 19.37,16.09 18.84,15.87z"/>
</vector>

View file

@ -48,41 +48,95 @@
</LinearLayout>
<Button
android:id="@+id/keyboard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/control_button"
android:text="K"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/mb2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/control_button"
android:text="MB2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/keyboard" />
<FrameLayout
android:id="@+id/keyboardFrame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent">
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:src="@drawable/ic_keyboard" />
<Button
android:id="@+id/keyboard"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/control_button" />
<Button
android:id="@+id/mouseMode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/control_button"
android:text="M"
app:layout_constraintBottom_toTopOf="@+id/keyboard"
app:layout_constraintStart_toStartOf="@+id/keyboard" />
</FrameLayout>
<Button
android:id="@+id/camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/control_button"
android:text="C"
app:layout_constraintBottom_toTopOf="@+id/mb2"
app:layout_constraintStart_toStartOf="@+id/mb2" />
<FrameLayout
android:id="@+id/mb2Frame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/keyboardFrame">
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:src="@drawable/ic_mouse2" />
<Button
android:id="@+id/mb2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/control_button" />
</FrameLayout>
<FrameLayout
android:id="@+id/mouseModeFrame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/keyboardFrame"
app:layout_constraintStart_toStartOf="@id/keyboardFrame">
<ImageView
android:id="@+id/mouseModeIco"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:src="@drawable/touch" />
<Button
android:id="@+id/mouseMode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/control_button" />
</FrameLayout>
<FrameLayout
android:id="@+id/cameraFrame"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/mb2Frame"
app:layout_constraintStart_toStartOf="@id/mb2Frame">
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center"
android:scaleType="fitCenter"
android:src="@drawable/ic_camera" />
<Button
android:id="@+id/camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/control_button" />
</FrameLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -2,7 +2,7 @@
<resources>
<!-- App name part -->
<string name="app_name">2009Scape</string>
<string name="app_short_name">20009Scape</string>
<string name="app_short_name">2009Scape</string>
<string name="app_motd">Launch 2009Scape on your device!</string>
<!-- Action bar part -->

View file

@ -29,9 +29,21 @@
app2:showSeekBarValue="true"
app2:selectable="false"
app2:seekBarIncrement="5"
app2:defaultValue="60"
android:icon="@drawable/ic_setting_screen_resolution"
/>
<net.kdt.pojavlaunch.prefs.CustomSeekBarPreference
android:id="@+id/customSeekBarPreference"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:icon="@drawable/ic_setting_gesture_time"
android:key="xinset"
android:summary="Add padding/insets around the HD Client to help with reachability"
android:title="Canvas Padding"
app2:seekBarIncrement="10"
app2:selectable="false"
app2:showSeekBarValue="true" />
<SwitchPreference
android:title="@string/preference_sustained_performance_title"
android:summary="@string/preference_sustained_performance_description"

View file

@ -3,3 +3,6 @@ org.gradle.configureondemand=true
android.useAndroidX=true
android.bundle.language.enableSplit=false
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false

View file

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists