From 0a3385acd229b8c1fc9e4c7951cf251aec7dadaa Mon Sep 17 00:00:00 2001 From: artDev Date: Fri, 4 Feb 2022 19:51:31 +0300 Subject: [PATCH 01/70] add Arc capes DNS injector --- .../src/main/assets/arc_dns_injector.jar | Bin 0 -> 13243 bytes .../kdt/pojavlaunch/PojavLoginActivity.java | 1 + .../prefs/LauncherPreferences.java | 2 + .../net/kdt/pojavlaunch/utils/JREUtils.java | 8 +- .../src/main/res/values/strings.xml | 2 +- .../src/main/res/xml/pref_misc.xml | 5 + arc_dns_injector/.gitignore | 1 + arc_dns_injector/build.gradle | 15 + .../artdeell/arcdns/ArcDNSInjectorAgent.java | 20 + .../git/artdeell/arcdns/CacheUtilCommons.java | 324 ++++++++++++++++ .../git/artdeell/arcdns/CacheUtil_J8.java | 153 ++++++++ .../git/artdeell/arcdns/CacheUtil_J9.java | 145 +++++++ .../artdeell/arcdns/other/JavaVersion.java | 366 ++++++++++++++++++ settings.gradle | 1 + 14 files changed, 1040 insertions(+), 3 deletions(-) create mode 100644 app_pojavlauncher/src/main/assets/arc_dns_injector.jar create mode 100644 arc_dns_injector/.gitignore create mode 100644 arc_dns_injector/build.gradle create mode 100644 arc_dns_injector/src/main/java/git/artdeell/arcdns/ArcDNSInjectorAgent.java create mode 100644 arc_dns_injector/src/main/java/git/artdeell/arcdns/CacheUtilCommons.java create mode 100644 arc_dns_injector/src/main/java/git/artdeell/arcdns/CacheUtil_J8.java create mode 100644 arc_dns_injector/src/main/java/git/artdeell/arcdns/CacheUtil_J9.java create mode 100644 arc_dns_injector/src/main/java/git/artdeell/arcdns/other/JavaVersion.java diff --git a/app_pojavlauncher/src/main/assets/arc_dns_injector.jar b/app_pojavlauncher/src/main/assets/arc_dns_injector.jar new file mode 100644 index 0000000000000000000000000000000000000000..3c9ddd6bf377c3efdb4f9439231f654c2b9a5332 GIT binary patch literal 13243 zcma*O1yEeiwmnR64esvl?(XgmK?V!1gC)4Tdmy;GTX1&^4uiXEkT0ow-<99H_x-

eX20*|+xK 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 XJk;-8BN!OM?~CGh=Fy+!&!_(n&s|-S literal 0 HcmV?d00001 diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java index 7f71feffe..4366ae75c 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java @@ -340,6 +340,7 @@ public class PojavLoginActivity extends BaseActivity // TODO: Remove after implement. Tools.copyAssetFile(this, "launcher_profiles.json", Tools.DIR_GAME_NEW, false); Tools.copyAssetFile(this,"resolv.conf",Tools.DIR_DATA, true); + Tools.copyAssetFile(this,"arc_dns_injector.jar",Tools.DIR_DATA, true); AssetManager am = this.getAssets(); unpackComponent(am, "caciocavallo"); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java index f005a4389..a2375ae02 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/LauncherPreferences.java @@ -38,6 +38,7 @@ public class LauncherPreferences public static boolean PREF_VBO_DISABLE_HACK = false; public static boolean PREF_VIRTUAL_MOUSE_START = false; public static boolean PREF_OPENGL_VERSION_HACK = false; + public static boolean PREF_ARC_CAPES = false; public static void loadPreferences(Context ctx) { @@ -71,6 +72,7 @@ public class LauncherPreferences PREF_VBO_DISABLE_HACK = DEFAULT_PREF.getBoolean("vbo_disable_hack", false); PREF_VIRTUAL_MOUSE_START = DEFAULT_PREF.getBoolean("mouse_start", false); PREF_OPENGL_VERSION_HACK = DEFAULT_PREF.getBoolean("gles_version_hack", false); + PREF_ARC_CAPES = DEFAULT_PREF.getBoolean("arc_capes",false); /* if (PREF_CUSTOM_JAVA_ARGS.isEmpty()) { diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java index f62ce4dfa..d5f9e0c2c 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java @@ -343,7 +343,8 @@ public class JREUtils { List userArguments = parseJavaArguments(LauncherPreferences.PREF_CUSTOM_JAVA_ARGS); String resolvFile; resolvFile = new File(Tools.DIR_DATA,"resolv.conf").getAbsolutePath(); - String[] overridableArguments = new String[]{ + + ArrayList overridableArguments = new ArrayList<>(Arrays.asList( "-Djava.home=" + Tools.DIR_HOME_JRE, "-Djava.io.tmpdir=" + ctx.getCacheDir().getAbsolutePath(), "-Duser.home=" + new File(Tools.DIR_GAME_NEW).getParent(), @@ -366,7 +367,10 @@ public class JREUtils { "-Dnet.minecraft.clientmodname=" + Tools.APP_NAME, "-Dfml.earlyprogresswindow=false" //Forge 1.14+ workaround - }; + )); + if(LauncherPreferences.PREF_ARC_CAPES) { + overridableArguments.add("-javaagent:"+new File(Tools.DIR_DATA,"arc_dns_injector.jar").getAbsolutePath()+"=23.95.137.176"); + } List additionalArguments = new ArrayList<>(); for(String arg : overridableArguments) { String strippedArg = arg.substring(0,arg.indexOf('=')); diff --git a/app_pojavlauncher/src/main/res/values/strings.xml b/app_pojavlauncher/src/main/res/values/strings.xml index 1bd9ab9f7..c56acc483 100644 --- a/app_pojavlauncher/src/main/res/values/strings.xml +++ b/app_pojavlauncher/src/main/res/values/strings.xml @@ -292,5 +292,5 @@ Force openGL 1 Help with compatibility on some old versions Arc Capes - Enables capes from Arc. For more information please visit https://arccapes.com + Enables capes from Arc. For more information please visit https://arccapes.com. Requires OptiFine. diff --git a/app_pojavlauncher/src/main/res/xml/pref_misc.xml b/app_pojavlauncher/src/main/res/xml/pref_misc.xml index dff30194a..bb241cfbf 100644 --- a/app_pojavlauncher/src/main/res/xml/pref_misc.xml +++ b/app_pojavlauncher/src/main/res/xml/pref_misc.xml @@ -26,6 +26,11 @@ android:key="checkLibraries" android:summary="@string/mcl_setting_check_libraries_subtitle" android:title="@string/mcl_setting_check_libraries" /> + diff --git a/arc_dns_injector/.gitignore b/arc_dns_injector/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/arc_dns_injector/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/arc_dns_injector/build.gradle b/arc_dns_injector/build.gradle new file mode 100644 index 000000000..85e789bf6 --- /dev/null +++ b/arc_dns_injector/build.gradle @@ -0,0 +1,15 @@ +plugins { + id 'java-library' +} + +java { + sourceCompatibility = JavaVersion.VERSION_1_7 + targetCompatibility = JavaVersion.VERSION_1_7 +} +jar { + manifest { + attributes("Manifest-Version": "1.0", + "PreMain-Class": "git.artdeell.arcdns.ArcDNSInjectorAgent") + } + destinationDirectory.set(file("../app_pojavlauncher/src/main/assets/")) +} \ No newline at end of file diff --git a/arc_dns_injector/src/main/java/git/artdeell/arcdns/ArcDNSInjectorAgent.java b/arc_dns_injector/src/main/java/git/artdeell/arcdns/ArcDNSInjectorAgent.java new file mode 100644 index 000000000..70fbb05fa --- /dev/null +++ b/arc_dns_injector/src/main/java/git/artdeell/arcdns/ArcDNSInjectorAgent.java @@ -0,0 +1,20 @@ +package git.artdeell.arcdns; + +public class ArcDNSInjectorAgent { + public static void premain(String args) { + System.out.println("Arc Capes DNS Injector"); + System.out.println("Parts of Alibaba's DCM library were used, please read https://github.com/alibaba/java-dns-cache-manipulator/blob/main/README.md for more info"); + try { + String[] injectedIps = new String[]{args}; + if (CacheUtilCommons.isJavaVersionAtMost8()) { + CacheUtil_J8.setInetAddressCache("s.optifine.net", injectedIps, CacheUtilCommons.NEVER_EXPIRATION); + } else { + CacheUtil_J9.setInetAddressCache("s.optifine.net", injectedIps, CacheUtilCommons.NEVER_EXPIRATION); + } + System.out.println("Added DNS cache entry: s.optifine.net/"+args); + }catch (Exception e) { + System.out.println("Failed to inject cache!"); + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/arc_dns_injector/src/main/java/git/artdeell/arcdns/CacheUtilCommons.java b/arc_dns_injector/src/main/java/git/artdeell/arcdns/CacheUtilCommons.java new file mode 100644 index 000000000..5de79fb24 --- /dev/null +++ b/arc_dns_injector/src/main/java/git/artdeell/arcdns/CacheUtilCommons.java @@ -0,0 +1,324 @@ +package git.artdeell.arcdns; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import git.artdeell.arcdns.other.JavaVersion; + +public class CacheUtilCommons { + public static final long NEVER_EXPIRATION = Long.MAX_VALUE; + static InetAddress[] toInetAddressArray(String host, String[] ips) throws UnknownHostException { + InetAddress[] addresses = new InetAddress[ips.length]; + for (int i = 0; i < addresses.length; i++) { + addresses[i] = InetAddress.getByAddress(host, ip2ByteArray(ips[i])); + } + return addresses; + } + private static final String INVALID_IP_V6_ADDRESS = ": invalid IPv6 address"; + private static final String INVALID_IP_ADDRESS = ": invalid IP address"; + + static byte[] ip2ByteArray(String ip) { + boolean ipv6Expected = false; + if (ip.charAt(0) == '[') { + // This is supposed to be an IPv6 literal + if (ip.length() > 2 && ip.charAt(ip.length() - 1) == ']') { + ip = ip.substring(1, ip.length() - 1); + ipv6Expected = true; + } else { + // This was supposed to be a IPv6 address, but it's not! + throw new IllegalArgumentException(ip + INVALID_IP_V6_ADDRESS); + } + } + + if (Character.digit(ip.charAt(0), 16) != -1 || (ip.charAt(0) == ':')) { + // see if it is IPv4 address + byte[] address = textToNumericFormatV4(ip); + if (address != null) return address; + + // see if it is IPv6 address + // Check if a numeric or string zone id is present + address = textToNumericFormatV6(ip); + if (address != null) return address; + + if (ipv6Expected) { + throw new IllegalArgumentException(ip + INVALID_IP_V6_ADDRESS); + } else { + throw new IllegalArgumentException(ip + INVALID_IP_ADDRESS); + } + } else { + throw new IllegalArgumentException(ip + INVALID_IP_ADDRESS); + } + } + private static final int INADDR4SZ = 4; + private static final int INADDR16SZ = 16; + private static final int INT16SZ = 2; + + /* + * Converts IPv4 address in its textual presentation form + * into its numeric binary form. + * + * @param src a String representing an IPv4 address in standard format + * @return a byte array representing the IPv4 numeric address + */ + @SuppressWarnings("fallthrough") + static byte[] textToNumericFormatV4(String src) + { + byte[] res = new byte[INADDR4SZ]; + + long tmpValue = 0; + int currByte = 0; + boolean newOctet = true; + + int len = src.length(); + if (len == 0 || len > 15) { + return null; + } + /* + * When only one part is given, the value is stored directly in + * the network address without any byte rearrangement. + * + * When a two part address is supplied, the last part is + * interpreted as a 24-bit quantity and placed in the right + * most three bytes of the network address. This makes the + * two part address format convenient for specifying Class A + * network addresses as net.host. + * + * When a three part address is specified, the last part is + * interpreted as a 16-bit quantity and placed in the right + * most two bytes of the network address. This makes the + * three part address format convenient for specifying + * Class B net- work addresses as 128.net.host. + * + * When four parts are specified, each is interpreted as a + * byte of data and assigned, from left to right, to the + * four bytes of an IPv4 address. + * + * We determine and parse the leading parts, if any, as single + * byte values in one pass directly into the resulting byte[], + * then the remainder is treated as a 8-to-32-bit entity and + * translated into the remaining bytes in the array. + */ + for (int i = 0; i < len; i++) { + char c = src.charAt(i); + if (c == '.') { + if (newOctet || tmpValue < 0 || tmpValue > 0xff || currByte == 3) { + return null; + } + res[currByte++] = (byte) (tmpValue & 0xff); + tmpValue = 0; + newOctet = true; + } else { + int digit = Character.digit(c, 10); + if (digit < 0) { + return null; + } + tmpValue *= 10; + tmpValue += digit; + newOctet = false; + } + } + if (newOctet || tmpValue < 0 || tmpValue >= (1L << ((4 - currByte) * 8))) { + return null; + } + switch (currByte) { + case 0: + res[0] = (byte) ((tmpValue >> 24) & 0xff); + case 1: + res[1] = (byte) ((tmpValue >> 16) & 0xff); + case 2: + res[2] = (byte) ((tmpValue >> 8) & 0xff); + case 3: + res[3] = (byte) ((tmpValue >> 0) & 0xff); + } + return res; + } + + /* + * Convert IPv6 presentation level address to network order binary form. + * credit: + * Converted from C code from Solaris 8 (inet_pton) + * + * Any component of the string following a per-cent % is ignored. + * + * @param src a String representing an IPv6 address in textual format + * @return a byte array representing the IPv6 numeric address + */ + static byte[] textToNumericFormatV6(String src) + { + // Shortest valid string is "::", hence at least 2 chars + if (src.length() < 2) { + return null; + } + + int colonp; + char ch; + boolean saw_xdigit; + int val; + char[] srcb = src.toCharArray(); + byte[] dst = new byte[INADDR16SZ]; + + int srcb_length = srcb.length; + int pc = src.indexOf ('%'); + if (pc == srcb_length -1) { + return null; + } + + if (pc != -1) { + srcb_length = pc; + } + + colonp = -1; + int i = 0, j = 0; + /* Leading :: requires some special handling. */ + if (srcb[i] == ':') + if (srcb[++i] != ':') + return null; + int curtok = i; + saw_xdigit = false; + val = 0; + while (i < srcb_length) { + ch = srcb[i++]; + int chval = Character.digit(ch, 16); + if (chval != -1) { + val <<= 4; + val |= chval; + if (val > 0xffff) + return null; + saw_xdigit = true; + continue; + } + if (ch == ':') { + curtok = i; + if (!saw_xdigit) { + if (colonp != -1) + return null; + colonp = j; + continue; + } else if (i == srcb_length) { + return null; + } + if (j + INT16SZ > INADDR16SZ) + return null; + dst[j++] = (byte) ((val >> 8) & 0xff); + dst[j++] = (byte) (val & 0xff); + saw_xdigit = false; + val = 0; + continue; + } + if (ch == '.' && ((j + INADDR4SZ) <= INADDR16SZ)) { + String ia4 = src.substring(curtok, srcb_length); + /* check this IPv4 address has 3 dots, ie. A.B.C.D */ + int dot_count = 0, index=0; + while ((index = ia4.indexOf ('.', index)) != -1) { + dot_count ++; + index ++; + } + if (dot_count != 3) { + return null; + } + byte[] v4addr = textToNumericFormatV4(ia4); + if (v4addr == null) { + return null; + } + for (int k = 0; k < INADDR4SZ; k++) { + dst[j++] = v4addr[k]; + } + saw_xdigit = false; + break; /* '\0' was seen by inet_pton4(). */ + } + return null; + } + if (saw_xdigit) { + if (j + INT16SZ > INADDR16SZ) + return null; + dst[j++] = (byte) ((val >> 8) & 0xff); + dst[j++] = (byte) (val & 0xff); + } + + if (colonp != -1) { + int n = j - colonp; + + if (j == INADDR16SZ) + return null; + for (i = 1; i <= n; i++) { + dst[INADDR16SZ - i] = dst[colonp + n - i]; + dst[colonp + n - i] = 0; + } + j = INADDR16SZ; + } + if (j != INADDR16SZ) + return null; + byte[] newdst = convertFromIPv4MappedAddress(dst); + if (newdst != null) { + return newdst; + } else { + return dst; + } + } + + /* + * Convert IPv4-Mapped address to IPv4 address. Both input and + * returned value are in network order binary form. + * + * @param src a String representing an IPv4-Mapped address in textual format + * @return a byte array representing the IPv4 numeric address + */ + private static byte[] convertFromIPv4MappedAddress(byte[] addr) { + if (isIPv4MappedAddress(addr)) { + byte[] newAddr = new byte[INADDR4SZ]; + System.arraycopy(addr, 12, newAddr, 0, INADDR4SZ); + return newAddr; + } + return null; + } + + /** + * Utility routine to check if the InetAddress is an + * IPv4 mapped IPv6 address. + * + * @return a boolean indicating if the InetAddress is + * an IPv4 mapped IPv6 address; or false if address is IPv4 address. + */ + private static boolean isIPv4MappedAddress(byte[] addr) { + if (addr.length < INADDR16SZ) { + return false; + } + if ((addr[0] == 0x00) && (addr[1] == 0x00) && + (addr[2] == 0x00) && (addr[3] == 0x00) && + (addr[4] == 0x00) && (addr[5] == 0x00) && + (addr[6] == 0x00) && (addr[7] == 0x00) && + (addr[8] == 0x00) && (addr[9] == 0x00) && + (addr[10] == (byte)0xff) && + (addr[11] == (byte)0xff)) { + return true; + } + return false; + } + public static boolean isJavaVersionAtMost8() { + return JAVA_SPECIFICATION_VERSION_AS_ENUM.atMost(JavaVersion.JAVA_1_8); + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // + // Below source code is copied from commons-lang-3.12.0: + // + // https://github.com/apache/commons-lang/blob/rel/commons-lang-3.12.0/src/main/java/org/apache/commons/lang3/SystemUtils.java + // + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + private static final String JAVA_SPECIFICATION_VERSION = getSystemProperty("java.specification.version"); + private static final JavaVersion JAVA_SPECIFICATION_VERSION_AS_ENUM = JavaVersion.get(JAVA_SPECIFICATION_VERSION); + + @SuppressWarnings({"CommentedOutCode", "SameParameterValue"}) + private static String getSystemProperty(final String property) { + try { + return System.getProperty(property); + } catch (final SecurityException ex) { + // we are not allowed to look at this property + // System.err.println("Caught a SecurityException reading the system property '" + property + // + "'; the SystemUtils property value will default to null."); + return null; + } + } + +} diff --git a/arc_dns_injector/src/main/java/git/artdeell/arcdns/CacheUtil_J8.java b/arc_dns_injector/src/main/java/git/artdeell/arcdns/CacheUtil_J8.java new file mode 100644 index 000000000..7c53da9be --- /dev/null +++ b/arc_dns_injector/src/main/java/git/artdeell/arcdns/CacheUtil_J8.java @@ -0,0 +1,153 @@ +package git.artdeell.arcdns; + +import static git.artdeell.arcdns.CacheUtilCommons.NEVER_EXPIRATION; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Map; + + +public final class CacheUtil_J8 { + + public static void setInetAddressCache(String host, String[] ips, long expireMillis) + throws UnknownHostException, IllegalAccessException, InstantiationException, + InvocationTargetException, ClassNotFoundException, NoSuchFieldException { + host = host.toLowerCase(); + long expiration = expireMillis == NEVER_EXPIRATION ? NEVER_EXPIRATION : System.currentTimeMillis() + expireMillis; + Object entry = newCacheEntry(host, ips, expiration); + + synchronized (getAddressCacheOfInetAddress()) { + getCache().put(host, entry); + getNegativeCache().remove(host); + } + } + + private static Object newCacheEntry(String host, String[] ips, long expiration) + throws UnknownHostException, ClassNotFoundException, IllegalAccessException, + InvocationTargetException, InstantiationException { + // InetAddress.CacheEntry has only one constructor + return getConstructorOfInetAddress$CacheEntry().newInstance(CacheUtilCommons.toInetAddressArray(host, ips), expiration); + } + + private static volatile Constructor constructorOfInetAddress$CacheEntry = null; + + private static Constructor getConstructorOfInetAddress$CacheEntry() throws ClassNotFoundException { + if (constructorOfInetAddress$CacheEntry != null) return constructorOfInetAddress$CacheEntry; + + synchronized (CacheUtilCommons.class) { + // double check + if (constructorOfInetAddress$CacheEntry != null) return constructorOfInetAddress$CacheEntry; + + final String className = "java.net.InetAddress$CacheEntry"; + final Class clazz = Class.forName(className); + + // InetAddress.CacheEntry has only one constructor: + // - for jdk 6, constructor signature is CacheEntry(Object address, long expiration) + // - for jdk 7/8, constructor signature is CacheEntry(InetAddress[] addresses, long expiration) + // + // code in jdk 6: + // https://hg.openjdk.java.net/jdk6/jdk6/jdk/file/8deef18bb749/src/share/classes/java/net/InetAddress.java#l739 + // code in jdk 7: + // https://hg.openjdk.java.net/jdk7u/jdk7u/jdk/file/4dd5e486620d/src/share/classes/java/net/InetAddress.java#l742 + // code in jdk 8: + // https://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/45e4e636b757/src/share/classes/java/net/InetAddress.java#l748 + final Constructor constructor = clazz.getDeclaredConstructors()[0]; + constructor.setAccessible(true); + + constructorOfInetAddress$CacheEntry = constructor; + return constructor; + } + } + + public static void removeInetAddressCache(String host) + throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException { + host = host.toLowerCase(); + + synchronized (getAddressCacheOfInetAddress()) { + getCache().remove(host); + getNegativeCache().remove(host); + } + } + + private static Map getCache() + throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException { + return getCacheOfInetAddress$Cache0(getAddressCacheOfInetAddress()); + } + + private static Map getNegativeCache() + throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException { + return getCacheOfInetAddress$Cache0(getNegativeCacheOfInetAddress()); + } + + + private static volatile Field cacheMapFieldOfInetAddress$Cache = null; + + @SuppressWarnings("unchecked") + private static Map getCacheOfInetAddress$Cache0(Object inetAddressCache) + throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException { + if (cacheMapFieldOfInetAddress$Cache == null) { + synchronized (CacheUtil_J8.class) { + if (cacheMapFieldOfInetAddress$Cache == null) { // double check + final Class clazz = Class.forName("java.net.InetAddress$Cache"); + final Field f = clazz.getDeclaredField("cache"); + f.setAccessible(true); + cacheMapFieldOfInetAddress$Cache = f; + } + } + } + + return (Map) cacheMapFieldOfInetAddress$Cache.get(inetAddressCache); + } + + private static Object getAddressCacheOfInetAddress() + throws NoSuchFieldException, IllegalAccessException { + return getAddressCacheAndNegativeCacheOfInetAddress0()[0]; + } + + private static Object getNegativeCacheOfInetAddress() + throws NoSuchFieldException, IllegalAccessException { + return getAddressCacheAndNegativeCacheOfInetAddress0()[1]; + } + + private static volatile Object[] ADDRESS_CACHE_AND_NEGATIVE_CACHE = null; + + private static Object[] getAddressCacheAndNegativeCacheOfInetAddress0() + throws NoSuchFieldException, IllegalAccessException { + if (ADDRESS_CACHE_AND_NEGATIVE_CACHE != null) return ADDRESS_CACHE_AND_NEGATIVE_CACHE; + + synchronized (CacheUtil_J8.class) { + // double check + if (ADDRESS_CACHE_AND_NEGATIVE_CACHE != null) return ADDRESS_CACHE_AND_NEGATIVE_CACHE; + + final Field cacheField = InetAddress.class.getDeclaredField("addressCache"); + cacheField.setAccessible(true); + + final Field negativeCacheField = InetAddress.class.getDeclaredField("negativeCache"); + negativeCacheField.setAccessible(true); + + ADDRESS_CACHE_AND_NEGATIVE_CACHE = new Object[]{ + cacheField.get(InetAddress.class), + negativeCacheField.get(InetAddress.class) + }; + return ADDRESS_CACHE_AND_NEGATIVE_CACHE; + } + } + + private static boolean isDnsCacheEntryExpired(String host) { + return null == host || "0.0.0.0".equals(host); + } + + public static void clearInetAddressCache() + throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException { + synchronized (getAddressCacheOfInetAddress()) { + getCache().clear(); + getNegativeCache().clear(); + } + } + + private CacheUtil_J8() { + } +} diff --git a/arc_dns_injector/src/main/java/git/artdeell/arcdns/CacheUtil_J9.java b/arc_dns_injector/src/main/java/git/artdeell/arcdns/CacheUtil_J9.java new file mode 100644 index 000000000..b54060bae --- /dev/null +++ b/arc_dns_injector/src/main/java/git/artdeell/arcdns/CacheUtil_J9.java @@ -0,0 +1,145 @@ +package git.artdeell.arcdns; +import static git.artdeell.arcdns.CacheUtilCommons.NEVER_EXPIRATION; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentSkipListSet; +public class CacheUtil_J9 { + public static void setInetAddressCache(String host, String[] ips, long expireMillis) + throws UnknownHostException, IllegalAccessException, InstantiationException, + InvocationTargetException, ClassNotFoundException, NoSuchFieldException { + long expiration = expireMillis == NEVER_EXPIRATION ? NEVER_EXPIRATION : System.nanoTime() + expireMillis * 1_000_000; + Object cachedAddresses = newCachedAddresses(host, ips, expiration); + + getCacheOfInetAddress().put(host, cachedAddresses); + getExpirySetOfInetAddress().add(cachedAddresses); + } + + private static Object newCachedAddresses(String host, String[] ips, long expiration) + throws ClassNotFoundException, UnknownHostException, IllegalAccessException, + InvocationTargetException, InstantiationException { + // InetAddress.CachedAddresses has only one constructor + return getConstructorOfInetAddress$CachedAddresses().newInstance(host, CacheUtilCommons.toInetAddressArray(host, ips), expiration); + } + + private static volatile Constructor constructorOfInetAddress$CachedAddresses = null; + + private static Constructor getConstructorOfInetAddress$CachedAddresses() throws ClassNotFoundException { + if (constructorOfInetAddress$CachedAddresses != null) return constructorOfInetAddress$CachedAddresses; + + synchronized (CacheUtilCommons.class) { + // double check + if (constructorOfInetAddress$CachedAddresses != null) return constructorOfInetAddress$CachedAddresses; + + final Class clazz = Class.forName(inetAddress$CachedAddresses_ClassName); + + // InetAddress.CacheEntry has only one constructor: + // + // - for jdk 9-jdk12, constructor signature is CachedAddresses(String host, InetAddress[] inetAddresses, long expiryTime) + // code in jdk 9: + // https://hg.openjdk.java.net/jdk9/jdk9/jdk/file/65464a307408/src/java.base/share/classes/java/net/InetAddress.java#l783 + // code in jdk 11: + // https://hg.openjdk.java.net/jdk/jdk11/file/1ddf9a99e4ad/src/java.base/share/classes/java/net/InetAddress.java#l787 + final Constructor constructor = clazz.getDeclaredConstructors()[0]; + constructor.setAccessible(true); + + constructorOfInetAddress$CachedAddresses = constructor; + return constructor; + } + } + + public static void removeInetAddressCache(String host) throws NoSuchFieldException, IllegalAccessException { + getCacheOfInetAddress().remove(host); + removeHostFromExpirySetOfInetAddress(host); + } + + /** + * @see #getExpirySetOfInetAddress() + */ + private static void removeHostFromExpirySetOfInetAddress(String host) + throws NoSuchFieldException, IllegalAccessException { + for (Iterator iterator = getExpirySetOfInetAddress().iterator(); iterator.hasNext(); ) { + Object cachedAddresses = iterator.next(); + if (getHostOfInetAddress$CacheAddress(cachedAddresses).equals(host)) { + iterator.remove(); + } + } + } + + private static volatile Field hostFieldOfInetAddress$CacheAddress = null; + + private static String getHostOfInetAddress$CacheAddress(Object cachedAddresses) + throws NoSuchFieldException, IllegalAccessException { + if (hostFieldOfInetAddress$CacheAddress == null) { + synchronized (CacheUtil_J9.class) { + if (hostFieldOfInetAddress$CacheAddress == null) { // double check + final Field f = cachedAddresses.getClass().getDeclaredField("host"); + f.setAccessible(true); + hostFieldOfInetAddress$CacheAddress = f; + } + } + } + return (String) hostFieldOfInetAddress$CacheAddress.get(cachedAddresses); + } + + + ////////////////////////////////////////////////////////////////////////////// + // getters of static cache related fields of InetAddress + ////////////////////////////////////////////////////////////////////////////// + + @SuppressWarnings("unchecked") + private static ConcurrentMap getCacheOfInetAddress() + throws NoSuchFieldException, IllegalAccessException { + return (ConcurrentMap) getCacheAndExpirySetOfInetAddress0()[0]; + } + + @SuppressWarnings("unchecked") + private static ConcurrentSkipListSet getExpirySetOfInetAddress() + throws NoSuchFieldException, IllegalAccessException { + return (ConcurrentSkipListSet) getCacheAndExpirySetOfInetAddress0()[1]; + } + + private static volatile Object[] ADDRESS_CACHE_AND_EXPIRY_SET = null; + + private static Object[] getCacheAndExpirySetOfInetAddress0() + throws NoSuchFieldException, IllegalAccessException { + if (ADDRESS_CACHE_AND_EXPIRY_SET != null) return ADDRESS_CACHE_AND_EXPIRY_SET; + + synchronized (CacheUtil_J9.class) { + if (ADDRESS_CACHE_AND_EXPIRY_SET != null) return ADDRESS_CACHE_AND_EXPIRY_SET; + + final Field cacheField = InetAddress.class.getDeclaredField("cache"); + cacheField.setAccessible(true); + + final Field expirySetField = InetAddress.class.getDeclaredField("expirySet"); + expirySetField.setAccessible(true); + + ADDRESS_CACHE_AND_EXPIRY_SET = new Object[]{ + cacheField.get(InetAddress.class), + expirySetField.get(InetAddress.class) + }; + + return ADDRESS_CACHE_AND_EXPIRY_SET; + } + } + + ////////////////////////////////////////////////////////////////////////////// + + private static final String inetAddress$CachedAddresses_ClassName = "java.net.InetAddress$CachedAddresses"; + public static void clearInetAddressCache() throws NoSuchFieldException, IllegalAccessException { + getCacheOfInetAddress().clear(); + getExpirySetOfInetAddress().clear(); + } + + private CacheUtil_J9() { + } + +} diff --git a/arc_dns_injector/src/main/java/git/artdeell/arcdns/other/JavaVersion.java b/arc_dns_injector/src/main/java/git/artdeell/arcdns/other/JavaVersion.java new file mode 100644 index 000000000..2f0afb47d --- /dev/null +++ b/arc_dns_injector/src/main/java/git/artdeell/arcdns/other/JavaVersion.java @@ -0,0 +1,366 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package git.artdeell.arcdns.other; + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// This source code file is copied and small adopted from commons-lang-3.12.0: +// +// https://github.com/apache/commons-lang/blob/rel/commons-lang-3.12.0/src/main/java/org/apache/commons/lang3/JavaVersion.java +// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +/** + *

An enum representing all the versions of the Java specification. + * This is intended to mirror available values from the + * java.specification.version System property.

+ * + * @since 3.0 + */ +@SuppressWarnings({"unused", "SameParameterValue"}) +public +enum JavaVersion { + + /** + * The Java version reported by Android. This is not an official Java version number. + */ + JAVA_0_9(1.5f, "0.9"), + + /** + * Java 1.1. + */ + JAVA_1_1(1.1f, "1.1"), + + /** + * Java 1.2. + */ + JAVA_1_2(1.2f, "1.2"), + + /** + * Java 1.3. + */ + JAVA_1_3(1.3f, "1.3"), + + /** + * Java 1.4. + */ + JAVA_1_4(1.4f, "1.4"), + + /** + * Java 1.5. + */ + JAVA_1_5(1.5f, "1.5"), + + /** + * Java 1.6. + */ + JAVA_1_6(1.6f, "1.6"), + + /** + * Java 1.7. + */ + JAVA_1_7(1.7f, "1.7"), + + /** + * Java 1.8. + */ + JAVA_1_8(1.8f, "1.8"), + + /** + * Java 1.9. + * + * @deprecated As of release 3.5, replaced by {@link #JAVA_9} + */ + @Deprecated + JAVA_1_9(9.0f, "9"), + + /** + * Java 9. + * + * @since 3.5 + */ + JAVA_9(9.0f, "9"), + + /** + * Java 10. + * + * @since 3.7 + */ + JAVA_10(10.0f, "10"), + + /** + * Java 11. + * + * @since 3.8 + */ + JAVA_11(11.0f, "11"), + + /** + * Java 12. + * + * @since 3.9 + */ + JAVA_12(12.0f, "12"), + + /** + * Java 13. + * + * @since 3.9 + */ + JAVA_13(13.0f, "13"), + + /** + * Java 14. + * + * @since 3.11 + */ + JAVA_14(14.0f, "14"), + + /** + * Java 15. + * + * @since 3.11 + */ + JAVA_15(15.0f, "15"), + + /** + * Java 16. + * + * @since 3.11 + */ + JAVA_16(16.0f, "16"), + + /** + * Java 17. + * + * @since 3.12.0 + */ + JAVA_17(17.0f, "17"), + + /** + * The most recent java version. Mainly introduced to avoid to break when a new version of Java is used. + */ + JAVA_RECENT(maxVersion(), Float.toString(maxVersion())); + + /** + * The float value. + */ + private final float value; + + /** + * The standard name. + */ + private final String name; + + /** + * Constructor. + * + * @param value the float value + * @param name the standard name, not null + */ + JavaVersion(final float value, final String name) { + this.value = value; + this.name = name; + } + + //----------------------------------------------------------------------- + + /** + *

Whether this version of Java is at least the version of Java passed in.

+ * + *

For example:
+ * {@code myVersion.atLeast(JavaVersion.JAVA_1_4)}

+ * + * @param requiredVersion the version to check against, not null + * @return true if this version is equal to or greater than the specified version + */ + public boolean atLeast(final JavaVersion requiredVersion) { + return this.value >= requiredVersion.value; + } + + //----------------------------------------------------------------------- + + /** + *

Whether this version of Java is at most the version of Java passed in.

+ * + *

For example:
+ * {@code myVersion.atMost(JavaVersion.JAVA_1_4)}

+ * + * @param requiredVersion the version to check against, not null + * @return true if this version is equal to or greater than the specified version + * @since 3.9 + */ + public boolean atMost(final JavaVersion requiredVersion) { + return this.value <= requiredVersion.value; + } + + /** + * Transforms the given string with a Java version number to the + * corresponding constant of this enumeration class. This method is used + * internally. + * + * @param nom the Java version as string + * @return the corresponding enumeration constant or null if the + * version is unknown + */ + // helper for static importing + static JavaVersion getJavaVersion(final String nom) { + return get(nom); + } + + /** + * Transforms the given string with a Java version number to the + * corresponding constant of this enumeration class. This method is used + * internally. + * + * @param versionStr the Java version as string + * @return the corresponding enumeration constant or null if the + * version is unknown + */ + public static JavaVersion get(final String versionStr) { + if (versionStr == null) { + return null; + } + switch (versionStr) { + case "0.9": + return JAVA_0_9; + case "1.1": + return JAVA_1_1; + case "1.2": + return JAVA_1_2; + case "1.3": + return JAVA_1_3; + case "1.4": + return JAVA_1_4; + case "1.5": + return JAVA_1_5; + case "1.6": + return JAVA_1_6; + case "1.7": + return JAVA_1_7; + case "1.8": + return JAVA_1_8; + case "9": + return JAVA_9; + case "10": + return JAVA_10; + case "11": + return JAVA_11; + case "12": + return JAVA_12; + case "13": + return JAVA_13; + case "14": + return JAVA_14; + case "15": + return JAVA_15; + case "16": + return JAVA_16; + case "17": + return JAVA_17; + } + final float v = toFloatVersion(versionStr); + if ((v - 1.) < 1.) { // then we need to check decimals > .9 + final int firstComma = Math.max(versionStr.indexOf('.'), versionStr.indexOf(',')); + final int end = Math.max(versionStr.length(), versionStr.indexOf(',', firstComma)); + if (Float.parseFloat(versionStr.substring(firstComma + 1, end)) > .9f) { + return JAVA_RECENT; + } + } else if (v > 10) { + return JAVA_RECENT; + } + return null; + } + + //----------------------------------------------------------------------- + + /** + *

The string value is overridden to return the standard name.

+ * + *

For example, {@code "1.5"}.

+ * + * @return the name, not null + */ + @Override + public String toString() { + return name; + } + + /** + * Gets the Java Version from the system or 99.0 if the {@code java.specification.version} system property is not set. + * + * @return the value of {@code java.specification.version} system property or 99.0 if it is not set. + */ + private static float maxVersion() { + final float v = toFloatVersion(System.getProperty("java.specification.version", "99.0")); + if (v > 0) { + return v; + } + return 99f; + } + + /** + * Parses a float value from a String. + * + * @param value the String to parse. + * @return the float value represented by the string or -1 if the given String can not be parsed. + */ + private static float toFloatVersion(final String value) { + final int defaultReturnValue = -1; + if (value.contains(".")) { + final String[] toParse = value.split("\\."); + if (toParse.length >= 2) { + return toFloat(toParse[0] + '.' + toParse[1], defaultReturnValue); + } + } else { + return toFloat(value, defaultReturnValue); + } + return defaultReturnValue; + } + + /** + *

Convert a {@code String} to a {@code float}, returning a + * default value if the conversion fails.

+ * + *

If the string {@code str} is {@code null}, the default + * value is returned.

+ * + *
+     *   NumberUtils.toFloat(null, 1.1f)   = 1.0f
+     *   NumberUtils.toFloat("", 1.1f)     = 1.1f
+     *   NumberUtils.toFloat("1.5", 0.0f)  = 1.5f
+     * 
+ * + * @param str the string to convert, may be {@code null} + * @param defaultValue the default value + * @return the float represented by the string, or defaultValue + * if conversion fails + * @since 2.1 + */ + private static float toFloat(final String str, final float defaultValue) { + if (str == null) { + return defaultValue; + } + try { + return Float.parseFloat(str); + } catch (final NumberFormatException nfe) { + return defaultValue; + } + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 1e810efdd..cb6045552 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,3 +2,4 @@ rootProject.name='PojavLauncher' include ':jre_lwjgl3glfw' include ':app_pojavlauncher' +include ':arc_dns_injector' From fb0a96a33fa611e304d26dd2d33ffaec9832d9f6 Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh <40482367+khanhduytran0@users.noreply.github.com> Date: Thu, 10 Feb 2022 11:00:57 +0700 Subject: [PATCH 02/70] Bug fix: Arc DNS injector breaks on Java 17 Error: Failed to inject cache! java.lang.reflect.InaccessibleObjectException: Unable to make java.net.InetAddress$CachedAddresses(java.lang.String,java.net.InetAddress[],long) accessible: module java.base does not "opens java.net" to unnamed module @4157f54e --- app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java index 7c2c23dfa..150f1f77f 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -136,6 +136,9 @@ public final class Tools { // Only Java 8 supports headful AWT for now if (JREUtils.jreReleaseList.get("JAVA_VERSION").equals("1.8.0")) { getCacioJavaArgs(javaArgList, false); + } else if (LauncherPreferences.PREF_ARC_CAPES) { + // Opens the java.net package to Arc DNS injector on Java 9+ + javaArgList.add("--add-opens=java.base/java.net=ALL-UNNAMED"); } /* From 7c3d1712e9148d73bdc567c0693fef127ee9089d Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh <40482367+khanhduytran0@users.noreply.github.com> Date: Tue, 15 Feb 2022 17:28:08 +0700 Subject: [PATCH 03/70] =?UTF-8?q?Validate=20assets=20even=20if=20it?= =?UTF-8?q?=E2=80=99s=20fully=20downloaded=20(#2730)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java index b560a505a..8f8890ce7 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java @@ -427,8 +427,8 @@ public class MinecraftDownloaderTask extends AsyncTask workQueue = new LinkedBlockingQueue<>(); final ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 500, TimeUnit.MILLISECONDS, workQueue); mActivity.mIsAssetsProcessing = true; - File hasDownloadedFile = new File(outputDir, "downloaded/" + assetsVersion + ".downloaded"); - if (!hasDownloadedFile.exists()) { + //File hasDownloadedFile = new File(outputDir, "downloaded/" + assetsVersion + ".downloaded"); + if (true) { //(!hasDownloadedFile.exists()) { System.out.println("Assets begin time: " + System.currentTimeMillis()); Map assetsObjects = assets.objects; int assetsSizeBytes=0; From 4e3fdf7f95a065281d56328d7850e55d7651dfbd Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh <40482367+khanhduytran0@users.noreply.github.com> Date: Tue, 15 Feb 2022 17:32:28 +0700 Subject: [PATCH 04/70] Update MinecraftDownloaderTask.java --- .../net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java index 8f8890ce7..fc2e390c4 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java @@ -476,8 +476,8 @@ public class MinecraftDownloaderTask extends AsyncTask Date: Sat, 26 Feb 2022 06:16:04 +0700 Subject: [PATCH 05/70] Clear Microsoft auth cookies before load the page Closes #2749 Closes #2579 Closes #2447 --- .../authenticator/microsoft/ui/MicrosoftLoginGUIActivity.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/microsoft/ui/MicrosoftLoginGUIActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/microsoft/ui/MicrosoftLoginGUIActivity.java index 6285cbb59..d82f17986 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/microsoft/ui/MicrosoftLoginGUIActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/microsoft/ui/MicrosoftLoginGUIActivity.java @@ -8,6 +8,7 @@ import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.ViewGroup; +import android.webkit.CookieManager; import android.webkit.WebResourceRequest; import android.webkit.WebSettings; import android.webkit.WebView; @@ -24,6 +25,7 @@ public class MicrosoftLoginGUIActivity extends AppCompatActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + CookieManager.getInstance().removeAllCookie(); waitDialog = new ProgressDialog(this); waitDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); waitDialog.setIndeterminate(true); From 902632cae115c65b1b786fb8548f8199f421d741 Mon Sep 17 00:00:00 2001 From: github-actions Date: Fri, 25 Feb 2022 23:19:29 +0000 Subject: [PATCH 06/70] CI: Update vgpu --- .../src/main/jniLibs/arm64-v8a/libvgpu.so | Bin 1483824 -> 1483824 bytes .../src/main/jniLibs/armeabi-v7a/libvgpu.so | Bin 1155432 -> 1155432 bytes .../src/main/jniLibs/x86/libvgpu.so | Bin 1474856 -> 1474856 bytes .../src/main/jniLibs/x86_64/libvgpu.so | Bin 1623432 -> 1623432 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libvgpu.so b/app_pojavlauncher/src/main/jniLibs/arm64-v8a/libvgpu.so index b9eead908e19fc685e4575a96bb381ab7be4440f..bf536edf7e3a7bbec6a6a9816aae6bf9967244f7 100644 GIT binary patch delta 150 zcmdmRB5DH=2{4Jo>{9)h5Ms!G_W$waXKb_t|ETXe+^oXXuEN9!#2}g(h*^M`6^Pk@ zm>q~YfS41Axqz4(h-A*fLIWSg|@3O39sxEaZ627FfvszGB7e?Ffz6> YG`BJ~ZhtsI7>GrHSakct31a@j0A)}sRsaA1 delta 150 zcmdmRB5DH=2{4IxeA>sl=HgqMAfZmB{ZW_7m&-qy+N{FVuEN9!#2}g(h*^M`6^Pk@ zm>q~YfS41Axqz4(h-A*fLIWSg|@3O39sxE@k-27Fg8#yGB7e?FtD^T YF}E@{Z+|#J7>GrHSakct31a@j0CpTJe*gdg diff --git a/app_pojavlauncher/src/main/jniLibs/armeabi-v7a/libvgpu.so b/app_pojavlauncher/src/main/jniLibs/armeabi-v7a/libvgpu.so index a04bf59afa3d4de077e251b6411913377c644e0f..201cd7db5c3e4296d9487310751c5ee4b13694ad 100644 GIT binary patch delta 130 zcmaEH$nC`;w+(j~MT|eq?~6I>bFxxWJGF1x-QCI6yepbNFt&eS1Yss1W(HywAZ7(( zHXvpPVh$kY1Y#~A<_2OOAm#;PJ|O1b{((`zlTpMiHA%t9RKdu=$cVwn*vint%D}AM Nmsw!DFSDTZJOE4pFlPV& delta 130 zcmaEH$nC`;w+(j~MJDW$yp`$0euMD@U)am&#VY6GCj~ZtU~K=u2*ON2%nZaVK+Fon zY(UHo#2i4(3B+7L%nigmK+Frod_c^<{R5+bC!>g0VxEGrfr62Nkr9J|rIm?=m4QXO NFSEdQUuHq+c>w10FOUEL diff --git a/app_pojavlauncher/src/main/jniLibs/x86/libvgpu.so b/app_pojavlauncher/src/main/jniLibs/x86/libvgpu.so index 033aeac1dc599bbcb921cfb64e2613c1d4567f63..892f5a28b7bf4bcf5d7d83b2713c71eb0866bfe8 100644 GIT binary patch delta 146 zcmZ3{6t$u$YQr5ykuNp(%uL%(ez_VY@&C-t?_4+2uGckxU~K=u2*ON2%nZaVK+Fon zY(UHo#2i4(3B+7L%nigmK+Frod_c?(!~#Gpxcvj8(8`x0ZmCHMMy3iz21Z5%}TC{p90MfBNy#N3J delta 146 zcmZ3{6t$u$YQr5yk)^^j`rj+xzH#$7->c}Fty7XBebzO9U~K=u2*ON2%nZaVK+Fon zY(UHo#2i4(3B+7L%nigmK+Frod_c?(!~#Gpxcvj8(8`x0UWs`M#s&&T21Z5<29{PP Y7FH$(?Q35P0kJR;i)>%}TC{p903*jdSpWb4 diff --git a/app_pojavlauncher/src/main/jniLibs/x86_64/libvgpu.so b/app_pojavlauncher/src/main/jniLibs/x86_64/libvgpu.so index 68ed10f0321d3821ca44b389875040fc339e35fe..7acd39adeb10f03a21117f68ea5e74f55e8fb7f0 100644 GIT binary patch delta 158 zcmeC^PVVSV-mrp6WMyoF+@%qV%Oftm!NAhWq`h{!2oQ?`u^14GZ?By$!L0`X2JbpB From 491c16ecaba09835afaeff9425c99fca057f96c0 Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh <40482367+khanhduytran0@users.noreply.github.com> Date: Mon, 28 Feb 2022 09:00:13 +0700 Subject: [PATCH 07/70] Fix ArrayIndexOutOfBoundsException when glfwGetKey(0) --- jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java index 702fa1155..86ff22abd 100644 --- a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java @@ -497,7 +497,7 @@ public class GLFW private static ArrayMap mGLFWWindowMap; public static boolean mGLFWIsGrabbing, mGLFWIsInputReady, mGLFWIsUseStackQueue = false; - public static final byte[] keyDownBuffer = new byte[316]; + public static final byte[] keyDownBuffer = new byte[317]; private static final String PROP_WINDOW_WIDTH = "glfwstub.windowWidth"; private static final String PROP_WINDOW_HEIGHT= "glfwstub.windowHeight"; public static long mainContext = 0; @@ -1099,7 +1099,7 @@ public class GLFW break; case CallbackBridge.EVENT_TYPE_KEY: if (mGLFWKeyCallback != null) { - keyDownBuffer[dataArr[1]-32]=(byte)(int)dataArr[3]; + keyDownBuffer[Math.max(0, dataArr[1]-31)]=(byte)(int)dataArr[3]; mGLFWKeyCallback.invoke(ptr, dataArr[1], dataArr[2], dataArr[3], dataArr[4]); } break; @@ -1191,7 +1191,7 @@ public class GLFW } public static int glfwGetKey(@NativeType("GLFWwindow *") long window, int key) { - return keyDownBuffer[key-32]; + return keyDownBuffer[Math.max(0, dataArr[1]-31)]; } public static int glfwGetMouseButton(@NativeType("GLFWwindow *") long window, int button) { From 8244236645ac3983b35d74db90e48d5f51018089 Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh <40482367+khanhduytran0@users.noreply.github.com> Date: Mon, 28 Feb 2022 09:13:29 +0700 Subject: [PATCH 08/70] Update GLFW.java --- jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java index 86ff22abd..2786347a9 100644 --- a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java @@ -1191,7 +1191,7 @@ public class GLFW } public static int glfwGetKey(@NativeType("GLFWwindow *") long window, int key) { - return keyDownBuffer[Math.max(0, dataArr[1]-31)]; + return keyDownBuffer[Math.max(0, key-31)]; } public static int glfwGetMouseButton(@NativeType("GLFWwindow *") long window, int button) { From dcac1c9a978c8543bba0f84d1c8bd0e2685c6fc9 Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh <40482367+khanhduytran0@users.noreply.github.com> Date: Mon, 28 Feb 2022 09:54:33 +0700 Subject: [PATCH 09/70] Update LWJGL component version --- app_pojavlauncher/src/main/assets/components/lwjgl3/version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/version b/app_pojavlauncher/src/main/assets/components/lwjgl3/version index 4dc8ff272..e5b42f549 100644 --- a/app_pojavlauncher/src/main/assets/components/lwjgl3/version +++ b/app_pojavlauncher/src/main/assets/components/lwjgl3/version @@ -1 +1 @@ -20211115 +20220228 From 1f1d542ed79ce591efc9171dfbfe50cd93dd2bbb Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh <40482367+khanhduytran0@users.noreply.github.com> Date: Wed, 2 Mar 2022 19:58:03 +0700 Subject: [PATCH 10/70] Fix a NPE when windowAttribs.get() = null java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "java.util.Map.get(Object)" is null at org.lwjgl.glfw.GLFW.glfwGetWindowAttrib(GLFW.java:895) --- jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java index 2786347a9..2860c8976 100644 --- a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java @@ -892,7 +892,11 @@ public class GLFW } public static int glfwGetWindowAttrib(@NativeType("GLFWwindow *") long window, int attrib) { - return internalGetWindow(window).windowAttribs.get(attrib); + Object obj = internalGetWindow(window).windowAttribs.get(attrib); + if (obj == null) { + return 0; + } + return (int) obj; } public static void glfwSetWindowAttrib(@NativeType("GLFWwindow *") long window, int attrib, int value) { From b0af8e43f4634a14f6652fd080bb1e0f09184879 Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh <40482367+khanhduytran0@users.noreply.github.com> Date: Wed, 2 Mar 2022 20:00:36 +0700 Subject: [PATCH 11/70] Use HashMap.getOrDefault() --- jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java index 2860c8976..930f51a8b 100644 --- a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java @@ -892,11 +892,7 @@ public class GLFW } public static int glfwGetWindowAttrib(@NativeType("GLFWwindow *") long window, int attrib) { - Object obj = internalGetWindow(window).windowAttribs.get(attrib); - if (obj == null) { - return 0; - } - return (int) obj; + return internalGetWindow(window).windowAttribs.getOrDefault(attrib, 0); } public static void glfwSetWindowAttrib(@NativeType("GLFWwindow *") long window, int attrib, int value) { From a0262bd08bd76da4d86575602075811c0078b431 Mon Sep 17 00:00:00 2001 From: khanhduytran0 Date: Fri, 4 Mar 2022 08:21:05 +0700 Subject: [PATCH 12/70] Update GLFW window state (hover, visibility) This fixes DynamicFPS mod being broken --- .../src/main/assets/components/lwjgl3/version | 2 +- .../net/kdt/pojavlaunch/BaseMainActivity.java | 14 ++++++++++++++ .../net/kdt/pojavlaunch/LWJGLGLFWKeycode.java | 5 ++++- .../java/org/lwjgl/glfw/CallbackBridge.java | 3 ++- .../src/main/jni/input_bridge_v3.c | 18 ++++++++++++++++++ .../src/main/java/org/lwjgl/glfw/GLFW.java | 4 +++- 6 files changed, 42 insertions(+), 4 deletions(-) diff --git a/app_pojavlauncher/src/main/assets/components/lwjgl3/version b/app_pojavlauncher/src/main/assets/components/lwjgl3/version index e5b42f549..bdd22c5d4 100644 --- a/app_pojavlauncher/src/main/assets/components/lwjgl3/version +++ b/app_pojavlauncher/src/main/assets/components/lwjgl3/version @@ -1 +1 @@ -20220228 +20220304 diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java index ea46a30bb..49ef73fd7 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java @@ -152,6 +152,7 @@ public class BaseMainActivity extends BaseActivity { final int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; final View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility(uiOptions); + CallbackBridge.nativeSetWindowAttrib(LWJGLGLFWKeycode.GLFW_HOVERED, 1); } @Override @@ -159,10 +160,23 @@ public class BaseMainActivity extends BaseActivity { if (CallbackBridge.isGrabbing()){ sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_ESCAPE); } + CallbackBridge.nativeSetWindowAttrib(LWJGLGLFWKeycode.GLFW_HOVERED, 0); mIsResuming = false; super.onPause(); } + @Override + protected void onStart() { + super.onStart(); + CallbackBridge.nativeSetWindowAttrib(LWJGLGLFWKeycode.GLFW_VISIBLE, 1); + } + + @Override + protected void onStop() { + CallbackBridge.nativeSetWindowAttrib(LWJGLGLFWKeycode.GLFW_VISIBLE, 0); + super.onStop(); + } + public static void fullyExit() { android.os.Process.killProcess(android.os.Process.myPid()); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LWJGLGLFWKeycode.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LWJGLGLFWKeycode.java index 5482b01f6..1f1d4ede0 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LWJGLGLFWKeycode.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LWJGLGLFWKeycode.java @@ -195,5 +195,8 @@ public class LWJGLGLFWKeycode GLFW_MOUSE_BUTTON_LEFT = GLFW_MOUSE_BUTTON_1, GLFW_MOUSE_BUTTON_RIGHT = GLFW_MOUSE_BUTTON_2, GLFW_MOUSE_BUTTON_MIDDLE = GLFW_MOUSE_BUTTON_3; - + + public static final int + GLFW_VISIBLE = 0x20004, + GLFW_HOVERED = 0x2000B; } diff --git a/app_pojavlauncher/src/main/java/org/lwjgl/glfw/CallbackBridge.java b/app_pojavlauncher/src/main/java/org/lwjgl/glfw/CallbackBridge.java index 7a3d20552..bdaf7e1bf 100644 --- a/app_pojavlauncher/src/main/java/org/lwjgl/glfw/CallbackBridge.java +++ b/app_pojavlauncher/src/main/java/org/lwjgl/glfw/CallbackBridge.java @@ -211,7 +211,8 @@ public class CallbackBridge { private static native void nativeSendMouseButton(int button, int action, int mods); private static native void nativeSendScroll(double xoffset, double yoffset); private static native void nativeSendScreenSize(int width, int height); - + public static native void nativeSetWindowAttrib(int attrib, int value); + public static native boolean nativeIsGrabbing(); static { System.loadLibrary("pojavexec"); diff --git a/app_pojavlauncher/src/main/jni/input_bridge_v3.c b/app_pojavlauncher/src/main/jni/input_bridge_v3.c index b9df89e76..59e2306fd 100644 --- a/app_pojavlauncher/src/main/jni/input_bridge_v3.c +++ b/app_pojavlauncher/src/main/jni/input_bridge_v3.c @@ -363,3 +363,21 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendScroll(JNIEn JNIEXPORT void JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetShowingWindow(JNIEnv* env, jclass clazz, jlong window) { showingWindow = (long) window; } + +JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSetWindowAttrib(JNIEnv* env, jclass clazz, jint attrib, jint value) { + if (!showingWindow) { + return; // nothing to do yet + } + + jclass glfwClazz = (*runtimeJNIEnvPtr_JRE)->FindClass(runtimeJNIEnvPtr_JRE, "org/lwjgl/glfw/GLFW"); + assert(glfwClazz != NULL); + jmethodID glfwMethod = (*runtimeJNIEnvPtr_JRE)->GetStaticMethodID(runtimeJNIEnvPtr_JRE, glfwMethod, "glfwSetWindowAttrib", "(JII)V"); + assert(glfwMethod != NULL); + + (*runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod( + runtimeJNIEnvPtr_JRE, + glfwClazz, glfwMethod, + (jlong) showingWindow, attrib, value + ); +} + diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java index 930f51a8b..1b15369b2 100644 --- a/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/glfw/GLFW.java @@ -995,9 +995,11 @@ public class GLFW win.width = mGLFWWindowWidth; win.height = mGLFWWindowHeight; - win.title = title; + win.windowAttribs.put(GLFW_HOVERED, 1); + win.windowAttribs.put(GLFW_VISIBLE, 1); + mGLFWWindowMap.put(ptr, win); mainContext = ptr; return ptr; From 4d31b982ab14767a97582672b0e40bf54635e3e1 Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh <40482367+khanhduytran0@users.noreply.github.com> Date: Fri, 4 Mar 2022 09:20:02 +0700 Subject: [PATCH 13/70] =?UTF-8?q?Don=E2=80=99t=20change=20inheritsFrom=20w?= =?UTF-8?q?hile=20parsing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java index 150f1f77f..cff1aa87c 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -554,7 +554,7 @@ public final class Tools { }catch(IOException e) { throw new RuntimeException("Can't find the source version for "+ versionName +" (req version="+customVer.inheritsFrom+")"); } - inheritsVer.inheritsFrom = inheritsVer.id; + //inheritsVer.inheritsFrom = inheritsVer.id; insertSafety(inheritsVer, customVer, "assetIndex", "assets", "id", "mainClass", "minecraftArguments", From 4cfbf4c9aae1c165632a4be4df681b38e17422c1 Mon Sep 17 00:00:00 2001 From: khanhduytran0 Date: Sat, 5 Mar 2022 08:00:34 +0700 Subject: [PATCH 14/70] Fix wrong JNIEnv passed in nativeSetWindowAttrib --- app_pojavlauncher/src/main/jni/input_bridge_v3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app_pojavlauncher/src/main/jni/input_bridge_v3.c b/app_pojavlauncher/src/main/jni/input_bridge_v3.c index 59e2306fd..afac0231e 100644 --- a/app_pojavlauncher/src/main/jni/input_bridge_v3.c +++ b/app_pojavlauncher/src/main/jni/input_bridge_v3.c @@ -369,9 +369,9 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSetWindowAttrib( return; // nothing to do yet } - jclass glfwClazz = (*runtimeJNIEnvPtr_JRE)->FindClass(runtimeJNIEnvPtr_JRE, "org/lwjgl/glfw/GLFW"); + jclass glfwClazz = (*runtimeJNIEnvPtr_ANDROID)->FindClass(runtimeJNIEnvPtr_ANDROID, "org/lwjgl/glfw/GLFW"); assert(glfwClazz != NULL); - jmethodID glfwMethod = (*runtimeJNIEnvPtr_JRE)->GetStaticMethodID(runtimeJNIEnvPtr_JRE, glfwMethod, "glfwSetWindowAttrib", "(JII)V"); + jmethodID glfwMethod = (*runtimeJNIEnvPtr_ANDROID)->GetStaticMethodID(runtimeJNIEnvPtr_ANDROID, glfwMethod, "glfwSetWindowAttrib", "(JII)V"); assert(glfwMethod != NULL); (*runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod( From d18faffce67c5079c1c2229a3b1eba0adbb5e55e Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh <40482367+khanhduytran0@users.noreply.github.com> Date: Sat, 5 Mar 2022 11:40:07 +0700 Subject: [PATCH 15/70] wrong ptr again --- app_pojavlauncher/src/main/jni/input_bridge_v3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app_pojavlauncher/src/main/jni/input_bridge_v3.c b/app_pojavlauncher/src/main/jni/input_bridge_v3.c index afac0231e..55cf5e1ae 100644 --- a/app_pojavlauncher/src/main/jni/input_bridge_v3.c +++ b/app_pojavlauncher/src/main/jni/input_bridge_v3.c @@ -374,8 +374,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSetWindowAttrib( jmethodID glfwMethod = (*runtimeJNIEnvPtr_ANDROID)->GetStaticMethodID(runtimeJNIEnvPtr_ANDROID, glfwMethod, "glfwSetWindowAttrib", "(JII)V"); assert(glfwMethod != NULL); - (*runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod( - runtimeJNIEnvPtr_JRE, + (*runtimeJNIEnvPtr_ANDROID)->CallStaticVoidMethod( + runtimeJNIEnvPtr_ANDROID, glfwClazz, glfwMethod, (jlong) showingWindow, attrib, value ); From 6fe447410c7549fc6672a2840dc57c1f27c47abf Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Fri, 25 Feb 2022 23:28:24 +0100 Subject: [PATCH 16/70] Refactor ExtraCore --- .../net/kdt/pojavlaunch/extra/ExtraCore.java | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/extra/ExtraCore.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/extra/ExtraCore.java index 3e26c24ef..e14ad285f 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/extra/ExtraCore.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/extra/ExtraCore.java @@ -17,24 +17,24 @@ public final class ExtraCore { private ExtraCore(){} // Singleton instance - private static ExtraCore extraCoreSingleton = null; + private static ExtraCore sExtraCoreSingleton = null; // Store the key-value pair - private final Map valueMap = new ConcurrentHashMap<>(); + private final Map mValueMap = new ConcurrentHashMap<>(); // Store what each ExtraListener listen to - private final Map>> listenerMap = new ConcurrentHashMap<>(); + private final Map>> mListenerMap = new ConcurrentHashMap<>(); // All public methods will pass through this one private static ExtraCore getInstance(){ - if(extraCoreSingleton == null){ + if(sExtraCoreSingleton == null){ synchronized(ExtraCore.class){ - if(extraCoreSingleton == null){ - extraCoreSingleton = new ExtraCore(); + if(sExtraCoreSingleton == null){ + sExtraCoreSingleton = new ExtraCore(); } } } - return extraCoreSingleton; + return sExtraCoreSingleton; } /** @@ -45,8 +45,8 @@ public final class ExtraCore { public static void setValue(String key, Object value){ if(value == null || key == null) return; // null values create an NPE on insertion - getInstance().valueMap.put(key, value); - ConcurrentLinkedQueue> extraListenerList = getInstance().listenerMap.get(key); + getInstance().mValueMap.put(key, value); + ConcurrentLinkedQueue> extraListenerList = getInstance().mListenerMap.get(key); if(extraListenerList == null) return; //No listeners for(WeakReference listener : extraListenerList){ if(listener.get() == null){ @@ -63,17 +63,17 @@ public final class ExtraCore { /** @return The value behind the key */ public static Object getValue(String key){ - return getInstance().valueMap.get(key); + return getInstance().mValueMap.get(key); } /** Remove the key and its value from the valueMap */ public static void removeValue(String key){ - getInstance().valueMap.remove(key); + getInstance().mValueMap.remove(key); } /** Remove all values */ public static void removeAllValues(){ - getInstance().valueMap.clear(); + getInstance().mValueMap.clear(); } /** @@ -82,11 +82,11 @@ public final class ExtraCore { * @param listener The ExtraListener to link */ public static void addExtraListener(String key, ExtraListener listener){ - ConcurrentLinkedQueue> listenerList = getInstance().listenerMap.get(key); + ConcurrentLinkedQueue> listenerList = getInstance().mListenerMap.get(key); // Look for new sets if(listenerList == null){ listenerList = new ConcurrentLinkedQueue<>(); - getInstance().listenerMap.put(key, listenerList); + getInstance().mListenerMap.put(key, listenerList); } // This is kinda naive, I should look for duplicates @@ -100,11 +100,11 @@ public final class ExtraCore { * @param listener The ExtraListener to unlink */ public static void removeExtraListenerFromValue(String key, ExtraListener listener){ - ConcurrentLinkedQueue> listenerList = getInstance().listenerMap.get(key); + ConcurrentLinkedQueue> listenerList = getInstance().mListenerMap.get(key); // Look for new sets if(listenerList == null){ listenerList = new ConcurrentLinkedQueue<>(); - getInstance().listenerMap.put(key, listenerList); + getInstance().mListenerMap.put(key, listenerList); } // Removes all occurrences of ExtraListener and all null references @@ -122,11 +122,11 @@ public final class ExtraCore { * @param key The key to which ExtraListener are linked */ public static void removeAllExtraListenersFromValue(String key){ - ConcurrentLinkedQueue> listenerList = getInstance().listenerMap.get(key); + ConcurrentLinkedQueue> listenerList = getInstance().mListenerMap.get(key); // Look for new sets if(listenerList == null){ listenerList = new ConcurrentLinkedQueue<>(); - getInstance().listenerMap.put(key, listenerList); + getInstance().mListenerMap.put(key, listenerList); } listenerList.clear(); @@ -136,7 +136,7 @@ public final class ExtraCore { * Remove all ExtraListeners from listening to any value */ public static void removeAllExtraListeners(){ - getInstance().listenerMap.clear(); + getInstance().mListenerMap.clear(); } } \ No newline at end of file From 668b49eeb826cacad732f60f40615ee58ba51278 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Fri, 25 Feb 2022 23:28:42 +0100 Subject: [PATCH 17/70] Refactor ConsoleFragment.java --- .../fragments/ConsoleFragment.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ConsoleFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ConsoleFragment.java index df917a536..40b7bcfae 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ConsoleFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ConsoleFragment.java @@ -2,6 +2,7 @@ package net.kdt.pojavlaunch.fragments; import android.os.*; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import android.view.*; import android.widget.*; @@ -12,34 +13,33 @@ import android.graphics.*; import androidx.fragment.app.Fragment; -public class ConsoleFragment extends Fragment -{ - public TextView consoleView; +public class ConsoleFragment extends Fragment { + public TextView mConsoleView; + @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); View view = inflater.inflate(R.layout.lmaintab_consolelog, container, false); - consoleView = (TextView) view.findViewById(R.id.lmaintabconsoleLogTextView); - consoleView.setTypeface(Typeface.MONOSPACE); - consoleView.setHint(this.getText(R.string.main_nolog)); + mConsoleView = (TextView) view.findViewById(R.id.lmaintabconsoleLogTextView); + mConsoleView.setTypeface(Typeface.MONOSPACE); + mConsoleView.setHint(this.getText(R.string.main_nolog)); return view; } @Override - public void onResume() - { + public void onResume() { super.onResume(); - consoleView = (TextView) getView().findViewById(R.id.lmaintabconsoleLogTextView); + mConsoleView = (TextView) getView().findViewById(R.id.lmaintabconsoleLogTextView); } public void putLog(String str) { - if (consoleView == null) { - consoleView = (TextView) getView().findViewById(R.id.lmaintabconsoleLogTextView); + if (mConsoleView == null) { + mConsoleView = (TextView) getView().findViewById(R.id.lmaintabconsoleLogTextView); } - consoleView.append(str); + mConsoleView.append(str); } } From 9705b01bb31c3c2c5e28bb0c70a06c9c0bad5df3 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Fri, 25 Feb 2022 23:28:55 +0100 Subject: [PATCH 18/70] Refactor CrashFragment.java --- .../pojavlaunch/fragments/CrashFragment.java | 121 +++++++++--------- 1 file changed, 60 insertions(+), 61 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/CrashFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/CrashFragment.java index 4ad687bfc..b6cb32e63 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/CrashFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/CrashFragment.java @@ -2,7 +2,10 @@ package net.kdt.pojavlaunch.fragments; import android.os.*; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; + +import android.util.Log; import android.view.*; import android.widget.*; import java.io.*; @@ -11,80 +14,76 @@ import net.kdt.pojavlaunch.*; import android.graphics.*; import androidx.fragment.app.Fragment; -public class CrashFragment extends Fragment -{ - public static String lastCrashFile = Tools.DIR_DATA + "/lastcrash.txt"; - - private String crashContent; - private TextView crashView; - - public boolean resetCrashLog = false; - - public static boolean isNewCrash(File crashLog) throws Exception { - String content = Tools.read(crashLog.getAbsolutePath()); - return crashLog != null && content.startsWith("---- Minecraft Crash Report ----"); - } - - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - super.onCreateView(inflater, container, savedInstanceState); - View view = inflater.inflate(R.layout.lmaintab_crashlog, container, false); +public class CrashFragment extends Fragment { + public static String LAST_CRASH_FILE = Tools.DIR_DATA + "/lastcrash.txt"; - return view; - } - - @Override - public void onActivityCreated(Bundle b) - { - super.onActivityCreated(b); - - crashView = (TextView) getView().findViewById(R.id.lmaintabconsoleLogCrashTextView); - crashView.setTypeface(Typeface.MONOSPACE); - crashView.setHint(this.getText(R.string.main_nocrash)); + private TextView mCrashView; + public boolean mResetCrashLog = false; - } - @Override - public void onResume() - { + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + super.onCreateView(inflater, container, savedInstanceState); + return inflater.inflate(R.layout.lmaintab_crashlog, container, false); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + mCrashView = (TextView) getView().findViewById(R.id.lmaintabconsoleLogCrashTextView); + mCrashView.setTypeface(Typeface.MONOSPACE); + mCrashView.setHint(this.getText(R.string.main_nocrash)); + } + + + @Override + public void onResume(){ super.onResume(); refreshCrashFile(); } - - public void refreshCrashFile() - { + + private void refreshCrashFile() { + // Default text + mCrashView.setText(""); + setLastCrash(""); + + if(mResetCrashLog) return; + + File crashLog = Tools.lastFileModified(Tools.DIR_HOME_CRASH); + String lastCrash = getLastCrash(); + String crashContent; try { - if(!resetCrashLog){ - File crashLog = Tools.lastFileModified(Tools.DIR_HOME_CRASH); - String lastCrash = getLastCrash(); - if (isNewCrash(crashLog)) { - crashContent = Tools.read(crashLog.getAbsolutePath()); - Tools.write(crashLog.getAbsolutePath(), "\n" + crashContent); - setLastCrash(crashLog.getAbsolutePath()); - crashView.setText(crashContent); - } else if(!lastCrash.isEmpty()) { - crashContent = Tools.read(lastCrash); - crashView.setText(crashContent); - } else throw new Exception(); - } else throw new Exception(); - } catch (Exception e) { - // Can't find crash or no NEW crashes - crashView.setText(""/*Log.getStackTraceString(e)*/); - setLastCrash(""); + if (isNewCrash(crashLog)) { + crashContent = Tools.read(crashLog.getAbsolutePath()); + Tools.write(crashLog.getAbsolutePath(), "\n" + crashContent); + setLastCrash(crashLog.getAbsolutePath()); + mCrashView.setText(crashContent); + } else if(!lastCrash.isEmpty()) { + crashContent = Tools.read(lastCrash); + mCrashView.setText(crashContent); + } + }catch (IOException ioException){ + Log.e("CrashFragment", ioException.toString()); } } - - public void setLastCrash(String newValue) { + + private static boolean isNewCrash(File crashLog) throws IOException { + String content = Tools.read(crashLog.getAbsolutePath()); + return crashLog != null && content.startsWith("---- Minecraft Crash Report ----"); + } + + private void setLastCrash(String newValue) { try { - Tools.write(lastCrashFile, newValue); - } catch (Throwable th) { - throw new RuntimeException(th); + Tools.write(LAST_CRASH_FILE, newValue); + } catch (IOException ioException) { + throw new RuntimeException(ioException); } } - - public String getLastCrash() { + + private String getLastCrash() { try { - return Tools.read(lastCrashFile); - } catch (Throwable th) { + return Tools.read(LAST_CRASH_FILE); + } catch (IOException ioException) { return ""; } } From a78e66f79302b31925c90282149a5490fe6496d5 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Fri, 25 Feb 2022 23:39:03 +0100 Subject: [PATCH 19/70] Refactor LauncherFragment.java --- .../fragments/LauncherFragment.java | 155 +++++++++--------- 1 file changed, 77 insertions(+), 78 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LauncherFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LauncherFragment.java index c0a3be4a5..758b56f74 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LauncherFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LauncherFragment.java @@ -4,12 +4,12 @@ import android.content.Intent; import android.graphics.Color; import android.net.Uri; import android.os.Bundle; + +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.fragment.app.Fragment; -import android.os.Handler; -import android.os.Looper; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -25,74 +25,45 @@ import net.kdt.pojavlaunch.prefs.LauncherPreferences; import java.io.IOException; import java.net.HttpURLConnection; -import java.net.MalformedURLException; import java.net.URL; -import java.util.HashMap; import java.util.Locale; -import java.util.Objects; -public class LauncherFragment extends Fragment -{ - private WebView webNews; - private View view; - private Thread validUrlSelectorThread; - private String validChangelog = "/changelog.html"; - private Handler mainHandler = new Handler(Looper.getMainLooper()); - private boolean interruptLoad = false; - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - super.onCreateView(inflater, container, savedInstanceState); - view = inflater.inflate(R.layout.lmaintab_news, container, false); - return view; - } - public void selectValidUrl() { - String lang = LauncherPreferences.PREF_LANGUAGE; - if(lang.equals("default")) lang = Locale.getDefault().getLanguage(); - final String localizedUrl = "/changelog-"+lang+".html"; - if(!tryUrl(Tools.URL_HOME+localizedUrl)) return; - else { - mainHandler.post(()->{ - interruptLoad = true; - validChangelog = localizedUrl; - webNews.loadUrl(Tools.URL_HOME+validChangelog); - }); - } - } - public boolean tryUrl(String url) { - Log.i("ChangelogLocale","Trying localized url: "+url); - try { - HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); - conn.connect(); - Log.i("ChangelogLocale","Code: "+conn.getResponseCode()); - return ("" + conn.getResponseCode()).startsWith("2"); - }catch (IOException e) { - e.printStackTrace(); - return false; - } - } +public class LauncherFragment extends Fragment { + + private WebView mNewsWebview; + private View mRootView; + private Thread mValidUrlSelectorThread; + private String mValidChangelog = "/changelog.html"; + private boolean mInterruptLoad = false; + @Override - public void onActivityCreated(Bundle p1) - { - super.onActivityCreated(p1); - mainHandler = new Handler(Looper.myLooper()); - webNews = (WebView) getView().findViewById(R.id.lmaintabnewsNewsView); - webNews.setWebViewClient(new WebViewClient(){ + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + super.onCreateView(inflater, container, savedInstanceState); + mRootView = inflater.inflate(R.layout.lmaintab_news, container, false); + return mRootView; + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + mNewsWebview = (WebView) getView().findViewById(R.id.lmaintabnewsNewsView); + mNewsWebview.setWebViewClient(new WebViewClient(){ // API < 23 @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { Log.i("WebNews",failingUrl + ": "+description); - if(webNews != null){ - if(validUrlSelectorThread.isAlive()) validUrlSelectorThread.interrupt(); - removeWebView(); - //Change the background to match the other pages. - //We change it only when the webView is removed to avoid huge overdraw. - LauncherFragment.this.view.setBackgroundColor(Color.parseColor("#44000000")); - } + if(mNewsWebview == null) return; + + if(mValidUrlSelectorThread.isAlive()) mValidUrlSelectorThread.interrupt(); + removeWebView(); + //Change the background to match the other pages. + //We change it only when the webView is removed to avoid huge overdraw. + LauncherFragment.this.mRootView.setBackgroundColor(Color.parseColor("#44000000")); } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { - if(!url.equals(Tools.URL_HOME + validChangelog)){ + if(!url.equals(Tools.URL_HOME + mValidChangelog)){ Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); startActivity(i); return true; @@ -104,17 +75,17 @@ public class LauncherFragment extends Fragment @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { Log.i("WebNews",error.getDescription()+""); - if(webNews != null){ - if(validUrlSelectorThread.isAlive()) validUrlSelectorThread.interrupt(); - removeWebView(); - LauncherFragment.this.view.setBackgroundColor(Color.parseColor("#44000000")); - } + if(mNewsWebview == null) return; + + if(mValidUrlSelectorThread.isAlive()) mValidUrlSelectorThread.interrupt(); + removeWebView(); + LauncherFragment.this.mRootView.setBackgroundColor(Color.parseColor("#44000000")); } @RequiresApi(23) @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { - if(!request.getUrl().toString().equals(Tools.URL_HOME + validChangelog)){ + if(!request.getUrl().toString().equals(Tools.URL_HOME + mValidChangelog)){ Intent i = new Intent(Intent.ACTION_VIEW, request.getUrl()); startActivity(i); return true; @@ -122,36 +93,64 @@ public class LauncherFragment extends Fragment return false; } }); - webNews.clearCache(true); - webNews.getSettings().setJavaScriptEnabled(true); - validUrlSelectorThread = new Thread(this::selectValidUrl); - validUrlSelectorThread.start(); - if(!interruptLoad)webNews.loadUrl(Tools.URL_HOME + validChangelog); + + mNewsWebview.clearCache(true); + mNewsWebview.getSettings().setJavaScriptEnabled(true); + mValidUrlSelectorThread = new Thread(this::selectValidUrl); + mValidUrlSelectorThread.start(); + if(!mInterruptLoad) mNewsWebview.loadUrl(Tools.URL_HOME + mValidChangelog); + } + + private void selectValidUrl() { + String lang = LauncherPreferences.PREF_LANGUAGE; + if(lang.equals("default")) lang = Locale.getDefault().getLanguage(); + final String localizedUrl = "/changelog-" + lang + ".html"; + + if(!tryUrl(Tools.URL_HOME+localizedUrl)) return; + + requireActivity().runOnUiThread(() -> { + mInterruptLoad = true; + mValidChangelog = localizedUrl; + mNewsWebview.loadUrl(Tools.URL_HOME + mValidChangelog); + }); + } + + private boolean tryUrl(String url) { + Log.i("ChangelogLocale","Trying localized url: "+url); + try { + HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); + conn.connect(); + Log.i("ChangelogLocale","Code: "+conn.getResponseCode()); + return ("" + conn.getResponseCode()).startsWith("2"); + }catch (IOException e) { + e.printStackTrace(); + return false; + } } private void removeWebView() { //Removing the parent which contain the webView crashes the viewPager. //So I just try to "minimize" its impact on memory instead - webNews.clearHistory(); - webNews.clearCache(true); + mNewsWebview.clearHistory(); + mNewsWebview.clearCache(true); // Loading a blank page is optional, but will ensure that the WebView isn't doing anything when you destroy it. - webNews.loadUrl("about:blank"); + mNewsWebview.loadUrl("about:blank"); - webNews.onPause(); - webNews.removeAllViews(); - webNews.destroyDrawingCache(); + mNewsWebview.onPause(); + mNewsWebview.removeAllViews(); + mNewsWebview.destroyDrawingCache(); // make sure to call webNews.resumeTimers(). - webNews.pauseTimers(); + mNewsWebview.pauseTimers(); - webNews.setVisibility(View.GONE); + mNewsWebview.setVisibility(View.GONE); - webNews.destroy(); + mNewsWebview.destroy(); // Null out the reference so that you don't end up re-using it. - webNews = null; + mNewsWebview = null; } From 9b35bc084ffbdfc9b397826b480fdb9eb2c5fa41 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 00:32:46 +0100 Subject: [PATCH 20/70] Refactor multiRT --- .../kdt/pojavlaunch/BaseLauncherActivity.java | 13 +- .../pojavlaunch/JavaGUILauncherActivity.java | 3 +- .../multirt/MultiRTConfigDialog.java | 34 +-- .../kdt/pojavlaunch/multirt/MultiRTUtils.java | 209 +++++++++--------- .../multirt/RTRecyclerViewAdapter.java | 169 +++++++------- .../pojavlaunch/multirt/RTSpinnerAdapter.java | 50 ++--- .../net/kdt/pojavlaunch/multirt/Runtime.java | 26 +++ .../prefs/PerVersionConfigDialog.java | 13 +- .../prefs/RuntimeManagerPreference.java | 3 +- .../tasks/MinecraftDownloaderTask.java | 13 +- 10 files changed, 278 insertions(+), 255 deletions(-) create mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/Runtime.java diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseLauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseLauncherActivity.java index b891d7227..7fc551a02 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseLauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseLauncherActivity.java @@ -4,20 +4,15 @@ import static net.kdt.pojavlaunch.Tools.getFileName; import android.app.*; import android.content.*; -import android.database.Cursor; import android.net.Uri; -import android.provider.OpenableColumns; -import android.text.*; -import android.text.method.*; import android.view.*; import android.webkit.MimeTypeMap; import android.widget.*; import androidx.annotation.Nullable; -import androidx.appcompat.app.*; -import com.kdt.pickafile.*; + import java.io.*; -import net.kdt.pojavlaunch.fragments.*; + import net.kdt.pojavlaunch.multirt.MultiRTConfigDialog; import net.kdt.pojavlaunch.multirt.MultiRTUtils; import net.kdt.pojavlaunch.prefs.*; @@ -65,7 +60,7 @@ public abstract class BaseLauncherActivity extends BaseActivity { public static final int RUN_MOD_INSTALLER = 2050; private void installMod(boolean customJavaArgs) { - if (MultiRTUtils.getExactJREName(8) == null) { + if (MultiRTUtils.getExactJreName(8) == null) { Toast.makeText(this, R.string.multirt_nojava8rt, Toast.LENGTH_LONG).show(); return; } @@ -190,7 +185,7 @@ public abstract class BaseLauncherActivity extends BaseActivity { BaseLauncherActivity.this.runOnUiThread(() -> { barrier.dismiss(); mRuntimeConfigDialog.refresh(); - mRuntimeConfigDialog.dialog.show(); + mRuntimeConfigDialog.mDialog.show(); }); }); t.start(); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java index ca77a0e0f..7f0cc9033 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java @@ -1,6 +1,5 @@ package net.kdt.pojavlaunch; -import android.graphics.*; import android.os.*; import android.util.*; import android.view.*; @@ -71,7 +70,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc if (JREUtils.jreReleaseList.get("JAVA_VERSION").equals("1.8.0")) { MultiRTUtils.setRuntimeNamed(this,LauncherPreferences.PREF_DEFAULT_RUNTIME); } else { - MultiRTUtils.setRuntimeNamed(this,MultiRTUtils.getExactJREName(8)); + MultiRTUtils.setRuntimeNamed(this,MultiRTUtils.getExactJreName(8)); JREUtils.jreReleaseList = JREUtils.readJREReleaseProperties(); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTConfigDialog.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTConfigDialog.java index e00eb8e45..24731a15f 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTConfigDialog.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTConfigDialog.java @@ -14,31 +14,33 @@ import net.kdt.pojavlaunch.R; public class MultiRTConfigDialog { public static final int MULTIRT_PICK_RUNTIME = 2048; public static final int MULTIRT_PICK_RUNTIME_STARTUP = 2049; - public AlertDialog dialog; - public RecyclerView dialogView; - public void prepare(BaseLauncherActivity ctx) { - AlertDialog.Builder builder = new AlertDialog.Builder(ctx); + public AlertDialog mDialog; + public RecyclerView mDialogView; + + public void prepare(BaseLauncherActivity activity) { + mDialogView = new RecyclerView(activity); + mDialogView.setLayoutManager(new LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)); + mDialogView.setAdapter(new RTRecyclerViewAdapter(this)); + + AlertDialog.Builder builder = new AlertDialog.Builder(activity); builder.setTitle(R.string.multirt_config_title); - dialogView = new RecyclerView(ctx); - LinearLayoutManager linearLayoutManager = new LinearLayoutManager(ctx); - linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); - dialogView.setLayoutManager(linearLayoutManager); - dialogView.setAdapter(new RTRecyclerViewAdapter(this)); - builder.setView(dialogView); - builder.setPositiveButton(R.string.multirt_config_add, (dialog, which) -> openRuntimeSelector(ctx,MULTIRT_PICK_RUNTIME)); + builder.setView(mDialogView); + builder.setPositiveButton(R.string.multirt_config_add, (dialog, which) -> openRuntimeSelector(activity,MULTIRT_PICK_RUNTIME)); builder.setNegativeButton(R.string.mcn_exit_call, (dialog, which) -> dialog.cancel()); - dialog = builder.create(); + mDialog = builder.create(); } + public void refresh() { - RecyclerView.Adapter adapter = dialogView.getAdapter(); - if(adapter != null)dialogView.getAdapter().notifyDataSetChanged(); + RecyclerView.Adapter adapter = mDialogView.getAdapter(); + if(adapter != null) mDialogView.getAdapter().notifyDataSetChanged(); } - public static void openRuntimeSelector(Activity ctx, int code) { + + public static void openRuntimeSelector(Activity activity, int code) { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("xz"); if(mimeType == null) mimeType = "*/*"; intent.setType(mimeType); - ctx.startActivityForResult(intent,code); + activity.startActivityForResult(intent,code); } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTUtils.java index 3cf4ab32c..38ec39f98 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTUtils.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTUtils.java @@ -2,6 +2,7 @@ package net.kdt.pojavlaunch.multirt; import android.content.Context; import android.system.Os; +import android.util.Log; import net.kdt.pojavlaunch.R; import net.kdt.pojavlaunch.Tools; @@ -22,135 +23,102 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.Objects; public class MultiRTUtils { - public static HashMap cache = new HashMap<>(); - public static class Runtime { - public Runtime(String name) { - this.name = name; - } - public String name; - public String versionString; - public String arch; - public int javaVersion; + public interface RuntimeProgressReporter { + void reportStringProgress(int resId, Object ... stuff); + } + + private static final HashMap sCache = new HashMap<>(); + + private static final File RUNTIME_FOLDER = new File(Tools.MULTIRT_HOME); + private static final String JAVA_VERSION_STR = "JAVA_VERSION=\""; + private static final String OS_ARCH_STR = "OS_ARCH=\""; - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Runtime runtime = (Runtime) o; - return name.equals(runtime.name); - } - @Override - public int hashCode() { - return Objects.hash(name); - } - } - public static interface ProgressReporterThingy { - void reportStringProgress(int resid, Object ... stuff); - } - private static final File runtimeFolder = new File(Tools.MULTIRT_HOME); - private static final String JAVA_VERSION_str = "JAVA_VERSION=\""; - private static final String OS_ARCH_str = "OS_ARCH=\""; public static List getRuntimes() { - if(!runtimeFolder.exists()) runtimeFolder.mkdirs(); - ArrayList ret = new ArrayList<>(); + if(!RUNTIME_FOLDER.exists()) RUNTIME_FOLDER.mkdirs(); + + ArrayList runtimes = new ArrayList<>(); System.out.println("Fetch runtime list"); - for(File f : runtimeFolder.listFiles()) { - ret.add(read(f.getName())); + for(File f : RUNTIME_FOLDER.listFiles()) { + runtimes.add(read(f.getName())); } - return ret; + return runtimes; } - public static String getExactJREName(int majorVersion) { + + public static String getExactJreName(int majorVersion) { List runtimes = getRuntimes(); - for(Runtime r : runtimes) { - if(r.javaVersion == majorVersion) { - return r.name; - } - } + for(Runtime r : runtimes) + if(r.javaVersion == majorVersion)return r.name; + return null; } - public static String getNearestJREName(int majorVersion) { + + public static String getNearestJreName(int majorVersion) { List runtimes = getRuntimes(); int diff_factor = Integer.MAX_VALUE; String result = null; for(Runtime r : runtimes) { - if(r.javaVersion >= majorVersion) { // lower - not useful - int currentFactor = r.javaVersion - majorVersion; - if(diff_factor > currentFactor) { - result = r.name; - diff_factor = currentFactor; - } + if(r.javaVersion < majorVersion) continue; // lower - not useful + + int currentFactor = r.javaVersion - majorVersion; + if(diff_factor > currentFactor) { + result = r.name; + diff_factor = currentFactor; } } + return result; } - public static void installRuntimeNamed(InputStream runtimeInputStream, String name, ProgressReporterThingy thingy) throws IOException { - File dest = new File(runtimeFolder,"/"+name); + + public static void installRuntimeNamed(InputStream runtimeInputStream, String name, RuntimeProgressReporter progressReporter) throws IOException { + File dest = new File(RUNTIME_FOLDER,"/"+name); File tmp = new File(dest,"temporary"); if(dest.exists()) FileUtils.deleteDirectory(dest); dest.mkdirs(); FileOutputStream fos = new FileOutputStream(tmp); - thingy.reportStringProgress(R.string.multirt_progress_caching); + progressReporter.reportStringProgress(R.string.multirt_progress_caching); IOUtils.copy(runtimeInputStream,fos); fos.close(); runtimeInputStream.close(); - uncompressTarXZ(tmp,dest,thingy); + uncompressTarXZ(tmp,dest,progressReporter); tmp.delete(); read(name); } - private static void __installRuntimeNamed__NoRM(InputStream runtimeInputStream, File dest, ProgressReporterThingy thingy) throws IOException { - File tmp = new File(dest,"temporary"); - FileOutputStream fos = new FileOutputStream(tmp); - thingy.reportStringProgress(R.string.multirt_progress_caching); - IOUtils.copy(runtimeInputStream,fos); - fos.close(); - runtimeInputStream.close(); - uncompressTarXZ(tmp,dest,thingy); - tmp.delete(); - } + public static void postPrepare(Context ctx, String name) throws IOException { - File dest = new File(runtimeFolder,"/"+name); + File dest = new File(RUNTIME_FOLDER,"/" + name); if(!dest.exists()) return; - Runtime r = read(name); + Runtime runtime = read(name); String libFolder = "lib"; - if(new File(dest,libFolder+"/"+r.arch).exists()) libFolder = libFolder+"/"+r.arch; - File ftIn = new File(dest, libFolder+ "/libfreetype.so.6"); + if(new File(dest,libFolder + "/" + runtime.arch).exists()) libFolder = libFolder + "/" + runtime.arch; + File ftIn = new File(dest, libFolder + "/libfreetype.so.6"); File ftOut = new File(dest, libFolder + "/libfreetype.so"); if (ftIn.exists() && (!ftOut.exists() || ftIn.length() != ftOut.length())) { ftIn.renameTo(ftOut); } // Refresh libraries - copyDummyNativeLib(ctx,"libawt_xawt.so",dest,libFolder); + copyDummyNativeLib(ctx,"libawt_xawt.so", dest, libFolder); } - private static void copyDummyNativeLib(Context ctx, String name, File dest, String libFolder) throws IOException { - File fileLib = new File(dest, "/"+libFolder + "/" + name); - fileLib.delete(); - FileInputStream is = new FileInputStream(new File(ctx.getApplicationInfo().nativeLibraryDir, name)); - FileOutputStream os = new FileOutputStream(fileLib); - IOUtils.copy(is, os); - is.close(); - os.close(); - } - public static Runtime installRuntimeNamedBinpack(InputStream universalFileInputStream, InputStream platformBinsInputStream, String name, String binpackVersion, ProgressReporterThingy thingy) throws IOException { - File dest = new File(runtimeFolder,"/"+name); + public static Runtime installRuntimeNamedBinpack(InputStream universalFileInputStream, InputStream platformBinsInputStream, String name, String binpackVersion, RuntimeProgressReporter thingy) throws IOException { + File dest = new File(RUNTIME_FOLDER,"/"+name); if(dest.exists()) FileUtils.deleteDirectory(dest); dest.mkdirs(); - __installRuntimeNamed__NoRM(universalFileInputStream,dest,thingy); - __installRuntimeNamed__NoRM(platformBinsInputStream,dest,thingy); - File binpack_verfile = new File(runtimeFolder,"/"+name+"/pojav_version"); + installRuntimeNamedNoRemove(universalFileInputStream,dest,thingy); + installRuntimeNamedNoRemove(platformBinsInputStream,dest,thingy); + File binpack_verfile = new File(RUNTIME_FOLDER,"/"+name+"/pojav_version"); FileOutputStream fos = new FileOutputStream(binpack_verfile); fos.write(binpackVersion.getBytes()); fos.close(); - cache.remove(name); // Force reread + sCache.remove(name); // Force reread return read(name); } + public static String __internal__readBinpackVersion(String name) { - File binpack_verfile = new File(runtimeFolder,"/"+name+"/pojav_version"); + File binpack_verfile = new File(RUNTIME_FOLDER,"/"+name+"/pojav_version"); try { if (binpack_verfile.exists()) { return Tools.read(binpack_verfile.getAbsolutePath()); @@ -162,38 +130,42 @@ public class MultiRTUtils { return null; } } + public static void removeRuntimeNamed(String name) throws IOException { - File dest = new File(runtimeFolder,"/"+name); + File dest = new File(RUNTIME_FOLDER,"/"+name); if(dest.exists()) { FileUtils.deleteDirectory(dest); - cache.remove(name); + sCache.remove(name); } } + public static void setRuntimeNamed(Context ctx, String name) throws IOException { - File dest = new File(runtimeFolder,"/"+name); + File dest = new File(RUNTIME_FOLDER,"/"+name); if((!dest.exists()) || MultiRTUtils.forceReread(name).versionString == null) throw new RuntimeException("Selected runtime is broken!"); Tools.DIR_HOME_JRE = dest.getAbsolutePath(); JREUtils.relocateLibPath(ctx); } + public static Runtime forceReread(String name) { - cache.remove(name); + sCache.remove(name); return read(name); } + public static Runtime read(String name) { - if(cache.containsKey(name)) return cache.get(name); - Runtime retur; - File release = new File(runtimeFolder,"/"+name+"/release"); + if(sCache.containsKey(name)) return sCache.get(name); + Runtime returnRuntime; + File release = new File(RUNTIME_FOLDER,"/"+name+"/release"); if(!release.exists()) { return new Runtime(name); } try { String content = Tools.read(release.getAbsolutePath()); - int _JAVA_VERSION_index = content.indexOf(JAVA_VERSION_str); - int _OS_ARCH_index = content.indexOf(OS_ARCH_str); - if(_JAVA_VERSION_index != -1 && _OS_ARCH_index != -1) { - _JAVA_VERSION_index += JAVA_VERSION_str.length(); - _OS_ARCH_index += OS_ARCH_str.length(); - String javaVersion = content.substring(_JAVA_VERSION_index,content.indexOf('"',_JAVA_VERSION_index)); + int javaVersionIndex = content.indexOf(JAVA_VERSION_STR); + int osArchIndex = content.indexOf(OS_ARCH_STR); + if(javaVersionIndex != -1 && osArchIndex != -1) { + javaVersionIndex += JAVA_VERSION_STR.length(); + osArchIndex += OS_ARCH_STR.length(); + String javaVersion = content.substring(javaVersionIndex,content.indexOf('"', javaVersionIndex)); String[] javaVersionSplit = javaVersion.split("\\."); int javaVersionInt; if (javaVersionSplit[0].equals("1")) { @@ -201,25 +173,46 @@ public class MultiRTUtils { } else { javaVersionInt = Integer.parseInt(javaVersionSplit[0]); } - Runtime r = new Runtime(name); - r.arch = content.substring(_OS_ARCH_index,content.indexOf('"',_OS_ARCH_index)); - r.javaVersion = javaVersionInt; - r.versionString = javaVersion; - retur = r; + Runtime runtime = new Runtime(name); + runtime.arch = content.substring(osArchIndex,content.indexOf('"', osArchIndex)); + runtime.javaVersion = javaVersionInt; + runtime.versionString = javaVersion; + returnRuntime = runtime; }else{ - retur = new Runtime(name); + returnRuntime = new Runtime(name); } }catch(IOException e) { - retur = new Runtime(name); + returnRuntime = new Runtime(name); } - cache.put(name,retur); - return retur; + sCache.put(name, returnRuntime); + return returnRuntime; } - private static void uncompressTarXZ(final File tarFile, final File dest, final ProgressReporterThingy thingy) throws IOException { - dest.mkdirs(); - TarArchiveInputStream tarIn = null; - tarIn = new TarArchiveInputStream( + private static void copyDummyNativeLib(Context ctx, String name, File dest, String libFolder) throws IOException { + File fileLib = new File(dest, "/"+libFolder + "/" + name); + fileLib.delete(); + FileInputStream is = new FileInputStream(new File(ctx.getApplicationInfo().nativeLibraryDir, name)); + FileOutputStream os = new FileOutputStream(fileLib); + IOUtils.copy(is, os); + is.close(); + os.close(); + } + + private static void installRuntimeNamedNoRemove(InputStream runtimeInputStream, File dest, RuntimeProgressReporter progressReporter) throws IOException { + File tmp = new File(dest,"temporary"); + FileOutputStream fos = new FileOutputStream(tmp); + progressReporter.reportStringProgress(R.string.multirt_progress_caching); + IOUtils.copy(runtimeInputStream,fos); + fos.close(); + runtimeInputStream.close(); + uncompressTarXZ(tmp,dest,progressReporter); + tmp.delete(); + } + + private static void uncompressTarXZ(final File tarFile, final File dest, final RuntimeProgressReporter thingy) throws IOException { + dest.mkdirs(); + + TarArchiveInputStream tarIn = new TarArchiveInputStream( new XZCompressorInputStream( new BufferedInputStream( new FileInputStream(tarFile) @@ -251,7 +244,7 @@ public class MultiRTUtils { // Libcore one support all Android versions Os.symlink(tarEntry.getName(), tarEntry.getLinkName()); } catch (Throwable e) { - e.printStackTrace(); + Log.e("MultiRT", e.toString()); } } else if (tarEntry.isDirectory()) { diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTRecyclerViewAdapter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTRecyclerViewAdapter.java index 54bb5a4f8..e2765f967 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTRecyclerViewAdapter.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTRecyclerViewAdapter.java @@ -23,10 +23,12 @@ import java.io.IOException; import java.util.List; public class RTRecyclerViewAdapter extends RecyclerView.Adapter { - MultiRTConfigDialog dialog; + + MultiRTConfigDialog mConfigDialog; public RTRecyclerViewAdapter(MultiRTConfigDialog dialog) { - this.dialog = dialog; + this.mConfigDialog = dialog; } + @NonNull @Override public RTViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { @@ -36,102 +38,111 @@ public class RTRecyclerViewAdapter extends RecyclerView.Adapter runtimes = MultiRTUtils.getRuntimes(); + final List runtimes = MultiRTUtils.getRuntimes(); holder.bindRuntime(runtimes.get(position),position); } - public boolean isDefaultRuntime(MultiRTUtils.Runtime rt) { - return LauncherPreferences.PREF_DEFAULT_RUNTIME.equals(rt.name); - } - public void setDefault(MultiRTUtils.Runtime rt){ - LauncherPreferences.PREF_DEFAULT_RUNTIME = rt.name; - LauncherPreferences.DEFAULT_PREF.edit().putString("defaultRuntime",LauncherPreferences.PREF_DEFAULT_RUNTIME).apply(); - RTRecyclerViewAdapter.this.notifyDataSetChanged(); - } + @Override public int getItemCount() { return MultiRTUtils.getRuntimes().size(); } + + public boolean isDefaultRuntime(Runtime rt) { + return LauncherPreferences.PREF_DEFAULT_RUNTIME.equals(rt.name); + } + + public void setDefault(Runtime rt){ + LauncherPreferences.PREF_DEFAULT_RUNTIME = rt.name; + LauncherPreferences.DEFAULT_PREF.edit().putString("defaultRuntime",LauncherPreferences.PREF_DEFAULT_RUNTIME).apply(); + RTRecyclerViewAdapter.this.notifyDataSetChanged(); + } + + public class RTViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ - final TextView javaVersionView; - final TextView fullJavaVersionView; - final ColorStateList defaultColors; - final Button setDefaultButton; - final Context ctx; - MultiRTUtils.Runtime currentRuntime; - int currentPosition; + final TextView mJavaVersionTextView; + final TextView mFullJavaVersionTextView; + final ColorStateList mDefaultColors; + final Button mSetDefaultButton; + final Context mContext; + Runtime mCurrentRuntime; + int mCurrentPosition; + public RTViewHolder(View itemView) { super(itemView); - javaVersionView = itemView.findViewById(R.id.multirt_view_java_version); - fullJavaVersionView = itemView.findViewById(R.id.multirt_view_java_version_full); + mJavaVersionTextView = itemView.findViewById(R.id.multirt_view_java_version); + mFullJavaVersionTextView = itemView.findViewById(R.id.multirt_view_java_version_full); + mSetDefaultButton = itemView.findViewById(R.id.multirt_view_setdefaultbtn); + mSetDefaultButton.setOnClickListener(this); + mDefaultColors = mFullJavaVersionTextView.getTextColors(); + mContext = itemView.getContext(); itemView.findViewById(R.id.multirt_view_removebtn).setOnClickListener(this); - setDefaultButton = itemView.findViewById(R.id.multirt_view_setdefaultbtn); - setDefaultButton.setOnClickListener(this); - defaultColors = fullJavaVersionView.getTextColors(); - ctx = itemView.getContext(); - } - public void bindRuntime(MultiRTUtils.Runtime rt, int pos) { - currentRuntime = rt; - currentPosition = pos; - if(rt.versionString != null && Tools.DEVICE_ARCHITECTURE == Architecture.archAsInt(rt.arch)) { - javaVersionView.setText(ctx.getString(R.string.multirt_java_ver, rt.name, rt.javaVersion)); - fullJavaVersionView.setText(rt.versionString); - fullJavaVersionView.setTextColor(defaultColors); - setDefaultButton.setVisibility(View.VISIBLE); - boolean default_ = isDefaultRuntime(rt); - setDefaultButton.setEnabled(!default_); - setDefaultButton.setText(default_?R.string.multirt_config_setdefault_already:R.string.multirt_config_setdefault); - }else{ - if(rt.versionString == null){ - fullJavaVersionView.setText(R.string.multirt_runtime_corrupt); - }else{ - fullJavaVersionView.setText(ctx.getString(R.string.multirt_runtime_incompatiblearch, rt.arch)); - } - javaVersionView.setText(rt.name); - fullJavaVersionView.setTextColor(Color.RED); - setDefaultButton.setVisibility(View.GONE); - } } @Override - public void onClick(View v) { - if(v.getId() == R.id.multirt_view_removebtn) { - if (currentRuntime != null) { - if(MultiRTUtils.getRuntimes().size() < 2 && setDefaultButton.isShown()) { - AlertDialog.Builder bldr = new AlertDialog.Builder(ctx); - bldr.setTitle(R.string.global_error); - bldr.setMessage(R.string.multirt_config_removeerror_last); - bldr.setPositiveButton(android.R.string.ok,(adapter, which)->adapter.dismiss()); - bldr.show(); - return; - } + public void onClick(View view) { + if(view.getId() == R.id.multirt_view_removebtn) { + if (mCurrentRuntime == null) return; - final ProgressDialog barrier = new ProgressDialog(ctx); - barrier.setMessage(ctx.getString(R.string.global_waiting)); - barrier.setProgressStyle(ProgressDialog.STYLE_SPINNER); - barrier.setCancelable(false); - barrier.show(); - Thread t = new Thread(() -> { - try { - MultiRTUtils.removeRuntimeNamed(currentRuntime.name); - } catch (IOException e) { - Tools.showError(itemView.getContext(), e); - } - v.post(() -> { - if(isDefaultRuntime(currentRuntime)) setDefault(MultiRTUtils.getRuntimes().get(0)); - barrier.dismiss(); - RTRecyclerViewAdapter.this.notifyDataSetChanged(); - dialog.dialog.show(); - }); - }); - t.start(); + if(MultiRTUtils.getRuntimes().size() < 2 && mSetDefaultButton.isShown()) { + AlertDialog.Builder bldr = new AlertDialog.Builder(mContext); + bldr.setTitle(R.string.global_error); + bldr.setMessage(R.string.multirt_config_removeerror_last); + bldr.setPositiveButton(android.R.string.ok,(adapter, which)->adapter.dismiss()); + bldr.show(); + return; } - }else if(v.getId() == R.id.multirt_view_setdefaultbtn) { - if(currentRuntime != null) { - setDefault(currentRuntime); + + final ProgressDialog barrier = new ProgressDialog(mContext); + barrier.setMessage(mContext.getString(R.string.global_waiting)); + barrier.setProgressStyle(ProgressDialog.STYLE_SPINNER); + barrier.setCancelable(false); + barrier.show(); + Thread t = new Thread(() -> { + try { + MultiRTUtils.removeRuntimeNamed(mCurrentRuntime.name); + } catch (IOException e) { + Tools.showError(itemView.getContext(), e); + } + view.post(() -> { + if(isDefaultRuntime(mCurrentRuntime)) setDefault(MultiRTUtils.getRuntimes().get(0)); + barrier.dismiss(); + RTRecyclerViewAdapter.this.notifyDataSetChanged(); + mConfigDialog.mDialog.show(); + }); + }); + t.start(); + + }else if(view.getId() == R.id.multirt_view_setdefaultbtn) { + if(mCurrentRuntime != null) { + setDefault(mCurrentRuntime); RTRecyclerViewAdapter.this.notifyDataSetChanged(); } } } + public void bindRuntime(Runtime runtime, int pos) { + mCurrentRuntime = runtime; + mCurrentPosition = pos; + if(runtime.versionString != null && Tools.DEVICE_ARCHITECTURE == Architecture.archAsInt(runtime.arch)) { + mJavaVersionTextView.setText(mContext.getString(R.string.multirt_java_ver, runtime.name, runtime.javaVersion)); + mFullJavaVersionTextView.setText(runtime.versionString); + mFullJavaVersionTextView.setTextColor(mDefaultColors); + mSetDefaultButton.setVisibility(View.VISIBLE); + boolean defaultRuntime = isDefaultRuntime(runtime); + mSetDefaultButton.setEnabled(!defaultRuntime); + mSetDefaultButton.setText(defaultRuntime ? R.string.multirt_config_setdefault_already:R.string.multirt_config_setdefault); + return; + } + + // Problematic runtime moment + if(runtime.versionString == null){ + mFullJavaVersionTextView.setText(R.string.multirt_runtime_corrupt); + }else{ + mFullJavaVersionTextView.setText(mContext.getString(R.string.multirt_runtime_incompatiblearch, runtime.arch)); + } + mJavaVersionTextView.setText(runtime.name); + mFullJavaVersionTextView.setTextColor(Color.RED); + mSetDefaultButton.setVisibility(View.GONE); + } } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTSpinnerAdapter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTSpinnerAdapter.java index 4a499c371..8940ad5fc 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTSpinnerAdapter.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTSpinnerAdapter.java @@ -16,39 +16,39 @@ import net.kdt.pojavlaunch.R; import java.util.List; public class RTSpinnerAdapter implements SpinnerAdapter { - final Context ctx; - List runtimes; - public RTSpinnerAdapter(@NonNull Context context, List runtimes) { - this.runtimes = runtimes; - MultiRTUtils.Runtime runtime = new MultiRTUtils.Runtime(""); + final Context mContext; + List mRuntimes; + public RTSpinnerAdapter(@NonNull Context context, List runtimes) { + mRuntimes = runtimes; + Runtime runtime = new Runtime(""); runtime.versionString = ""; - this.runtimes.add(runtime); - ctx = context; + mRuntimes.add(runtime); + mContext = context; } @Override public void registerDataSetObserver(DataSetObserver observer) { - + //STUB } @Override public void unregisterDataSetObserver(DataSetObserver observer) { - + //STUB } @Override public int getCount() { - return runtimes.size(); + return mRuntimes.size(); } @Override public Object getItem(int position) { - return runtimes.get(position); + return mRuntimes.get(position); } @Override public long getItemId(int position) { - return runtimes.get(position).name.hashCode(); + return mRuntimes.get(position).name.hashCode(); } @Override @@ -59,25 +59,25 @@ public class RTSpinnerAdapter implements SpinnerAdapter { @NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { - View v = convertView!=null? + View view = convertView != null? convertView: - LayoutInflater.from(ctx).inflate(R.layout.multirt_recyclable_view,parent,false); + LayoutInflater.from(mContext).inflate(R.layout.multirt_recyclable_view,parent,false); - MultiRTUtils.Runtime rt = runtimes.get(position); + Runtime runtime = mRuntimes.get(position); - final TextView javaVersionView = v.findViewById(R.id.multirt_view_java_version); - final TextView fullJavaVersionView = v.findViewById(R.id.multirt_view_java_version_full); - v.findViewById(R.id.multirt_view_removebtn).setVisibility(View.GONE); - v.findViewById(R.id.multirt_view_setdefaultbtn).setVisibility(View.GONE); + final TextView javaVersionView = view.findViewById(R.id.multirt_view_java_version); + final TextView fullJavaVersionView = view.findViewById(R.id.multirt_view_java_version_full); + view.findViewById(R.id.multirt_view_removebtn).setVisibility(View.GONE); + view.findViewById(R.id.multirt_view_setdefaultbtn).setVisibility(View.GONE); - if(rt.versionString != null) { - javaVersionView.setText(ctx.getString(R.string.multirt_java_ver, rt.name, rt.javaVersion)); - fullJavaVersionView.setText(rt.versionString); + if(runtime.versionString != null) { + javaVersionView.setText(mContext.getString(R.string.multirt_java_ver, runtime.name, runtime.javaVersion)); + fullJavaVersionView.setText(runtime.versionString); }else{ - javaVersionView.setText(rt.name); + javaVersionView.setText(runtime.name); fullJavaVersionView.setText(R.string.multirt_runtime_corrupt); } - return v; + return view; } @Override @@ -92,7 +92,7 @@ public class RTSpinnerAdapter implements SpinnerAdapter { @Override public boolean isEmpty() { - return runtimes.isEmpty(); + return mRuntimes.isEmpty(); } @Override diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/Runtime.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/Runtime.java new file mode 100644 index 000000000..9c4d7897e --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/Runtime.java @@ -0,0 +1,26 @@ +package net.kdt.pojavlaunch.multirt; + +import java.util.Objects; + +public class Runtime { + public Runtime(String name) { + this.name = name; + } + + public String name; + public String versionString; + public String arch; + public int javaVersion; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Runtime runtime = (Runtime) o; + return name.equals(runtime.name); + } + @Override + public int hashCode() { + return Objects.hash(name); + } +} \ No newline at end of file diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/PerVersionConfigDialog.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/PerVersionConfigDialog.java index 78db13c93..79bb595b3 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/PerVersionConfigDialog.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/PerVersionConfigDialog.java @@ -13,13 +13,12 @@ import androidx.appcompat.app.AlertDialog; import net.kdt.pojavlaunch.R; import net.kdt.pojavlaunch.multirt.MultiRTUtils; import net.kdt.pojavlaunch.multirt.RTSpinnerAdapter; -import net.kdt.pojavlaunch.tasks.RefreshVersionListTask; +import net.kdt.pojavlaunch.multirt.Runtime; import net.kdt.pojavlaunch.value.PerVersionConfig; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.List; @@ -27,7 +26,7 @@ public class PerVersionConfigDialog{ final Context ctx; final AlertDialog dialog; final View v; - List runtimes; + List runtimes; final Spinner javaVMSpinner; final Spinner rendererSpinner; final EditText customDirText; @@ -58,7 +57,7 @@ public class PerVersionConfigDialog{ public void refreshRuntimes() { if(runtimes!=null)runtimes.clear(); runtimes = MultiRTUtils.getRuntimes(); - //runtimes.add(new MultiRTUtils.Runtime("")); + //runtimes.add(new Runtime("")); } private void save(DialogInterface i, int which) { if(selectedGameVersion == null) { @@ -75,7 +74,7 @@ public class PerVersionConfigDialog{ if(rendererSpinner.getSelectedItemPosition() == renderNames.size()) conf1.renderer = null; else conf1.renderer = renderNames.get(rendererSpinner.getSelectedItemPosition()); - String runtime=((MultiRTUtils.Runtime)javaVMSpinner.getSelectedItem()).name;; + String runtime=((Runtime)javaVMSpinner.getSelectedItem()).name;; if(!runtime.equals(""))conf1.selectedRuntime=runtime; else conf1.selectedRuntime=null; @@ -97,13 +96,13 @@ public class PerVersionConfigDialog{ refreshRuntimes(); javaVMSpinner.setAdapter(new RTSpinnerAdapter(ctx,runtimes)); { - int jvm_index = runtimes.indexOf(new MultiRTUtils.Runtime("")); + int jvm_index = runtimes.indexOf(new Runtime("")); int rnd_index = rendererSpinner.getAdapter().getCount()-1; if (conf != null) { customDirText.setText(conf.gamePath); jvmArgsEditText.setText(conf.jvmArgs); if (conf.selectedRuntime != null) { - int nindex = runtimes.indexOf(new MultiRTUtils.Runtime(conf.selectedRuntime)); + int nindex = runtimes.indexOf(new Runtime(conf.selectedRuntime)); if (nindex != -1) jvm_index = nindex; } if(conf.renderer != null) { diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/RuntimeManagerPreference.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/RuntimeManagerPreference.java index 24ff16977..d6c2356ca 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/RuntimeManagerPreference.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/RuntimeManagerPreference.java @@ -6,7 +6,6 @@ import android.util.AttributeSet; import androidx.preference.Preference; import net.kdt.pojavlaunch.BaseLauncherActivity; -import net.kdt.pojavlaunch.multirt.MultiRTConfigDialog; public class RuntimeManagerPreference extends Preference{ public RuntimeManagerPreference(Context ctx) { @@ -20,6 +19,6 @@ public class RuntimeManagerPreference extends Preference{ @Override protected void onClick() { super.onClick(); - ((BaseLauncherActivity)this.getContext()).mRuntimeConfigDialog.dialog.show(); + ((BaseLauncherActivity)this.getContext()).mRuntimeConfigDialog.mDialog.show(); } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java index fc2e390c4..0a35f60e9 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java @@ -2,20 +2,18 @@ package net.kdt.pojavlaunch.tasks; import android.app.*; import android.content.*; -import android.content.res.AssetManager; -import android.graphics.*; import android.os.*; import android.util.*; -import com.google.gson.*; + import java.io.*; import java.util.*; import java.util.concurrent.*; import net.kdt.pojavlaunch.*; import net.kdt.pojavlaunch.multirt.MultiRTUtils; +import net.kdt.pojavlaunch.multirt.Runtime; import net.kdt.pojavlaunch.prefs.*; import net.kdt.pojavlaunch.utils.*; import net.kdt.pojavlaunch.value.*; -import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles; import org.apache.commons.io.*; @@ -97,9 +95,10 @@ public class MinecraftDownloaderTask extends AsyncTask Date: Sat, 26 Feb 2022 00:39:34 +0100 Subject: [PATCH 21/70] Refactor ControlOffsetPreference.java --- .../prefs/ControlOffsetPreference.java | 71 +++++++++---------- 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/ControlOffsetPreference.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/ControlOffsetPreference.java index 3d07fb242..d2dc60701 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/ControlOffsetPreference.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/ControlOffsetPreference.java @@ -20,9 +20,7 @@ import net.kdt.pojavlaunch.R; /** Custom preference class displaying a dialog */ public class ControlOffsetPreference extends Preference { - private AlertDialog preferenceDialog; - - + private AlertDialog mPreferenceDialog; public ControlOffsetPreference(Context context, AttributeSet attrs) { super(context, attrs); @@ -34,43 +32,19 @@ public class ControlOffsetPreference extends Preference { init(); } - - private void init(){ - // Setup visual values - if(getTitle() == null){ - setTitle(R.string.preference_control_offset_title); - setSummary(R.string.preference_control_offset_description); - } - if(getIcon() == null){ - setIcon(android.R.drawable.radiobutton_off_background); - } - - // Prepare Alert dialog - AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getContext()); - dialogBuilder.setView(R.layout.control_offset_preference_dialog); - dialogBuilder.setTitle(getContext().getString(R.string.control_offset_title)); - - dialogBuilder.setPositiveButton(android.R.string.ok, null); - dialogBuilder.setNegativeButton(android.R.string.cancel, null); - - preferenceDialog = dialogBuilder.create(); - - - } - @Override protected void onClick() { - preferenceDialog.show(); + mPreferenceDialog.show(); - SeekBar topOffsetSeekbar = preferenceDialog.findViewById(R.id.control_offset_top_seekbar); - SeekBar rightOffsetSeekbar = preferenceDialog.findViewById(R.id.control_offset_right_seekbar); - SeekBar bottomOffsetSeekbar = preferenceDialog.findViewById(R.id.control_offset_bottom_seekbar); - SeekBar leftOffsetSeekbar = preferenceDialog.findViewById(R.id.control_offset_left_seekbar); + SeekBar topOffsetSeekbar = mPreferenceDialog.findViewById(R.id.control_offset_top_seekbar); + SeekBar rightOffsetSeekbar = mPreferenceDialog.findViewById(R.id.control_offset_right_seekbar); + SeekBar bottomOffsetSeekbar = mPreferenceDialog.findViewById(R.id.control_offset_bottom_seekbar); + SeekBar leftOffsetSeekbar = mPreferenceDialog.findViewById(R.id.control_offset_left_seekbar); - TextView topOffsetTextView = preferenceDialog.findViewById(R.id.control_offset_top_textview); - TextView rightOffsetTextView = preferenceDialog.findViewById(R.id.control_offset_right_textview); - TextView bottomOffsetTextView = preferenceDialog.findViewById(R.id.control_offset_bottom_textview); - TextView leftOffsetTextView = preferenceDialog.findViewById(R.id.control_offset_left_textview); + TextView topOffsetTextView = mPreferenceDialog.findViewById(R.id.control_offset_top_textview); + TextView rightOffsetTextView = mPreferenceDialog.findViewById(R.id.control_offset_right_textview); + TextView bottomOffsetTextView = mPreferenceDialog.findViewById(R.id.control_offset_bottom_textview); + TextView leftOffsetTextView = mPreferenceDialog.findViewById(R.id.control_offset_left_textview); SeekBar.OnSeekBarChangeListener seekBarChangeListener = new SeekBar.OnSeekBarChangeListener() { @Override @@ -118,15 +92,36 @@ public class ControlOffsetPreference extends Preference { seekBarChangeListener.onProgressChanged(leftOffsetSeekbar, PREF_CONTROL_LEFT_OFFSET, false); // Custom writing to preferences - preferenceDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(view -> { + mPreferenceDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(view -> { DEFAULT_PREF.edit().putInt("controlTopOffset", topOffsetSeekbar.getProgress()).apply(); DEFAULT_PREF.edit().putInt("controlRightOffset", rightOffsetSeekbar.getProgress()).apply(); DEFAULT_PREF.edit().putInt("controlBottomOffset", bottomOffsetSeekbar.getProgress()).apply(); DEFAULT_PREF.edit().putInt("controlLeftOffset", leftOffsetSeekbar.getProgress()).apply(); - preferenceDialog.dismiss(); + mPreferenceDialog.dismiss(); }); } + private void init(){ + // Setup visual values + if(getTitle() == null){ + setTitle(R.string.preference_control_offset_title); + setSummary(R.string.preference_control_offset_description); + } + if(getIcon() == null){ + setIcon(android.R.drawable.radiobutton_off_background); + } + + // Prepare Alert dialog + AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getContext()); + dialogBuilder.setView(R.layout.control_offset_preference_dialog); + dialogBuilder.setTitle(getContext().getString(R.string.control_offset_title)); + + dialogBuilder.setPositiveButton(android.R.string.ok, null); + dialogBuilder.setNegativeButton(android.R.string.cancel, null); + + mPreferenceDialog = dialogBuilder.create(); + } + } From 098c4c7f894ff2b8c1e5c9062fd74d0118939414 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 00:39:43 +0100 Subject: [PATCH 22/70] Refactor CustomSeekBarPreference.java --- .../prefs/CustomSeekBarPreference.java | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/CustomSeekBarPreference.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/CustomSeekBarPreference.java index a6425b1a6..925289dd2 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/CustomSeekBarPreference.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/CustomSeekBarPreference.java @@ -16,11 +16,11 @@ import net.kdt.pojavlaunch.R; public class CustomSeekBarPreference extends SeekBarPreference { /** The suffix displayed */ - private String suffix = ""; + private String mSuffix = ""; /** Custom minimum value to provide the same behavior as the usual setMin */ private int mMin; /** The textview associated by default to the preference */ - private TextView textView; + private TextView mTextView; public CustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { @@ -37,7 +37,6 @@ public class CustomSeekBarPreference extends SeekBarPreference { public CustomSeekBarPreference(Context context, AttributeSet attrs) { this(context, attrs, R.attr.seekBarPreferenceStyle); - } public CustomSeekBarPreference(Context context) { @@ -58,8 +57,8 @@ public class CustomSeekBarPreference extends SeekBarPreference { TextView titleTextView = (TextView) view.findViewById(android.R.id.title); titleTextView.setTextColor(Color.WHITE); - textView = (TextView) view.findViewById(R.id.seekbar_value); - textView.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START); + mTextView = (TextView) view.findViewById(R.id.seekbar_value); + mTextView.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START); SeekBar seekBar = (SeekBar) view.findViewById(R.id.seekbar); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @@ -71,7 +70,7 @@ public class CustomSeekBarPreference extends SeekBarPreference { progress = progress * getSeekBarIncrement(); progress -= mMin; - textView.setText(String.valueOf(progress + mMin)); + mTextView.setText(String.valueOf(progress + mMin)); updateTextViewWithSuffix(); } @@ -94,20 +93,12 @@ public class CustomSeekBarPreference extends SeekBarPreference { updateTextViewWithSuffix(); } - - private void updateTextViewWithSuffix(){ - if(!textView.getText().toString().endsWith(suffix)){ - textView.setText(String.format("%s%s", textView.getText(), suffix)); - } - - } - /** * Set a suffix to be appended on the TextView associated to the value * @param suffix The suffix to append as a String */ public void setSuffix(String suffix) { - this.suffix = suffix; + this.mSuffix = suffix; } /** @@ -119,4 +110,11 @@ public class CustomSeekBarPreference extends SeekBarPreference { setMin(min); setMax(max); } + + + private void updateTextViewWithSuffix(){ + if(!mTextView.getText().toString().endsWith(mSuffix)){ + mTextView.setText(String.format("%s%s", mTextView.getText(), mSuffix)); + } + } } From 2a37553815405c4f2b34b08047cb134bc8333c3f Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 10:48:08 +0100 Subject: [PATCH 23/70] Refactor PerVersionConfigDialog.java --- .../prefs/PerVersionConfigDialog.java | 138 +++++++++--------- 1 file changed, 70 insertions(+), 68 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/PerVersionConfigDialog.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/PerVersionConfigDialog.java index 79bb595b3..eb14119fc 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/PerVersionConfigDialog.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/PerVersionConfigDialog.java @@ -17,103 +17,105 @@ import net.kdt.pojavlaunch.multirt.Runtime; import net.kdt.pojavlaunch.value.PerVersionConfig; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; public class PerVersionConfigDialog{ - final Context ctx; - final AlertDialog dialog; - final View v; - List runtimes; - final Spinner javaVMSpinner; - final Spinner rendererSpinner; - final EditText customDirText; - final EditText jvmArgsEditText; - final List renderNames; - String selectedGameVersion = null; - public PerVersionConfigDialog(Context _ctx) { - ctx = _ctx; - v = LayoutInflater.from(ctx).inflate(R.layout.pvc_popup,null); - javaVMSpinner = v.findViewById(R.id.pvc_javaVm); - rendererSpinner = v.findViewById(R.id.pvc_renderer); - { - List renderList = new ArrayList<>(); - Collections.addAll(renderList, ctx.getResources().getStringArray(R.array.renderer)); - renderList.add("Default"); - renderNames = Arrays.asList(ctx.getResources().getStringArray(R.array.renderer_values)); - rendererSpinner.setAdapter(new ArrayAdapter<>(ctx, android.R.layout.simple_spinner_dropdown_item,renderList)); - } - customDirText = v.findViewById(R.id.pvc_customDir); - jvmArgsEditText = v.findViewById(R.id.pvc_jvmArgs); - AlertDialog.Builder builder = new AlertDialog.Builder(ctx); - builder.setView(v); + final Context mContext; + final AlertDialog mDialog; + final View mRootView; + List mRuntimes; + final Spinner mJvmSpinner; + final Spinner mRendererSpinner; + final EditText mCustomDirEditText; + final EditText mJvmArgsEditText; + final List mRendererNames; + String mSelectedGameVersion = null; + + public PerVersionConfigDialog(Context ctx) { + mContext = ctx; + mRootView = LayoutInflater.from(mContext).inflate(R.layout.pvc_popup,null); + mJvmSpinner = mRootView.findViewById(R.id.pvc_javaVm); + mRendererSpinner = mRootView.findViewById(R.id.pvc_renderer); + + List renderList = Arrays.asList(mContext.getResources().getStringArray(R.array.renderer)); + renderList.add("Default"); + mRendererNames = Arrays.asList(mContext.getResources().getStringArray(R.array.renderer_values)); + mRendererSpinner.setAdapter(new ArrayAdapter<>(mContext, android.R.layout.simple_spinner_dropdown_item, renderList)); + + mCustomDirEditText = mRootView.findViewById(R.id.pvc_customDir); + mJvmArgsEditText = mRootView.findViewById(R.id.pvc_jvmArgs); + AlertDialog.Builder builder = new AlertDialog.Builder(mContext); + builder.setView(mRootView); builder.setTitle(R.string.pvc_title); - builder.setNegativeButton(android.R.string.cancel,(dialogInterface,i)->dialogInterface.dismiss()); - builder.setPositiveButton(android.R.string.ok,this::save); - dialog = builder.create(); + builder.setNegativeButton(android.R.string.cancel, null); + builder.setPositiveButton(android.R.string.ok, this::save); + mDialog = builder.create(); } + public void refreshRuntimes() { - if(runtimes!=null)runtimes.clear(); - runtimes = MultiRTUtils.getRuntimes(); + if(mRuntimes !=null) mRuntimes.clear(); + mRuntimes = MultiRTUtils.getRuntimes(); //runtimes.add(new Runtime("")); } - private void save(DialogInterface i, int which) { - if(selectedGameVersion == null) { - i.dismiss(); + + private void save(DialogInterface dialogInterface, int which) { + if(mSelectedGameVersion == null) { + dialogInterface.dismiss(); return; } - PerVersionConfig.VersionConfig conf1 = PerVersionConfig.configMap.get(selectedGameVersion); - if(conf1==null){ - conf1=new PerVersionConfig.VersionConfig(); + + PerVersionConfig.VersionConfig versionConfig = PerVersionConfig.configMap.get(mSelectedGameVersion); + if(versionConfig == null){ + versionConfig = new PerVersionConfig.VersionConfig(); } - conf1.jvmArgs=jvmArgsEditText.getText().toString(); - conf1.gamePath=customDirText.getText().toString(); + versionConfig.jvmArgs= mJvmArgsEditText.getText().toString(); + versionConfig.gamePath= mCustomDirEditText.getText().toString(); - if(rendererSpinner.getSelectedItemPosition() == renderNames.size()) conf1.renderer = null; - else conf1.renderer = renderNames.get(rendererSpinner.getSelectedItemPosition()); + if(mRendererSpinner.getSelectedItemPosition() == mRendererNames.size()) versionConfig.renderer = null; + else versionConfig.renderer = mRendererNames.get(mRendererSpinner.getSelectedItemPosition()); - String runtime=((Runtime)javaVMSpinner.getSelectedItem()).name;; - if(!runtime.equals(""))conf1.selectedRuntime=runtime; - else conf1.selectedRuntime=null; + String runtime=((Runtime) mJvmSpinner.getSelectedItem()).name;; + if(!runtime.equals(""))versionConfig.selectedRuntime=runtime; + else versionConfig.selectedRuntime = null; - PerVersionConfig.configMap.put(selectedGameVersion,conf1); + PerVersionConfig.configMap.put(mSelectedGameVersion, versionConfig); try{ PerVersionConfig.update(); }catch(IOException e){ e.printStackTrace(); } } + public boolean openConfig(String selectedVersion) { - selectedGameVersion = selectedVersion; + mSelectedGameVersion = selectedVersion; try{ PerVersionConfig.update(); }catch(IOException e){ e.printStackTrace(); } - PerVersionConfig.VersionConfig conf=PerVersionConfig.configMap.get(selectedGameVersion); + PerVersionConfig.VersionConfig versionConfig = PerVersionConfig.configMap.get(mSelectedGameVersion); refreshRuntimes(); - javaVMSpinner.setAdapter(new RTSpinnerAdapter(ctx,runtimes)); - { - int jvm_index = runtimes.indexOf(new Runtime("")); - int rnd_index = rendererSpinner.getAdapter().getCount()-1; - if (conf != null) { - customDirText.setText(conf.gamePath); - jvmArgsEditText.setText(conf.jvmArgs); - if (conf.selectedRuntime != null) { - int nindex = runtimes.indexOf(new Runtime(conf.selectedRuntime)); - if (nindex != -1) jvm_index = nindex; - } - if(conf.renderer != null) { - int nindex = renderNames.indexOf(conf.renderer); - if (nindex != -1) rnd_index = nindex; - } + mJvmSpinner.setAdapter(new RTSpinnerAdapter(mContext, mRuntimes)); + + int jvmIndex = mRuntimes.indexOf(new Runtime("")); + int rendererIndex = mRendererSpinner.getAdapter().getCount()-1; + if (versionConfig != null) { + mCustomDirEditText.setText(versionConfig.gamePath); + mJvmArgsEditText.setText(versionConfig.jvmArgs); + if (versionConfig.selectedRuntime != null) { + int nIndex = mRuntimes.indexOf(new Runtime(versionConfig.selectedRuntime)); + if (nIndex != -1) jvmIndex = nIndex; + } + if(versionConfig.renderer != null) { + int nIndex = mRendererNames.indexOf(versionConfig.renderer); + if (nIndex != -1) rendererIndex = nIndex; } - javaVMSpinner.setSelection(jvm_index); - rendererSpinner.setSelection(rnd_index); } - dialog.show(); + mJvmSpinner.setSelection(jvmIndex); + mRendererSpinner.setSelection(rendererIndex); + + mDialog.show(); return true; - } + } } From 3618bb63100a07e406ffb628d2a49e4666743f8b Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 10:49:49 +0100 Subject: [PATCH 24/70] Update RuntimeManagerPreference.java --- .../java/net/kdt/pojavlaunch/prefs/RuntimeManagerPreference.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/RuntimeManagerPreference.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/RuntimeManagerPreference.java index d6c2356ca..90d459726 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/RuntimeManagerPreference.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/RuntimeManagerPreference.java @@ -16,6 +16,7 @@ public class RuntimeManagerPreference extends Preference{ super(ctx, attrs); setPersistent(false); } + @Override protected void onClick() { super.onClick(); From 534e244ba5c080a9a352d1ed53ae30400d245298 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 15:41:28 +0100 Subject: [PATCH 25/70] Refactor AWTCanvasView.java --- .../net/kdt/pojavlaunch/AWTCanvasView.java | 124 +++++++++--------- 1 file changed, 59 insertions(+), 65 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/AWTCanvasView.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/AWTCanvasView.java index f9183f1b9..9bf6a5f21 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/AWTCanvasView.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/AWTCanvasView.java @@ -10,56 +10,20 @@ import net.kdt.pojavlaunch.utils.*; import org.lwjgl.glfw.*; public class AWTCanvasView extends TextureView implements TextureView.SurfaceTextureListener, Runnable { + private final int MAX_SIZE = 100; + private final double NANOS = 1000000000.0; + private int mScaleFactor; private int[] mScales; private int mWidth, mHeight; private boolean mIsDestroyed = false; - - private TextPaint fpsPaint; - private boolean attached = false; + private final TextPaint mFpsPaint; + private boolean mAttached = false; + private boolean mDrawing; // Temporary count fps https://stackoverflow.com/a/13729241 - private LinkedList times = new LinkedList(){{add(System.nanoTime());}}; - private final int MAX_SIZE = 100; - private final double NANOS = 1000000000.0; - - /** Calculates and returns frames per second */ - private double fps() { - long lastTime = System.nanoTime(); - double difference = (lastTime - times.getFirst()) / NANOS; - times.addLast(lastTime); - int size = times.size(); - if (size > MAX_SIZE) { - times.removeFirst(); - } - return difference > 0 ? times.size() / difference : 0.0; - } - - /** Computes the scale to better fit the screen */ - void initScaleFactors(){ - initScaleFactors(0); - } - - void initScaleFactors(int forcedScale){ - //Could be optimized - if(forcedScale < 1) { //Auto scale - int minDimension = Math.min(CallbackBridge.physicalHeight, CallbackBridge.physicalWidth); - mScaleFactor = Math.max(((3 * minDimension) / 1080) - 1, 1); - }else{ - mScaleFactor = forcedScale; - } - - int[] scales = new int[2]; //Left, Top - - scales[0] = (CallbackBridge.physicalWidth/2); - scales[0] -= scales[0]/mScaleFactor; - - scales[1] = (CallbackBridge.physicalHeight/2); - scales[1] -= scales[1]/mScaleFactor; - - mScales = scales; - } + private final LinkedList mTimes = new LinkedList(){{add(System.nanoTime());}}; public AWTCanvasView(Context ctx) { this(ctx, null); @@ -67,11 +31,10 @@ public class AWTCanvasView extends TextureView implements TextureView.SurfaceTex public AWTCanvasView(Context ctx, AttributeSet attrs) { super(ctx, attrs); - // setWillNotDraw(false); - fpsPaint = new TextPaint(); - fpsPaint.setColor(Color.WHITE); - fpsPaint.setTextSize(20); + mFpsPaint = new TextPaint(); + mFpsPaint.setColor(Color.WHITE); + mFpsPaint.setTextSize(20); setSurfaceTextureListener(this); initScaleFactors(); @@ -101,21 +64,19 @@ public class AWTCanvasView extends TextureView implements TextureView.SurfaceTex @Override public void onSurfaceTextureUpdated(SurfaceTexture texture) { } - - private boolean mDrawing; - private Surface mSurface; + @Override public void run() { Canvas canvas; - mSurface = new Surface(getSurfaceTexture()); + Surface surface = new Surface(getSurfaceTexture()); try { - while (!mIsDestroyed && mSurface.isValid()) { - canvas = mSurface.lockCanvas(null); + while (!mIsDestroyed && surface.isValid()) { + canvas = surface.lockCanvas(null); canvas.drawRGB(0, 0, 0); - if (!attached) { - attached = CallbackBridge.nativeAttachThreadToOther(true, BaseMainActivity.isInputStackCall); + if (!mAttached) { + mAttached = CallbackBridge.nativeAttachThreadToOther(true, BaseMainActivity.isInputStackCall); } else { int[] rgbArray = JREUtils.renderAWTScreenFrame(/* canvas, mWidth, mHeight */); mDrawing = rgbArray != null; @@ -123,22 +84,55 @@ public class AWTCanvasView extends TextureView implements TextureView.SurfaceTex canvas.save(); canvas.scale(mScaleFactor, mScaleFactor); - canvas.translate(-mScales[0],-mScales[1]); - + canvas.translate(-mScales[0], -mScales[1]); canvas.drawBitmap(rgbArray, 0, CallbackBridge.physicalWidth, 0, 0, CallbackBridge.physicalWidth, CallbackBridge.physicalHeight, true, null); canvas.restore(); - } - rgbArray = null; - // System.gc(); } - canvas.drawText("FPS: " + (Math.round(fps() * 10) / 10) + ", attached=" + attached + ", drawing=" + mDrawing, 50, 50, fpsPaint); - - mSurface.unlockCanvasAndPost(canvas); + canvas.drawText("FPS: " + (Math.round(fps() * 10) / 10) + ", attached=" + mAttached + ", drawing=" + mDrawing, 50, 50, mFpsPaint); + surface.unlockCanvasAndPost(canvas); } - } catch (Throwable th) { - Tools.showError(getContext(), th); + } catch (Throwable throwable) { + Tools.showError(getContext(), throwable); } + surface.release(); + } + + /** Computes the scale to better fit the screen */ + void initScaleFactors(){ + initScaleFactors(0); + } + + void initScaleFactors(int forcedScale){ + //Could be optimized + if(forcedScale < 1) { //Auto scale + int minDimension = Math.min(CallbackBridge.physicalHeight, CallbackBridge.physicalWidth); + mScaleFactor = Math.max(((3 * minDimension) / 1080) - 1, 1); + }else{ + mScaleFactor = forcedScale; + } + + int[] scales = new int[2]; //Left, Top + + scales[0] = (CallbackBridge.physicalWidth/2); + scales[0] -= scales[0]/mScaleFactor; + + scales[1] = (CallbackBridge.physicalHeight/2); + scales[1] -= scales[1]/mScaleFactor; + + mScales = scales; + } + + /** Calculates and returns frames per second */ + private double fps() { + long lastTime = System.nanoTime(); + double difference = (lastTime - mTimes.getFirst()) / NANOS; + mTimes.addLast(lastTime); + int size = mTimes.size(); + if (size > MAX_SIZE) { + mTimes.removeFirst(); + } + return difference > 0 ? mTimes.size() / difference : 0.0; } } From 751e1356aa9dcb8e1f940bf141ab36a215cce426 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 15:41:43 +0100 Subject: [PATCH 26/70] Update AWTInputEvent.java --- .../src/main/java/net/kdt/pojavlaunch/AWTInputEvent.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/AWTInputEvent.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/AWTInputEvent.java index de924007d..58217ec26 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/AWTInputEvent.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/AWTInputEvent.java @@ -24,8 +24,7 @@ package net.kdt.pojavlaunch; * or visit www.oracle.com if you need additional information or have any * questions. */ -public class AWTInputEvent -{ +public class AWTInputEvent { // InputEvent /** * This flag indicates that the Shift key was down when the event From e56e748c8ecda95edd9428a0a340ffff1045f263 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 15:41:54 +0100 Subject: [PATCH 27/70] Refactor BaseActivity.java --- .../src/main/java/net/kdt/pojavlaunch/BaseActivity.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseActivity.java index 1b7710b3a..04347eeea 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseActivity.java @@ -7,8 +7,7 @@ import net.kdt.pojavlaunch.utils.*; import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_IGNORE_NOTCH; -public class BaseActivity extends AppCompatActivity -{ +public abstract class BaseActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -24,7 +23,7 @@ public class BaseActivity extends AppCompatActivity @Override public void startActivity(Intent i) { super.startActivity(i); - new Throwable("StartActivity").printStackTrace(); + //new Throwable("StartActivity").printStackTrace(); } @Override From 6176bf180303a1ee5a723010369cd9cb8e5b33ef Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 15:45:47 +0100 Subject: [PATCH 28/70] Remove CustomTabs.java, GLTextureView.java, and InstallerTask.java --- .../java/net/kdt/pojavlaunch/CustomTabs.java | 16 - .../net/kdt/pojavlaunch/GLTextureView.java | 1821 ----------------- .../net/kdt/pojavlaunch/InstallerTask.java | 52 - 3 files changed, 1889 deletions(-) delete mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomTabs.java delete mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/GLTextureView.java delete mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/InstallerTask.java diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomTabs.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomTabs.java deleted file mode 100644 index 5f99814ce..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomTabs.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.kdt.pojavlaunch; - -import android.content.*; -import android.net.*; -import androidx.browser.customtabs.*; - -public class CustomTabs { - - public static void openTab(Context context, String url) { - CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); - builder.setShowTitle(true); - - CustomTabsIntent customTabsIntent = builder.build(); - customTabsIntent.launchUrl(context, Uri.parse(url)); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/GLTextureView.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/GLTextureView.java deleted file mode 100644 index 40af9b420..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/GLTextureView.java +++ /dev/null @@ -1,1821 +0,0 @@ -package net.kdt.pojavlaunch; - -import java.io.Writer; -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import javax.microedition.khronos.egl.EGL10; -import javax.microedition.khronos.egl.EGL11; -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.egl.EGLContext; -import javax.microedition.khronos.egl.EGLDisplay; -import javax.microedition.khronos.egl.EGLSurface; -import javax.microedition.khronos.opengles.GL; -import javax.microedition.khronos.opengles.GL10; -import android.content.Context; -import android.graphics.SurfaceTexture; -import android.opengl.GLDebugHelper; -import android.util.AttributeSet; -import android.util.Log; -import android.view.TextureView; -import android.view.View; - -public class GLTextureView - extends TextureView - implements TextureView.SurfaceTextureListener, - View.OnLayoutChangeListener { - - private final static String TAG = "GLTextureView"; - private final static boolean LOG_ALL = false; - private final static boolean LOG_ATTACH_DETACH = LOG_ALL; - private final static boolean LOG_THREADS = LOG_ALL; - private final static boolean LOG_PAUSE_RESUME = LOG_ALL; - private final static boolean LOG_SURFACE = LOG_ALL; - private final static boolean LOG_RENDERER = LOG_ALL; - private final static boolean LOG_RENDERER_DRAW_FRAME = LOG_ALL; - private final static boolean LOG_EGL = LOG_ALL; - /** - * The renderer only renders - * when the surface is created, or when {@link #requestRender} is called. - * - * @see #getRenderMode() - * @see #setRenderMode(int) - * @see #requestRender() - */ - public final static int RENDERMODE_WHEN_DIRTY = 0; - /** - * The renderer is called - * continuously to re-render the scene. - * - * @see #getRenderMode() - * @see #setRenderMode(int) - */ - public final static int RENDERMODE_CONTINUOUSLY = 1; - - /** - * Check glError() after every GL call and throw an exception if glError indicates - * that an error has occurred. This can be used to help track down which OpenGL ES call - * is causing an error. - * - * @see #getDebugFlags - * @see #setDebugFlags - */ - public final static int DEBUG_CHECK_GL_ERROR = 1; - - /** - * Log GL calls to the system log at "verbose" level with tag "GLTextureView". - * - * @see #getDebugFlags - * @see #setDebugFlags - */ - public final static int DEBUG_LOG_GL_CALLS = 2; - - /** - * Standard View constructor. In order to render something, you - * must call {@link #setRenderer} to register a renderer. - */ - public GLTextureView(Context context) { - super(context); - init(); - } - - /** - * Standard View constructor. In order to render something, you - * must call {@link #setRenderer} to register a renderer. - */ - public GLTextureView(Context context, AttributeSet attrs) { - super(context, attrs); - init(); - } - - @Override - protected void finalize() throws Throwable { - try { - if (mGLThread != null) { - // GLThread may still be running if this view was never - // attached to a window. - mGLThread.requestExitAndWait(); - } - } finally { - super.finalize(); - } - } - - private void init() { - setSurfaceTextureListener(this); - } - - /** - * Set the glWrapper. If the glWrapper is not null, its - * {@link GLWrapper#wrap(javax.microedition.khronos.opengles.GL)} method is called - * whenever a surface is created. A GLWrapper can be used to wrap - * the GL object that's passed to the renderer. Wrapping a GL - * object enables examining and modifying the behavior of the - * GL calls made by the renderer. - *

- * Wrapping is typically used for debugging purposes. - *

- * The default value is null. - * @param glWrapper the new GLWrapper - */ - public void setGLWrapper(GLWrapper glWrapper) { - mGLWrapper = glWrapper; - } - - /** - * Set the debug flags to a new value. The value is - * constructed by OR-together zero or more - * of the DEBUG_CHECK_* constants. The debug flags take effect - * whenever a surface is created. The default value is zero. - * @param debugFlags the new debug flags - * @see #DEBUG_CHECK_GL_ERROR - * @see #DEBUG_LOG_GL_CALLS - */ - public void setDebugFlags(int debugFlags) { - mDebugFlags = debugFlags; - } - - /** - * Get the current value of the debug flags. - * @return the current value of the debug flags. - */ - public int getDebugFlags() { - return mDebugFlags; - } - - /** - * Control whether the EGL context is preserved when the GLTextureView is paused and - * resumed. - *

- * If set to true, then the EGL context may be preserved when the GLTextureView is paused. - * Whether the EGL context is actually preserved or not depends upon whether the - * Android device that the program is running on can support an arbitrary number of EGL - * contexts or not. Devices that can only support a limited number of EGL contexts must - * release the EGL context in order to allow multiple applications to share the GPU. - *

- * If set to false, the EGL context will be released when the GLTextureView is paused, - * and recreated when the GLTextureView is resumed. - *

- * - * The default is false. - * - * @param preserveOnPause preserve the EGL context when paused - */ - public void setPreserveEGLContextOnPause(boolean preserveOnPause) { - mPreserveEGLContextOnPause = preserveOnPause; - } - - /** - * @return true if the EGL context will be preserved when paused - */ - public boolean getPreserveEGLContextOnPause() { - return mPreserveEGLContextOnPause; - } - - /** - * Set the renderer associated with this view. Also starts the thread that - * will call the renderer, which in turn causes the rendering to start. - *

This method should be called once and only once in the life-cycle of - * a GLTextureView. - *

The following GLTextureView methods can only be called before - * setRenderer is called: - *

    - *
  • {@link #setEGLConfigChooser(boolean)} - *
  • {@link #setEGLConfigChooser(EGLConfigChooser)} - *
  • {@link #setEGLConfigChooser(int, int, int, int, int, int)} - *
- *

- * The following GLTextureView methods can only be called after - * setRenderer is called: - *

    - *
  • {@link #getRenderMode()} - *
  • {@link #onPause()} - *
  • {@link #onResume()} - *
  • {@link #queueEvent(Runnable)} - *
  • {@link #requestRender()} - *
  • {@link #setRenderMode(int)} - *
- * - * @param renderer the renderer to use to perform OpenGL drawing. - */ - public void setRenderer(Renderer renderer) { - checkRenderThreadState(); - if (mEGLConfigChooser == null) { - mEGLConfigChooser = new SimpleEGLConfigChooser(true); - } - if (mEGLContextFactory == null) { - mEGLContextFactory = new DefaultContextFactory(); - } - if (mEGLWindowSurfaceFactory == null) { - mEGLWindowSurfaceFactory = new DefaultWindowSurfaceFactory(); - } - mRenderer = renderer; - mGLThread = new GLThread(mThisWeakRef); - mGLThread.start(); - } - - /** - * Install a custom EGLContextFactory. - *

If this method is - * called, it must be called before {@link #setRenderer(Renderer)} - * is called. - *

- * If this method is not called, then by default - * a context will be created with no shared context and - * with a null attribute list. - */ - public void setEGLContextFactory(EGLContextFactory factory) { - checkRenderThreadState(); - mEGLContextFactory = factory; - } - - /** - * Install a custom EGLWindowSurfaceFactory. - *

If this method is - * called, it must be called before {@link #setRenderer(Renderer)} - * is called. - *

- * If this method is not called, then by default - * a window surface will be created with a null attribute list. - */ - public void setEGLWindowSurfaceFactory(EGLWindowSurfaceFactory factory) { - checkRenderThreadState(); - mEGLWindowSurfaceFactory = factory; - } - - /** - * Install a custom EGLConfigChooser. - *

If this method is - * called, it must be called before {@link #setRenderer(Renderer)} - * is called. - *

- * If no setEGLConfigChooser method is called, then by default the - * view will choose an EGLConfig that is compatible with the current - * android.view.Surface, with a depth buffer depth of - * at least 16 bits. - * @param configChooser - */ - public void setEGLConfigChooser(EGLConfigChooser configChooser) { - checkRenderThreadState(); - mEGLConfigChooser = configChooser; - } - - /** - * Install a config chooser which will choose a config - * as close to 16-bit RGB as possible, with or without an optional depth - * buffer as close to 16-bits as possible. - *

If this method is - * called, it must be called before {@link #setRenderer(Renderer)} - * is called. - *

- * If no setEGLConfigChooser method is called, then by default the - * view will choose an RGB_888 surface with a depth buffer depth of - * at least 16 bits. - * - * @param needDepth - */ - public void setEGLConfigChooser(boolean needDepth) { - setEGLConfigChooser(new SimpleEGLConfigChooser(needDepth)); - } - - /** - * Install a config chooser which will choose a config - * with at least the specified depthSize and stencilSize, - * and exactly the specified redSize, greenSize, blueSize and alphaSize. - *

If this method is - * called, it must be called before {@link #setRenderer(Renderer)} - * is called. - *

- * If no setEGLConfigChooser method is called, then by default the - * view will choose an RGB_888 surface with a depth buffer depth of - * at least 16 bits. - * - */ - public void setEGLConfigChooser(int redSize, int greenSize, int blueSize, - int alphaSize, int depthSize, int stencilSize) { - setEGLConfigChooser(new ComponentSizeChooser(redSize, greenSize, - blueSize, alphaSize, depthSize, stencilSize)); - } - - /** - * Inform the default EGLContextFactory and default EGLConfigChooser - * which EGLContext client version to pick. - *

Use this method to create an OpenGL ES 2.0-compatible context. - * Example: - *

-     *     public MyView(Context context) {
-     *         super(context);
-     *         setEGLContextClientVersion(2); // Pick an OpenGL ES 2.0 context.
-     *         setRenderer(new MyRenderer());
-     *     }
-     * 
- *

Note: Activities which require OpenGL ES 2.0 should indicate this by - * setting @lt;uses-feature android:glEsVersion="0x00020000" /> in the activity's - * AndroidManifest.xml file. - *

If this method is called, it must be called before {@link #setRenderer(Renderer)} - * is called. - *

This method only affects the behavior of the default EGLContexFactory and the - * default EGLConfigChooser. If - * {@link #setEGLContextFactory(EGLContextFactory)} has been called, then the supplied - * EGLContextFactory is responsible for creating an OpenGL ES 2.0-compatible context. - * If - * {@link #setEGLConfigChooser(EGLConfigChooser)} has been called, then the supplied - * EGLConfigChooser is responsible for choosing an OpenGL ES 2.0-compatible config. - * @param version The EGLContext client version to choose. Use 2 for OpenGL ES 2.0 - */ - public void setEGLContextClientVersion(int version) { - checkRenderThreadState(); - mEGLContextClientVersion = version; - } - - /** - * Set the rendering mode. When renderMode is - * RENDERMODE_CONTINUOUSLY, the renderer is called - * repeatedly to re-render the scene. When renderMode - * is RENDERMODE_WHEN_DIRTY, the renderer only rendered when the surface - * is created, or when {@link #requestRender} is called. Defaults to RENDERMODE_CONTINUOUSLY. - *

- * Using RENDERMODE_WHEN_DIRTY can improve battery life and overall system performance - * by allowing the GPU and CPU to idle when the view does not need to be updated. - *

- * This method can only be called after {@link #setRenderer(Renderer)} - * - * @param renderMode one of the RENDERMODE_X constants - * @see #RENDERMODE_CONTINUOUSLY - * @see #RENDERMODE_WHEN_DIRTY - */ - public void setRenderMode(int renderMode) { - mGLThread.setRenderMode(renderMode); - } - - /** - * Get the current rendering mode. May be called - * from any thread. Must not be called before a renderer has been set. - * @return the current rendering mode. - * @see #RENDERMODE_CONTINUOUSLY - * @see #RENDERMODE_WHEN_DIRTY - */ - public int getRenderMode() { - return mGLThread.getRenderMode(); - } - - /** - * Request that the renderer render a frame. - * This method is typically used when the render mode has been set to - * {@link #RENDERMODE_WHEN_DIRTY}, so that frames are only rendered on demand. - * May be called - * from any thread. Must not be called before a renderer has been set. - */ - public void requestRender() { - mGLThread.requestRender(); - } - - /** - * This method is part of the SurfaceHolder.Callback interface, and is - * not normally called or subclassed by clients of GLTextureView. - */ - public void surfaceCreated(SurfaceTexture texture) { - mGLThread.surfaceCreated(); - } - - /** - * This method is part of the SurfaceHolder.Callback interface, and is - * not normally called or subclassed by clients of GLTextureView. - */ - public void surfaceDestroyed(SurfaceTexture texture) { - // Surface will be destroyed when we return - mGLThread.surfaceDestroyed(); - } - - /** - * This method is part of the SurfaceHolder.Callback interface, and is - * not normally called or subclassed by clients of GLTextureView. - */ - public void surfaceChanged(SurfaceTexture texture, int format, int w, int h) { - mGLThread.onWindowResize(w, h); - } - - /** - * Inform the view that the activity is paused. The owner of this view must - * call this method when the activity is paused. Calling this method will - * pause the rendering thread. - * Must not be called before a renderer has been set. - */ - public void onPause() { - mGLThread.onPause(); - } - - /** - * Inform the view that the activity is resumed. The owner of this view must - * call this method when the activity is resumed. Calling this method will - * recreate the OpenGL display and resume the rendering - * thread. - * Must not be called before a renderer has been set. - */ - public void onResume() { - mGLThread.onResume(); - } - - /** - * Queue a runnable to be run on the GL rendering thread. This can be used - * to communicate with the Renderer on the rendering thread. - * Must not be called before a renderer has been set. - * @param r the runnable to be run on the GL rendering thread. - */ - public void queueEvent(Runnable r) { - mGLThread.queueEvent(r); - } - - /** - * This method is used as part of the View class and is not normally - * called or subclassed by clients of GLTextureView. - */ - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - if (LOG_ATTACH_DETACH) { - Log.d(TAG, "onAttachedToWindow reattach =" + mDetached); - } - if (mDetached && (mRenderer != null)) { - int renderMode = RENDERMODE_CONTINUOUSLY; - if (mGLThread != null) { - renderMode = mGLThread.getRenderMode(); - } - mGLThread = new GLThread(mThisWeakRef); - if (renderMode != RENDERMODE_CONTINUOUSLY) { - mGLThread.setRenderMode(renderMode); - } - mGLThread.start(); - } - mDetached = false; - } - - /** - * This method is used as part of the View class and is not normally - * called or subclassed by clients of GLTextureView. - * Must not be called before a renderer has been set. - */ - @Override - protected void onDetachedFromWindow() { - if (LOG_ATTACH_DETACH) { - Log.d(TAG, "onDetachedFromWindow"); - } - if (mGLThread != null) { - mGLThread.requestExitAndWait(); - } - mDetached = true; - super.onDetachedFromWindow(); - } - - public void onLayoutChange(View v, int left, int top, int right, int bottom, - int oldLeft, int oldTop, int oldRight, int oldBottom) { - surfaceChanged(getSurfaceTexture(), 0, right - left, bottom - top); - } - - public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { - surfaceCreated(surface); - surfaceChanged(surface, 0, width, height); - } - - public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { - surfaceChanged(surface, 0, width, height); - } - - public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { - // MOD: Code replaced: -/* - surfaceDestroyed(surface); - return true; -*/ - // MOD: Replaced to: - if (sGLThreadManager.shouldTerminateEGLWhenPausing() && !mPreserveEGLContextOnPause) { - surfaceDestroyed(surface); - return true; - } - return false; - } - - public void onSurfaceTextureUpdated(SurfaceTexture surface) { - requestRender(); - } - - // ---------------------------------------------------------------------- - - /** - * An interface used to wrap a GL interface. - *

Typically - * used for implementing debugging and tracing on top of the default - * GL interface. You would typically use this by creating your own class - * that implemented all the GL methods by delegating to another GL instance. - * Then you could add your own behavior before or after calling the - * delegate. All the GLWrapper would do was instantiate and return the - * wrapper GL instance: - *

-     * class MyGLWrapper implements GLWrapper {
-     *     GL wrap(GL gl) {
-     *         return new MyGLImplementation(gl);
-     *     }
-     *     static class MyGLImplementation implements GL,GL10,GL11,... {
-     *         ...
-     *     }
-     * }
-     * 
- * @see #setGLWrapper(GLWrapper) - */ - public interface GLWrapper { - /** - * Wraps a gl interface in another gl interface. - * @param gl a GL interface that is to be wrapped. - * @return either the input argument or another GL object that wraps the input argument. - */ - GL wrap(GL gl); - } - - /** - * A generic renderer interface. - *

- * The renderer is responsible for making OpenGL calls to render a frame. - *

- * GLTextureView clients typically create their own classes that implement - * this interface, and then call {@link GLTextureView#setRenderer} to - * register the renderer with the GLTextureView. - *

- * - *

- *

Developer Guides

- *

For more information about how to use OpenGL, read the - * OpenGL developer guide.

- *
- * - *

Threading

- * The renderer will be called on a separate thread, so that rendering - * performance is decoupled from the UI thread. Clients typically need to - * communicate with the renderer from the UI thread, because that's where - * input events are received. Clients can communicate using any of the - * standard Java techniques for cross-thread communication, or they can - * use the {@link GLTextureView#queueEvent(Runnable)} convenience method. - *

- *

EGL Context Lost

- * There are situations where the EGL rendering context will be lost. This - * typically happens when device wakes up after going to sleep. When - * the EGL context is lost, all OpenGL resources (such as textures) that are - * associated with that context will be automatically deleted. In order to - * keep rendering correctly, a renderer must recreate any lost resources - * that it still needs. The {@link #onSurfaceCreated(javax.microedition.khronos.opengles.GL10, javax.microedition.khronos.egl.EGLConfig)} method - * is a convenient place to do this. - * - * - * @see #setRenderer(Renderer) - */ - public interface Renderer { - /** - * Called when the surface is created or recreated. - *

- * Called when the rendering thread - * starts and whenever the EGL context is lost. The EGL context will typically - * be lost when the Android device awakes after going to sleep. - *

- * Since this method is called at the beginning of rendering, as well as - * every time the EGL context is lost, this method is a convenient place to put - * code to create resources that need to be created when the rendering - * starts, and that need to be recreated when the EGL context is lost. - * Textures are an example of a resource that you might want to create - * here. - *

- * Note that when the EGL context is lost, all OpenGL resources associated - * with that context will be automatically deleted. You do not need to call - * the corresponding "glDelete" methods such as glDeleteTextures to - * manually delete these lost resources. - *

- * @param gl the GL interface. Use instanceof to - * test if the interface supports GL11 or higher interfaces. - * @param config the EGLConfig of the created surface. Can be used - * to create matching pbuffers. - */ - void onSurfaceCreated(GL10 gl, EGLConfig config); - - /** - * Called when the surface changed size. - *

- * Called after the surface is created and whenever - * the OpenGL ES surface size changes. - *

- * Typically you will set your viewport here. If your camera - * is fixed then you could also set your projection matrix here: - *

-         * void onSurfaceChanged(GL10 gl, int width, int height) {
-         *     gl.glViewport(0, 0, width, height);
-         *     // for a fixed camera, set the projection too
-         *     float ratio = (float) width / height;
-         *     gl.glMatrixMode(GL10.GL_PROJECTION);
-         *     gl.glLoadIdentity();
-         *     gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
-         * }
-         * 
- * @param gl the GL interface. Use instanceof to - * test if the interface supports GL11 or higher interfaces. - * @param width - * @param height - */ - void onSurfaceChanged(GL10 gl, int width, int height); - - /** - * Called to draw the current frame. - *

- * This method is responsible for drawing the current frame. - *

- * The implementation of this method typically looks like this: - *

-         * void onDrawFrame(GL10 gl) {
-         *     gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
-         *     //... other gl calls to render the scene ...
-         * }
-         * 
- * @param gl the GL interface. Use instanceof to - * test if the interface supports GL11 or higher interfaces. - */ - void onDrawFrame(GL10 gl); - - void onSurfaceDestroyed(GL10 gl); - } - - /** - * An interface for customizing the eglCreateContext and eglDestroyContext calls. - *

- * This interface must be implemented by clients wishing to call - * {@link GLTextureView#setEGLContextFactory(EGLContextFactory)} - */ - public interface EGLContextFactory { - EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig); - void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context); - } - - private class DefaultContextFactory implements EGLContextFactory { - private int EGL_CONTEXT_CLIENT_VERSION = 0x3098; - - public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig config) { - int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, mEGLContextClientVersion, - EGL10.EGL_NONE }; - - return egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, - mEGLContextClientVersion != 0 ? attrib_list : null); - } - - public void destroyContext(EGL10 egl, EGLDisplay display, - EGLContext context) { - if (!egl.eglDestroyContext(display, context)) { - Log.e("DefaultContextFactory", "display:" + display + " context: " + context); - if (LOG_THREADS) { - Log.i("DefaultContextFactory", "tid=" + Thread.currentThread().getId()); - } - EglHelper.throwEglException("eglDestroyContex", egl.eglGetError()); - } - } - } - - /** - * An interface for customizing the eglCreateWindowSurface and eglDestroySurface calls. - *

- * This interface must be implemented by clients wishing to call - * {@link GLTextureView#setEGLWindowSurfaceFactory(EGLWindowSurfaceFactory)} - */ - public interface EGLWindowSurfaceFactory { - /** - * @return null if the surface cannot be constructed. - */ - EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display, EGLConfig config, - Object nativeWindow); - void destroySurface(EGL10 egl, EGLDisplay display, EGLSurface surface); - } - - private static class DefaultWindowSurfaceFactory implements EGLWindowSurfaceFactory { - - public EGLSurface createWindowSurface(EGL10 egl, EGLDisplay display, - EGLConfig config, Object nativeWindow) { - EGLSurface result = null; - try { - result = egl.eglCreateWindowSurface(display, config, nativeWindow, null); - } catch (IllegalArgumentException e) { - // This exception indicates that the surface flinger surface - // is not valid. This can happen if the surface flinger surface has - // been torn down, but the application has not yet been - // notified via SurfaceHolder.Callback.surfaceDestroyed. - // In theory the application should be notified first, - // but in practice sometimes it is not. See b/4588890 - Log.e(TAG, "eglCreateWindowSurface", e); - } - return result; - } - - public void destroySurface(EGL10 egl, EGLDisplay display, - EGLSurface surface) { - egl.eglDestroySurface(display, surface); - } - } - - /** - * An interface for choosing an EGLConfig configuration from a list of - * potential configurations. - *

- * This interface must be implemented by clients wishing to call - * {@link GLTextureView#setEGLConfigChooser(EGLConfigChooser)} - */ - public interface EGLConfigChooser { - /** - * Choose a configuration from the list. Implementors typically - * implement this method by calling - * {@link EGL10#eglChooseConfig} and iterating through the results. Please consult the - * EGL specification available from The Khronos Group to learn how to call eglChooseConfig. - * @param egl the EGL10 for the current display. - * @param display the current display. - * @return the chosen configuration. - */ - EGLConfig chooseConfig(EGL10 egl, EGLDisplay display); - } - - private abstract class BaseConfigChooser - implements EGLConfigChooser { - public BaseConfigChooser(int[] configSpec) { - mConfigSpec = filterConfigSpec(configSpec); - } - - public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { - int[] num_config = new int[1]; - if (!egl.eglChooseConfig(display, mConfigSpec, null, 0, - num_config)) { - throw new IllegalArgumentException("eglChooseConfig failed"); - } - - int numConfigs = num_config[0]; - - if (numConfigs <= 0) { - throw new IllegalArgumentException( - "No configs match configSpec"); - } - - EGLConfig[] configs = new EGLConfig[numConfigs]; - if (!egl.eglChooseConfig(display, mConfigSpec, configs, numConfigs, - num_config)) { - throw new IllegalArgumentException("eglChooseConfig#2 failed"); - } - EGLConfig config = chooseConfig(egl, display, configs); - if (config == null) { - throw new IllegalArgumentException("No config chosen"); - } - return config; - } - - abstract EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, - EGLConfig[] configs); - - protected int[] mConfigSpec; - - private int[] filterConfigSpec(int[] configSpec) { - if (mEGLContextClientVersion != 2) { - return configSpec; - } - /* We know none of the subclasses define EGL_RENDERABLE_TYPE. - * And we know the configSpec is well formed. - */ - int len = configSpec.length; - int[] newConfigSpec = new int[len + 2]; - // net.kdt.pojavlaunch.SystemCrackResolver.arraycopy(configSpec, 0, newConfigSpec, 0, len-1); - for (int i = 0; i < len; i++) { - newConfigSpec[i] = configSpec[i]; - } - newConfigSpec[len-1] = EGL10.EGL_RENDERABLE_TYPE; - newConfigSpec[len] = 4; /* EGL_OPENGL_ES2_BIT */ - newConfigSpec[len+1] = EGL10.EGL_NONE; - return newConfigSpec; - } - } - - /** - * Choose a configuration with exactly the specified r,g,b,a sizes, - * and at least the specified depth and stencil sizes. - */ - private class ComponentSizeChooser extends BaseConfigChooser { - public ComponentSizeChooser(int redSize, int greenSize, int blueSize, - int alphaSize, int depthSize, int stencilSize) { - super(new int[] { - EGL10.EGL_RED_SIZE, redSize, - EGL10.EGL_GREEN_SIZE, greenSize, - EGL10.EGL_BLUE_SIZE, blueSize, - EGL10.EGL_ALPHA_SIZE, alphaSize, - EGL10.EGL_DEPTH_SIZE, depthSize, - EGL10.EGL_STENCIL_SIZE, stencilSize, - EGL10.EGL_NONE}); - mValue = new int[1]; - mRedSize = redSize; - mGreenSize = greenSize; - mBlueSize = blueSize; - mAlphaSize = alphaSize; - mDepthSize = depthSize; - mStencilSize = stencilSize; - } - - @Override - public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, - EGLConfig[] configs) { - for (EGLConfig config : configs) { - int d = findConfigAttrib(egl, display, config, - EGL10.EGL_DEPTH_SIZE, 0); - int s = findConfigAttrib(egl, display, config, - EGL10.EGL_STENCIL_SIZE, 0); - if ((d >= mDepthSize) && (s >= mStencilSize)) { - int r = findConfigAttrib(egl, display, config, - EGL10.EGL_RED_SIZE, 0); - int g = findConfigAttrib(egl, display, config, - EGL10.EGL_GREEN_SIZE, 0); - int b = findConfigAttrib(egl, display, config, - EGL10.EGL_BLUE_SIZE, 0); - int a = findConfigAttrib(egl, display, config, - EGL10.EGL_ALPHA_SIZE, 0); - if ((r == mRedSize) && (g == mGreenSize) - && (b == mBlueSize) && (a == mAlphaSize)) { - return config; - } - } - } - return null; - } - - private int findConfigAttrib(EGL10 egl, EGLDisplay display, - EGLConfig config, int attribute, int defaultValue) { - - if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { - return mValue[0]; - } - return defaultValue; - } - - private int[] mValue; - // Subclasses can adjust these values: - protected int mRedSize; - protected int mGreenSize; - protected int mBlueSize; - protected int mAlphaSize; - protected int mDepthSize; - protected int mStencilSize; - } - - /** - * This class will choose a RGB_888 surface with - * or without a depth buffer. - * - */ - private class SimpleEGLConfigChooser extends ComponentSizeChooser { - public SimpleEGLConfigChooser(boolean withDepthBuffer) { - super(8, 8, 8, 0, withDepthBuffer ? 16 : 0, 0); - } - } - - /** - * An EGL helper class. - */ - - private static class EglHelper { - public EglHelper(WeakReference glSurfaceViewWeakRef) { - mGLSurfaceViewWeakRef = glSurfaceViewWeakRef; - } - - /** - * Initialize EGL for a given configuration spec. - * @param - */ - public void start() { - if (LOG_EGL) { - Log.w("EglHelper", "start() tid=" + Thread.currentThread().getId()); - } - /* - * Get an EGL instance - */ - mEgl = (EGL10) EGLContext.getEGL(); - - /* - * Get to the default display. - */ - mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); - - if (mEglDisplay == EGL10.EGL_NO_DISPLAY) { - throw new RuntimeException("eglGetDisplay failed"); - } - - /* - * We can now initialize EGL for that display - */ - int[] version = new int[2]; - if(!mEgl.eglInitialize(mEglDisplay, version)) { - throw new RuntimeException("eglInitialize failed"); - } - GLTextureView view = mGLSurfaceViewWeakRef.get(); - if (view == null) { - mEglConfig = null; - mEglContext = null; - } else { - mEglConfig = view.mEGLConfigChooser.chooseConfig(mEgl, mEglDisplay); - - /* - * Create an EGL context. We want to do this as rarely as we can, because an - * EGL context is a somewhat heavy object. - */ - mEglContext = view.mEGLContextFactory.createContext(mEgl, mEglDisplay, mEglConfig); - } - if (mEglContext == null || mEglContext == EGL10.EGL_NO_CONTEXT) { - mEglContext = null; - throwEglException("createContext"); - } - if (LOG_EGL) { - Log.w("EglHelper", "createContext " + mEglContext + " tid=" + Thread.currentThread().getId()); - } - - mEglSurface = null; - } - - /** - * Create an egl surface for the current SurfaceHolder surface. If a surface - * already exists, destroy it before creating the new surface. - * - * @return true if the surface was created successfully. - */ - public boolean createSurface() { - if (LOG_EGL) { - Log.w("EglHelper", "createSurface() tid=" + Thread.currentThread().getId()); - } - /* - * Check preconditions. - */ - if (mEgl == null) { - throw new RuntimeException("egl not initialized"); - } - if (mEglDisplay == null) { - throw new RuntimeException("eglDisplay not initialized"); - } - if (mEglConfig == null) { - throw new RuntimeException("mEglConfig not initialized"); - } - - /* - * The window size has changed, so we need to create a new - * surface. - */ - destroySurfaceImp(); - - /* - * Create an EGL surface we can render into. - */ - GLTextureView view = mGLSurfaceViewWeakRef.get(); - if (view != null) { - mEglSurface = view.mEGLWindowSurfaceFactory.createWindowSurface(mEgl, - mEglDisplay, mEglConfig, view.getSurfaceTexture()); - } else { - mEglSurface = null; - } - - if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) { - int error = mEgl.eglGetError(); - if (error == EGL10.EGL_BAD_NATIVE_WINDOW) { - Log.e("EglHelper", "createWindowSurface returned EGL_BAD_NATIVE_WINDOW."); - } - return false; - } - - /* - * Before we can issue GL commands, we need to make sure - * the context is current and bound to a surface. - */ - if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { - /* - * Could not make the context current, probably because the underlying - * SurfaceView surface has been destroyed. - */ - logEglErrorAsWarning("EGLHelper", "eglMakeCurrent", mEgl.eglGetError()); - return false; - } - - return true; - } - - /** - * Create a GL object for the current EGL context. - * @return - */ - GL createGL() { - - GL gl = mEglContext.getGL(); - GLTextureView view = mGLSurfaceViewWeakRef.get(); - if (view != null) { - if (view.mGLWrapper != null) { - gl = view.mGLWrapper.wrap(gl); - } - - if ((view.mDebugFlags & (DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS)) != 0) { - int configFlags = 0; - Writer log = null; - if ((view.mDebugFlags & DEBUG_CHECK_GL_ERROR) != 0) { - configFlags |= GLDebugHelper.CONFIG_CHECK_GL_ERROR; - } - if ((view.mDebugFlags & DEBUG_LOG_GL_CALLS) != 0) { - log = new LogWriter(); - } - gl = GLDebugHelper.wrap(gl, configFlags, log); - } - } - return gl; - } - - /** - * Display the current render surface. - * @return the EGL error code from eglSwapBuffers. - */ - public int swap() { - if (! mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) { - return mEgl.eglGetError(); - } - return EGL10.EGL_SUCCESS; - } - - public void destroySurface() { - if (LOG_EGL) { - Log.w("EglHelper", "destroySurface() tid=" + Thread.currentThread().getId()); - } - destroySurfaceImp(); - } - - private void destroySurfaceImp() { - if (mEglSurface != null && mEglSurface != EGL10.EGL_NO_SURFACE) { - mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, - EGL10.EGL_NO_SURFACE, - EGL10.EGL_NO_CONTEXT); - GLTextureView view = mGLSurfaceViewWeakRef.get(); - if (view != null) { - view.mEGLWindowSurfaceFactory.destroySurface(mEgl, mEglDisplay, mEglSurface); - } - mEglSurface = null; - } - } - - public void finish() { - if (LOG_EGL) { - Log.w("EglHelper", "finish() tid=" + Thread.currentThread().getId()); - } - if (mEglContext != null) { - GLTextureView view = mGLSurfaceViewWeakRef.get(); - if (view != null) { - view.mEGLContextFactory.destroyContext(mEgl, mEglDisplay, mEglContext); - } - mEglContext = null; - } - if (mEglDisplay != null) { - mEgl.eglTerminate(mEglDisplay); - mEglDisplay = null; - } - } - - private void throwEglException(String function) { - throwEglException(function, mEgl.eglGetError()); - } - - public static void throwEglException(String function, int error) { - String message = formatEglError(function, error); - if (LOG_THREADS) { - Log.e("EglHelper", "throwEglException tid=" + Thread.currentThread().getId() + " " - + message); - } - throw new RuntimeException(message); - } - - public static void logEglErrorAsWarning(String tag, String function, int error) { - Log.w(tag, formatEglError(function, error)); - } - - public static String formatEglError(String function, int error) { - return function + " failed: " + error; - } - - private WeakReference mGLSurfaceViewWeakRef; - EGL10 mEgl; - EGLDisplay mEglDisplay; - EGLSurface mEglSurface; - EGLConfig mEglConfig; - EGLContext mEglContext; - - } - - /** - * A generic GL Thread. Takes care of initializing EGL and GL. Delegates - * to a Renderer instance to do the actual drawing. Can be configured to - * render continuously or on request. - * - * All potentially blocking synchronization is done through the - * sGLThreadManager object. This avoids multiple-lock ordering issues. - * - */ - static class GLThread extends Thread { - GLThread(WeakReference glSurfaceViewWeakRef) { - super(); - mWidth = 0; - mHeight = 0; - mRequestRender = true; - mRenderMode = RENDERMODE_CONTINUOUSLY; - mGLSurfaceViewWeakRef = glSurfaceViewWeakRef; - } - - @Override - public void run() { - setName("GLThread " + getId()); - if (LOG_THREADS) { - Log.i("GLThread", "starting tid=" + getId()); - } - - try { - guardedRun(); - } catch (InterruptedException e) { - // fall thru and exit normally - } finally { - sGLThreadManager.threadExiting(this); - } - } - - /* - * This private method should only be called inside a - * synchronized(sGLThreadManager) block. - */ - private void stopEglSurfaceLocked() { - if (mHaveEglSurface) { - mHaveEglSurface = false; - mEglHelper.destroySurface(); - } - } - - /* - * This private method should only be called inside a - * synchronized(sGLThreadManager) block. - */ - private void stopEglContextLocked() { - if (mHaveEglContext) { - mEglHelper.finish(); - mHaveEglContext = false; - sGLThreadManager.releaseEglContextLocked(this); - } - } - private void guardedRun() throws InterruptedException { - mEglHelper = new EglHelper(mGLSurfaceViewWeakRef); - mHaveEglContext = false; - mHaveEglSurface = false; - try { - GL10 gl = null; - boolean createEglContext = false; - boolean createEglSurface = false; - boolean createGlInterface = false; - boolean lostEglContext = false; - boolean sizeChanged = false; - boolean wantRenderNotification = false; - boolean doRenderNotification = false; - boolean askedToReleaseEglContext = false; - int w = 0; - int h = 0; - Runnable event = null; - - while (true) { - synchronized (sGLThreadManager) { - while (true) { - if (mShouldExit) { - return; - } - - if (! mEventQueue.isEmpty()) { - event = mEventQueue.remove(0); - break; - } - - // Update the pause state. - boolean pausing = false; - if (mPaused != mRequestPaused) { - pausing = mRequestPaused; - mPaused = mRequestPaused; - sGLThreadManager.notifyAll(); - if (LOG_PAUSE_RESUME) { - Log.i("GLThread", "mPaused is now " + mPaused + " tid=" + getId()); - } - } - - // Do we need to give up the EGL context? - if (mShouldReleaseEglContext) { - if (LOG_SURFACE) { - Log.i("GLThread", "releasing EGL context because asked to tid=" + getId()); - } - stopEglSurfaceLocked(); - stopEglContextLocked(); - mShouldReleaseEglContext = false; - askedToReleaseEglContext = true; - } - - // Have we lost the EGL context? - if (lostEglContext) { - stopEglSurfaceLocked(); - stopEglContextLocked(); - lostEglContext = false; - } - - // When pausing, release the EGL surface: - if (pausing && mHaveEglSurface) { - if (LOG_SURFACE) { - Log.i("GLThread", "releasing EGL surface because paused tid=" + getId()); - } - stopEglSurfaceLocked(); - } - - // When pausing, optionally release the EGL Context: - if (pausing && mHaveEglContext) { - GLTextureView view = mGLSurfaceViewWeakRef.get(); - boolean preserveEglContextOnPause = view == null ? - false : view.mPreserveEGLContextOnPause; - if (!preserveEglContextOnPause || sGLThreadManager.shouldReleaseEGLContextWhenPausing()) { - stopEglContextLocked(); - if (LOG_SURFACE) { - Log.i("GLThread", "releasing EGL context because paused tid=" + getId()); - } - } - } - - // When pausing, optionally terminate EGL: - if (pausing) { - if (sGLThreadManager.shouldTerminateEGLWhenPausing()) { - mEglHelper.finish(); - if (LOG_SURFACE) { - Log.i("GLThread", "terminating EGL because paused tid=" + getId()); - } - } - } - - // Have we lost the SurfaceView surface? - if ((! mHasSurface) && (! mWaitingForSurface)) { - if (LOG_SURFACE) { - Log.i("GLThread", "noticed surfaceView surface lost tid=" + getId()); - } - if (mHaveEglSurface) { - stopEglSurfaceLocked(); - } - mWaitingForSurface = true; - mSurfaceIsBad = false; - sGLThreadManager.notifyAll(); - } - - // Have we acquired the surface view surface? - if (mHasSurface && mWaitingForSurface) { - if (LOG_SURFACE) { - Log.i("GLThread", "noticed surfaceView surface acquired tid=" + getId()); - } - mWaitingForSurface = false; - sGLThreadManager.notifyAll(); - } - - if (doRenderNotification) { - if (LOG_SURFACE) { - Log.i("GLThread", "sending render notification tid=" + getId()); - } - wantRenderNotification = false; - doRenderNotification = false; - mRenderComplete = true; - sGLThreadManager.notifyAll(); - } - - // Ready to draw? - if (readyToDraw()) { - - // If we don't have an EGL context, try to acquire one. - if (! mHaveEglContext) { - if (askedToReleaseEglContext) { - askedToReleaseEglContext = false; - } else if (sGLThreadManager.tryAcquireEglContextLocked(this)) { - try { - mEglHelper.start(); - } catch (RuntimeException t) { - sGLThreadManager.releaseEglContextLocked(this); - throw t; - } - mHaveEglContext = true; - createEglContext = true; - - sGLThreadManager.notifyAll(); - } - } - - if (mHaveEglContext && !mHaveEglSurface) { - mHaveEglSurface = true; - createEglSurface = true; - createGlInterface = true; - sizeChanged = true; - } - - if (mHaveEglSurface) { - if (mSizeChanged) { - sizeChanged = true; - w = mWidth; - h = mHeight; - wantRenderNotification = true; - if (LOG_SURFACE) { - Log.i("GLThread", - "noticing that we want render notification tid=" - + getId()); - } - - // Destroy and recreate the EGL surface. - createEglSurface = true; - - mSizeChanged = false; - } - mRequestRender = false; - sGLThreadManager.notifyAll(); - break; - } - } - - // By design, this is the only place in a GLThread thread where we wait(). - if (LOG_THREADS) { - Log.i("GLThread", "waiting tid=" + getId() - + " mHaveEglContext: " + mHaveEglContext - + " mHaveEglSurface: " + mHaveEglSurface - + " mPaused: " + mPaused - + " mHasSurface: " + mHasSurface - + " mSurfaceIsBad: " + mSurfaceIsBad - + " mWaitingForSurface: " + mWaitingForSurface - + " mWidth: " + mWidth - + " mHeight: " + mHeight - + " mRequestRender: " + mRequestRender - + " mRenderMode: " + mRenderMode); - } - sGLThreadManager.wait(); - } - } // end of synchronized(sGLThreadManager) - - if (event != null) { - event.run(); - event = null; - continue; - } - - if (createEglSurface) { - if (LOG_SURFACE) { - Log.w("GLThread", "egl createSurface"); - } - if (!mEglHelper.createSurface()) { - synchronized(sGLThreadManager) { - mSurfaceIsBad = true; - sGLThreadManager.notifyAll(); - } - continue; - } - createEglSurface = false; - } - - if (createGlInterface) { - gl = (GL10) mEglHelper.createGL(); - - sGLThreadManager.checkGLDriver(gl); - createGlInterface = false; - } - - if (createEglContext) { - if (LOG_RENDERER) { - Log.w("GLThread", "onSurfaceCreated"); - } - GLTextureView view = mGLSurfaceViewWeakRef.get(); - if (view != null) { - view.mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig); - } - createEglContext = false; - } - - if (sizeChanged) { - if (LOG_RENDERER) { - Log.w("GLThread", "onSurfaceChanged(" + w + ", " + h + ")"); - } - GLTextureView view = mGLSurfaceViewWeakRef.get(); - if (view != null) { - view.mRenderer.onSurfaceChanged(gl, w, h); - } - sizeChanged = false; - } - - if (LOG_RENDERER_DRAW_FRAME) { - Log.w("GLThread", "onDrawFrame tid=" + getId()); - } - { - GLTextureView view = mGLSurfaceViewWeakRef.get(); - if (view != null) { - view.mRenderer.onDrawFrame(gl); - } - } - int swapError = mEglHelper.swap(); - switch (swapError) { - case EGL10.EGL_SUCCESS: - break; - case EGL11.EGL_CONTEXT_LOST: - if (LOG_SURFACE) { - Log.i("GLThread", "egl context lost tid=" + getId()); - } - lostEglContext = true; - break; - default: - // Other errors typically mean that the current surface is bad, - // probably because the SurfaceView surface has been destroyed, - // but we haven't been notified yet. - // Log the error to help developers understand why rendering stopped. - EglHelper.logEglErrorAsWarning("GLThread", "eglSwapBuffers", swapError); - - synchronized(sGLThreadManager) { - mSurfaceIsBad = true; - sGLThreadManager.notifyAll(); - } - break; - } - - if (wantRenderNotification) { - doRenderNotification = true; - } - } - - } finally { - /* - * clean-up everything... - */ - synchronized (sGLThreadManager) { - stopEglSurfaceLocked(); - stopEglContextLocked(); - } - } - } - - public boolean ableToDraw() { - return mHaveEglContext && mHaveEglSurface && readyToDraw(); - } - - private boolean readyToDraw() { - return (!mPaused) && mHasSurface && (!mSurfaceIsBad) - && (mWidth > 0) && (mHeight > 0) - && (mRequestRender || (mRenderMode == RENDERMODE_CONTINUOUSLY)); - } - - public void setRenderMode(int renderMode) { - if ( !((RENDERMODE_WHEN_DIRTY <= renderMode) && (renderMode <= RENDERMODE_CONTINUOUSLY)) ) { - throw new IllegalArgumentException("renderMode"); - } - synchronized(sGLThreadManager) { - mRenderMode = renderMode; - sGLThreadManager.notifyAll(); - } - } - - public int getRenderMode() { - synchronized(sGLThreadManager) { - return mRenderMode; - } - } - - public void requestRender() { - synchronized(sGLThreadManager) { - mRequestRender = true; - sGLThreadManager.notifyAll(); - } - } - - public void surfaceCreated() { - synchronized(sGLThreadManager) { - if (LOG_THREADS) { - Log.i("GLThread", "surfaceCreated tid=" + getId()); - } - mHasSurface = true; - sGLThreadManager.notifyAll(); - while((mWaitingForSurface) && (!mExited)) { - try { - sGLThreadManager.wait(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - } - } - - public void surfaceDestroyed() { - synchronized(sGLThreadManager) { - if (LOG_THREADS) { - Log.i("GLThread", "surfaceDestroyed tid=" + getId()); - // new Throwable("Surface destroy calling at???").printStackTrace(); - } - mHasSurface = false; - sGLThreadManager.notifyAll(); - while((!mWaitingForSurface) && (!mExited)) { - try { - sGLThreadManager.wait(); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - } - } - - public void onPause() { - synchronized (sGLThreadManager) { - if (LOG_PAUSE_RESUME) { - Log.i("GLThread", "onPause tid=" + getId()); - } - mRequestPaused = true; - sGLThreadManager.notifyAll(); - while ((! mExited) && (! mPaused)) { - if (LOG_PAUSE_RESUME) { - Log.i("Main thread", "onPause waiting for mPaused."); - } - try { - sGLThreadManager.wait(); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - } - } - - public void onResume() { - synchronized (sGLThreadManager) { - if (LOG_PAUSE_RESUME) { - Log.i("GLThread", "onResume tid=" + getId()); - } - mRequestPaused = false; - mRequestRender = true; - mRenderComplete = false; - sGLThreadManager.notifyAll(); - while ((! mExited) && mPaused && (!mRenderComplete)) { - if (LOG_PAUSE_RESUME) { - Log.i("Main thread", "onResume waiting for !mPaused."); - } - try { - sGLThreadManager.wait(); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - } - } - - public void onWindowResize(int w, int h) { - synchronized (sGLThreadManager) { - mWidth = w; - mHeight = h; - mSizeChanged = true; - mRequestRender = true; - mRenderComplete = false; - sGLThreadManager.notifyAll(); - - // Wait for thread to react to resize and render a frame - while (! mExited && !mPaused && !mRenderComplete - && ableToDraw()) { - if (LOG_SURFACE) { - Log.i("Main thread", "onWindowResize waiting for render complete from tid=" + getId()); - } - try { - sGLThreadManager.wait(); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - } - } - - public void requestExitAndWait() { - // don't call this from GLThread thread or it is a guaranteed - // deadlock! - synchronized(sGLThreadManager) { - mShouldExit = true; - sGLThreadManager.notifyAll(); - while (! mExited) { - try { - sGLThreadManager.wait(); - } catch (InterruptedException ex) { - Thread.currentThread().interrupt(); - } - } - } - } - - public void requestReleaseEglContextLocked() { - mShouldReleaseEglContext = true; - sGLThreadManager.notifyAll(); - } - - /** - * Queue an "event" to be run on the GL rendering thread. - * @param r the runnable to be run on the GL rendering thread. - */ - public void queueEvent(Runnable r) { - if (r == null) { - throw new IllegalArgumentException("r must not be null"); - } - synchronized(sGLThreadManager) { - mEventQueue.add(r); - sGLThreadManager.notifyAll(); - } - } - - // Once the thread is started, all accesses to the following member - // variables are protected by the sGLThreadManager monitor - private boolean mShouldExit; - private boolean mExited; - private boolean mRequestPaused; - private boolean mPaused; - private boolean mHasSurface; - private boolean mSurfaceIsBad; - private boolean mWaitingForSurface; - private boolean mHaveEglContext; - private boolean mHaveEglSurface; - private boolean mShouldReleaseEglContext; - private int mWidth; - private int mHeight; - private int mRenderMode; - private boolean mRequestRender; - private boolean mRenderComplete; - private ArrayList mEventQueue = new ArrayList(); - private boolean mSizeChanged = true; - - // End of member variables protected by the sGLThreadManager monitor. - - private EglHelper mEglHelper; - - /** - * Set once at thread construction time, nulled out when the parent view is garbage - * called. This weak reference allows the GLTextureView to be garbage collected while - * the GLThread is still alive. - */ - private WeakReference mGLSurfaceViewWeakRef; - - } - - static class LogWriter extends Writer { - - @Override public void close() { - flushBuilder(); - } - - @Override public void flush() { - flushBuilder(); - } - - @Override public void write(char[] buf, int offset, int count) { - for(int i = 0; i < count; i++) { - char c = buf[offset + i]; - if ( c == '\n') { - flushBuilder(); - } - else { - mBuilder.append(c); - } - } - } - - private void flushBuilder() { - if (mBuilder.length() > 0) { - Log.v("GLTextureView", mBuilder.toString()); - mBuilder.delete(0, mBuilder.length()); - } - } - - private StringBuilder mBuilder = new StringBuilder(); - } - - - private void checkRenderThreadState() { - if (mGLThread != null) { - throw new IllegalStateException( - "setRenderer has already been called for this instance."); - } - } - - private static class GLThreadManager { - private static String TAG = "GLThreadManager"; - - public synchronized void threadExiting(GLThread thread) { - if (LOG_THREADS) { - Log.i("GLThread", "exiting tid=" + thread.getId()); - } - thread.mExited = true; - if (mEglOwner == thread) { - mEglOwner = null; - } - notifyAll(); - } - - /* - * Tries once to acquire the right to use an EGL - * context. Does not block. Requires that we are already - * in the sGLThreadManager monitor when this is called. - * - * @return true if the right to use an EGL context was acquired. - */ - public boolean tryAcquireEglContextLocked(GLThread thread) { - if (mEglOwner == thread || mEglOwner == null) { - mEglOwner = thread; - notifyAll(); - return true; - } - checkGLESVersion(); - if (mMultipleGLESContextsAllowed) { - return true; - } - // Notify the owning thread that it should release the context. - // TODO: implement a fairness policy. Currently - // if the owning thread is drawing continuously it will just - // reacquire the EGL context. - if (mEglOwner != null) { - mEglOwner.requestReleaseEglContextLocked(); - } - return false; - } - - /* - * Releases the EGL context. Requires that we are already in the - * sGLThreadManager monitor when this is called. - */ - public void releaseEglContextLocked(GLThread thread) { - if (mEglOwner == thread) { - mEglOwner = null; - } - notifyAll(); - } - - public synchronized boolean shouldReleaseEGLContextWhenPausing() { - // Release the EGL context when pausing even if - // the hardware supports multiple EGL contexts. - // Otherwise the device could run out of EGL contexts. - return mLimitedGLESContexts; - } - - public synchronized boolean shouldTerminateEGLWhenPausing() { - checkGLESVersion(); - return !mMultipleGLESContextsAllowed; - } - - public synchronized void checkGLDriver(GL10 gl) { - if (! mGLESDriverCheckComplete) { - checkGLESVersion(); - String renderer = gl.glGetString(GL10.GL_RENDERER); - if (mGLESVersion < kGLES_20) { - mMultipleGLESContextsAllowed = - ! renderer.startsWith(kMSM7K_RENDERER_PREFIX); - notifyAll(); - } - mLimitedGLESContexts = !mMultipleGLESContextsAllowed; - if (LOG_SURFACE) { - Log.w(TAG, "checkGLDriver renderer = \"" + renderer + "\" multipleContextsAllowed = " - + mMultipleGLESContextsAllowed - + " mLimitedGLESContexts = " + mLimitedGLESContexts); - } - mGLESDriverCheckComplete = true; - } - } - - private void checkGLESVersion() { - if (! mGLESVersionCheckComplete) { -// mGLESVersion = SystemProperties.getInt( -// "ro.opengles.version", -// ConfigurationInfo.GL_ES_VERSION_UNDEFINED); -// if (mGLESVersion >= kGLES_20) { -// mMultipleGLESContextsAllowed = true; -// } -// if (LOG_SURFACE) { -// Log.w(TAG, "checkGLESVersion mGLESVersion =" + -// " " + mGLESVersion + " mMultipleGLESContextsAllowed = " + mMultipleGLESContextsAllowed); -// } - mGLESVersionCheckComplete = true; - } - } - - /** - * This check was required for some pre-Android-3.0 hardware. Android 3.0 provides - * support for hardware-accelerated views, therefore multiple EGL contexts are - * supported on all Android 3.0+ EGL drivers. - */ - private boolean mGLESVersionCheckComplete; - private int mGLESVersion; - private boolean mGLESDriverCheckComplete; - private boolean mMultipleGLESContextsAllowed; - private boolean mLimitedGLESContexts; - private static final int kGLES_20 = 0x20000; - private static final String kMSM7K_RENDERER_PREFIX = - "Q3Dimension MSM7500 "; - private GLThread mEglOwner; - } - - private static final GLThreadManager sGLThreadManager = new GLThreadManager(); - - private final WeakReference mThisWeakRef = - new WeakReference(this); - private GLThread mGLThread; - private Renderer mRenderer; - private boolean mDetached; - private EGLConfigChooser mEGLConfigChooser; - private EGLContextFactory mEGLContextFactory; - private EGLWindowSurfaceFactory mEGLWindowSurfaceFactory; - private GLWrapper mGLWrapper; - private int mDebugFlags; - private int mEGLContextClientVersion; - private boolean mPreserveEGLContextOnPause; -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/InstallerTask.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/InstallerTask.java deleted file mode 100644 index 5e6b84f2c..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/InstallerTask.java +++ /dev/null @@ -1,52 +0,0 @@ -package net.kdt.pojavlaunch; -import android.os.*; - -public class InstallerTask extends AsyncTask -{ - @Override - protected String doInBackground(String[] p1) - { - try - { - downloadLibraries(p1[0]); - dexMinecraftLibs(); - downloadMinecraft(p1[0]); - dexMinecraftClient(p1[0]); - downloadAssets(p1[0]); - } - catch (Exception e) - { - return e.getMessage(); - } - return null; - } - @Override - protected void onPostExecute(String result) - { - super.onPostExecute(result); - - if(result == null){ - //No errors - } - } - private void downloadLibraries(String versionName) throws Exception - { - - } - private void dexMinecraftLibs() throws Exception - { - - } - private void downloadMinecraft(String versionName) throws Exception - { - - } - private void dexMinecraftClient(String version) throws Exception - { - - } - private void downloadAssets(String versionName) throws Exception - { - - } -} From 7393ec2645d3c8997bbaf8d96fcd51625d25dd06 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 15:46:27 +0100 Subject: [PATCH 29/70] Refactor ExitActivity.java --- .../net/kdt/pojavlaunch/ExitActivity.java | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ExitActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ExitActivity.java index 3ef4e53a9..1fa7de72d 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ExitActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ExitActivity.java @@ -1,6 +1,7 @@ package net.kdt.pojavlaunch; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; @@ -11,13 +12,7 @@ import androidx.appcompat.app.AppCompatActivity; @Keep public class ExitActivity extends AppCompatActivity { - public static void showExitMessage(Context ctx, int code) { - Intent i = new Intent(ctx,ExitActivity.class); - i.putExtra("code",code); - i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - ctx.startActivity(i); - } + @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -26,14 +21,20 @@ public class ExitActivity extends AppCompatActivity { if(extras != null) { code = extras.getInt("code",-1); } + new AlertDialog.Builder(this) .setMessage(getString(R.string.mcn_exit_title,code)) - .setPositiveButton(android.R.string.ok,(dialog,which)->{ - dialog.dismiss(); - ExitActivity.this.finish(); - }).setOnCancelListener((z)->{ - ExitActivity.this.finish(); - }) + .setPositiveButton(android.R.string.ok, null) + .setOnDismissListener(dialog -> ExitActivity.this.finish()) .show(); } + + public static void showExitMessage(Context ctx, int code) { + Intent i = new Intent(ctx,ExitActivity.class); + i.putExtra("code",code); + i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + ctx.startActivity(i); + } + } From cda7d3a50f21dfbf69523396732200de351ec701 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 15:47:25 +0100 Subject: [PATCH 30/70] Refactor FatalErrorActivity.java --- .../kdt/pojavlaunch/FatalErrorActivity.java | 63 ++++++------------- 1 file changed, 20 insertions(+), 43 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java index c7bb1da41..87dd4f545 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java @@ -1,70 +1,47 @@ package net.kdt.pojavlaunch; -import android.app.*; import android.content.*; import android.os.*; import androidx.appcompat.app.*; import android.util.*; import androidx.appcompat.app.AlertDialog; -public class FatalErrorActivity extends AppCompatActivity -{ - public static void showError(Context ctx, String savePath, boolean storageAllow, /* boolean isFatalErr, */ Throwable th) { - Intent ferrorIntent = new Intent(ctx, FatalErrorActivity.class); - ferrorIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - ferrorIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - ferrorIntent.putExtra("throwable", th); - ferrorIntent.putExtra("savePath", savePath); - ferrorIntent.putExtra("storageAllow", storageAllow); - // ferrorIntent.putExtra("isFatal", isFatalErr); - ctx.startActivity(ferrorIntent); - } - +public class FatalErrorActivity extends AppCompatActivity { + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle extras = getIntent().getExtras(); boolean storageAllow = extras.getBoolean("storageAllow"); - final String strStackTrace = Log.getStackTraceString((Throwable) extras.getSerializable("throwable")); + final String stackTrace = Log.getStackTraceString((Throwable) extras.getSerializable("throwable")); String strSavePath = extras.getString("savePath"); String errHeader = storageAllow ? "Crash stack trace saved to " + strSavePath + "." : "Storage permission is required to save crash stack trace!"; - // boolean isFatalError = extras.getBoolean("isFatal", false); - new AlertDialog.Builder(this) .setTitle(R.string.error_fatal) - .setMessage(errHeader + "\n\n" + strStackTrace) - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){ + .setMessage(errHeader + "\n\n" + stackTrace) + .setPositiveButton(android.R.string.ok, (p1, p2) -> finish()) + .setNegativeButton(R.string.global_restart, (p1, p2) -> startActivity(new Intent(FatalErrorActivity.this, PojavLoginActivity.class))) + .setNeutralButton(android.R.string.copy, (p1, p2) -> { + ClipboardManager mgr = (ClipboardManager) FatalErrorActivity.this.getSystemService(CLIPBOARD_SERVICE); + mgr.setPrimaryClip(ClipData.newPlainText("error", stackTrace)); - @Override - public void onClick(DialogInterface p1, int p2) { - finish(); - } + finish(); }) - .setNegativeButton(R.string.global_restart, new DialogInterface.OnClickListener(){ - - @Override - public void onClick(DialogInterface p1, int p2) { - startActivity(new Intent(FatalErrorActivity.this, PojavLoginActivity.class)); - } - }) - .setNeutralButton(android.R.string.copy, new DialogInterface.OnClickListener(){ - - @Override - public void onClick(DialogInterface p1, int p2) { - ClipboardManager mgr = (ClipboardManager) FatalErrorActivity.this.getSystemService(CLIPBOARD_SERVICE); - mgr.setPrimaryClip(ClipData.newPlainText("error", strStackTrace)); - - finish(); - } - }) - //.setNegativeButton("Report (not available)", null) .setCancelable(false) .show(); - - // Tools.showError(this, isFatalError ? R.string.error_fatal : R.string.global_error, th, true); + } + + public static void showError(Context ctx, String savePath, boolean storageAllow, Throwable th) { + Intent ferrorIntent = new Intent(ctx, FatalErrorActivity.class); + ferrorIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); + ferrorIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + ferrorIntent.putExtra("throwable", th); + ferrorIntent.putExtra("savePath", savePath); + ferrorIntent.putExtra("storageAllow", storageAllow); + ctx.startActivity(ferrorIntent); } } From 3c34532117bd788fc37fa2c5f466db0fc4b0a71e Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 15:49:20 +0100 Subject: [PATCH 31/70] Refactor JavaGUILauncherActivity.java --- .../pojavlaunch/JavaGUILauncherActivity.java | 297 ++++++++---------- 1 file changed, 126 insertions(+), 171 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java index 7f0cc9033..1d648bea2 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java @@ -1,5 +1,6 @@ package net.kdt.pojavlaunch; +import android.annotation.SuppressLint; import android.os.*; import android.util.*; import android.view.*; @@ -22,49 +23,101 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc private static final int MSG_LEFT_MOUSE_BUTTON_CHECK = 1028; private AWTCanvasView mTextureView; - private LoggerView loggerView; + private LoggerView mLoggerView; - private LinearLayout touchPad; - private ImageView mousePointer; + private LinearLayout mTouchPad; + private ImageView mMousePointerImageView; private GestureDetector gestureDetector; + + private boolean mSkipDetectMod, mIsVirtualMouseEnabled; + + private int mScaleFactor; + private int[] mScaleFactors = initScaleFactors(); - private final Object mDialogLock = new Object(); - - private boolean mSkipDetectMod, isVirtualMouseEnabled; - - private int scaleFactor; - private int[] scaleFactors = initScaleFactors(); - - private final int fingerStillThreshold = 8; - private int initialX; - private int initialY; - private static boolean triggeredLeftMouseButton = false; - private Handler theHandler = new Handler() { - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_LEFT_MOUSE_BUTTON_CHECK: { - float x = CallbackBridge.mouseX; - float y = CallbackBridge.mouseY; - if (CallbackBridge.isGrabbing() && - Math.abs(initialX - x) < fingerStillThreshold && - Math.abs(initialY - y) < fingerStillThreshold) { - triggeredLeftMouseButton = true; - AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK, true); - } - } break; - } - } - }; - + @SuppressLint("ClickableViewAccessibility") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.install_mod); - Tools.updateWindowSize(this); Logger.getInstance().reset(); - + + mTouchPad = findViewById(R.id.main_touchpad); + mLoggerView = findViewById(R.id.launcherLoggerView); + mMousePointerImageView = findViewById(R.id.main_mouse_pointer); + mTextureView = findViewById(R.id.installmod_surfaceview); + gestureDetector = new GestureDetector(this, new SingleTapConfirm()); + mTouchPad.setFocusable(false); + mTouchPad.setVisibility(View.GONE); + + findViewById(R.id.installmod_mouse_pri).setOnTouchListener(this); + findViewById(R.id.installmod_mouse_sec).setOnTouchListener(this); + + mMousePointerImageView.post(() -> { + ViewGroup.LayoutParams params = mMousePointerImageView.getLayoutParams(); + params.width = (int) (36 / 100f * LauncherPreferences.PREF_MOUSESCALE); + params.height = (int) (54 / 100f * LauncherPreferences.PREF_MOUSESCALE); + }); + + mTouchPad.setOnTouchListener((v, event) -> { + // MotionEvent reports input details from the touch screen + // and other input controls. In this case, you are only + // interested in events where the touch position changed. + // int index = event.getActionIndex(); + int action = event.getActionMasked(); + + float x = event.getX(); + float y = event.getY(); + float prevX, prevY, mouseX, mouseY; + if(event.getHistorySize() > 0) { + prevX = event.getHistoricalX(0); + prevY = event.getHistoricalY(0); + }else{ + prevX = x; + prevY = y; + } + + mouseX = mMousePointerImageView.getX(); + mouseY = mMousePointerImageView.getY(); + + if (gestureDetector.onTouchEvent(event)) { + sendScaledMousePosition(mouseX,mouseY); + AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK); + } 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)); + placeMouseAt(mouseX, mouseY); + sendScaledMousePosition(mouseX, mouseY); + } + } + + // debugText.setText(CallbackBridge.DEBUG_STRING.toString()); + CallbackBridge.DEBUG_STRING.setLength(0); + return true; + }); + + mTextureView.setOnTouchListener((v, event) -> { + float x = event.getX(); + float y = event.getY(); + if (gestureDetector.onTouchEvent(event)) { + sendScaledMousePosition(x, y); + AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK); + return true; + } + + switch (event.getActionMasked()) { + case MotionEvent.ACTION_UP: // 1 + case MotionEvent.ACTION_CANCEL: // 3 + case MotionEvent.ACTION_POINTER_UP: // 6 + break; + case MotionEvent.ACTION_MOVE: // 2 + sendScaledMousePosition(x, y); + break; + } + return true; + }); + try { JREUtils.jreReleaseList = JREUtils.readJREReleaseProperties(LauncherPreferences.PREF_DEFAULT_RUNTIME); if (JREUtils.jreReleaseList.get("JAVA_VERSION").equals("1.8.0")) { @@ -73,118 +126,18 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc MultiRTUtils.setRuntimeNamed(this,MultiRTUtils.getExactJreName(8)); JREUtils.jreReleaseList = JREUtils.readJREReleaseProperties(); } - - loggerView = findViewById(R.id.launcherLoggerView); - gestureDetector = new GestureDetector(this, new SingleTapConfirm()); - findViewById(R.id.installmod_mouse_pri).setOnTouchListener(this); - findViewById(R.id.installmod_mouse_sec).setOnTouchListener(this); - - this.touchPad = findViewById(R.id.main_touchpad); - touchPad.setFocusable(false); - touchPad.setVisibility(View.GONE); - - this.mousePointer = findViewById(R.id.main_mouse_pointer); - this.mousePointer.post(() -> { - ViewGroup.LayoutParams params = mousePointer.getLayoutParams(); - params.width = (int) (36 / 100f * LauncherPreferences.PREF_MOUSESCALE); - params.height = (int) (54 / 100f * LauncherPreferences.PREF_MOUSESCALE); - }); - - touchPad.setOnTouchListener(new OnTouchListener(){ - private float prevX, prevY; - @Override - public boolean onTouch(View v, MotionEvent event) { - // MotionEvent reports input details from the touch screen - // and other input controls. In this case, you are only - // interested in events where the touch position changed. - // int index = event.getActionIndex(); - - int action = event.getActionMasked(); - - float x = event.getX(); - float y = event.getY(); - if(event.getHistorySize() > 0) { - prevX = event.getHistoricalX(0); - prevY = event.getHistoricalY(0); - }else{ - prevX = x; - prevY = y; - } - float mouseX = mousePointer.getX(); - float mouseY = mousePointer.getY(); - - if (gestureDetector.onTouchEvent(event)) { - - sendScaledMousePosition(mouseX,mouseY); - - AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK); - - - } else { - switch (action) { - case MotionEvent.ACTION_UP: // 1 - case MotionEvent.ACTION_CANCEL: // 3 - case MotionEvent.ACTION_POINTER_UP: // 6 - break; - case 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)); - placeMouseAt(mouseX, mouseY); - - sendScaledMousePosition(mouseX,mouseY); - /* - if (!CallbackBridge.isGrabbing()) { - CallbackBridge.sendMouseKeycode(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, 0, isLeftMouseDown); - CallbackBridge.sendMouseKeycode(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT, 0, isRightMouseDown); - } - */ - break; - } - } - - // debugText.setText(CallbackBridge.DEBUG_STRING.toString()); - CallbackBridge.DEBUG_STRING.setLength(0); - - return true; - } - }); - placeMouseAt(CallbackBridge.physicalWidth / 2, CallbackBridge.physicalHeight / 2); - - // this.textLogBehindGL = (TextView) findViewById(R.id.main_log_behind_GL); - // this.textLogBehindGL.setTypeface(Typeface.MONOSPACE); final File modFile = (File) getIntent().getExtras().getSerializable("modFile"); final String javaArgs = getIntent().getExtras().getString("javaArgs"); - mTextureView = findViewById(R.id.installmod_surfaceview); - mTextureView.setOnTouchListener((v, event) -> { - float x = event.getX(); - float y = event.getY(); - if (gestureDetector.onTouchEvent(event)) { - sendScaledMousePosition(x, y); - AWTInputBridge.sendMousePress(AWTInputEvent.BUTTON1_DOWN_MASK); - return true; - } - - switch (event.getActionMasked()) { - case MotionEvent.ACTION_UP: // 1 - case MotionEvent.ACTION_CANCEL: // 3 - case MotionEvent.ACTION_POINTER_UP: // 6 - break; - case MotionEvent.ACTION_MOVE: // 2 - sendScaledMousePosition(x, y); - break; - } - return true; - }); - mSkipDetectMod = getIntent().getExtras().getBoolean("skipDetectMod", false); if (mSkipDetectMod) { new Thread(() -> launchJavaRuntime(modFile, javaArgs), "JREMainThread").start(); return; } + // No skip detection openLogOutput(null); new Thread(() -> { @@ -208,6 +161,14 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc } } + @Override + public void onResume() { + super.onResume(); + final int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; + final View decorView = getWindow().getDecorView(); + decorView.setSystemUiVisibility(uiOptions); + } + @Override public boolean onTouch(View v, MotionEvent e) { boolean isDown; @@ -238,18 +199,18 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc } public void placeMouseAdd(float x, float y) { - this.mousePointer.setX(mousePointer.getX() + x); - this.mousePointer.setY(mousePointer.getY() + y); + mMousePointerImageView.setX(mMousePointerImageView.getX() + x); + mMousePointerImageView.setY(mMousePointerImageView.getY() + y); } public void placeMouseAt(float x, float y) { - this.mousePointer.setX(x); - this.mousePointer.setY(y); + mMousePointerImageView.setX(x); + mMousePointerImageView.setY(y); } void sendScaledMousePosition(float x, float y){ - AWTInputBridge.sendMousePos((int) map(x,0,CallbackBridge.physicalWidth, scaleFactors[0], scaleFactors[2]), - (int) map(y,0,CallbackBridge.physicalHeight, scaleFactors[1], scaleFactors[3])); + AWTInputBridge.sendMousePos((int) map(x,0,CallbackBridge.physicalWidth, mScaleFactors[0], mScaleFactors[2]), + (int) map(y,0,CallbackBridge.physicalHeight, mScaleFactors[1], mScaleFactors[3])); } public void forceClose(View v) { @@ -257,29 +218,24 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc } public void openLogOutput(View v) { - loggerView.setVisibility(View.VISIBLE); + mLoggerView.setVisibility(View.VISIBLE); } public void closeLogOutput(View view) { if (mSkipDetectMod) { - loggerView.setVisibility(View.GONE); + mLoggerView.setVisibility(View.GONE); } else { forceClose(null); } } public void toggleVirtualMouse(View v) { - isVirtualMouseEnabled = !isVirtualMouseEnabled; - touchPad.setVisibility(isVirtualMouseEnabled ? View.VISIBLE : View.GONE); + mIsVirtualMouseEnabled = !mIsVirtualMouseEnabled; + mTouchPad.setVisibility(mIsVirtualMouseEnabled ? View.VISIBLE : View.GONE); Toast.makeText(this, - isVirtualMouseEnabled ? R.string.control_mouseon : R.string.control_mouseoff, + mIsVirtualMouseEnabled ? R.string.control_mouseon : R.string.control_mouseoff, Toast.LENGTH_SHORT).show(); } - - private int doCustomInstall(File modFile, String javaArgs) throws IOException { - mSkipDetectMod = true; - return launchJavaRuntime(modFile, javaArgs); - } public int launchJavaRuntime(File modFile, String javaArgs) { JREUtils.redirectAndPrintJRELog(this); @@ -312,13 +268,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc } } - @Override - public void onResume() { - super.onResume(); - final int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; - final View decorView = getWindow().getDecorView(); - decorView.setSystemUiVisibility(uiOptions); - } + int[] initScaleFactors(){ return initScaleFactors(true); @@ -329,37 +279,42 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc if(autoScale) { //Auto scale int minDimension = Math.min(CallbackBridge.physicalHeight, CallbackBridge.physicalWidth); - scaleFactor = Math.max(((3 * minDimension) / 1080) - 1, 1); + mScaleFactor = Math.max(((3 * minDimension) / 1080) - 1, 1); } int[] scales = new int[4]; //Left, Top, Right, Bottom scales[0] = (CallbackBridge.physicalWidth/2); - scales[0] -= scales[0]/scaleFactor; + scales[0] -= scales[0]/ mScaleFactor; scales[1] = (CallbackBridge.physicalHeight/2); - scales[1] -= scales[1]/scaleFactor; + scales[1] -= scales[1]/ mScaleFactor; scales[2] = (CallbackBridge.physicalWidth/2); - scales[2] += scales[2]/scaleFactor; + scales[2] += scales[2]/ mScaleFactor; scales[3] = (CallbackBridge.physicalHeight/2); - scales[3] += scales[3]/scaleFactor; + scales[3] += scales[3]/ mScaleFactor; return scales; } public void scaleDown(View view) { - scaleFactor = Math.max(scaleFactor - 1, 1); - scaleFactors = initScaleFactors(false); - mTextureView.initScaleFactors(scaleFactor); - sendScaledMousePosition(mousePointer.getX(),mousePointer.getY()); + mScaleFactor = Math.max(mScaleFactor - 1, 1); + mScaleFactors = initScaleFactors(false); + mTextureView.initScaleFactors(mScaleFactor); + sendScaledMousePosition(mMousePointerImageView.getX(), mMousePointerImageView.getY()); } public void scaleUp(View view) { - scaleFactor = Math.min(scaleFactor + 1, 6); - scaleFactors = initScaleFactors(false); - mTextureView.initScaleFactors(scaleFactor); - sendScaledMousePosition(mousePointer.getX(),mousePointer.getY()); + mScaleFactor = Math.min(mScaleFactor + 1, 6); + mScaleFactors = initScaleFactors(false); + mTextureView.initScaleFactors(mScaleFactor); + sendScaledMousePosition(mMousePointerImageView.getX(), mMousePointerImageView.getY()); + } + + private int doCustomInstall(File modFile, String javaArgs) throws IOException { + mSkipDetectMod = true; + return launchJavaRuntime(modFile, javaArgs); } } From 6976a9a93fe69d4912d4db45c82560360df04db8 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 15:49:36 +0100 Subject: [PATCH 32/70] Refactor Logger.java --- .../main/java/net/kdt/pojavlaunch/Logger.java | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Logger.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Logger.java index 42ef19442..d6987d9ea 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Logger.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Logger.java @@ -12,12 +12,12 @@ import java.lang.ref.WeakReference; */ @Keep public class Logger { - private static Logger loggerSingleton = null; + private static Logger sLoggerSingleton = null; /* Instance variables */ - private final File logFile; - private PrintStream logStream; - private WeakReference logListenerWeakReference = null; + private final File mLogFile; + private PrintStream mLogStream; + private WeakReference mLogListenerWeakReference = null; /* No public construction */ private Logger(){ @@ -25,25 +25,25 @@ public class Logger { } private Logger(String fileName){ - logFile = new File(Tools.DIR_GAME_HOME, fileName); + mLogFile = new File(Tools.DIR_GAME_HOME, fileName); // Make a new instance of the log file - logFile.delete(); + mLogFile.delete(); try { - logFile.createNewFile(); - logStream = new PrintStream(logFile.getAbsolutePath()); + mLogFile.createNewFile(); + mLogStream = new PrintStream(mLogFile.getAbsolutePath()); }catch (IOException e){e.printStackTrace();} } public static Logger getInstance(){ - if(loggerSingleton == null){ + if(sLoggerSingleton == null){ synchronized(Logger.class){ - if(loggerSingleton == null){ - loggerSingleton = new Logger(); + if(sLoggerSingleton == null){ + sLoggerSingleton = new Logger(); } } } - return loggerSingleton; + return sLoggerSingleton; } @@ -55,22 +55,22 @@ public class Logger { /** Print the text to the log file, no china censoring there */ public void appendToLogUnchecked(String text){ - logStream.println(text); + mLogStream.println(text); notifyLogListener(text); } /** Reset the log file, effectively erasing any previous logs */ public void reset(){ try{ - logFile.delete(); - logFile.createNewFile(); - logStream = new PrintStream(logFile.getAbsolutePath()); + mLogFile.delete(); + mLogFile.createNewFile(); + mLogStream = new PrintStream(mLogFile.getAbsolutePath()); }catch (IOException e){ e.printStackTrace();} } /** Disables the printing */ public void shutdown(){ - logStream.close(); + mLogStream.close(); } /** @@ -91,15 +91,15 @@ public class Logger { /** Link a log listener to the logger */ public void setLogListener(eventLogListener logListener){ - this.logListenerWeakReference = new WeakReference<>(logListener); + this.mLogListenerWeakReference = new WeakReference<>(logListener); } /** Notifies the event listener, if it exists */ private void notifyLogListener(String text){ - if(logListenerWeakReference == null) return; - eventLogListener logListener = logListenerWeakReference.get(); + if(mLogListenerWeakReference == null) return; + eventLogListener logListener = mLogListenerWeakReference.get(); if(logListener == null){ - logListenerWeakReference = null; + mLogListenerWeakReference = null; return; } logListener.onEventLogged(text); From 9cdb43c162655f8c033c9debd2e77093ec02a96e Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 15:50:04 +0100 Subject: [PATCH 33/70] Refactor PojavApplication.java --- .../net/kdt/pojavlaunch/PojavApplication.java | 60 +++++++++---------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavApplication.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavApplication.java index 8b27f901d..059e49eb8 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavApplication.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavApplication.java @@ -14,40 +14,37 @@ import java.util.*; import net.kdt.pojavlaunch.utils.*; -public class PojavApplication extends Application -{ +public class PojavApplication extends Application { public static String CRASH_REPORT_TAG = "PojavCrashReport"; @Override public void onCreate() { - Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){ - @Override - public void uncaughtException(Thread thread, Throwable th) { - boolean storagePermAllowed = Build.VERSION.SDK_INT < 23 || ActivityCompat.checkSelfPermission(PojavApplication.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; - File crashFile = new File(storagePermAllowed ? Tools.DIR_GAME_HOME : Tools.DIR_DATA, "latestcrash.txt"); - try { - // Write to file, since some devices may not able to show error - crashFile.getParentFile().mkdirs(); - crashFile.createNewFile(); - PrintStream crashStream = new PrintStream(crashFile); - crashStream.append("PojavLauncher crash report\n"); - crashStream.append(" - Time: " + DateFormat.getDateTimeInstance().format(new Date()) + "\n"); - crashStream.append(" - Device: " + Build.PRODUCT + " " + Build.MODEL + "\n"); - crashStream.append(" - Android version: " + Build.VERSION.RELEASE + "\n"); - crashStream.append(" - Crash stack trace:\n"); - crashStream.append(" - Launcher version: " + BuildConfig.VERSION_NAME + "\n"); - crashStream.append(Log.getStackTraceString(th)); - crashStream.close(); - } catch (Throwable th2) { - Log.e(CRASH_REPORT_TAG, " - Exception attempt saving crash stack trace:", th2); - Log.e(CRASH_REPORT_TAG, " - The crash stack trace was:", th); - } - - FatalErrorActivity.showError(PojavApplication.this, crashFile.getAbsolutePath(), storagePermAllowed, th); - // android.os.Process.killProcess(android.os.Process.myPid()); - - BaseMainActivity.fullyExit(); + Thread.setDefaultUncaughtExceptionHandler((thread, th) -> { + boolean storagePermAllowed = Build.VERSION.SDK_INT < 23 || + ActivityCompat.checkSelfPermission(PojavApplication.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; + File crashFile = new File(storagePermAllowed ? Tools.DIR_GAME_HOME : Tools.DIR_DATA, "latestcrash.txt"); + try { + // Write to file, since some devices may not able to show error + crashFile.getParentFile().mkdirs(); + crashFile.createNewFile(); + PrintStream crashStream = new PrintStream(crashFile); + crashStream.append("PojavLauncher crash report\n"); + crashStream.append(" - Time: " + DateFormat.getDateTimeInstance().format(new Date()) + "\n"); + crashStream.append(" - Device: " + Build.PRODUCT + " " + Build.MODEL + "\n"); + crashStream.append(" - Android version: " + Build.VERSION.RELEASE + "\n"); + crashStream.append(" - Crash stack trace:\n"); + crashStream.append(" - Launcher version: " + BuildConfig.VERSION_NAME + "\n"); + crashStream.append(Log.getStackTraceString(th)); + crashStream.close(); + } catch (Throwable throwable) { + Log.e(CRASH_REPORT_TAG, " - Exception attempt saving crash stack trace:", throwable); + Log.e(CRASH_REPORT_TAG, " - The crash stack trace was:", th); } + + FatalErrorActivity.showError(PojavApplication.this, crashFile.getAbsolutePath(), storagePermAllowed, th); + // android.os.Process.killProcess(android.os.Process.myPid()); + + BaseMainActivity.fullyExit(); }); try { @@ -70,10 +67,9 @@ public class PojavApplication extends Application .concat("/x86"); } - - } catch (Throwable th) { + } catch (Throwable throwable) { Intent ferrorIntent = new Intent(this, FatalErrorActivity.class); - ferrorIntent.putExtra("throwable", th); + ferrorIntent.putExtra("throwable", throwable); startActivity(ferrorIntent); } } From ee279209f6ea3c6a700d3b95d36718c03f6166b0 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 15:51:12 +0100 Subject: [PATCH 34/70] Refactor Touchpad.java --- .../java/net/kdt/pojavlaunch/Touchpad.java | 171 +++++++++--------- 1 file changed, 85 insertions(+), 86 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java index 348388bd7..32c422bb0 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java @@ -27,19 +27,19 @@ import org.lwjgl.glfw.CallbackBridge; */ public class Touchpad extends FrameLayout { /* Whether the Touchpad should be displayed */ - private boolean displayState; + private boolean mDisplayState; /* Mouse pointer icon used by the touchpad */ - private final ImageView mousePointer = new ImageView(getContext()); + private final ImageView mMousePointerImageView = new ImageView(getContext()); /* Detect a classic android Tap */ - private final GestureDetector singleTapDetector = new GestureDetector(getContext(), new SingleTapConfirm()); + private final GestureDetector mSingleTapDetector = new GestureDetector(getContext(), new SingleTapConfirm()); /* Resolution scaler option, allow downsizing a window */ - private final float scaleFactor = DEFAULT_PREF.getInt("resolutionRatio",100)/100f; + private final float mScaleFactor = DEFAULT_PREF.getInt("resolutionRatio",100)/100f; /* Current pointer ID to move the mouse */ - private int currentPointerID = -1000; + private int mCurrentPointerID = -1000; /* Previous MotionEvent position, not scale */ - private float prevX, prevY; + private float mPrevX, mPrevY; /* Last first pointer positions non-scaled, used to scroll distance */ - private float scrollLastInitialX, scrollLastInitialY; + private float mScrollLastInitialX, mScrollLastInitialY; public Touchpad(@NonNull Context context) { this(context, null); @@ -50,56 +50,6 @@ public class Touchpad extends FrameLayout { init(); } - private void init(){ - // Setup mouse pointer - mousePointer.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.mouse_pointer, getContext().getTheme())); - mousePointer.post(() -> { - ViewGroup.LayoutParams params = mousePointer.getLayoutParams(); - params.width = (int) (36 / 100f * LauncherPreferences.PREF_MOUSESCALE); - params.height = (int) (54 / 100f * LauncherPreferences.PREF_MOUSESCALE); - }); - addView(mousePointer); - setFocusable(false); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - setDefaultFocusHighlightEnabled(false); - } - - // When the game is grabbing, we should not display the mouse - disable(); - displayState = false; - Thread virtualMouseGrabThread = new Thread(() -> { - while (true) { - if (!CallbackBridge.isGrabbing() && displayState && getVisibility() != VISIBLE) { - post(this::enable); - }else{ - if ((CallbackBridge.isGrabbing() && getVisibility() != View.GONE) || !displayState && getVisibility() == VISIBLE) { - post(this::disable); - } - } - - } - }, "VirtualMouseGrabThread"); - virtualMouseGrabThread.setPriority(Thread.MIN_PRIORITY); - virtualMouseGrabThread.start(); - } - - /** Enable the touchpad */ - public void enable(){ - setVisibility(VISIBLE); - placeMouseAt(currentDisplayMetrics.widthPixels / 2, currentDisplayMetrics.heightPixels / 2); - } - - /** Disable the touchpad and hides the mouse */ - public void disable(){ - setVisibility(GONE); - } - - /** @return The new state, enabled or disabled */ - public boolean switchState(){ - displayState = !displayState; - return displayState; - } - @Override public boolean onTouchEvent(MotionEvent event) { // MotionEvent reports input details from the touch screen @@ -114,77 +64,126 @@ public class Touchpad extends FrameLayout { float x = event.getX(); float y = event.getY(); - float mouseX = mousePointer.getX(); - float mouseY = mousePointer.getY(); + float mouseX = mMousePointerImageView.getX(); + float mouseY = mMousePointerImageView.getY(); - if (singleTapDetector.onTouchEvent(event)) { - CallbackBridge.mouseX = (mouseX * scaleFactor); - CallbackBridge.mouseY = (mouseY * scaleFactor); + if (mSingleTapDetector.onTouchEvent(event)) { + CallbackBridge.mouseX = (mouseX * mScaleFactor); + CallbackBridge.mouseY = (mouseY * mScaleFactor); CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); - CallbackBridge.sendMouseKeycode(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT); + CallbackBridge.sendMouseKeycode(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT); return true; } switch (action) { case MotionEvent.ACTION_POINTER_DOWN: // 5 - scrollLastInitialX = event.getX(); - scrollLastInitialY = event.getY(); + mScrollLastInitialX = event.getX(); + mScrollLastInitialY = event.getY(); break; case MotionEvent.ACTION_DOWN: - prevX = x; - prevY = y; - currentPointerID = event.getPointerId(0); + mPrevX = x; + mPrevY = y; + mCurrentPointerID = event.getPointerId(0); break; case MotionEvent.ACTION_MOVE: // 2 //Scrolling feature if (!LauncherPreferences.PREF_DISABLE_GESTURES && !CallbackBridge.isGrabbing() && event.getPointerCount() >= 2) { - int hScroll = ((int) (event.getX() - scrollLastInitialX)) / FINGER_SCROLL_THRESHOLD; - int vScroll = ((int) (event.getY() - scrollLastInitialY)) / FINGER_SCROLL_THRESHOLD; + int hScroll = ((int) (event.getX() - mScrollLastInitialX)) / FINGER_SCROLL_THRESHOLD; + int vScroll = ((int) (event.getY() - mScrollLastInitialY)) / FINGER_SCROLL_THRESHOLD; if(vScroll != 0 || hScroll != 0){ CallbackBridge.sendScroll(hScroll, vScroll); - scrollLastInitialX = event.getX(); - scrollLastInitialY = event.getY(); + mScrollLastInitialX = event.getX(); + mScrollLastInitialY = event.getY(); } break; } // Mouse movement - if(currentPointerID == event.getPointerId(0)) { - mouseX = Math.max(0, Math.min(currentDisplayMetrics.widthPixels, mouseX + (x - prevX) * LauncherPreferences.PREF_MOUSESPEED)); - mouseY = Math.max(0, Math.min(currentDisplayMetrics.heightPixels, mouseY + (y - prevY) * LauncherPreferences.PREF_MOUSESPEED)); + if(mCurrentPointerID == event.getPointerId(0)) { + mouseX = Math.max(0, Math.min(currentDisplayMetrics.widthPixels, mouseX + (x - mPrevX) * LauncherPreferences.PREF_MOUSESPEED)); + mouseY = Math.max(0, Math.min(currentDisplayMetrics.heightPixels, mouseY + (y - mPrevY) * LauncherPreferences.PREF_MOUSESPEED)); placeMouseAt(mouseX, mouseY); CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); - }else currentPointerID = event.getPointerId(0); + }else mCurrentPointerID = event.getPointerId(0); - prevX = x; - prevY = y; + mPrevX = x; + mPrevY = y; break; case MotionEvent.ACTION_UP: - prevX = x; - prevY = y; - currentPointerID = -1000; + mPrevX = x; + mPrevY = y; + mCurrentPointerID = -1000; break; } - //debugText.setText(CallbackBridge.DEBUG_STRING.toString()); CallbackBridge.DEBUG_STRING.setLength(0); return true; } + /** Enable the touchpad */ + public void enable(){ + setVisibility(VISIBLE); + placeMouseAt(currentDisplayMetrics.widthPixels / 2, currentDisplayMetrics.heightPixels / 2); + } + + /** Disable the touchpad and hides the mouse */ + public void disable(){ + setVisibility(GONE); + } + + /** @return The new state, enabled or disabled */ + public boolean switchState(){ + mDisplayState = !mDisplayState; + return mDisplayState; + } + public void placeMouseAt(float x, float y) { - mousePointer.setX(x); - mousePointer.setY(y); - CallbackBridge.mouseX = (x * scaleFactor); - CallbackBridge.mouseY = (y * scaleFactor); + mMousePointerImageView.setX(x); + mMousePointerImageView.setY(y); + CallbackBridge.mouseX = (x * mScaleFactor); + CallbackBridge.mouseY = (y * mScaleFactor); CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); } + private void init(){ + // Setup mouse pointer + mMousePointerImageView.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.mouse_pointer, getContext().getTheme())); + mMousePointerImageView.post(() -> { + ViewGroup.LayoutParams params = mMousePointerImageView.getLayoutParams(); + params.width = (int) (36 / 100f * LauncherPreferences.PREF_MOUSESCALE); + params.height = (int) (54 / 100f * LauncherPreferences.PREF_MOUSESCALE); + }); + addView(mMousePointerImageView); + setFocusable(false); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + setDefaultFocusHighlightEnabled(false); + } + + // When the game is grabbing, we should not display the mouse + disable(); + mDisplayState = false; + Thread virtualMouseGrabThread = new Thread(() -> { + while (true) { + if (!CallbackBridge.isGrabbing() && mDisplayState && getVisibility() != VISIBLE) { + post(this::enable); + }else{ + if ((CallbackBridge.isGrabbing() && getVisibility() != View.GONE) || !mDisplayState && getVisibility() == VISIBLE) { + post(this::disable); + } + } + + } + }, "VirtualMouseGrabThread"); + virtualMouseGrabThread.setPriority(Thread.MIN_PRIORITY); + virtualMouseGrabThread.start(); + } + } From d474ef2b911d3fe91c6bead630243de3a10d1e70 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 15:54:06 +0100 Subject: [PATCH 35/70] Refactor CallbackBridge.java --- .../main/java/org/lwjgl/glfw/CallbackBridge.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/app_pojavlauncher/src/main/java/org/lwjgl/glfw/CallbackBridge.java b/app_pojavlauncher/src/main/java/org/lwjgl/glfw/CallbackBridge.java index bdaf7e1bf..79b2f1fbb 100644 --- a/app_pojavlauncher/src/main/java/org/lwjgl/glfw/CallbackBridge.java +++ b/app_pojavlauncher/src/main/java/org/lwjgl/glfw/CallbackBridge.java @@ -1,12 +1,8 @@ package org.lwjgl.glfw; -import java.io.*; -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; -import java.util.*; import android.os.Handler; import android.os.Looper; -import android.widget.*; + import net.kdt.pojavlaunch.*; import android.content.*; @@ -20,6 +16,9 @@ public class CallbackBridge { public static volatile int physicalWidth, physicalHeight; public static float mouseX, mouseY; public static StringBuilder DEBUG_STRING = new StringBuilder(); + private static boolean threadAttached; + public volatile static boolean holdingAlt, holdingCapslock, holdingCtrl, + holdingNumlock, holdingShift; public static void putMouseEventWithCoords(int button, float x, float y) { @@ -34,7 +33,7 @@ public class CallbackBridge { sendMouseKeycode(button, CallbackBridge.getCurrentMods(), isDown); } - private static boolean threadAttached; + public static void sendCursorPos(float x, float y) { if (!threadAttached) { threadAttached = CallbackBridge.nativeAttachThreadToOther(true, BaseMainActivity.isInputStackCall); @@ -158,8 +157,7 @@ public class CallbackBridge { private static native void nativeSendData(boolean isAndroid, int type, String data); */ - public volatile static boolean holdingAlt, holdingCapslock, holdingCtrl, - holdingNumlock, holdingShift; + public static int getCurrentMods() { int currMods = 0; if (holdingAlt) { From be3a22a4efdef973dab63426ca86085b6ed5ac63 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 15:56:06 +0100 Subject: [PATCH 36/70] Refactor GameFolderProvider.java --- .../net/kdt/pojavlaunch/scoped/GameFolderProvider.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/scoped/GameFolderProvider.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/scoped/GameFolderProvider.java index cdf997062..c8a92ba1f 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/scoped/GameFolderProvider.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/scoped/GameFolderProvider.java @@ -23,7 +23,7 @@ import java.util.Collections; import java.util.LinkedList; public class GameFolderProvider extends DocumentsProvider { - static File baseDir = new File(Tools.DIR_GAME_HOME); + static File sBaseDir = new File(Tools.DIR_GAME_HOME); private static final String[] DEFAULT_ROOT_PROJECTION = new String[]{ Root.COLUMN_ROOT_ID, Root.COLUMN_MIME_TYPES, @@ -47,13 +47,13 @@ public class GameFolderProvider extends DocumentsProvider { public Cursor queryRoots(String[] projection) throws FileNotFoundException { final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_ROOT_PROJECTION); final MatrixCursor.RowBuilder row = result.newRow(); - row.add(Root.COLUMN_ROOT_ID, baseDir.getAbsolutePath()); - row.add(Root.COLUMN_DOCUMENT_ID, baseDir.getAbsolutePath()); + row.add(Root.COLUMN_ROOT_ID, sBaseDir.getAbsolutePath()); + row.add(Root.COLUMN_DOCUMENT_ID, sBaseDir.getAbsolutePath()); row.add(Root.COLUMN_SUMMARY, null); row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE | Root.FLAG_SUPPORTS_RECENTS | Root.FLAG_SUPPORTS_SEARCH); row.add(Root.COLUMN_TITLE, getContext().getString(R.string.app_name)); row.add(Root.COLUMN_MIME_TYPES, "*/*"); - row.add(Root.COLUMN_AVAILABLE_BYTES, baseDir.getFreeSpace()); + row.add(Root.COLUMN_AVAILABLE_BYTES, sBaseDir.getFreeSpace()); row.add(Root.COLUMN_ICON, R.mipmap.ic_launcher); return result; } @@ -112,7 +112,7 @@ public class GameFolderProvider extends DocumentsProvider { final File file = pending.removeFirst(); boolean isInsideGameDir; try { - isInsideGameDir = file.getCanonicalPath().startsWith(baseDir.getCanonicalPath()); + isInsideGameDir = file.getCanonicalPath().startsWith(sBaseDir.getCanonicalPath()); } catch (IOException e) { isInsideGameDir = true; } From c891ecf27f929e781f520deb4b3b9df96afb17ac Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 16:04:51 +0100 Subject: [PATCH 37/70] Rename LWJGLGLFWKeycode class --- .../net/kdt/pojavlaunch/BaseMainActivity.java | 5 +- .../EfficientAndroidLWJGLKeycode.java | 221 +++++++++--------- .../net/kdt/pojavlaunch/LWJGLGLFWKeycode.java | 3 +- .../customcontrols/ControlData.java | 4 +- .../customcontrols/CustomControls.java | 25 +- .../customcontrols/LayoutConverter.java | 16 +- .../customcontrols/TouchCharInput.java | 8 +- .../customcontrols/buttons/ControlButton.java | 9 +- .../customcontrols/gamepad/Gamepad.java | 12 +- .../customcontrols/gamepad/GamepadMap.java | 54 ++--- .../java/org/lwjgl/glfw/CallbackBridge.java | 20 +- 11 files changed, 178 insertions(+), 199 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java index 49ef73fd7..816f364d6 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java @@ -11,7 +11,6 @@ import static org.lwjgl.glfw.CallbackBridge.windowWidth; import android.app.*; import android.content.*; import android.content.pm.PackageManager; -import android.graphics.*; import android.os.*; import android.util.*; import android.view.*; @@ -158,7 +157,7 @@ public class BaseMainActivity extends BaseActivity { @Override protected void onPause() { if (CallbackBridge.isGrabbing()){ - sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_ESCAPE); + sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_ESCAPE); } CallbackBridge.nativeSetWindowAttrib(LWJGLGLFWKeycode.GLFW_HOVERED, 0); mIsResuming = false; @@ -328,7 +327,7 @@ public class BaseMainActivity extends BaseActivity { public boolean dispatchKeyEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && !touchCharInput.isEnabled()) { if(event.getAction() != KeyEvent.ACTION_UP) return true; // We eat it anyway - sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_ESCAPE); + sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_ESCAPE); return true; } return super.dispatchKeyEvent(event); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/EfficientAndroidLWJGLKeycode.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/EfficientAndroidLWJGLKeycode.java index a7677b4c0..881216b4f 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/EfficientAndroidLWJGLKeycode.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/EfficientAndroidLWJGLKeycode.java @@ -25,159 +25,148 @@ public class EfficientAndroidLWJGLKeycode { /* BINARY SEARCH IS PERFORMED ON THE androidKeycodes ARRAY ! WHEN ADDING A MAPPING, ADD IT SO THE androidKeycodes ARRAY STAYS SORTED ! */ // Mapping Android Keycodes to LWJGL Keycodes - add(KeyEvent.KEYCODE_UNKNOWN,LWJGLGLFWKeycode.GLFW_KEY_UNKNOWN); - add(KeyEvent.KEYCODE_HOME, LWJGLGLFWKeycode.GLFW_KEY_HOME); + add(KeyEvent.KEYCODE_UNKNOWN, LwjglGlfwKeycode.GLFW_KEY_UNKNOWN); + add(KeyEvent.KEYCODE_HOME, LwjglGlfwKeycode.GLFW_KEY_HOME); // Escape key - add(KeyEvent.KEYCODE_BACK, LWJGLGLFWKeycode.GLFW_KEY_ESCAPE); + add(KeyEvent.KEYCODE_BACK, LwjglGlfwKeycode.GLFW_KEY_ESCAPE); // 0-9 keys - add(KeyEvent.KEYCODE_0, LWJGLGLFWKeycode.GLFW_KEY_0); //7 - add(KeyEvent.KEYCODE_1, LWJGLGLFWKeycode.GLFW_KEY_1); - add(KeyEvent.KEYCODE_2, LWJGLGLFWKeycode.GLFW_KEY_2); - add(KeyEvent.KEYCODE_3, LWJGLGLFWKeycode.GLFW_KEY_3); - add(KeyEvent.KEYCODE_4, LWJGLGLFWKeycode.GLFW_KEY_4); - add(KeyEvent.KEYCODE_5, LWJGLGLFWKeycode.GLFW_KEY_5); - add(KeyEvent.KEYCODE_6, LWJGLGLFWKeycode.GLFW_KEY_6); - add(KeyEvent.KEYCODE_7, LWJGLGLFWKeycode.GLFW_KEY_7); - add(KeyEvent.KEYCODE_8, LWJGLGLFWKeycode.GLFW_KEY_8); - add(KeyEvent.KEYCODE_9, LWJGLGLFWKeycode.GLFW_KEY_9); //16 + add(KeyEvent.KEYCODE_0, LwjglGlfwKeycode.GLFW_KEY_0); //7 + add(KeyEvent.KEYCODE_1, LwjglGlfwKeycode.GLFW_KEY_1); + add(KeyEvent.KEYCODE_2, LwjglGlfwKeycode.GLFW_KEY_2); + add(KeyEvent.KEYCODE_3, LwjglGlfwKeycode.GLFW_KEY_3); + add(KeyEvent.KEYCODE_4, LwjglGlfwKeycode.GLFW_KEY_4); + add(KeyEvent.KEYCODE_5, LwjglGlfwKeycode.GLFW_KEY_5); + add(KeyEvent.KEYCODE_6, LwjglGlfwKeycode.GLFW_KEY_6); + add(KeyEvent.KEYCODE_7, LwjglGlfwKeycode.GLFW_KEY_7); + add(KeyEvent.KEYCODE_8, LwjglGlfwKeycode.GLFW_KEY_8); + add(KeyEvent.KEYCODE_9, LwjglGlfwKeycode.GLFW_KEY_9); //16 - add(KeyEvent.KEYCODE_POUND,LWJGLGLFWKeycode.GLFW_KEY_3); + add(KeyEvent.KEYCODE_POUND, LwjglGlfwKeycode.GLFW_KEY_3); // Arrow keys - add(KeyEvent.KEYCODE_DPAD_UP, LWJGLGLFWKeycode.GLFW_KEY_UP); //19 - add(KeyEvent.KEYCODE_DPAD_DOWN, LWJGLGLFWKeycode.GLFW_KEY_DOWN); - add(KeyEvent.KEYCODE_DPAD_LEFT, LWJGLGLFWKeycode.GLFW_KEY_LEFT); - add(KeyEvent.KEYCODE_DPAD_RIGHT, LWJGLGLFWKeycode.GLFW_KEY_RIGHT); //22 + add(KeyEvent.KEYCODE_DPAD_UP, LwjglGlfwKeycode.GLFW_KEY_UP); //19 + add(KeyEvent.KEYCODE_DPAD_DOWN, LwjglGlfwKeycode.GLFW_KEY_DOWN); + add(KeyEvent.KEYCODE_DPAD_LEFT, LwjglGlfwKeycode.GLFW_KEY_LEFT); + add(KeyEvent.KEYCODE_DPAD_RIGHT, LwjglGlfwKeycode.GLFW_KEY_RIGHT); //22 // A-Z keys - add(KeyEvent.KEYCODE_A, LWJGLGLFWKeycode.GLFW_KEY_A); //29 - add(KeyEvent.KEYCODE_B, LWJGLGLFWKeycode.GLFW_KEY_B); - add(KeyEvent.KEYCODE_C, LWJGLGLFWKeycode.GLFW_KEY_C); - add(KeyEvent.KEYCODE_D, LWJGLGLFWKeycode.GLFW_KEY_D); - add(KeyEvent.KEYCODE_E, LWJGLGLFWKeycode.GLFW_KEY_E); - add(KeyEvent.KEYCODE_F, LWJGLGLFWKeycode.GLFW_KEY_F); - add(KeyEvent.KEYCODE_G, LWJGLGLFWKeycode.GLFW_KEY_G); - add(KeyEvent.KEYCODE_H, LWJGLGLFWKeycode.GLFW_KEY_H); - add(KeyEvent.KEYCODE_I, LWJGLGLFWKeycode.GLFW_KEY_I); - add(KeyEvent.KEYCODE_J, LWJGLGLFWKeycode.GLFW_KEY_J); - add(KeyEvent.KEYCODE_K, LWJGLGLFWKeycode.GLFW_KEY_K); - add(KeyEvent.KEYCODE_L, LWJGLGLFWKeycode.GLFW_KEY_L); - add(KeyEvent.KEYCODE_M, LWJGLGLFWKeycode.GLFW_KEY_M); - add(KeyEvent.KEYCODE_N, LWJGLGLFWKeycode.GLFW_KEY_N); - add(KeyEvent.KEYCODE_O, LWJGLGLFWKeycode.GLFW_KEY_O); - add(KeyEvent.KEYCODE_P, LWJGLGLFWKeycode.GLFW_KEY_P); - add(KeyEvent.KEYCODE_Q, LWJGLGLFWKeycode.GLFW_KEY_Q); - add(KeyEvent.KEYCODE_R, LWJGLGLFWKeycode.GLFW_KEY_R); - add(KeyEvent.KEYCODE_S, LWJGLGLFWKeycode.GLFW_KEY_S); - add(KeyEvent.KEYCODE_T, LWJGLGLFWKeycode.GLFW_KEY_T); - add(KeyEvent.KEYCODE_U, LWJGLGLFWKeycode.GLFW_KEY_U); - add(KeyEvent.KEYCODE_V, LWJGLGLFWKeycode.GLFW_KEY_V); - add(KeyEvent.KEYCODE_W, LWJGLGLFWKeycode.GLFW_KEY_W); - add(KeyEvent.KEYCODE_X, LWJGLGLFWKeycode.GLFW_KEY_X); - add(KeyEvent.KEYCODE_Y, LWJGLGLFWKeycode.GLFW_KEY_Y); - add(KeyEvent.KEYCODE_Z, LWJGLGLFWKeycode.GLFW_KEY_Z); //54 + add(KeyEvent.KEYCODE_A, LwjglGlfwKeycode.GLFW_KEY_A); //29 + add(KeyEvent.KEYCODE_B, LwjglGlfwKeycode.GLFW_KEY_B); + add(KeyEvent.KEYCODE_C, LwjglGlfwKeycode.GLFW_KEY_C); + add(KeyEvent.KEYCODE_D, LwjglGlfwKeycode.GLFW_KEY_D); + add(KeyEvent.KEYCODE_E, LwjglGlfwKeycode.GLFW_KEY_E); + add(KeyEvent.KEYCODE_F, LwjglGlfwKeycode.GLFW_KEY_F); + add(KeyEvent.KEYCODE_G, LwjglGlfwKeycode.GLFW_KEY_G); + add(KeyEvent.KEYCODE_H, LwjglGlfwKeycode.GLFW_KEY_H); + add(KeyEvent.KEYCODE_I, LwjglGlfwKeycode.GLFW_KEY_I); + add(KeyEvent.KEYCODE_J, LwjglGlfwKeycode.GLFW_KEY_J); + add(KeyEvent.KEYCODE_K, LwjglGlfwKeycode.GLFW_KEY_K); + add(KeyEvent.KEYCODE_L, LwjglGlfwKeycode.GLFW_KEY_L); + add(KeyEvent.KEYCODE_M, LwjglGlfwKeycode.GLFW_KEY_M); + add(KeyEvent.KEYCODE_N, LwjglGlfwKeycode.GLFW_KEY_N); + add(KeyEvent.KEYCODE_O, LwjglGlfwKeycode.GLFW_KEY_O); + add(KeyEvent.KEYCODE_P, LwjglGlfwKeycode.GLFW_KEY_P); + add(KeyEvent.KEYCODE_Q, LwjglGlfwKeycode.GLFW_KEY_Q); + add(KeyEvent.KEYCODE_R, LwjglGlfwKeycode.GLFW_KEY_R); + add(KeyEvent.KEYCODE_S, LwjglGlfwKeycode.GLFW_KEY_S); + add(KeyEvent.KEYCODE_T, LwjglGlfwKeycode.GLFW_KEY_T); + add(KeyEvent.KEYCODE_U, LwjglGlfwKeycode.GLFW_KEY_U); + add(KeyEvent.KEYCODE_V, LwjglGlfwKeycode.GLFW_KEY_V); + add(KeyEvent.KEYCODE_W, LwjglGlfwKeycode.GLFW_KEY_W); + add(KeyEvent.KEYCODE_X, LwjglGlfwKeycode.GLFW_KEY_X); + add(KeyEvent.KEYCODE_Y, LwjglGlfwKeycode.GLFW_KEY_Y); + add(KeyEvent.KEYCODE_Z, LwjglGlfwKeycode.GLFW_KEY_Z); //54 - add(KeyEvent.KEYCODE_COMMA, LWJGLGLFWKeycode.GLFW_KEY_COMMA); - add(KeyEvent.KEYCODE_PERIOD, LWJGLGLFWKeycode.GLFW_KEY_PERIOD); + add(KeyEvent.KEYCODE_COMMA, LwjglGlfwKeycode.GLFW_KEY_COMMA); + add(KeyEvent.KEYCODE_PERIOD, LwjglGlfwKeycode.GLFW_KEY_PERIOD); // Alt keys - add(KeyEvent.KEYCODE_ALT_LEFT, LWJGLGLFWKeycode.GLFW_KEY_LEFT_ALT); - add(KeyEvent.KEYCODE_ALT_RIGHT, LWJGLGLFWKeycode.GLFW_KEY_RIGHT_ALT); + add(KeyEvent.KEYCODE_ALT_LEFT, LwjglGlfwKeycode.GLFW_KEY_LEFT_ALT); + add(KeyEvent.KEYCODE_ALT_RIGHT, LwjglGlfwKeycode.GLFW_KEY_RIGHT_ALT); // Shift keys - add(KeyEvent.KEYCODE_SHIFT_LEFT, LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT); - add(KeyEvent.KEYCODE_SHIFT_RIGHT, LWJGLGLFWKeycode.GLFW_KEY_RIGHT_SHIFT); + add(KeyEvent.KEYCODE_SHIFT_LEFT, LwjglGlfwKeycode.GLFW_KEY_LEFT_SHIFT); + add(KeyEvent.KEYCODE_SHIFT_RIGHT, LwjglGlfwKeycode.GLFW_KEY_RIGHT_SHIFT); - add(KeyEvent.KEYCODE_TAB, LWJGLGLFWKeycode.GLFW_KEY_TAB); - add(KeyEvent.KEYCODE_SPACE, LWJGLGLFWKeycode.GLFW_KEY_SPACE); - add(KeyEvent.KEYCODE_ENTER, LWJGLGLFWKeycode.GLFW_KEY_ENTER); //66 - add(KeyEvent.KEYCODE_DEL, LWJGLGLFWKeycode.GLFW_KEY_BACKSPACE); // Backspace - add(KeyEvent.KEYCODE_GRAVE, LWJGLGLFWKeycode.GLFW_KEY_GRAVE_ACCENT); - add(KeyEvent.KEYCODE_MINUS, LWJGLGLFWKeycode.GLFW_KEY_MINUS); - add(KeyEvent.KEYCODE_EQUALS, LWJGLGLFWKeycode.GLFW_KEY_EQUAL); - add(KeyEvent.KEYCODE_LEFT_BRACKET, LWJGLGLFWKeycode.GLFW_KEY_LEFT_BRACKET); - add(KeyEvent.KEYCODE_RIGHT_BRACKET, LWJGLGLFWKeycode.GLFW_KEY_RIGHT_BRACKET); - add(KeyEvent.KEYCODE_BACKSLASH, LWJGLGLFWKeycode.GLFW_KEY_BACKSLASH); - add(KeyEvent.KEYCODE_SEMICOLON, LWJGLGLFWKeycode.GLFW_KEY_SEMICOLON); //74 + add(KeyEvent.KEYCODE_TAB, LwjglGlfwKeycode.GLFW_KEY_TAB); + add(KeyEvent.KEYCODE_SPACE, LwjglGlfwKeycode.GLFW_KEY_SPACE); + add(KeyEvent.KEYCODE_ENTER, LwjglGlfwKeycode.GLFW_KEY_ENTER); //66 + add(KeyEvent.KEYCODE_DEL, LwjglGlfwKeycode.GLFW_KEY_BACKSPACE); // Backspace + add(KeyEvent.KEYCODE_GRAVE, LwjglGlfwKeycode.GLFW_KEY_GRAVE_ACCENT); + add(KeyEvent.KEYCODE_MINUS, LwjglGlfwKeycode.GLFW_KEY_MINUS); + add(KeyEvent.KEYCODE_EQUALS, LwjglGlfwKeycode.GLFW_KEY_EQUAL); + add(KeyEvent.KEYCODE_LEFT_BRACKET, LwjglGlfwKeycode.GLFW_KEY_LEFT_BRACKET); + add(KeyEvent.KEYCODE_RIGHT_BRACKET, LwjglGlfwKeycode.GLFW_KEY_RIGHT_BRACKET); + add(KeyEvent.KEYCODE_BACKSLASH, LwjglGlfwKeycode.GLFW_KEY_BACKSLASH); + add(KeyEvent.KEYCODE_SEMICOLON, LwjglGlfwKeycode.GLFW_KEY_SEMICOLON); //74 - add(KeyEvent.KEYCODE_SLASH, LWJGLGLFWKeycode.GLFW_KEY_SLASH); //76 - add(KeyEvent.KEYCODE_AT,LWJGLGLFWKeycode.GLFW_KEY_2); + add(KeyEvent.KEYCODE_SLASH, LwjglGlfwKeycode.GLFW_KEY_SLASH); //76 + add(KeyEvent.KEYCODE_AT, LwjglGlfwKeycode.GLFW_KEY_2); - add(KeyEvent.KEYCODE_PLUS, LWJGLGLFWKeycode.GLFW_KEY_KP_ADD); + add(KeyEvent.KEYCODE_PLUS, LwjglGlfwKeycode.GLFW_KEY_KP_ADD); // Page keys - add(KeyEvent.KEYCODE_PAGE_UP, LWJGLGLFWKeycode.GLFW_KEY_PAGE_UP); //92 - add(KeyEvent.KEYCODE_PAGE_DOWN, LWJGLGLFWKeycode.GLFW_KEY_PAGE_DOWN); + add(KeyEvent.KEYCODE_PAGE_UP, LwjglGlfwKeycode.GLFW_KEY_PAGE_UP); //92 + add(KeyEvent.KEYCODE_PAGE_DOWN, LwjglGlfwKeycode.GLFW_KEY_PAGE_DOWN); - add(KeyEvent.KEYCODE_ESCAPE, LWJGLGLFWKeycode.GLFW_KEY_ESCAPE); + add(KeyEvent.KEYCODE_ESCAPE, LwjglGlfwKeycode.GLFW_KEY_ESCAPE); // Control keys - add(KeyEvent.KEYCODE_CTRL_LEFT, LWJGLGLFWKeycode.GLFW_KEY_LEFT_CONTROL); - add(KeyEvent.KEYCODE_CTRL_RIGHT, LWJGLGLFWKeycode.GLFW_KEY_RIGHT_CONTROL); + add(KeyEvent.KEYCODE_CTRL_LEFT, LwjglGlfwKeycode.GLFW_KEY_LEFT_CONTROL); + add(KeyEvent.KEYCODE_CTRL_RIGHT, LwjglGlfwKeycode.GLFW_KEY_RIGHT_CONTROL); - add(KeyEvent.KEYCODE_CAPS_LOCK, LWJGLGLFWKeycode.GLFW_KEY_CAPS_LOCK); - add(KeyEvent.KEYCODE_BREAK, LWJGLGLFWKeycode.GLFW_KEY_PAUSE); - add(KeyEvent.KEYCODE_INSERT, LWJGLGLFWKeycode.GLFW_KEY_INSERT); + add(KeyEvent.KEYCODE_CAPS_LOCK, LwjglGlfwKeycode.GLFW_KEY_CAPS_LOCK); + add(KeyEvent.KEYCODE_BREAK, LwjglGlfwKeycode.GLFW_KEY_PAUSE); + add(KeyEvent.KEYCODE_INSERT, LwjglGlfwKeycode.GLFW_KEY_INSERT); // Fn keys - add(KeyEvent.KEYCODE_F1, LWJGLGLFWKeycode.GLFW_KEY_F1); //131 - add(KeyEvent.KEYCODE_F2, LWJGLGLFWKeycode.GLFW_KEY_F2); - add(KeyEvent.KEYCODE_F3, LWJGLGLFWKeycode.GLFW_KEY_F3); - add(KeyEvent.KEYCODE_F4, LWJGLGLFWKeycode.GLFW_KEY_F4); - add(KeyEvent.KEYCODE_F5, LWJGLGLFWKeycode.GLFW_KEY_F5); - add(KeyEvent.KEYCODE_F6, LWJGLGLFWKeycode.GLFW_KEY_F6); - add(KeyEvent.KEYCODE_F7, LWJGLGLFWKeycode.GLFW_KEY_F7); - add(KeyEvent.KEYCODE_F8, LWJGLGLFWKeycode.GLFW_KEY_F8); - add(KeyEvent.KEYCODE_F9, LWJGLGLFWKeycode.GLFW_KEY_F9); - add(KeyEvent.KEYCODE_F10, LWJGLGLFWKeycode.GLFW_KEY_F10); - add(KeyEvent.KEYCODE_F11, LWJGLGLFWKeycode.GLFW_KEY_F11); - add(KeyEvent.KEYCODE_F12, LWJGLGLFWKeycode.GLFW_KEY_F12); //142 + add(KeyEvent.KEYCODE_F1, LwjglGlfwKeycode.GLFW_KEY_F1); //131 + add(KeyEvent.KEYCODE_F2, LwjglGlfwKeycode.GLFW_KEY_F2); + add(KeyEvent.KEYCODE_F3, LwjglGlfwKeycode.GLFW_KEY_F3); + add(KeyEvent.KEYCODE_F4, LwjglGlfwKeycode.GLFW_KEY_F4); + add(KeyEvent.KEYCODE_F5, LwjglGlfwKeycode.GLFW_KEY_F5); + add(KeyEvent.KEYCODE_F6, LwjglGlfwKeycode.GLFW_KEY_F6); + add(KeyEvent.KEYCODE_F7, LwjglGlfwKeycode.GLFW_KEY_F7); + add(KeyEvent.KEYCODE_F8, LwjglGlfwKeycode.GLFW_KEY_F8); + add(KeyEvent.KEYCODE_F9, LwjglGlfwKeycode.GLFW_KEY_F9); + add(KeyEvent.KEYCODE_F10, LwjglGlfwKeycode.GLFW_KEY_F10); + add(KeyEvent.KEYCODE_F11, LwjglGlfwKeycode.GLFW_KEY_F11); + add(KeyEvent.KEYCODE_F12, LwjglGlfwKeycode.GLFW_KEY_F12); //142 // Num keys - add(KeyEvent.KEYCODE_NUM_LOCK, LWJGLGLFWKeycode.GLFW_KEY_NUM_LOCK); //143 - add(KeyEvent.KEYCODE_NUMPAD_0, LWJGLGLFWKeycode.GLFW_KEY_0); - add(KeyEvent.KEYCODE_NUMPAD_1, LWJGLGLFWKeycode.GLFW_KEY_1); - add(KeyEvent.KEYCODE_NUMPAD_2, LWJGLGLFWKeycode.GLFW_KEY_2); - add(KeyEvent.KEYCODE_NUMPAD_3, LWJGLGLFWKeycode.GLFW_KEY_3); - add(KeyEvent.KEYCODE_NUMPAD_4, LWJGLGLFWKeycode.GLFW_KEY_4); - add(KeyEvent.KEYCODE_NUMPAD_5, LWJGLGLFWKeycode.GLFW_KEY_5); - add(KeyEvent.KEYCODE_NUMPAD_6, LWJGLGLFWKeycode.GLFW_KEY_6); - add(KeyEvent.KEYCODE_NUMPAD_7, LWJGLGLFWKeycode.GLFW_KEY_7); - add(KeyEvent.KEYCODE_NUMPAD_8, LWJGLGLFWKeycode.GLFW_KEY_8); - add(KeyEvent.KEYCODE_NUMPAD_9, LWJGLGLFWKeycode.GLFW_KEY_9); - add(KeyEvent.KEYCODE_NUMPAD_DIVIDE, LWJGLGLFWKeycode.GLFW_KEY_KP_DIVIDE); - add(KeyEvent.KEYCODE_NUMPAD_MULTIPLY, LWJGLGLFWKeycode.GLFW_KEY_KP_MULTIPLY); - add(KeyEvent.KEYCODE_NUMPAD_SUBTRACT, LWJGLGLFWKeycode.GLFW_KEY_KP_SUBTRACT); - add(KeyEvent.KEYCODE_NUMPAD_ADD, LWJGLGLFWKeycode.GLFW_KEY_KP_ADD); - add(KeyEvent.KEYCODE_NUMPAD_DOT, LWJGLGLFWKeycode.GLFW_KEY_PERIOD); - add(KeyEvent.KEYCODE_NUMPAD_COMMA, LWJGLGLFWKeycode.GLFW_KEY_COMMA); - add(KeyEvent.KEYCODE_NUMPAD_ENTER, LWJGLGLFWKeycode.GLFW_KEY_ENTER); - add(KeyEvent.KEYCODE_NUMPAD_EQUALS, LWJGLGLFWKeycode.GLFW_KEY_EQUAL); //161 + add(KeyEvent.KEYCODE_NUM_LOCK, LwjglGlfwKeycode.GLFW_KEY_NUM_LOCK); //143 + add(KeyEvent.KEYCODE_NUMPAD_0, LwjglGlfwKeycode.GLFW_KEY_0); + add(KeyEvent.KEYCODE_NUMPAD_1, LwjglGlfwKeycode.GLFW_KEY_1); + add(KeyEvent.KEYCODE_NUMPAD_2, LwjglGlfwKeycode.GLFW_KEY_2); + add(KeyEvent.KEYCODE_NUMPAD_3, LwjglGlfwKeycode.GLFW_KEY_3); + add(KeyEvent.KEYCODE_NUMPAD_4, LwjglGlfwKeycode.GLFW_KEY_4); + add(KeyEvent.KEYCODE_NUMPAD_5, LwjglGlfwKeycode.GLFW_KEY_5); + add(KeyEvent.KEYCODE_NUMPAD_6, LwjglGlfwKeycode.GLFW_KEY_6); + add(KeyEvent.KEYCODE_NUMPAD_7, LwjglGlfwKeycode.GLFW_KEY_7); + add(KeyEvent.KEYCODE_NUMPAD_8, LwjglGlfwKeycode.GLFW_KEY_8); + add(KeyEvent.KEYCODE_NUMPAD_9, LwjglGlfwKeycode.GLFW_KEY_9); + add(KeyEvent.KEYCODE_NUMPAD_DIVIDE, LwjglGlfwKeycode.GLFW_KEY_KP_DIVIDE); + add(KeyEvent.KEYCODE_NUMPAD_MULTIPLY, LwjglGlfwKeycode.GLFW_KEY_KP_MULTIPLY); + add(KeyEvent.KEYCODE_NUMPAD_SUBTRACT, LwjglGlfwKeycode.GLFW_KEY_KP_SUBTRACT); + add(KeyEvent.KEYCODE_NUMPAD_ADD, LwjglGlfwKeycode.GLFW_KEY_KP_ADD); + add(KeyEvent.KEYCODE_NUMPAD_DOT, LwjglGlfwKeycode.GLFW_KEY_PERIOD); + add(KeyEvent.KEYCODE_NUMPAD_COMMA, LwjglGlfwKeycode.GLFW_KEY_COMMA); + add(KeyEvent.KEYCODE_NUMPAD_ENTER, LwjglGlfwKeycode.GLFW_KEY_ENTER); + add(KeyEvent.KEYCODE_NUMPAD_EQUALS, LwjglGlfwKeycode.GLFW_KEY_EQUAL); //161 } - private static short index = 0; - - private static void add(int androidKeycode, short LWJGLKeycode){ - androidKeycodes[index] = androidKeycode; - LWJGLKeycodes[index] = LWJGLKeycode; - ++index; - } - - public static boolean containsKey(int keycode){ return getIndexByKey(keycode) >= 0; } - - public static String[] generateKeyName() { if (androidKeyNameArray == null) { - androidKeyNameArray = new String[androidKeycodes.length]; + androidKeyNameArray = new String[sAndroidKeycodes.length]; for(int i=0; i < androidKeyNameArray.length; ++i){ - androidKeyNameArray[i] = KeyEvent.keyCodeToString(androidKeycodes[i]).replace("KEYCODE_", ""); + androidKeyNameArray[i] = KeyEvent.keyCodeToString(sAndroidKeycodes[i]).replace("KEYCODE_", ""); } } return androidKeyNameArray; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LWJGLGLFWKeycode.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LWJGLGLFWKeycode.java index 1f1d4ede0..fc807ef06 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LWJGLGLFWKeycode.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LWJGLGLFWKeycode.java @@ -30,8 +30,7 @@ package net.kdt.pojavlaunch; -public class LWJGLGLFWKeycode -{ +public class LwjglGlfwKeycode { /** The unknown key. */ public static final short GLFW_KEY_UNKNOWN = 0; // should be -1 diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java index 11d210860..5a2ddded4 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java @@ -14,13 +14,11 @@ import net.objecthunter.exp4j.function.Function; import org.lwjgl.glfw.*; -import static net.kdt.pojavlaunch.LWJGLGLFWKeycode.GLFW_KEY_UNKNOWN; +import static net.kdt.pojavlaunch.LwjglGlfwKeycode.GLFW_KEY_UNKNOWN; import static org.lwjgl.glfw.CallbackBridge.sendKeyPress; import androidx.annotation.Keep; -import com.google.gson.annotations.SerializedName; - @Keep public class ControlData { diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java index 6197cc17b..7fd3f1bc0 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java @@ -3,12 +3,9 @@ import android.content.*; import androidx.annotation.Keep; -import com.google.gson.*; - import java.io.IOException; import java.util.*; import net.kdt.pojavlaunch.*; -import org.lwjgl.glfw.*; @Keep public class CustomControls { @@ -37,22 +34,22 @@ public class CustomControls { this.mControlDataList.add(new ControlData(ControlData.getSpecialButtons()[3])); // Secondary Mouse mControlDataList this.mControlDataList.add(new ControlData(ControlData.getSpecialButtons()[4])); // Virtual mouse toggle - this.mControlDataList.add(new ControlData(ctx, R.string.control_debug, new int[]{LWJGLGLFWKeycode.GLFW_KEY_F3}, "${margin}", "${margin}", false)); - this.mControlDataList.add(new ControlData(ctx, R.string.control_chat, new int[]{LWJGLGLFWKeycode.GLFW_KEY_T}, "${margin} * 2 + ${width}", "${margin}", false)); - this.mControlDataList.add(new ControlData(ctx, R.string.control_listplayers, new int[]{LWJGLGLFWKeycode.GLFW_KEY_TAB}, "${margin} * 4 + ${width} * 3", "${margin}", false)); - this.mControlDataList.add(new ControlData(ctx, R.string.control_thirdperson, new int[]{LWJGLGLFWKeycode.GLFW_KEY_F5}, "${margin}", "${height} + ${margin}", false)); + this.mControlDataList.add(new ControlData(ctx, R.string.control_debug, new int[]{LwjglGlfwKeycode.GLFW_KEY_F3}, "${margin}", "${margin}", false)); + this.mControlDataList.add(new ControlData(ctx, R.string.control_chat, new int[]{LwjglGlfwKeycode.GLFW_KEY_T}, "${margin} * 2 + ${width}", "${margin}", false)); + this.mControlDataList.add(new ControlData(ctx, R.string.control_listplayers, new int[]{LwjglGlfwKeycode.GLFW_KEY_TAB}, "${margin} * 4 + ${width} * 3", "${margin}", false)); + this.mControlDataList.add(new ControlData(ctx, R.string.control_thirdperson, new int[]{LwjglGlfwKeycode.GLFW_KEY_F5}, "${margin}", "${height} + ${margin}", false)); - this.mControlDataList.add(new ControlData(ctx, R.string.control_up, new int[]{LWJGLGLFWKeycode.GLFW_KEY_W}, "${margin} * 2 + ${width}", "${bottom} - ${margin} * 3 - ${height} * 2", true)); - this.mControlDataList.add(new ControlData(ctx, R.string.control_left, new int[]{LWJGLGLFWKeycode.GLFW_KEY_A}, "${margin}", "${bottom} - ${margin} * 2 - ${height}", true)); - this.mControlDataList.add(new ControlData(ctx, R.string.control_down, new int[]{LWJGLGLFWKeycode.GLFW_KEY_S}, "${margin} * 2 + ${width}", "${bottom} - ${margin}", true)); - this.mControlDataList.add(new ControlData(ctx, R.string.control_right, new int[]{LWJGLGLFWKeycode.GLFW_KEY_D}, "${margin} * 3 + ${width} * 2", "${bottom} - ${margin} * 2 - ${height}", true)); + this.mControlDataList.add(new ControlData(ctx, R.string.control_up, new int[]{LwjglGlfwKeycode.GLFW_KEY_W}, "${margin} * 2 + ${width}", "${bottom} - ${margin} * 3 - ${height} * 2", true)); + this.mControlDataList.add(new ControlData(ctx, R.string.control_left, new int[]{LwjglGlfwKeycode.GLFW_KEY_A}, "${margin}", "${bottom} - ${margin} * 2 - ${height}", true)); + this.mControlDataList.add(new ControlData(ctx, R.string.control_down, new int[]{LwjglGlfwKeycode.GLFW_KEY_S}, "${margin} * 2 + ${width}", "${bottom} - ${margin}", true)); + this.mControlDataList.add(new ControlData(ctx, R.string.control_right, new int[]{LwjglGlfwKeycode.GLFW_KEY_D}, "${margin} * 3 + ${width} * 2", "${bottom} - ${margin} * 2 - ${height}", true)); - this.mControlDataList.add(new ControlData(ctx, R.string.control_inventory, new int[]{LWJGLGLFWKeycode.GLFW_KEY_E}, "${margin} * 3 + ${width} * 2", "${bottom} - ${margin}", true)); + this.mControlDataList.add(new ControlData(ctx, R.string.control_inventory, new int[]{LwjglGlfwKeycode.GLFW_KEY_E}, "${margin} * 3 + ${width} * 2", "${bottom} - ${margin}", true)); - ControlData shiftData = new ControlData(ctx, R.string.control_shift, new int[]{LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT}, "${margin} * 2 + ${width}", "${screen_height} - ${margin} * 2 - ${height} * 2", true); + ControlData shiftData = new ControlData(ctx, R.string.control_shift, new int[]{LwjglGlfwKeycode.GLFW_KEY_LEFT_SHIFT}, "${margin} * 2 + ${width}", "${screen_height} - ${margin} * 2 - ${height} * 2", true); shiftData.isToggle = true; this.mControlDataList.add(shiftData); - this.mControlDataList.add(new ControlData(ctx, R.string.control_jump, new int[]{LWJGLGLFWKeycode.GLFW_KEY_SPACE}, "${right} - ${margin} * 2 - ${width}", "${bottom} - ${margin} * 2 - ${height}", true)); + this.mControlDataList.add(new ControlData(ctx, R.string.control_jump, new int[]{LwjglGlfwKeycode.GLFW_KEY_SPACE}, "${right} - ${margin} * 2 - ${width}", "${bottom} - ${margin} * 2 - ${height}", true)); //The default controls are conform to the V2 version = 4; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java index c0035ebac..c9316bca7 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/LayoutConverter.java @@ -2,7 +2,7 @@ package net.kdt.pojavlaunch.customcontrols; import com.google.gson.JsonSyntaxException; -import net.kdt.pojavlaunch.LWJGLGLFWKeycode; +import net.kdt.pojavlaunch.LwjglGlfwKeycode; import net.kdt.pojavlaunch.Tools; import org.json.JSONArray; @@ -83,10 +83,10 @@ public class LayoutConverter { for(int i = 0; i < layoutMainArray.length(); i++) { JSONObject button = layoutMainArray.getJSONObject(i); ControlData n_button = new ControlData(); - int[] keycodes = new int[] {LWJGLGLFWKeycode.GLFW_KEY_UNKNOWN, - LWJGLGLFWKeycode.GLFW_KEY_UNKNOWN, - LWJGLGLFWKeycode.GLFW_KEY_UNKNOWN, - LWJGLGLFWKeycode.GLFW_KEY_UNKNOWN}; + int[] keycodes = new int[] {LwjglGlfwKeycode.GLFW_KEY_UNKNOWN, + LwjglGlfwKeycode.GLFW_KEY_UNKNOWN, + LwjglGlfwKeycode.GLFW_KEY_UNKNOWN, + LwjglGlfwKeycode.GLFW_KEY_UNKNOWN}; n_button.isDynamicBtn = button.getBoolean("isDynamicBtn"); n_button.dynamicX = button.getString("dynamicX"); n_button.dynamicY = button.getString("dynamicY"); @@ -116,9 +116,9 @@ public class LayoutConverter { } if(button.getBoolean("isRound")) { n_button.cornerRadius = 35f; } int next_idx = 0; - if(button.getBoolean("holdShift")) { keycodes[next_idx] = LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT; next_idx++; } - if(button.getBoolean("holdCtrl")) { keycodes[next_idx] = LWJGLGLFWKeycode.GLFW_KEY_LEFT_CONTROL; next_idx++; } - if(button.getBoolean("holdAlt")) { keycodes[next_idx] = LWJGLGLFWKeycode.GLFW_KEY_LEFT_ALT; next_idx++; } + if(button.getBoolean("holdShift")) { keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_SHIFT; next_idx++; } + if(button.getBoolean("holdCtrl")) { keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_CONTROL; next_idx++; } + if(button.getBoolean("holdAlt")) { keycodes[next_idx] = LwjglGlfwKeycode.GLFW_KEY_LEFT_ALT; next_idx++; } keycodes[next_idx] = button.getInt("keycode"); n_button.keycodes = keycodes; empty.mControlDataList.add(n_button); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/TouchCharInput.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/TouchCharInput.java index 3d7c037df..52ca3a83c 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/TouchCharInput.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/TouchCharInput.java @@ -11,13 +11,11 @@ import android.content.res.Configuration; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.inputmethod.InputMethodManager; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import net.kdt.pojavlaunch.BaseMainActivity; -import net.kdt.pojavlaunch.LWJGLGLFWKeycode; +import net.kdt.pojavlaunch.LwjglGlfwKeycode; import net.kdt.pojavlaunch.R; import org.lwjgl.glfw.CallbackBridge; @@ -51,7 +49,7 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText if(isDoingInternalChanges)return; for(int i=0; i< lengthBefore; ++i){ - CallbackBridge.sendKeycode(LWJGLGLFWKeycode.GLFW_KEY_BACKSPACE, '\u0008', 0, 0, true); + CallbackBridge.sendKeycode(LwjglGlfwKeycode.GLFW_KEY_BACKSPACE, '\u0008', 0, 0, true); } for(int i=start, count = 0; count < lengthAfter; ++i){ CallbackBridge.sendChar(text.charAt(i), 0); @@ -127,7 +125,7 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText * Send the enter key. */ private void sendEnter(){ - sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_ENTER); + sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_ENTER); clear(); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlButton.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlButton.java index a599ad80d..36949e11a 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlButton.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlButton.java @@ -16,11 +16,10 @@ import net.kdt.pojavlaunch.customcontrols.ControlData; import net.kdt.pojavlaunch.customcontrols.ControlLayout; import net.kdt.pojavlaunch.customcontrols.handleview.*; import net.kdt.pojavlaunch.*; -import net.kdt.pojavlaunch.prefs.LauncherPreferences; import org.lwjgl.glfw.*; -import static net.kdt.pojavlaunch.LWJGLGLFWKeycode.GLFW_KEY_UNKNOWN; +import static net.kdt.pojavlaunch.LwjglGlfwKeycode.GLFW_KEY_UNKNOWN; import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_BUTTONSIZE; import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_CONTROL_BOTTOM_OFFSET; import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_CONTROL_LEFT_OFFSET; @@ -536,15 +535,15 @@ public class ControlButton extends androidx.appcompat.widget.AppCompatButton imp break; case ControlData.SPECIALBTN_MOUSEPRI: - sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, isDown); + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, isDown); break; case ControlData.SPECIALBTN_MOUSEMID: - sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_MIDDLE, isDown); + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_MIDDLE, isDown); break; case ControlData.SPECIALBTN_MOUSESEC: - sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT, isDown); + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, isDown); break; case ControlData.SPECIALBTN_SCROLLDOWN: diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java index 81db7f57f..c7aa5dcd0 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java @@ -15,7 +15,7 @@ import android.widget.Toast; import androidx.core.content.res.ResourcesCompat; import androidx.core.math.MathUtils; -import net.kdt.pojavlaunch.LWJGLGLFWKeycode; +import net.kdt.pojavlaunch.LwjglGlfwKeycode; import net.kdt.pojavlaunch.R; import net.kdt.pojavlaunch.prefs.LauncherPreferences; import net.kdt.pojavlaunch.utils.MCOptionUtils; @@ -403,7 +403,7 @@ public class Gamepad { default: - sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_SPACE, CallbackBridge.getCurrentMods(), isDown); + sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_SPACE, CallbackBridge.getCurrentMods(), isDown); break; } } @@ -418,11 +418,11 @@ public class Gamepad { if(isDown) CallbackBridge.sendScroll(0, 1); break; - case LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT: - sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT, isDown); + case LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT: + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, isDown); break; - case LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT: - sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, isDown); + case LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT: + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, isDown); break; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadMap.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadMap.java index 90ec915b6..ac33e4c8a 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadMap.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadMap.java @@ -1,6 +1,6 @@ package net.kdt.pojavlaunch.customcontrols.gamepad; -import net.kdt.pojavlaunch.LWJGLGLFWKeycode; +import net.kdt.pojavlaunch.LwjglGlfwKeycode; public class GamepadMap { @@ -76,33 +76,33 @@ public class GamepadMap { public static GamepadMap getDefaultGameMap(){ GamepadMap gameMap = new GamepadMap(); - gameMap.BUTTON_A.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_SPACE}; - gameMap.BUTTON_B.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_Q}; - gameMap.BUTTON_X.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_E}; - gameMap.BUTTON_Y.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_F}; + gameMap.BUTTON_A.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_SPACE}; + gameMap.BUTTON_B.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_Q}; + gameMap.BUTTON_X.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_E}; + gameMap.BUTTON_Y.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_F}; - gameMap.DIRECTION_FORWARD = new int[]{LWJGLGLFWKeycode.GLFW_KEY_W}; - gameMap.DIRECTION_BACKWARD = new int[]{LWJGLGLFWKeycode.GLFW_KEY_S}; - gameMap.DIRECTION_RIGHT = new int[]{LWJGLGLFWKeycode.GLFW_KEY_D}; - gameMap.DIRECTION_LEFT = new int[]{LWJGLGLFWKeycode.GLFW_KEY_A}; + gameMap.DIRECTION_FORWARD = new int[]{LwjglGlfwKeycode.GLFW_KEY_W}; + gameMap.DIRECTION_BACKWARD = new int[]{LwjglGlfwKeycode.GLFW_KEY_S}; + gameMap.DIRECTION_RIGHT = new int[]{LwjglGlfwKeycode.GLFW_KEY_D}; + gameMap.DIRECTION_LEFT = new int[]{LwjglGlfwKeycode.GLFW_KEY_A}; - gameMap.DPAD_UP.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT}; - gameMap.DPAD_DOWN.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_O}; //For mods ? - gameMap.DPAD_RIGHT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_K}; //For mods ? - gameMap.DPAD_LEFT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_J}; //For mods ? + gameMap.DPAD_UP.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_LEFT_SHIFT}; + gameMap.DPAD_DOWN.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_O}; //For mods ? + gameMap.DPAD_RIGHT.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_K}; //For mods ? + gameMap.DPAD_LEFT.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_J}; //For mods ? gameMap.SHOULDER_LEFT.keycodes = new int[]{GamepadMap.MOUSE_SCROLL_UP}; gameMap.SHOULDER_RIGHT.keycodes = new int[]{GamepadMap.MOUSE_SCROLL_DOWN}; - gameMap.TRIGGER_LEFT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT}; - gameMap.TRIGGER_RIGHT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT}; + gameMap.TRIGGER_LEFT.keycodes = new int[]{LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT}; + gameMap.TRIGGER_RIGHT.keycodes = new int[]{LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT}; - gameMap.THUMBSTICK_LEFT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_LEFT_CONTROL}; - gameMap.THUMBSTICK_RIGHT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT}; + gameMap.THUMBSTICK_LEFT.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_LEFT_CONTROL}; + gameMap.THUMBSTICK_RIGHT.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_LEFT_SHIFT}; gameMap.THUMBSTICK_RIGHT.isToggleable = true; - gameMap.BUTTON_START.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_ESCAPE}; - gameMap.BUTTON_SELECT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_TAB}; + gameMap.BUTTON_START.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_ESCAPE}; + gameMap.BUTTON_SELECT.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_TAB}; return gameMap; } @@ -113,10 +113,10 @@ public class GamepadMap { public static GamepadMap getDefaultMenuMap(){ GamepadMap menuMap = new GamepadMap(); - menuMap.BUTTON_A.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT}; - menuMap.BUTTON_B.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_ESCAPE}; - menuMap.BUTTON_X.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT}; - menuMap.BUTTON_Y.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT, LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT}; //Oops, doesn't work since left shift isn't properly applied. + menuMap.BUTTON_A.keycodes = new int[]{LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT}; + menuMap.BUTTON_B.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_ESCAPE}; + menuMap.BUTTON_X.keycodes = new int[]{LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT}; + menuMap.BUTTON_Y.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_LEFT_SHIFT, LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT}; //Oops, doesn't work since left shift isn't properly applied. menuMap.DIRECTION_FORWARD = new int[]{GamepadMap.MOUSE_SCROLL_UP, GamepadMap.MOUSE_SCROLL_UP, GamepadMap.MOUSE_SCROLL_UP, GamepadMap.MOUSE_SCROLL_UP, GamepadMap.MOUSE_SCROLL_UP}; menuMap.DIRECTION_BACKWARD = new int[]{GamepadMap.MOUSE_SCROLL_DOWN, GamepadMap.MOUSE_SCROLL_DOWN, GamepadMap.MOUSE_SCROLL_DOWN, GamepadMap.MOUSE_SCROLL_DOWN, GamepadMap.MOUSE_SCROLL_DOWN}; @@ -124,9 +124,9 @@ public class GamepadMap { menuMap.DIRECTION_LEFT = new int[]{}; menuMap.DPAD_UP.keycodes = new int[]{}; - menuMap.DPAD_DOWN.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_O}; //For mods ? - menuMap.DPAD_RIGHT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_K}; //For mods ? - menuMap.DPAD_LEFT.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_J}; //For mods ? + menuMap.DPAD_DOWN.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_O}; //For mods ? + menuMap.DPAD_RIGHT.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_K}; //For mods ? + menuMap.DPAD_LEFT.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_J}; //For mods ? menuMap.SHOULDER_LEFT.keycodes = new int[]{GamepadMap.MOUSE_SCROLL_UP}; menuMap.SHOULDER_RIGHT.keycodes = new int[]{GamepadMap.MOUSE_SCROLL_DOWN}; @@ -137,7 +137,7 @@ public class GamepadMap { menuMap.THUMBSTICK_LEFT.keycodes = new int[]{}; menuMap.THUMBSTICK_RIGHT.keycodes = new int[]{}; - menuMap.BUTTON_START.keycodes = new int[]{LWJGLGLFWKeycode.GLFW_KEY_ESCAPE}; + menuMap.BUTTON_START.keycodes = new int[]{LwjglGlfwKeycode.GLFW_KEY_ESCAPE}; menuMap.BUTTON_SELECT.keycodes = new int[]{}; return menuMap; diff --git a/app_pojavlauncher/src/main/java/org/lwjgl/glfw/CallbackBridge.java b/app_pojavlauncher/src/main/java/org/lwjgl/glfw/CallbackBridge.java index 79b2f1fbb..2781abeba 100644 --- a/app_pojavlauncher/src/main/java/org/lwjgl/glfw/CallbackBridge.java +++ b/app_pojavlauncher/src/main/java/org/lwjgl/glfw/CallbackBridge.java @@ -161,38 +161,38 @@ public class CallbackBridge { public static int getCurrentMods() { int currMods = 0; if (holdingAlt) { - currMods |= LWJGLGLFWKeycode.GLFW_MOD_ALT; + currMods |= LwjglGlfwKeycode.GLFW_MOD_ALT; } if (holdingCapslock) { - currMods |= LWJGLGLFWKeycode.GLFW_MOD_CAPS_LOCK; + currMods |= LwjglGlfwKeycode.GLFW_MOD_CAPS_LOCK; } if (holdingCtrl) { - currMods |= LWJGLGLFWKeycode.GLFW_MOD_CONTROL; + currMods |= LwjglGlfwKeycode.GLFW_MOD_CONTROL; } if (holdingNumlock) { - currMods |= LWJGLGLFWKeycode.GLFW_MOD_NUM_LOCK; + currMods |= LwjglGlfwKeycode.GLFW_MOD_NUM_LOCK; } if (holdingShift) { - currMods |= LWJGLGLFWKeycode.GLFW_MOD_SHIFT; + currMods |= LwjglGlfwKeycode.GLFW_MOD_SHIFT; } return currMods; } public static void setModifiers(int keyCode, boolean isDown){ switch (keyCode){ - case LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT: + case LwjglGlfwKeycode.GLFW_KEY_LEFT_SHIFT: CallbackBridge.holdingShift = isDown; return; - case LWJGLGLFWKeycode.GLFW_KEY_LEFT_CONTROL: + case LwjglGlfwKeycode.GLFW_KEY_LEFT_CONTROL: CallbackBridge.holdingCtrl = isDown; return; - case LWJGLGLFWKeycode.GLFW_KEY_LEFT_ALT: + case LwjglGlfwKeycode.GLFW_KEY_LEFT_ALT: CallbackBridge.holdingAlt = isDown; return; - case LWJGLGLFWKeycode.GLFW_KEY_CAPS_LOCK: + case LwjglGlfwKeycode.GLFW_KEY_CAPS_LOCK: CallbackBridge.holdingCapslock = isDown; return; - case LWJGLGLFWKeycode.GLFW_KEY_NUM_LOCK: + case LwjglGlfwKeycode.GLFW_KEY_NUM_LOCK: CallbackBridge.holdingNumlock = isDown; return; } From 8e092d9a8018d789f03e139c260cac0c5fc09d31 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 16:05:06 +0100 Subject: [PATCH 38/70] Refactor EfficientAndroidLWJGLKeycode.java --- .../EfficientAndroidLWJGLKeycode.java | 46 +++++++++---------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/EfficientAndroidLWJGLKeycode.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/EfficientAndroidLWJGLKeycode.java index 881216b4f..b8eb1a8dc 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/EfficientAndroidLWJGLKeycode.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/EfficientAndroidLWJGLKeycode.java @@ -4,8 +4,6 @@ import static org.lwjgl.glfw.CallbackBridge.sendKeyPress; import android.view.KeyEvent; -import net.kdt.pojavlaunch.prefs.LauncherPreferences; - import org.lwjgl.glfw.CallbackBridge; import java.util.Arrays; @@ -16,8 +14,8 @@ public class EfficientAndroidLWJGLKeycode { //The key being the android keycode from a KeyEvent //The value its LWJGL equivalent. private static final int KEYCODE_COUNT = 103; - private static final int[] androidKeycodes = new int[KEYCODE_COUNT]; - private static final short[] LWJGLKeycodes = new short[KEYCODE_COUNT]; + private static final int[] sAndroidKeycodes = new int[KEYCODE_COUNT]; + private static final short[] sLwjglKeycodes = new short[KEYCODE_COUNT]; private static String[] androidKeyNameArray; /* = new String[androidKeycodes.length]; */ static { @@ -176,7 +174,6 @@ public class EfficientAndroidLWJGLKeycode { execKey(keyEvent, getIndexByKey(keyEvent.getKeyCode())); } - public static void execKey(KeyEvent keyEvent, int valueIndex) { //valueIndex points to where the value is stored in the array. CallbackBridge.holdingAlt = keyEvent.isAltPressed(); @@ -185,19 +182,14 @@ public class EfficientAndroidLWJGLKeycode { CallbackBridge.holdingNumlock = keyEvent.isNumLockOn(); CallbackBridge.holdingShift = keyEvent.isShiftPressed(); - try { - System.out.println(keyEvent.getKeyCode() + " " +keyEvent.getDisplayLabel()); - char key = (char)(keyEvent.getUnicodeChar() != 0 ? keyEvent.getUnicodeChar() : '\u0000'); - sendKeyPress( - getValueByIndex(valueIndex), - key, - 0, - CallbackBridge.getCurrentMods(), - keyEvent.getAction() == KeyEvent.ACTION_DOWN); - - } catch (Throwable th) { - th.printStackTrace(); - } + System.out.println(keyEvent.getKeyCode() + " " +keyEvent.getDisplayLabel()); + char key = (char)(keyEvent.getUnicodeChar() != 0 ? keyEvent.getUnicodeChar() : '\u0000'); + sendKeyPress( + getValueByIndex(valueIndex), + key, + 0, + CallbackBridge.getCurrentMods(), + keyEvent.getAction() == KeyEvent.ACTION_DOWN); } public static void execKeyIndex(int index){ @@ -206,24 +198,28 @@ public class EfficientAndroidLWJGLKeycode { } public static int getValueByIndex(int index) { - return LWJGLKeycodes[index]; + return sLwjglKeycodes[index]; } public static int getIndexByKey(int key){ - return Arrays.binarySearch(androidKeycodes, key); + return Arrays.binarySearch(sAndroidKeycodes, key); } public static short getValue(int key){ - return LWJGLKeycodes[Arrays.binarySearch(androidKeycodes, key)]; + return sLwjglKeycodes[Arrays.binarySearch(sAndroidKeycodes, key)]; } + /** @return the index at which the key is in the array, searching linearly */ public static int getIndexByValue(int lwjglKey) { - //Since the LWJGL keycodes aren't sorted, linear search is used. //You should avoid using this function on performance critical areas - for (int i = 0; i < LWJGLKeycodes.length; i++) { - if(LWJGLKeycodes[i] == lwjglKey) return i; + for (int i = 0; i < sLwjglKeycodes.length; i++) { + if(sLwjglKeycodes[i] == lwjglKey) return i; } - return 0; } + + private static void add(int androidKeycode, short LWJGLKeycode){ + sAndroidKeycodes[sAndroidKeycodes.length - 1] = androidKeycode; + sLwjglKeycodes[sLwjglKeycodes.length - 1] = LWJGLKeycode; + } } From da99ef47ea2b80dd0f9af563edc7554ea7ff26ff Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 16:05:42 +0100 Subject: [PATCH 39/70] Refactor MinecraftGLView.java --- .../net/kdt/pojavlaunch/MinecraftGLView.java | 377 +++++++++--------- 1 file changed, 189 insertions(+), 188 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLView.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLView.java index ddcc65c13..cecdefe96 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLView.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLView.java @@ -11,20 +11,17 @@ import static org.lwjgl.glfw.CallbackBridge.windowWidth; import android.app.Activity; import android.content.*; import android.graphics.SurfaceTexture; -import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.*; import android.view.*; import android.widget.TextView; -import android.widget.Toast; import androidx.annotation.RequiresApi; import com.google.android.material.math.MathUtils; -import net.kdt.pojavlaunch.customcontrols.TouchCharInput; import net.kdt.pojavlaunch.customcontrols.gamepad.Gamepad; import net.kdt.pojavlaunch.prefs.LauncherPreferences; import net.kdt.pojavlaunch.utils.JREUtils; @@ -36,44 +33,6 @@ import org.lwjgl.glfw.CallbackBridge; * Class dealing with showing minecraft surface and taking inputs to dispatch them to minecraft */ public class MinecraftGLView extends TextureView { - /* Gamepad object for gamepad inputs, instantiated on need */ - private Gamepad gamepad = null; - /* Pointer Debug textview, used to show info about the pointer state */ - private TextView pointerDebugText; - /* Resolution scaler option, allow downsizing a window */ - private final float scaleFactor = LauncherPreferences.DEFAULT_PREF.getInt("resolutionRatio",100)/100f; - /* Display properties, such as resolution and DPI */ - private final DisplayMetrics displayMetrics = Tools.getDisplayMetrics((Activity) getContext()); - /* Sensitivity, adjusted according to screen size */ - private final double sensitivityFactor = (1.4 * (1080f/ displayMetrics.heightPixels)); - /* Use to detect simple and double taps */ - private final TapDetector singleTapDetector = new TapDetector(1, TapDetector.DETECTION_METHOD_BOTH); - private final TapDetector doubleTapDetector = new TapDetector(2, TapDetector.DETECTION_METHOD_DOWN); - /* MC GUI scale, listened by MCOptionUtils */ - private int GUIScale = getMcScale(); - private MCOptionUtils.MCOptionListener GUIScaleListener = () -> GUIScale = getMcScale(); - /* Surface ready listener, used by the activity to launch minecraft */ - SurfaceReadyListener surfaceReadyListener = null; - - /* List of hotbarKeys, used when clicking on the hotbar */ - private static final int[] hotbarKeys = { - LWJGLGLFWKeycode.GLFW_KEY_1, LWJGLGLFWKeycode.GLFW_KEY_2, LWJGLGLFWKeycode.GLFW_KEY_3, - LWJGLGLFWKeycode.GLFW_KEY_4, LWJGLGLFWKeycode.GLFW_KEY_5, LWJGLGLFWKeycode.GLFW_KEY_6, - LWJGLGLFWKeycode.GLFW_KEY_7, LWJGLGLFWKeycode.GLFW_KEY_8, LWJGLGLFWKeycode.GLFW_KEY_9}; - /* Last hotbar button (0-9) registered */ - private int lastHotbarKey = -1; - /* Events can start with only a move instead of an pointerDown due to mouse passthrough */ - private boolean shouldBeDown = false; - /* When fingers are really near to each other, it tends to either swap or remove a pointer ! */ - private int lastPointerCount = 0; - /* Previous MotionEvent position, not scale */ - private float prevX, prevY; - /* PointerID used for the moving camera */ - private int currentPointerID = -1000; - /* Initial first pointer positions non-scaled, used to test touch sloppiness */ - private float initialX, initialY; - /* Last first pointer positions non-scaled, used to scroll distance */ - private float scrollLastInitialX, scrollLastInitialY; /* How much distance a finger has to go for touch sloppiness to be disabled */ public static final int FINGER_STILL_THRESHOLD = (int) Tools.dpToPx(9); /* How much distance a finger has to go to scroll */ @@ -81,6 +40,46 @@ public class MinecraftGLView extends TextureView { /* Handle hotbar throw button and mouse mining button */ public static final int MSG_LEFT_MOUSE_BUTTON_CHECK = 1028; public static final int MSG_DROP_ITEM_BUTTON_CHECK = 1029; + + /* Gamepad object for gamepad inputs, instantiated on need */ + private Gamepad mGamepad = null; + /* Pointer Debug textview, used to show info about the pointer state */ + private TextView mPointerDebugTextView; + /* Resolution scaler option, allow downsizing a window */ + private final float mScaleFactor = LauncherPreferences.DEFAULT_PREF.getInt("resolutionRatio",100)/100f; + /* Display properties, such as resolution and DPI */ + private final DisplayMetrics mDisplayMetrics = Tools.getDisplayMetrics((Activity) getContext()); + /* Sensitivity, adjusted according to screen size */ + private final double mSensitivityFactor = (1.4 * (1080f/ mDisplayMetrics.heightPixels)); + /* Use to detect simple and double taps */ + private final TapDetector mSingleTapDetector = new TapDetector(1, TapDetector.DETECTION_METHOD_BOTH); + private final TapDetector mDoubleTapDetector = new TapDetector(2, TapDetector.DETECTION_METHOD_DOWN); + /* MC GUI scale, listened by MCOptionUtils */ + private int mGuiScale = getMcScale(); + private MCOptionUtils.MCOptionListener mGuiScaleListener = () -> mGuiScale = getMcScale(); + /* Surface ready listener, used by the activity to launch minecraft */ + SurfaceReadyListener mSurfaceReadyListener = null; + + /* List of hotbarKeys, used when clicking on the hotbar */ + private static final int[] sHotbarKeys = { + LwjglGlfwKeycode.GLFW_KEY_1, LwjglGlfwKeycode.GLFW_KEY_2, LwjglGlfwKeycode.GLFW_KEY_3, + LwjglGlfwKeycode.GLFW_KEY_4, LwjglGlfwKeycode.GLFW_KEY_5, LwjglGlfwKeycode.GLFW_KEY_6, + LwjglGlfwKeycode.GLFW_KEY_7, LwjglGlfwKeycode.GLFW_KEY_8, LwjglGlfwKeycode.GLFW_KEY_9}; + /* Last hotbar button (0-9) registered */ + private int mLastHotbarKey = -1; + /* Events can start with only a move instead of an pointerDown due to mouse passthrough */ + private boolean mShouldBeDown = false; + /* When fingers are really near to each other, it tends to either swap or remove a pointer ! */ + private int mLastPointerCount = 0; + /* Previous MotionEvent position, not scale */ + private float mPrevX, mPrevY; + /* PointerID used for the moving camera */ + private int mCurrentPointerID = -1000; + /* Initial first pointer positions non-scaled, used to test touch sloppiness */ + private float mInitialX, mInitialY; + /* Last first pointer positions non-scaled, used to scroll distance */ + private float mScrollLastInitialX, mScrollLastInitialY; + /* Handle hotbar throw button and mouse mining button */ private final Handler theHandler = new Handler(Looper.getMainLooper()) { public void handleMessage(Message msg) { if(msg.what == MSG_LEFT_MOUSE_BUTTON_CHECK) { @@ -88,15 +87,15 @@ public class MinecraftGLView extends TextureView { float x = CallbackBridge.mouseX; float y = CallbackBridge.mouseY; if (CallbackBridge.isGrabbing() && - MathUtils.dist(x, y, initialX, initialY) < FINGER_STILL_THRESHOLD) { - triggeredLeftMouseButton = true; - sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, true); + MathUtils.dist(x, y, mInitialX, mInitialY) < FINGER_STILL_THRESHOLD) { + mTriggeredLeftMouseButton = true; + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, true); } return; } if(msg.what == MSG_DROP_ITEM_BUTTON_CHECK) { if(CallbackBridge.isGrabbing()){ - sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_Q); + sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_Q); theHandler.sendEmptyMessageDelayed(MSG_DROP_ITEM_BUTTON_CHECK, 600); } return; @@ -105,7 +104,9 @@ public class MinecraftGLView extends TextureView { } }; /* Whether the button was triggered, used by the handler */ - private static boolean triggeredLeftMouseButton = false; + private boolean mTriggeredLeftMouseButton = false; + /* Whether the pointer debug has failed at some point */ + private boolean debugErrored = false; public MinecraftGLView(Context context) { @@ -119,68 +120,7 @@ public class MinecraftGLView extends TextureView { setOpaque(false); setFocusable(true); - MCOptionUtils.addMCOptionListener(GUIScaleListener); - } - - /** Initialize the view and all its settings */ - public void start(){ - // Add the pointer debug textview - pointerDebugText = new TextView(getContext()); - pointerDebugText.setX(0); - pointerDebugText.setY(0); - pointerDebugText.setVisibility(GONE); - ((ViewGroup)getParent()).addView(pointerDebugText); - - setSurfaceTextureListener(new SurfaceTextureListener() { - private boolean isCalled = false; - @Override - public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) { - windowWidth = Tools.getDisplayFriendlyRes(width, scaleFactor); - windowHeight = Tools.getDisplayFriendlyRes(height, scaleFactor); - texture.setDefaultBufferSize(windowWidth, windowHeight); - - //Load Minecraft options: - MCOptionUtils.load(); - MCOptionUtils.set("overrideWidth", String.valueOf(windowWidth)); - MCOptionUtils.set("overrideHeight", String.valueOf(windowHeight)); - MCOptionUtils.save(); - getMcScale(); - // Should we do that? - if(isCalled) return; - isCalled = true; - - JREUtils.setupBridgeWindow(new Surface(texture)); - - new Thread(() -> { - try { - Thread.sleep(200); - if(surfaceReadyListener != null){ - surfaceReadyListener.isReady(); - } - } catch (Throwable e) { - Tools.showError(getContext(), e, true); - } - }, "JVM Main thread").start(); - } - - @Override - public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) { - return true; - } - - @Override - public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) { - windowWidth = Tools.getDisplayFriendlyRes(width, scaleFactor); - windowHeight = Tools.getDisplayFriendlyRes(height, scaleFactor); - CallbackBridge.sendUpdateWindowSize(windowWidth, windowHeight); - getMcScale(); - } - - @Override - public void onSurfaceTextureUpdated(SurfaceTexture texture) { - texture.setDefaultBufferSize(windowWidth, windowHeight); - } - }); + MCOptionUtils.addMCOptionListener(mGuiScaleListener); } @@ -196,7 +136,7 @@ public class MinecraftGLView extends TextureView { // Mouse found if(CallbackBridge.isGrabbing()) return false; - CallbackBridge.sendCursorPos( e.getX(i) * scaleFactor, e.getY(i) * scaleFactor); + CallbackBridge.sendCursorPos( e.getX(i) * mScaleFactor, e.getY(i) * mScaleFactor); return true; //mouse event handled successfully } @@ -205,17 +145,17 @@ public class MinecraftGLView extends TextureView { //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() * scaleFactor); - CallbackBridge.mouseY = (e.getY() * scaleFactor); + CallbackBridge.mouseX = (e.getX() * mScaleFactor); + CallbackBridge.mouseY = (e.getY() * mScaleFactor); //One android click = one MC click - if(singleTapDetector.onTouchEvent(e)){ - CallbackBridge.putMouseEventWithCoords(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, CallbackBridge.mouseX, CallbackBridge.mouseY); + if(mSingleTapDetector.onTouchEvent(e)){ + CallbackBridge.putMouseEventWithCoords(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, CallbackBridge.mouseX, CallbackBridge.mouseY); return true; } } // Check double tap state, used for the hotbar - boolean hasDoubleTapped = doubleTapDetector.onTouchEvent(e); + boolean hasDoubleTapped = mDoubleTapDetector.onTouchEvent(e); switch (e.getActionMasked()) { case MotionEvent.ACTION_MOVE: @@ -227,46 +167,46 @@ public class MinecraftGLView extends TextureView { // Touch hover if(pointerCount == 1){ CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); - prevX = e.getX(); - prevY = e.getY(); + mPrevX = e.getX(); + mPrevY = e.getY(); break; } // Scrolling feature if(LauncherPreferences.PREF_DISABLE_GESTURES) break; // The pointer count can never be 0, and it is not 1, therefore it is >= 2 - int hScroll = ((int) (e.getX() - scrollLastInitialX)) / FINGER_SCROLL_THRESHOLD; - int vScroll = ((int) (e.getY() - scrollLastInitialY)) / FINGER_SCROLL_THRESHOLD; + int hScroll = ((int) (e.getX() - mScrollLastInitialX)) / FINGER_SCROLL_THRESHOLD; + int vScroll = ((int) (e.getY() - mScrollLastInitialY)) / FINGER_SCROLL_THRESHOLD; if(vScroll != 0 || hScroll != 0){ CallbackBridge.sendScroll(hScroll, vScroll); - scrollLastInitialX = e.getX(); - scrollLastInitialY = e.getY(); + mScrollLastInitialX = e.getX(); + mScrollLastInitialY = e.getY(); } break; } // Camera movement - int pointerIndex = e.findPointerIndex(currentPointerID); + int pointerIndex = e.findPointerIndex(mCurrentPointerID); int hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY()); // Start movement, due to new pointer or loss of pointer - if (pointerIndex == -1 || lastPointerCount != pointerCount || !shouldBeDown) { + if (pointerIndex == -1 || mLastPointerCount != pointerCount || !mShouldBeDown) { if(hudKeyHandled != -1) break; //No pointer attribution on hotbar - shouldBeDown = true; - currentPointerID = e.getPointerId(0); - prevX = e.getX(); - prevY = e.getY(); + mShouldBeDown = true; + mCurrentPointerID = e.getPointerId(0); + mPrevX = e.getX(); + mPrevY = e.getY(); break; } // Continue movement as usual if(hudKeyHandled == -1){ //No camera on hotbar - CallbackBridge.mouseX += (e.getX(pointerIndex) - prevX) * sensitivityFactor; - CallbackBridge.mouseY += (e.getY(pointerIndex) - prevY) * sensitivityFactor; + CallbackBridge.mouseX += (e.getX(pointerIndex) - mPrevX) * mSensitivityFactor; + CallbackBridge.mouseY += (e.getY(pointerIndex) - mPrevY) * mSensitivityFactor; } - prevX = e.getX(pointerIndex); - prevY = e.getY(pointerIndex); + mPrevX = e.getX(pointerIndex); + mPrevY = e.getY(pointerIndex); CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); break; @@ -278,35 +218,35 @@ public class MinecraftGLView extends TextureView { boolean isTouchInHotbar = hudKeyHandled != -1; if (isTouchInHotbar) { sendKeyPress(hudKeyHandled); - if(hasDoubleTapped && hudKeyHandled == lastHotbarKey){ + if(hasDoubleTapped && hudKeyHandled == mLastHotbarKey){ //Prevent double tapping Event on two different slots - sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_F); + sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_F); } theHandler.sendEmptyMessageDelayed(MSG_DROP_ITEM_BUTTON_CHECK, 350); CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); - lastHotbarKey = hudKeyHandled; + mLastHotbarKey = hudKeyHandled; break; } CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); - prevX = e.getX(); - prevY = e.getY(); + mPrevX = e.getX(); + mPrevY = e.getY(); if (CallbackBridge.isGrabbing()) { - currentPointerID = e.getPointerId(0); + mCurrentPointerID = e.getPointerId(0); // It cause hold left mouse while moving camera - initialX = CallbackBridge.mouseX; - initialY = CallbackBridge.mouseY; + mInitialX = CallbackBridge.mouseX; + mInitialY = CallbackBridge.mouseY; theHandler.sendEmptyMessageDelayed(MSG_LEFT_MOUSE_BUTTON_CHECK, LauncherPreferences.PREF_LONGPRESS_TRIGGER); } - lastHotbarKey = hudKeyHandled; + mLastHotbarKey = hudKeyHandled; break; case MotionEvent.ACTION_UP: // 1 case MotionEvent.ACTION_CANCEL: // 3 - shouldBeDown = false; - currentPointerID = -1; + mShouldBeDown = false; + mCurrentPointerID = -1; hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY()); isTouchInHotbar = hudKeyHandled != -1; @@ -315,49 +255,49 @@ public class MinecraftGLView extends TextureView { // Stop the dropping of items if (isTouchInHotbar) { - sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_Q, 0, false); + sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_Q, 0, false); theHandler.removeMessages(MSG_DROP_ITEM_BUTTON_CHECK); break; } // Remove the mouse left button - if(triggeredLeftMouseButton){ - sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, false); - triggeredLeftMouseButton = false; + if(mTriggeredLeftMouseButton){ + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, false); + mTriggeredLeftMouseButton = false; break; } theHandler.removeMessages(MSG_LEFT_MOUSE_BUTTON_CHECK); // In case of a short click, just send a quick right click if(!LauncherPreferences.PREF_DISABLE_GESTURES && - MathUtils.dist(initialX, initialY, CallbackBridge.mouseX, CallbackBridge.mouseY) < FINGER_STILL_THRESHOLD){ - sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT, true); - sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT, false); + MathUtils.dist(mInitialX, mInitialY, CallbackBridge.mouseX, CallbackBridge.mouseY) < FINGER_STILL_THRESHOLD){ + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, true); + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, false); } break; case MotionEvent.ACTION_POINTER_DOWN: // 5 //TODO Hey we could have some sort of middle click detection ? - scrollLastInitialX = e.getX(); - scrollLastInitialY = e.getY(); + mScrollLastInitialX = e.getX(); + mScrollLastInitialY = e.getY(); //Checking if we are pressing the hotbar to select the item hudKeyHandled = handleGuiBar((int)e.getX(e.getPointerCount()-1), (int) e.getY(e.getPointerCount()-1)); if(hudKeyHandled != -1){ sendKeyPress(hudKeyHandled); - if(hasDoubleTapped && hudKeyHandled == lastHotbarKey){ + if(hasDoubleTapped && hudKeyHandled == mLastHotbarKey){ //Prevent double tapping Event on two different slots - sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_F); + sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_F); } } - lastHotbarKey = hudKeyHandled; + mLastHotbarKey = hudKeyHandled; break; } // Actualise the pointer count - lastPointerCount = e.getPointerCount(); + mLastPointerCount = e.getPointerCount(); //debugText.setText(CallbackBridge.DEBUG_STRING.toString()); CallbackBridge.DEBUG_STRING.setLength(0); @@ -374,11 +314,11 @@ public class MinecraftGLView extends TextureView { int mouseCursorIndex = -1; if(Gamepad.isGamepadEvent(event)){ - if(gamepad == null){ - gamepad = new Gamepad(this, event.getDevice()); + if(mGamepad == null){ + mGamepad = new Gamepad(this, event.getDevice()); } - gamepad.update(event); + mGamepad.update(event); return true; } @@ -397,8 +337,8 @@ public class MinecraftGLView extends TextureView { } switch(event.getActionMasked()) { case MotionEvent.ACTION_HOVER_MOVE: - CallbackBridge.mouseX = (event.getX(mouseCursorIndex) * scaleFactor); - CallbackBridge.mouseY = (event.getY(mouseCursorIndex) * scaleFactor); + CallbackBridge.mouseX = (event.getX(mouseCursorIndex) * mScaleFactor); + CallbackBridge.mouseY = (event.getY(mouseCursorIndex) * mScaleFactor); CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); //debugText.setText(CallbackBridge.DEBUG_STRING.toString()); CallbackBridge.DEBUG_STRING.setLength(0); @@ -415,20 +355,20 @@ public class MinecraftGLView extends TextureView { } } - //TODO MOVE THIS SOMEWHERE ELSE - private boolean debugErrored = false; + + /** The input event for mouse with a captured pointer */ @RequiresApi(26) @Override public boolean dispatchCapturedPointerEvent(MotionEvent e) { - CallbackBridge.mouseX += (e.getX()*scaleFactor); - CallbackBridge.mouseY += (e.getY()*scaleFactor); + CallbackBridge.mouseX += (e.getX()* mScaleFactor); + CallbackBridge.mouseY += (e.getY()* mScaleFactor); if(!CallbackBridge.isGrabbing()){ releasePointerCapture(); clearFocus(); } - if (pointerDebugText.getVisibility() == View.VISIBLE && !debugErrored) { + if (mPointerDebugTextView.getVisibility() == View.VISIBLE && !debugErrored) { StringBuilder builder = new StringBuilder(); try { builder.append("PointerCapture debug\n"); @@ -448,12 +388,12 @@ public class MinecraftGLView extends TextureView { debugErrored = true; builder.append("Error getting debug. The debug will be stopped!\n").append(Log.getStackTraceString(th)); } finally { - pointerDebugText.setText(builder.toString()); + mPointerDebugTextView.setText(builder.toString()); builder.setLength(0); } } - pointerDebugText.setText(CallbackBridge.DEBUG_STRING.toString()); + mPointerDebugTextView.setText(CallbackBridge.DEBUG_STRING.toString()); CallbackBridge.DEBUG_STRING.setLength(0); switch (e.getActionMasked()) { case MotionEvent.ACTION_MOVE: @@ -506,7 +446,7 @@ public class MinecraftGLView extends TextureView { if(eventKeycode == KeyEvent.KEYCODE_BACK){ - sendMouseButton(LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT, event.getAction() == KeyEvent.ACTION_DOWN); + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, event.getAction() == KeyEvent.ACTION_DOWN); return true; } } @@ -514,11 +454,11 @@ public class MinecraftGLView extends TextureView { if(Gamepad.isGamepadEvent(event)){ - if(gamepad == null){ - gamepad = new Gamepad(this, event.getDevice()); + if(mGamepad == null){ + mGamepad = new Gamepad(this, event.getDevice()); } - gamepad.update(event); + mGamepad.update(event); return true; } @@ -532,11 +472,66 @@ public class MinecraftGLView extends TextureView { return false; } - /** Get the mouse direction as a string */ - private String getMoving(float pos, boolean xOrY) { - if (pos == 0) return "STOPPED"; - if (pos > 0) return xOrY ? "RIGHT" : "DOWN"; - return xOrY ? "LEFT" : "UP"; + + /** Initialize the view and all its settings */ + public void start(){ + // Add the pointer debug textview + mPointerDebugTextView = new TextView(getContext()); + mPointerDebugTextView.setX(0); + mPointerDebugTextView.setY(0); + mPointerDebugTextView.setVisibility(GONE); + ((ViewGroup)getParent()).addView(mPointerDebugTextView); + + setSurfaceTextureListener(new SurfaceTextureListener() { + private boolean isCalled = false; + @Override + public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) { + windowWidth = Tools.getDisplayFriendlyRes(width, mScaleFactor); + windowHeight = Tools.getDisplayFriendlyRes(height, mScaleFactor); + texture.setDefaultBufferSize(windowWidth, windowHeight); + + //Load Minecraft options: + MCOptionUtils.load(); + MCOptionUtils.set("overrideWidth", String.valueOf(windowWidth)); + MCOptionUtils.set("overrideHeight", String.valueOf(windowHeight)); + MCOptionUtils.save(); + getMcScale(); + // Should we do that? + if(isCalled) return; + isCalled = true; + + JREUtils.setupBridgeWindow(new Surface(texture)); + + new Thread(() -> { + try { + Thread.sleep(200); + if(mSurfaceReadyListener != null){ + mSurfaceReadyListener.isReady(); + } + } catch (Throwable e) { + Tools.showError(getContext(), e, true); + } + }, "JVM Main thread").start(); + } + + @Override + public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) { + return true; + } + + @Override + public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) { + windowWidth = Tools.getDisplayFriendlyRes(width, mScaleFactor); + windowHeight = Tools.getDisplayFriendlyRes(height, mScaleFactor); + CallbackBridge.sendUpdateWindowSize(windowWidth, windowHeight); + getMcScale(); + } + + @Override + public void onSurfaceTextureUpdated(SurfaceTexture texture) { + texture.setDefaultBufferSize(windowWidth, windowHeight); + } + }); } /** Convert the mouse button, then send it @@ -546,13 +541,13 @@ public class MinecraftGLView extends TextureView { int glfwButton = -256; switch (button) { case MotionEvent.BUTTON_PRIMARY: - glfwButton = LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT; + glfwButton = LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT; break; case MotionEvent.BUTTON_TERTIARY: - glfwButton = LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_MIDDLE; + glfwButton = LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_MIDDLE; break; case MotionEvent.BUTTON_SECONDARY: - glfwButton = LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT; + glfwButton = LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT; break; } if(glfwButton == -256) return false; @@ -560,8 +555,6 @@ public class MinecraftGLView extends TextureView { return true; } - - /** @return the hotbar key, given the position. -1 if no key are pressed */ public int handleGuiBar(int x, int y) { if (!CallbackBridge.isGrabbing()) return -1; @@ -574,17 +567,12 @@ public class MinecraftGLView extends TextureView { int barX = (CallbackBridge.physicalWidth / 2) - (barWidth / 2); if(x < barX || x >= barX + barWidth) return -1; - return hotbarKeys[(int) net.kdt.pojavlaunch.utils.MathUtils.map(x, barX, barX + barWidth, 0, 9)]; - } - - /** Return the size, given the UI scale size */ - private int mcscale(int input) { - return (int)((GUIScale * input)/scaleFactor); + return sHotbarKeys[(int) net.kdt.pojavlaunch.utils.MathUtils.map(x, barX, barX + barWidth, 0, 9)]; } /** Toggle the pointerDebugText visibility state */ public void togglepointerDebugging() { - pointerDebugText.setVisibility(pointerDebugText.getVisibility() == View.GONE ? View.VISIBLE : View.GONE); + mPointerDebugTextView.setVisibility(mPointerDebugTextView.getVisibility() == View.GONE ? View.VISIBLE : View.GONE); } /** A small interface called when the listener is ready for the first time */ @@ -593,6 +581,19 @@ public class MinecraftGLView extends TextureView { } public void setSurfaceReadyListener(SurfaceReadyListener listener){ - surfaceReadyListener = listener; + mSurfaceReadyListener = listener; + } + + + /** Return the size, given the UI scale size */ + private int mcscale(int input) { + return (int)((mGuiScale * input)/ mScaleFactor); + } + + /** Get the mouse direction as a string */ + private String getMoving(float pos, boolean xOrY) { + if (pos == 0) return "STOPPED"; + if (pos > 0) return xOrY ? "RIGHT" : "DOWN"; + return xOrY ? "LEFT" : "UP"; } } From cc26e7fa23a4a0a5bd16749e759ce76a47594dd9 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 16:05:52 +0100 Subject: [PATCH 40/70] Update ImportControlActivity.java --- .../main/java/net/kdt/pojavlaunch/ImportControlActivity.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ImportControlActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ImportControlActivity.java index 16afb9246..e1ae0ad5d 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ImportControlActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ImportControlActivity.java @@ -185,12 +185,10 @@ public class ImportControlActivity extends Activity { String jsonLayoutData = Tools.read(Tools.CTRLMAP_PATH + "/TMP_IMPORT_FILE.json"); JSONObject layoutJobj = new JSONObject(jsonLayoutData); return layoutJobj.has("version") && layoutJobj.has("mControlDataList"); - }catch (JSONException | IOException e) { e.printStackTrace(); return false; } - } public String getNameFromURI(Uri uri) { From 924d3a8b2033c99508f1422e4cea5814ab9e31da Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 16:07:59 +0100 Subject: [PATCH 41/70] Refactor CustomControlsActivity.java --- .../pojavlaunch/CustomControlsActivity.java | 160 ++++++++---------- 1 file changed, 68 insertions(+), 92 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomControlsActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomControlsActivity.java index 92795cd21..1dba07e59 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomControlsActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomControlsActivity.java @@ -5,13 +5,13 @@ import android.content.*; import android.os.*; import androidx.appcompat.app.*; -import androidx.preference.*; -import android.view.*; + import android.widget.*; import androidx.drawerlayout.widget.DrawerLayout; import com.google.android.material.navigation.NavigationView; +import com.google.gson.JsonSyntaxException; import com.kdt.pickafile.*; import java.io.*; @@ -19,18 +19,13 @@ import net.kdt.pojavlaunch.prefs.*; import net.kdt.pojavlaunch.customcontrols.*; - -public class CustomControlsActivity extends BaseActivity -{ - private DrawerLayout drawerLayout; - private NavigationView navDrawer; - private ControlLayout ctrlLayout; - - private SharedPreferences mPref; +public class CustomControlsActivity extends BaseActivity { + private DrawerLayout mDrawerLayout; + private NavigationView mDrawerNavigationView; + private ControlLayout mControlLayout; public boolean isModified = false; - public boolean isFromMainActivity = false; - private static String selectedName = "new_control"; + private static String sSelectedName = "new_control"; @Override protected void onCreate(Bundle savedInstanceState) { @@ -42,47 +37,40 @@ public class CustomControlsActivity extends BaseActivity } setContentView(R.layout.control_mapping); - - mPref = PreferenceManager.getDefaultSharedPreferences(this); - ctrlLayout = (ControlLayout) findViewById(R.id.customctrl_controllayout); + mControlLayout = (ControlLayout) findViewById(R.id.customctrl_controllayout); + mDrawerLayout = (DrawerLayout) findViewById(R.id.customctrl_drawerlayout); + mDrawerNavigationView = (NavigationView) findViewById(R.id.customctrl_navigation_view); - // Menu - drawerLayout = (DrawerLayout) findViewById(R.id.customctrl_drawerlayout); - - navDrawer = (NavigationView) findViewById(R.id.customctrl_navigation_view); - navDrawer.setNavigationItemSelectedListener( - new NavigationView.OnNavigationItemSelectedListener() { - @Override - public boolean onNavigationItemSelected(MenuItem menuItem) { + mDrawerNavigationView.setNavigationItemSelectedListener( + menuItem -> { switch (menuItem.getItemId()) { case R.id.menu_ctrl_load: - load(ctrlLayout); + load(mControlLayout); break; case R.id.menu_ctrl_add: - ctrlLayout.addControlButton(new ControlData("New")); + mControlLayout.addControlButton(new ControlData("New")); break; case R.id.menu_ctrl_add_drawer: - ctrlLayout.addDrawer(new ControlDrawerData()); + mControlLayout.addDrawer(new ControlDrawerData()); break; case R.id.menu_ctrl_selectdefault: - dialogSelectDefaultCtrl(ctrlLayout); + dialogSelectDefaultCtrl(mControlLayout); break; case R.id.menu_ctrl_save: - save(false,ctrlLayout); + save(false, mControlLayout); break; } //Toast.makeText(MainActivity.this, menuItem.getTitle() + ":" + menuItem.getItemId(), Toast.LENGTH_SHORT).show(); - drawerLayout.closeDrawers(); + mDrawerLayout.closeDrawers(); return true; - } - }); + }); - ctrlLayout.setActivity(this); - ctrlLayout.setModifiable(true); + mControlLayout.setActivity(this); + mControlLayout.setModifiable(true); - loadControl(LauncherPreferences.PREF_DEFAULTCTRL_PATH,ctrlLayout); + loadControl(LauncherPreferences.PREF_DEFAULTCTRL_PATH, mControlLayout); } @Override @@ -93,18 +81,7 @@ public class CustomControlsActivity extends BaseActivity return; } - save(true,ctrlLayout); - } - - private static void setDefaultControlJson(String path,ControlLayout ctrlLayout) { - try { - // Load before save to make sure control is not error - ctrlLayout.loadLayout(Tools.GLOBAL_GSON.fromJson(Tools.read(path), CustomControls.class)); - LauncherPreferences.DEFAULT_PREF.edit().putString("defaultCtrl", path).commit(); - LauncherPreferences.PREF_DEFAULTCTRL_PATH = path; - } catch (Throwable th) { - Tools.showError(ctrlLayout.getContext(), th); - } + save(true, mControlLayout); } public static void dialogSelectDefaultCtrl(final ControlLayout layout) { @@ -127,18 +104,12 @@ public class CustomControlsActivity extends BaseActivity dialog.show(); } - private static String doSaveCtrl(String name, final ControlLayout layout) throws Exception { - String jsonPath = Tools.CTRLMAP_PATH + "/" + name + ".json"; - layout.saveLayout(jsonPath); - - return jsonPath; - } public static void save(final boolean exit, final ControlLayout layout) { final Context ctx = layout.getContext(); final EditText edit = new EditText(ctx); edit.setSingleLine(); - edit.setText(selectedName); + edit.setText(sSelectedName); AlertDialog.Builder builder = new AlertDialog.Builder(ctx); builder.setTitle(R.string.global_save); @@ -162,51 +133,38 @@ public class CustomControlsActivity extends BaseActivity }); } final AlertDialog dialog = builder.create(); - dialog.setOnShowListener(new DialogInterface.OnShowListener() { + dialog.setOnShowListener(dialogInterface -> { - @Override - public void onShow(DialogInterface dialogInterface) { - - Button button = dialog.getButton(AlertDialog.BUTTON_POSITIVE); - button.setOnClickListener(new View.OnClickListener() { - - @Override - public void onClick(View view) { - if (edit.getText().toString().isEmpty()) { - edit.setError(ctx.getResources().getString(R.string.global_error_field_empty)); - } else { - try { - String jsonPath = doSaveCtrl(edit.getText().toString(),layout); - - Toast.makeText(ctx, ctx.getString(R.string.global_save) + ": " + jsonPath, Toast.LENGTH_SHORT).show(); - - dialog.dismiss(); - if (exit) { - if(ctx instanceof MainActivity) { - ((MainActivity) ctx).leaveCustomControls(); - }else{ - ((Activity)ctx).onBackPressed(); - } - //CustomControlsActivity.super.onBackPressed(); - } - } catch (Throwable th) { - Tools.showError(ctx, th, exit); - } - } - } - }); + Button button = dialog.getButton(AlertDialog.BUTTON_POSITIVE); + button.setOnClickListener(view -> { + if (edit.getText().toString().isEmpty()) { + edit.setError(ctx.getResources().getString(R.string.global_error_field_empty)); + return; } + + try { + String jsonPath = doSaveCtrl(edit.getText().toString(),layout); + Toast.makeText(ctx, ctx.getString(R.string.global_save) + ": " + jsonPath, Toast.LENGTH_SHORT).show(); + + dialog.dismiss(); + if (!exit) return; + + if(ctx instanceof MainActivity) { + ((MainActivity) ctx).leaveCustomControls(); + }else{ + ((Activity)ctx).onBackPressed(); + } + } catch (Throwable th) { + Tools.showError(ctx, th, exit); + } + }); + }); dialog.show(); } public static void load(final ControlLayout layout) { - /*ControlJsonSelector sel = new ControlJsonSelector(layout.getContext(), R.string.global_load); - sel.setFinishCallback((f)->{ - loadControl(f.getAbsolutePath(),layout); - }); - sel.show();*/ AlertDialog.Builder builder = new AlertDialog.Builder(layout.getContext()); builder.setTitle(R.string.global_load); builder.setPositiveButton(android.R.string.cancel, null); @@ -227,12 +185,30 @@ public class CustomControlsActivity extends BaseActivity dialog.show(); } + private static void setDefaultControlJson(String path,ControlLayout ctrlLayout) { + // Load before save to make sure control is not error + try { + ctrlLayout.loadLayout(Tools.GLOBAL_GSON.fromJson(Tools.read(path), CustomControls.class)); + LauncherPreferences.DEFAULT_PREF.edit().putString("defaultCtrl", path).apply(); + LauncherPreferences.PREF_DEFAULTCTRL_PATH = path; + } catch (IOException| JsonSyntaxException exception) { + Tools.showError(ctrlLayout.getContext(), exception); + } + } + + private static String doSaveCtrl(String name, final ControlLayout layout) throws Exception { + String jsonPath = Tools.CTRLMAP_PATH + "/" + name + ".json"; + layout.saveLayout(jsonPath); + + return jsonPath; + } + private static void loadControl(String path,ControlLayout layout) { try { layout.loadLayout(path); - selectedName = new File(path).getName(); + sSelectedName = new File(path).getName(); // Remove `.json` - selectedName = selectedName.substring(0, selectedName.length() - 5); + sSelectedName = sSelectedName.substring(0, sSelectedName.length() - 5); } catch (Exception e) { Tools.showError(layout.getContext(), e); } From 0625ce60d7117922a36d12fad35433fe13ebb92e Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 16:08:12 +0100 Subject: [PATCH 42/70] Update PojavLoginActivity.java --- .../src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java index 4366ae75c..30d060bac 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java @@ -69,9 +69,7 @@ import java.io.InputStreamReader; import java.util.Arrays; import java.util.Locale; -public class PojavLoginActivity extends BaseActivity -// MineActivity -{ +public class PojavLoginActivity extends BaseActivity { private final Object mLockStoragePerm = new Object(); private final Object mLockSelectJRE = new Object(); From b9c4723fee52ffe1355298bfde0a15aa2c3f9290 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 16:08:37 +0100 Subject: [PATCH 43/70] Refactor JAssets.java --- .../src/main/java/net/kdt/pojavlaunch/JAssets.java | 2 +- .../net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JAssets.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JAssets.java index d05c4bce7..684bd6bcc 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JAssets.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JAssets.java @@ -3,7 +3,7 @@ package net.kdt.pojavlaunch; import java.util.Map; public class JAssets { - public boolean map_to_resources; + public boolean mapToResources; public Map objects; } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java index 0a35f60e9..41aa16824 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java @@ -256,7 +256,7 @@ public class MinecraftDownloaderTask extends AsyncTask{ try { - if (!assets.map_to_resources) { + if (!assets.mapToResources) { downloadAsset(asset, objectsDir, downloadedSize); } else { downloadAssetMapped(asset, assetKey, outputDir, downloadedSize); From fa690f99a6ee1b96a9b477c6f5b97c91235a0730 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 17:34:39 +0100 Subject: [PATCH 44/70] Refactor LoggerView.java --- .../src/main/java/com/kdt/LoggerView.java | 53 ++++++++++--------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/app_pojavlauncher/src/main/java/com/kdt/LoggerView.java b/app_pojavlauncher/src/main/java/com/kdt/LoggerView.java index 7df8a4ad0..98b91f8ca 100644 --- a/app_pojavlauncher/src/main/java/com/kdt/LoggerView.java +++ b/app_pojavlauncher/src/main/java/com/kdt/LoggerView.java @@ -21,10 +21,10 @@ import net.kdt.pojavlaunch.R; * It has support for the Logger class */ public class LoggerView extends ConstraintLayout { - private Logger.eventLogListener logListener; - private ToggleButton toggleButton; - private ScrollView scrollView; - private TextView log; + private Logger.eventLogListener mLogListener; + private ToggleButton mToggleButton; + private ScrollView mScrollView; + private TextView mLogTextView; public LoggerView(@NonNull Context context) { @@ -36,50 +36,51 @@ public class LoggerView extends ConstraintLayout { init(); } + @Override + public void setVisibility(int visibility) { + super.setVisibility(visibility); + // Triggers the log view shown state by default when viewing it + mToggleButton.setChecked(visibility == VISIBLE); + } + /** * Inflate the layout, and add component behaviors */ private void init(){ inflate(getContext(), R.layout.loggerview_layout, this); - log = findViewById(R.id.content_log_view); - log.setTypeface(Typeface.MONOSPACE); + mLogTextView = findViewById(R.id.content_log_view); + mLogTextView.setTypeface(Typeface.MONOSPACE); //TODO clamp the max text so it doesn't go oob - log.setMaxLines(Integer.MAX_VALUE); - log.setEllipsize(null); - log.setVisibility(GONE); + mLogTextView.setMaxLines(Integer.MAX_VALUE); + mLogTextView.setEllipsize(null); + mLogTextView.setVisibility(GONE); // Toggle log visibility - toggleButton = findViewById(R.id.content_log_toggle_log); - toggleButton.setOnCheckedChangeListener( + mToggleButton = findViewById(R.id.content_log_toggle_log); + mToggleButton.setOnCheckedChangeListener( (compoundButton, isChecked) -> { - log.setVisibility(isChecked ? VISIBLE : GONE); - if(!isChecked) log.setText(""); + mLogTextView.setVisibility(isChecked ? VISIBLE : GONE); + if(!isChecked) mLogTextView.setText(""); }); - toggleButton.setChecked(false); + mToggleButton.setChecked(false); // Remove the loggerView from the user View ImageButton cancelButton = findViewById(R.id.log_view_cancel); cancelButton.setOnClickListener(view -> LoggerView.this.setVisibility(GONE)); // Set the scroll view - scrollView = findViewById(R.id.content_log_scroll); + mScrollView = findViewById(R.id.content_log_scroll); // Listen to logs - logListener = text -> { - if(log.getVisibility() != VISIBLE) return; + mLogListener = text -> { + if(mLogTextView.getVisibility() != VISIBLE) return; post(() -> { - log.append(text + '\n'); - scrollView.fullScroll(View.FOCUS_DOWN); + mLogTextView.append(text + '\n'); + mScrollView.fullScroll(View.FOCUS_DOWN); }); }; - Logger.getInstance().setLogListener(logListener); + Logger.getInstance().setLogListener(mLogListener); } - @Override - public void setVisibility(int visibility) { - super.setVisibility(visibility); - // Triggers the log view shown state by default when viewing it - toggleButton.setChecked(visibility == VISIBLE); - } } From f0326fec5a18b67aa384680bfe2319bfd1099571 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 17:34:58 +0100 Subject: [PATCH 45/70] Refactor DefocusableScrollView.java --- .../java/com/kdt/DefocusableScrollView.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/app_pojavlauncher/src/main/java/com/kdt/DefocusableScrollView.java b/app_pojavlauncher/src/main/java/com/kdt/DefocusableScrollView.java index 9bbde79b4..049a46b98 100644 --- a/app_pojavlauncher/src/main/java/com/kdt/DefocusableScrollView.java +++ b/app_pojavlauncher/src/main/java/com/kdt/DefocusableScrollView.java @@ -5,15 +5,15 @@ import android.graphics.Rect; import android.util.AttributeSet; import android.widget.ScrollView; +/** + Class allowing to ignore the focusing from an item such an EditText within it. + Ignoring it will stop the scrollView from refocusing on the view +*/ public class DefocusableScrollView extends ScrollView { - /* - What is this class for ? - It allows to ignore the focusing from an item such an EditText. - Ignoring it will stop the scrollView from refocusing on the view - */ - private boolean keepFocusing = false; + + private boolean mKeepFocusing = false; public DefocusableScrollView(Context context) { @@ -33,16 +33,16 @@ public class DefocusableScrollView extends ScrollView { } public void setKeepFocusing(boolean shouldKeepFocusing){ - keepFocusing = shouldKeepFocusing; + mKeepFocusing = shouldKeepFocusing; } public boolean isKeepFocusing(){ - return keepFocusing; + return mKeepFocusing; } @Override protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) { - if(!keepFocusing) return 0; + if(!mKeepFocusing) return 0; return super.computeScrollDeltaToGetChildRectOnScreen(rect); } From c0fc623c344871b83a1691b8c86fb039ddd249ee Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 17:35:02 +0100 Subject: [PATCH 46/70] Update MineButton.java --- app_pojavlauncher/src/main/java/com/kdt/mcgui/MineButton.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app_pojavlauncher/src/main/java/com/kdt/mcgui/MineButton.java b/app_pojavlauncher/src/main/java/com/kdt/mcgui/MineButton.java index d5cbc7042..6b17cd7a1 100644 --- a/app_pojavlauncher/src/main/java/com/kdt/mcgui/MineButton.java +++ b/app_pojavlauncher/src/main/java/com/kdt/mcgui/MineButton.java @@ -8,8 +8,7 @@ import androidx.core.content.res.ResourcesCompat; import net.kdt.pojavlaunch.R; -public class MineButton extends androidx.appcompat.widget.AppCompatButton -{ +public class MineButton extends androidx.appcompat.widget.AppCompatButton { public MineButton(Context ctx) { this(ctx, null); From 0205acb35794e24b751377b52b836e9cedad08b2 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 17:35:09 +0100 Subject: [PATCH 47/70] Update MineEditText.java --- .../src/main/java/com/kdt/mcgui/MineEditText.java | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/app_pojavlauncher/src/main/java/com/kdt/mcgui/MineEditText.java b/app_pojavlauncher/src/main/java/com/kdt/mcgui/MineEditText.java index 47e83cc9d..61315f928 100644 --- a/app_pojavlauncher/src/main/java/com/kdt/mcgui/MineEditText.java +++ b/app_pojavlauncher/src/main/java/com/kdt/mcgui/MineEditText.java @@ -4,22 +4,18 @@ import android.content.*; import android.util.*; import android.graphics.*; -public class MineEditText extends com.google.android.material.textfield.TextInputEditText -{ - public MineEditText(Context ctx) - { +public class MineEditText extends com.google.android.material.textfield.TextInputEditText { + public MineEditText(Context ctx) { super(ctx); init(); } - public MineEditText(Context ctx, AttributeSet attrs) - { + public MineEditText(Context ctx, AttributeSet attrs) { super(ctx, attrs); init(); } - public void init() - { + public void init() { setBackgroundColor(Color.parseColor("#131313")); setPadding(5, 5, 5, 5); } From 2bab1ada09d1cb5e770de7603ad17d899fb2d55d Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 17:35:21 +0100 Subject: [PATCH 48/70] Update PojavMigrator.java --- .../src/main/java/net/kdt/pojavlaunch/PojavMigrator.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavMigrator.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavMigrator.java index 825f4a49c..ed4082e7b 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavMigrator.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavMigrator.java @@ -6,8 +6,7 @@ import net.kdt.pojavlaunch.value.*; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; -public class PojavMigrator -{ +public class PojavMigrator { public static void migrateAccountData(Context ctx) { File oldAccDir = new File(Tools.DIR_ACCOUNT_OLD); if (oldAccDir.exists() && oldAccDir.isDirectory()) { From 90d1bde4e60df4ef38a36d16c762a89f30459591 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 17:35:33 +0100 Subject: [PATCH 49/70] Refactor TapDetector.java --- .../java/net/kdt/pojavlaunch/TapDetector.java | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/TapDetector.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/TapDetector.java index 9aaeeeeca..a76dd6d95 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/TapDetector.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/TapDetector.java @@ -22,10 +22,10 @@ public class TapDetector { private final static int TAP_MAX_DELTA_MS = 300; private final static int TAP_SLOP_SQUARE_PX = (int) Math.pow(Tools.dpToPx(100), 2); - private final int tapNumberToDetect; - private int currentTapNumber = 0; + private final int mTapNumberToDetect; + private int mCurrentTapNumber = 0; - private final int detectionMethod; + private final int mDetectionMethod; private long mLastEventTime = 0; private float mLastX = 9999; @@ -36,9 +36,9 @@ public class TapDetector { * @param detectionMethod Method used to detect touches. See DETECTION_METHOD constants above. */ public TapDetector(int tapNumberToDetect, int detectionMethod){ - this.detectionMethod = detectionMethod; + this.mDetectionMethod = detectionMethod; //We expect both ACTION_DOWN and ACTION_UP for the DETECTION_METHOD_BOTH - this.tapNumberToDetect = detectBothTouch() ? 2*tapNumberToDetect : tapNumberToDetect; + this.mTapNumberToDetect = detectBothTouch() ? 2*tapNumberToDetect : tapNumberToDetect; } /** @@ -78,17 +78,17 @@ public class TapDetector { mLastY = eventY; //Check for high enough speed and precision - if(currentTapNumber > 0){ + if(mCurrentTapNumber > 0){ if ((deltaTime < TAP_MIN_DELTA_MS || deltaTime > TAP_MAX_DELTA_MS) || ((deltaX*deltaX + deltaY*deltaY) > TAP_SLOP_SQUARE_PX)) { // We invalidate previous taps, not this one though - currentTapNumber = 0; + mCurrentTapNumber = 0; } } //A worthy tap happened - currentTapNumber += 1; - if(currentTapNumber >= tapNumberToDetect){ + mCurrentTapNumber += 1; + if(mCurrentTapNumber >= mTapNumberToDetect){ resetTapDetectionState(); return true; } @@ -101,22 +101,21 @@ public class TapDetector { * Reset the double tap values. */ private void resetTapDetectionState(){ - currentTapNumber = 0; + mCurrentTapNumber = 0; mLastEventTime = 0; mLastX = 9999; mLastY = 9999; } - private boolean detectDownTouch(){ - return (detectionMethod & DETECTION_METHOD_DOWN) == DETECTION_METHOD_DOWN; + return (mDetectionMethod & DETECTION_METHOD_DOWN) == DETECTION_METHOD_DOWN; } private boolean detectUpTouch(){ - return (detectionMethod & DETECTION_METHOD_UP) == DETECTION_METHOD_UP; + return (mDetectionMethod & DETECTION_METHOD_UP) == DETECTION_METHOD_UP; } private boolean detectBothTouch(){ - return detectionMethod == DETECTION_METHOD_BOTH; + return mDetectionMethod == DETECTION_METHOD_BOTH; } } From ed68aca2a320cf1060a486d722d8ed1018d09ddb Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 17:35:51 +0100 Subject: [PATCH 50/70] Refactor Tools.java --- .../main/java/net/kdt/pojavlaunch/Tools.java | 155 +++++------------- 1 file changed, 39 insertions(+), 116 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java index cff1aa87c..ad69b5707 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -435,42 +435,37 @@ public final class Tools { private static void showError(final Context ctx, final int titleId, final Throwable e, final boolean exitIfOk, final boolean showMore) { e.printStackTrace(); - Runnable runnable = new Runnable(){ - - @Override - public void run() - { - final String errMsg = showMore ? Log.getStackTraceString(e): e.getMessage(); - AlertDialog.Builder builder = new AlertDialog.Builder((Context) ctx) - .setTitle(titleId) - .setMessage(errMsg) - .setPositiveButton(android.R.string.ok, (DialogInterface.OnClickListener) (p1, p2) -> { - if(exitIfOk) { - if (ctx instanceof BaseMainActivity) { - BaseMainActivity.fullyExit(); - } else if (ctx instanceof Activity) { - ((Activity) ctx).finish(); - } + Runnable runnable = () -> { + final String errMsg = showMore ? Log.getStackTraceString(e): e.getMessage(); + AlertDialog.Builder builder = new AlertDialog.Builder((Context) ctx) + .setTitle(titleId) + .setMessage(errMsg) + .setPositiveButton(android.R.string.ok, (DialogInterface.OnClickListener) (p1, p2) -> { + if(exitIfOk) { + if (ctx instanceof BaseMainActivity) { + BaseMainActivity.fullyExit(); + } else if (ctx instanceof Activity) { + ((Activity) ctx).finish(); } - }) - .setNegativeButton(showMore ? R.string.error_show_less : R.string.error_show_more, (DialogInterface.OnClickListener) (p1, p2) -> showError(ctx, titleId, e, exitIfOk, !showMore)) - .setNeutralButton(android.R.string.copy, (DialogInterface.OnClickListener) (p1, p2) -> { - ClipboardManager mgr = (ClipboardManager) ctx.getSystemService(Context.CLIPBOARD_SERVICE); - mgr.setPrimaryClip(ClipData.newPlainText("error", Log.getStackTraceString(e))); - if(exitIfOk) { - if (ctx instanceof BaseMainActivity) { - BaseMainActivity.fullyExit(); - } else { - ((Activity) ctx).finish(); - } + } + }) + .setNegativeButton(showMore ? R.string.error_show_less : R.string.error_show_more, (DialogInterface.OnClickListener) (p1, p2) -> showError(ctx, titleId, e, exitIfOk, !showMore)) + .setNeutralButton(android.R.string.copy, (DialogInterface.OnClickListener) (p1, p2) -> { + ClipboardManager mgr = (ClipboardManager) ctx.getSystemService(Context.CLIPBOARD_SERVICE); + mgr.setPrimaryClip(ClipData.newPlainText("error", Log.getStackTraceString(e))); + if(exitIfOk) { + if (ctx instanceof BaseMainActivity) { + BaseMainActivity.fullyExit(); + } else { + ((Activity) ctx).finish(); } - }) - .setCancelable(!exitIfOk); - try { - builder.show(); - } catch (Throwable th) { - th.printStackTrace(); - } + } + }) + .setCancelable(!exitIfOk); + try { + builder.show(); + } catch (Throwable th) { + th.printStackTrace(); } }; @@ -481,8 +476,8 @@ public final class Tools { } } - public static void dialogOnUiThread(final Activity ctx, final CharSequence title, final CharSequence message) { - ctx.runOnUiThread(() -> new AlertDialog.Builder(ctx) + public static void dialogOnUiThread(final Activity activity, final CharSequence title, final CharSequence message) { + activity.runOnUiThread(() -> new AlertDialog.Builder(activity) .setTitle(title) .setMessage(message) .setPositiveButton(android.R.string.ok, null) @@ -650,23 +645,19 @@ public final class Tools { } public static String convertStream(InputStream inputStream, Charset charset) throws IOException { - String out = ""; + StringBuilder out = new StringBuilder(); int len; byte[] buf = new byte[512]; while((len = inputStream.read(buf))!=-1) { - out += new String(buf,0,len,charset); + out.append(new String(buf, 0, len, charset)); } - return out; + return out.toString(); } public static File lastFileModified(String dir) { File fl = new File(dir); - File[] files = fl.listFiles(new FileFilter() { - public boolean accept(File file) { - return file.isFile(); - } - }); + File[] files = fl.listFiles(File::isFile); long lastMod = Long.MIN_VALUE; File choice = null; @@ -682,13 +673,13 @@ public final class Tools { public static String read(InputStream is) throws IOException { - String out = ""; + StringBuilder out = new StringBuilder(); int len; byte[] buf = new byte[512]; while((len = is.read(buf))!=-1) { - out += new String(buf,0,len); + out.append(new String(buf, 0, len)); } - return out; + return out.toString(); } public static String read(String path) throws IOException { @@ -734,6 +725,7 @@ public final class Tools { public abstract static class DownloaderFeedback { public abstract void updateProgress(int curr, int max); } + public static void downloadFileMonitored(String urlInput,String nameOutput, DownloaderFeedback monitor) throws IOException { File nameOutputFile = new File(nameOutput); if (!nameOutputFile.exists()) { @@ -770,75 +762,6 @@ public final class Tools { return true; } } - public static class ZipTool - { - private ZipTool(){} - public static void zip(List files, File zipFile) throws IOException { - final int BUFFER_SIZE = 2048; - - BufferedInputStream origin = null; - ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile))); - - try { - byte data[] = new byte[BUFFER_SIZE]; - - for (File file : files) { - FileInputStream fileInputStream = new FileInputStream( file ); - - origin = new BufferedInputStream(fileInputStream, BUFFER_SIZE); - - try { - ZipEntry entry = new ZipEntry(file.getName()); - - out.putNextEntry(entry); - - int count; - while ((count = origin.read(data, 0, BUFFER_SIZE)) != -1) { - out.write(data, 0, count); - } - } - finally { - origin.close(); - } - } - } finally { - out.close(); - } - } - public static void unzip(File zipFile, File targetDirectory) throws IOException { - final int BUFFER_SIZE = 1024; - ZipInputStream zis = new ZipInputStream( - new BufferedInputStream(new FileInputStream(zipFile))); - try { - ZipEntry ze; - int count; - byte[] buffer = new byte[BUFFER_SIZE]; - while ((ze = zis.getNextEntry()) != null) { - File file = new File(targetDirectory, ze.getName()); - File dir = ze.isDirectory() ? file : file.getParentFile(); - if (!dir.isDirectory() && !dir.mkdirs()) - throw new FileNotFoundException("Failed to ensure directory: " + - dir.getAbsolutePath()); - if (ze.isDirectory()) - continue; - FileOutputStream fout = new FileOutputStream(file); - try { - while ((count = zis.read(buffer)) != -1) - fout.write(buffer, 0, count); - } finally { - fout.close(); - } - /* if time should be restored as well - long time = ze.getTime(); - if (time > 0) - file.setLastModified(time); - */ - } - } finally { - zis.close(); - } - } - } public static void ignoreNotch(boolean shouldIgnore, Activity ctx){ if (SDK_INT >= P) { From 22b45a152363fd260ae1103c0b2bbc22bbee16d6 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 17:36:03 +0100 Subject: [PATCH 51/70] Refactor TouchCharInput.java --- .../customcontrols/TouchCharInput.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/TouchCharInput.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/TouchCharInput.java index 52ca3a83c..890148363 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/TouchCharInput.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/TouchCharInput.java @@ -36,7 +36,7 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText } - private boolean isDoingInternalChanges = false; + private boolean mIsDoingInternalChanges = false; /** * We take the new chars, and send them to the game. @@ -46,9 +46,9 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText @Override protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { super.onTextChanged(text, start, lengthBefore, lengthAfter); - if(isDoingInternalChanges)return; + if(mIsDoingInternalChanges)return; - for(int i=0; i< lengthBefore; ++i){ + for(int i=0; i < lengthBefore; ++i){ CallbackBridge.sendKeycode(LwjglGlfwKeycode.GLFW_KEY_BACKSPACE, '\u0008', 0, 0, true); } for(int i=start, count = 0; count < lengthAfter; ++i){ @@ -113,20 +113,12 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText */ @SuppressLint("SetTextI18n") public void clear(){ - isDoingInternalChanges = true; + mIsDoingInternalChanges = true; //Braille space, doesn't trigger keyboard auto-complete //replacing directly the text without though setText avoids notifying changes setText(" "); setSelection(getText().length()); - isDoingInternalChanges = false; - } - - /** - * Send the enter key. - */ - private void sendEnter(){ - sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_ENTER); - clear(); + mIsDoingInternalChanges = false; } /** @@ -150,6 +142,13 @@ public class TouchCharInput extends androidx.appcompat.widget.AppCompatEditText setEnabled(false); } + /** + * Send the enter key. + */ + private void sendEnter(){ + sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_ENTER); + clear(); + } /** * This function deals with anything that has to be executed when the constructor is called From c68e205e4eb49476e625251a5129e5b8fb03e623 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 17:36:10 +0100 Subject: [PATCH 52/70] Update SingleTapConfirm.java --- .../src/main/java/net/kdt/pojavlaunch/SingleTapConfirm.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/SingleTapConfirm.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/SingleTapConfirm.java index bd82eb77f..ebfb922bc 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/SingleTapConfirm.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/SingleTapConfirm.java @@ -3,8 +3,7 @@ package net.kdt.pojavlaunch; import android.view.*; import android.view.GestureDetector.*; -public class SingleTapConfirm extends SimpleOnGestureListener -{ +public class SingleTapConfirm extends SimpleOnGestureListener { @Override public boolean onSingleTapUp(MotionEvent event) { return true; From 1a708dad7ee05f48d7b93bfa1d036701e9eac081 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 17:36:53 +0100 Subject: [PATCH 53/70] Refactor MCOptionUtils.java --- .../kdt/pojavlaunch/utils/MCOptionUtils.java | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/MCOptionUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/MCOptionUtils.java index 353f5343f..51114b68d 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/MCOptionUtils.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/MCOptionUtils.java @@ -20,22 +20,21 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; -public class MCOptionUtils -{ - private static final HashMap parameterMap = new HashMap<>(); - private static final ArrayList> optionListeners = new ArrayList<>(); - private static FileObserver fileObserver; +public class MCOptionUtils { + private static final HashMap sParameterMap = new HashMap<>(); + private static final ArrayList> sOptionListeners = new ArrayList<>(); + private static FileObserver sFileObserver; public interface MCOptionListener { /** Called when an option is changed. Don't know which one though */ void onOptionChanged(); } public static void load() { - if(fileObserver == null){ + if(sFileObserver == null){ setupFileObserver(); } - parameterMap.clear(); + sParameterMap.clear(); try { BufferedReader reader = new BufferedReader(new FileReader(Tools.DIR_GAME_NEW + "/options.txt")); @@ -46,7 +45,7 @@ public class MCOptionUtils Log.w(Tools.APP_NAME, "No colon on line \""+line+"\", skipping"); continue; } - parameterMap.put(line.substring(0,firstColonIndex), line.substring(firstColonIndex+1)); + sParameterMap.put(line.substring(0,firstColonIndex), line.substring(firstColonIndex+1)); } reader.close(); } catch (IOException e) { @@ -55,16 +54,16 @@ public class MCOptionUtils } public static void set(String key, String value) { - parameterMap.put(key,value); + sParameterMap.put(key,value); } /** Set an array of String, instead of a simple value. Not supported on all options */ public static void set(String key, List values){ - parameterMap.put(key, values.toString()); + sParameterMap.put(key, values.toString()); } public static String get(String key){ - return parameterMap.get(key); + return sParameterMap.get(key); } /** @return A list of values from an array stored as a string */ @@ -83,10 +82,10 @@ public class MCOptionUtils public static void save() { StringBuilder result = new StringBuilder(); - for(String key : parameterMap.keySet()) + for(String key : sParameterMap.keySet()) result.append(key) .append(':') - .append(parameterMap.get(key)) + .append(sParameterMap.get(key)) .append('\n'); try { @@ -114,7 +113,7 @@ public class MCOptionUtils * Listeners get notified of the change */ private static void setupFileObserver(){ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){ - fileObserver = new FileObserver(new File(Tools.DIR_GAME_NEW + "/options.txt"), FileObserver.MODIFY) { + sFileObserver = new FileObserver(new File(Tools.DIR_GAME_NEW + "/options.txt"), FileObserver.MODIFY) { @Override public void onEvent(int i, @Nullable String s) { MCOptionUtils.load(); @@ -122,7 +121,7 @@ public class MCOptionUtils } }; }else{ - fileObserver = new FileObserver(Tools.DIR_GAME_NEW + "/options.txt", FileObserver.MODIFY) { + sFileObserver = new FileObserver(Tools.DIR_GAME_NEW + "/options.txt", FileObserver.MODIFY) { @Override public void onEvent(int i, @Nullable String s) { MCOptionUtils.load(); @@ -131,12 +130,12 @@ public class MCOptionUtils }; } - fileObserver.startWatching(); + sFileObserver.startWatching(); } /** Notify the option listeners */ public static void notifyListeners(){ - for(WeakReference weakReference : optionListeners){ + for(WeakReference weakReference : sOptionListeners){ MCOptionListener optionListener = weakReference.get(); if(optionListener == null) continue; @@ -146,16 +145,16 @@ public class MCOptionUtils /** Add an option listener, notice how we don't have a reference to it */ public static void addMCOptionListener(MCOptionListener listener){ - optionListeners.add(new WeakReference<>(listener)); + sOptionListeners.add(new WeakReference<>(listener)); } /** Remove a listener from existence, or at least, its reference here */ public static void removeMCOptionListener(MCOptionListener listener){ - for(WeakReference weakReference : optionListeners){ + for(WeakReference weakReference : sOptionListeners){ MCOptionListener optionListener = weakReference.get(); if(optionListener == null) continue; if(optionListener == listener){ - optionListeners.remove(weakReference); + sOptionListeners.remove(weakReference); return; } } From cfaefef96e264dee7e6c6c545885f5458b2275a1 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 17:38:13 +0100 Subject: [PATCH 54/70] Refactor PojavProfile.java --- .../net/kdt/pojavlaunch/PojavProfile.java | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java index 8a6c1b339..d1a6709a9 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java @@ -12,10 +12,9 @@ import net.kdt.pojavlaunch.authenticator.mojang.RefreshListener; import net.kdt.pojavlaunch.authenticator.mojang.RefreshTokenTask; import net.kdt.pojavlaunch.value.MinecraftAccount; -public class PojavProfile -{ - private static String PROFILE_PREF = "pojav_profile"; - private static String PROFILE_PREF_FILE = "file"; +public class PojavProfile { + private static final String PROFILE_PREF = "pojav_profile"; + private static final String PROFILE_PREF_FILE = "file"; public static String PROFILE_PREF_TEMP_CONTENT = "tempContent"; public static SharedPreferences getPrefs(Context ctx) { @@ -33,26 +32,26 @@ public class PojavProfile public static MinecraftAccount getTempProfileContent() { try { - MinecraftAccount acc = MinecraftAccount.parse(Tools.read(Tools.DIR_DATA+"/cache/tempacc.json")); - if (acc.accessToken == null) { - acc.accessToken = "0"; + MinecraftAccount account = MinecraftAccount.parse(Tools.read(Tools.DIR_DATA+"/cache/tempacc.json")); + if (account.accessToken == null) { + account.accessToken = "0"; } - if (acc.clientToken == null) { - acc.clientToken = "0"; + if (account.clientToken == null) { + account.clientToken = "0"; } - if (acc.profileId == null) { - acc.profileId = "00000000-0000-0000-0000-000000000000"; + if (account.profileId == null) { + account.profileId = "00000000-0000-0000-0000-000000000000"; } - if (acc.username == null) { - acc.username = "0"; + if (account.username == null) { + account.username = "0"; } - if (acc.selectedVersion == null) { - acc.selectedVersion = "1.7.10"; + if (account.selectedVersion == null) { + account.selectedVersion = "1.7.10"; } - if (acc.msaRefreshToken == null) { - acc.msaRefreshToken = "0"; + if (account.msaRefreshToken == null) { + account.msaRefreshToken = "0"; } - return acc; + return account; }catch (IOException e) { Log.e(MinecraftAccount.class.getName(), "Caught an exception while loading the temporary profile",e); return null; From 150feccb83ccdc7632374d71ab2052e16f156421 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 17:39:04 +0100 Subject: [PATCH 55/70] Refactor JREUtils.java --- .../net/kdt/pojavlaunch/BaseMainActivity.java | 2 +- .../pojavlaunch/JavaGUILauncherActivity.java | 2 +- .../net/kdt/pojavlaunch/utils/JREUtils.java | 58 ++++++++----------- 3 files changed, 26 insertions(+), 36 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java index 816f364d6..be39a141a 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java @@ -204,7 +204,7 @@ public class BaseMainActivity extends BaseActivity { ((mVersionInfo.inheritsFrom == null || mVersionInfo.inheritsFrom.equals(mVersionInfo.id)) ? "" : " (" + mVersionInfo.inheritsFrom + ")")); - JREUtils.redirectAndPrintJRELog(this); + JREUtils.redirectAndPrintJRELog(); Tools.launchMinecraft(this, mProfile, mProfile.selectedVersion); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java index 1d648bea2..16fb5727d 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java @@ -238,7 +238,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc } public int launchJavaRuntime(File modFile, String javaArgs) { - JREUtils.redirectAndPrintJRELog(this); + JREUtils.redirectAndPrintJRELog(); try { List javaArgList = new ArrayList(); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java index d5f9e0c2c..21d2e69d0 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java @@ -1,7 +1,6 @@ package net.kdt.pojavlaunch.utils; import static net.kdt.pojavlaunch.Architecture.ARCH_X86; -import static net.kdt.pojavlaunch.Architecture.archAsString; import static net.kdt.pojavlaunch.Architecture.is64BitsDevice; import static net.kdt.pojavlaunch.Tools.LOCAL_RENDERER; import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_GLES_SHRINK_HACK; @@ -15,7 +14,6 @@ import android.system.*; import android.util.*; import android.widget.Toast; -import com.kdt.LoggerView; import com.oracle.dalvik.*; import java.io.*; import java.util.*; @@ -32,21 +30,20 @@ public class JREUtils { private JREUtils() {} public static String LD_LIBRARY_PATH; - private static String nativeLibDir; public static Map jreReleaseList; + public static String jvmLibraryPath; + private static String sNativeLibDir; public static String findInLdLibPath(String libName) { if(Os.getenv("LD_LIBRARY_PATH")==null) { try { if (LD_LIBRARY_PATH != null) { Os.setenv("LD_LIBRARY_PATH", LD_LIBRARY_PATH, true); - }else{ - return libName; } }catch (ErrnoException e) { e.printStackTrace(); - return libName; } + return libName; } for (String libPath : Os.getenv("LD_LIBRARY_PATH").split(":")) { File f = new File(libPath, libName); @@ -56,18 +53,22 @@ public class JREUtils { } return libName; } + public static ArrayList locateLibs(File path) { - ArrayList ret = new ArrayList<>(); + ArrayList returnValue = new ArrayList<>(); File[] list = path.listFiles(); - if(list != null) {for(File f : list) { - if(f.isFile() && f.getName().endsWith(".so")) { - ret.add(f); - }else if(f.isDirectory()) { - ret.addAll(locateLibs(f)); + if(list != null) { + for(File f : list) { + if(f.isFile() && f.getName().endsWith(".so")) { + returnValue.add(f); + }else if(f.isDirectory()) { + returnValue.addAll(locateLibs(f)); + } } - }} - return ret; + } + return returnValue; } + public static void initJavaRuntime() { dlopen(findInLdLibPath("libjli.so")); if(!dlopen("libjvm.so")){ @@ -86,13 +87,13 @@ public class JREUtils { for(File f : locateLibs(new File(Tools.DIR_HOME_JRE + "/" + Tools.DIRNAME_HOME_JRE))) { dlopen(f.getAbsolutePath()); } - dlopen(nativeLibDir + "/libopenal.so"); - + dlopen(sNativeLibDir + "/libopenal.so"); } public static Map readJREReleaseProperties() throws IOException { return readJREReleaseProperties(Tools.DIR_HOME_JRE); } + public static Map readJREReleaseProperties(String name) throws IOException { Map jreReleaseMap = new ArrayMap<>(); if (!name.contains("/")) { @@ -109,11 +110,11 @@ public class JREUtils { jreReleaseReader.close(); return jreReleaseMap; } - public static String jvmLibraryPath; - public static void redirectAndPrintJRELog(final Context ctx) { + + public static void redirectAndPrintJRELog() { Log.v("jrelog","Log starts here"); JREUtils.logToLogger(Logger.getInstance()); - Thread t = new Thread(new Runnable(){ + new Thread(new Runnable(){ int failTime = 0; ProcessBuilder logcatPb; @Override @@ -128,16 +129,6 @@ public class JREUtils { Log.i("jrelog-logcat","Starting logcat"); java.lang.Process p = logcatPb.start(); - // idk which better, both have a bug that printf(\n) in a single line - /* - BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); - String line; - while ((line = reader.readLine()) != null) { - act.appendlnToLog(line); - } - reader.close(); - */ - byte[] buf = new byte[1024]; int len; while ((len = p.getInputStream().read(buf)) != -1) { @@ -161,8 +152,7 @@ public class JREUtils { Logger.getInstance().appendToLog("Exception on logging thread:\n" + Log.getStackTraceString(e)); } } - }); - t.start(); + }).start(); Log.i("jrelog-logcat","Logcat thread started"); } @@ -172,7 +162,7 @@ public class JREUtils { JRE_ARCHITECTURE = "i386/i486/i586"; } - nativeLibDir = ctx.getApplicationInfo().nativeLibraryDir; + sNativeLibDir = ctx.getApplicationInfo().nativeLibraryDir; for (String arch : JRE_ARCHITECTURE.split("/")) { File f = new File(Tools.DIR_HOME_JRE, "lib/" + arch); @@ -191,7 +181,7 @@ public class JREUtils { "/system/" + libName + ":" + "/vendor/" + libName + ":" + "/vendor/" + libName + "/hw:" + - nativeLibDir + sNativeLibDir ); LD_LIBRARY_PATH = ldLibraryPath.toString(); } @@ -461,7 +451,7 @@ public class JREUtils { Log.e("RENDER_LIBRARY","Failed to load renderer " + renderLibrary + ". Falling back to GL4ES 1.1.4"); LOCAL_RENDERER = "opengles2"; renderLibrary = "libgl4es_114.so"; - dlopen(nativeLibDir + "/libgl4es_114.so"); + dlopen(sNativeLibDir + "/libgl4es_114.so"); } return renderLibrary; } From 8c62cef47b6a594b83977e1850540f947d9c4ffe Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 17:39:21 +0100 Subject: [PATCH 56/70] Refactor V117CompatUtil.java --- .../kdt/pojavlaunch/utils/V117CompatUtil.java | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/V117CompatUtil.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/V117CompatUtil.java index 8efb35cd0..f5bdc9587 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/V117CompatUtil.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/V117CompatUtil.java @@ -92,15 +92,17 @@ public class V117CompatUtil { Log.i("V117CompatDebug",rawList); return new ArrayList<>(Arrays.asList(rawList.split(","))); } + private static String regenPackList(List packs) { if(packs.size()==0) return "[]"; - String ret = "["+packs.get(0); + StringBuilder ret = new StringBuilder("[" + packs.get(0)); for(int i = 1; i < packs.size(); i++) { - ret += ","+packs.get(i); + ret.append(",").append(packs.get(i)); } - ret += "]"; - return ret; + ret.append("]"); + return ret.toString(); } + public static void runCheck(String version, Activity ctx) throws Exception{ PerVersionConfig.VersionConfig cfg = PerVersionConfig.configMap.get(version); @@ -115,25 +117,25 @@ public class V117CompatUtil { Object lock = new Object(); AtomicInteger proceed = new AtomicInteger(0); ctx.runOnUiThread(() -> { - AlertDialog.Builder bldr = new AlertDialog.Builder(ctx); - bldr.setTitle(R.string.global_warinng); - bldr.setMessage(R.string.compat_117_message); - bldr.setPositiveButton(android.R.string.ok, (dialog, which) -> { + AlertDialog.Builder builder = new AlertDialog.Builder(ctx); + builder.setTitle(R.string.global_warinng); + builder.setMessage(R.string.compat_117_message); + builder.setPositiveButton(android.R.string.ok, (dialog, which) -> { proceed.set(1); synchronized (lock) { lock.notifyAll(); } dialog.dismiss(); }); - bldr.setNegativeButton(android.R.string.cancel, (dialog, which) -> { + builder.setNegativeButton(android.R.string.cancel, (dialog, which) -> { synchronized (lock) { lock.notifyAll(); } dialog.dismiss(); }); - bldr.setNeutralButton(R.string.compat_11x_playanyway, (dialog, which) -> { + builder.setNeutralButton(R.string.compat_11x_playanyway, (dialog, which) -> { proceed.set(2); synchronized (lock) { lock.notifyAll(); } dialog.dismiss(); }); - bldr.setCancelable(false); - bldr.show(); + builder.setCancelable(false); + builder.show(); }); synchronized (lock) { @@ -158,6 +160,7 @@ public class V117CompatUtil { throw new MinecraftDownloaderTask.SilentException(); } } + public static void copyResourcePack(String gameDir, AssetManager am) throws IOException { File resourcepacksDir = new File(gameDir,"resourcepacks"); if(!resourcepacksDir.exists()) resourcepacksDir.mkdirs(); From 8f0e1ab3615494933c3dc6d343330eaeddc385a1 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 18:06:40 +0100 Subject: [PATCH 57/70] Refactor gamepad related files --- .../customcontrols/gamepad/Gamepad.java | 433 +++++++++--------- .../customcontrols/gamepad/GamepadButton.java | 28 +- .../customcontrols/gamepad/GamepadDpad.java | 13 +- .../gamepad/GamepadJoystick.java | 47 +- 4 files changed, 259 insertions(+), 262 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java index c7aa5dcd0..e0ab49553 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java @@ -40,60 +40,60 @@ import static org.lwjgl.glfw.CallbackBridge.sendMouseButton; public class Gamepad { /* Resolution scaler option, allow downsizing a window */ - private final float scaleFactor = LauncherPreferences.DEFAULT_PREF.getInt("resolutionRatio",100)/100f; + private final float mScaleFactor = LauncherPreferences.DEFAULT_PREF.getInt("resolutionRatio",100)/100f; /* Mouse positions, scaled by the scaleFactor */ - private float mouse_x, mouse_y; + private float mMouse_x, mMouse_y; /* Sensitivity, adjusted according to screen size */ - private final double sensitivityFactor = (1.4 * (1080f/ currentDisplayMetrics.heightPixels)); + private final double mSensitivityFactor = (1.4 * (1080f/ currentDisplayMetrics.heightPixels)); - private final ImageView pointerView; + private final ImageView mPointerImageView; - private final GamepadDpad gamepadDpad = new GamepadDpad(); + private final GamepadDpad mGamepadDpad = new GamepadDpad(); - private final GamepadJoystick leftJoystick; - private int currentJoystickDirection = DIRECTION_NONE; + private final GamepadJoystick mLeftJoystick; + private int mCurrentJoystickDirection = DIRECTION_NONE; - private final GamepadJoystick rightJoystick; - private float lastHorizontalValue = 0.0f; - private float lastVerticalValue = 0.0f; + private final GamepadJoystick mRightJoystick; + private float mLastHorizontalValue = 0.0f; + private float mLastVerticalValue = 0.0f; - private final double mouseMaxAcceleration = 2f; + private final double MOUSE_MAX_ACCELERATION = 2f; - private double mouseMagnitude; - private double mouseAngle; - private double mouseSensitivity = 19; + private double mMouseMagnitude; + private double mMouseAngle; + private double mMouseSensitivity = 19; - private final GamepadMap gameMap = GamepadMap.getDefaultGameMap(); - private final GamepadMap menuMap = GamepadMap.getDefaultMenuMap(); - private GamepadMap currentMap = gameMap; + private final GamepadMap mGameMap = GamepadMap.getDefaultGameMap(); + private final GamepadMap mMenuMap = GamepadMap.getDefaultMenuMap(); + private GamepadMap mCurrentMap = mGameMap; - private boolean lastGrabbingState = true; + private boolean mLastGrabbingState = true; //private final boolean mModifierDigitalTriggers; private final boolean mModifierAnalogTriggers; private boolean mModifierSwappedAxis = true; //Triggers and right stick axis are swapped. /* Choreographer with time to compute delta on ticking */ - private final Choreographer screenChoreographer; - private long lastFrameTime; + private final Choreographer mScreenChoreographer; + private long mLastFrameTime; /* Listen for change in gui scale */ - private MCOptionUtils.MCOptionListener GUIScaleListener = () -> notifyGUISizeChange(getMcScale()); + private MCOptionUtils.MCOptionListener mGuiScaleListener = () -> notifyGUISizeChange(getMcScale()); public Gamepad(View contextView, InputDevice inputDevice){ - screenChoreographer = Choreographer.getInstance(); + mScreenChoreographer = Choreographer.getInstance(); Choreographer.FrameCallback frameCallback = new Choreographer.FrameCallback() { @Override public void doFrame(long frameTimeNanos) { updateGrabbingState(); tick(frameTimeNanos); - screenChoreographer.postFrameCallback(this); + mScreenChoreographer.postFrameCallback(this); } }; - screenChoreographer.postFrameCallback(frameCallback); - lastFrameTime = System.nanoTime(); + mScreenChoreographer.postFrameCallback(frameCallback); + mLastFrameTime = System.nanoTime(); /* Add the listener for the cross hair */ - MCOptionUtils.addMCOptionListener(GUIScaleListener); + MCOptionUtils.addMCOptionListener(mGuiScaleListener); Toast.makeText(contextView.getContext(),"GAMEPAD CREATED", Toast.LENGTH_LONG).show(); for(InputDevice.MotionRange range : inputDevice.getMotionRanges()){ @@ -106,98 +106,31 @@ public class Gamepad { } } - leftJoystick = new GamepadJoystick(MotionEvent.AXIS_X, MotionEvent.AXIS_Y, inputDevice); + mLeftJoystick = new GamepadJoystick(MotionEvent.AXIS_X, MotionEvent.AXIS_Y, inputDevice); if(!mModifierSwappedAxis) - rightJoystick = new GamepadJoystick(MotionEvent.AXIS_Z, MotionEvent.AXIS_RZ, inputDevice); + mRightJoystick = new GamepadJoystick(MotionEvent.AXIS_Z, MotionEvent.AXIS_RZ, inputDevice); else - rightJoystick = new GamepadJoystick(MotionEvent.AXIS_RX, MotionEvent.AXIS_RY, inputDevice); + mRightJoystick = new GamepadJoystick(MotionEvent.AXIS_RX, MotionEvent.AXIS_RY, inputDevice); //mModifierDigitalTriggers = inputDevice.hasKeys(KeyEvent.KEYCODE_BUTTON_R2)[0]; mModifierAnalogTriggers = supportAnalogTriggers(inputDevice); Context ctx = contextView.getContext(); - pointerView = new ImageView(contextView.getContext()); - pointerView.setImageDrawable(ResourcesCompat.getDrawable(ctx.getResources(), R.drawable.pointer, ctx.getTheme())); - pointerView.getDrawable().setFilterBitmap(false); + mPointerImageView = new ImageView(contextView.getContext()); + mPointerImageView.setImageDrawable(ResourcesCompat.getDrawable(ctx.getResources(), R.drawable.pointer, ctx.getTheme())); + mPointerImageView.getDrawable().setFilterBitmap(false); - int size = (int) ((22 * getMcScale()) / scaleFactor); - pointerView.setLayoutParams(new FrameLayout.LayoutParams(size, size)); + int size = (int) ((22 * getMcScale()) / mScaleFactor); + mPointerImageView.setLayoutParams(new FrameLayout.LayoutParams(size, size)); - mouse_x = CallbackBridge.windowWidth/2; - mouse_y = CallbackBridge.windowHeight/2; - CallbackBridge.sendCursorPos(mouse_x, mouse_y); + mMouse_x = CallbackBridge.windowWidth/2; + mMouse_y = CallbackBridge.windowHeight/2; + CallbackBridge.sendCursorPos(mMouse_x, mMouse_y); placePointerView(CallbackBridge.physicalWidth/2, CallbackBridge.physicalHeight/2); - ((ViewGroup)contextView.getParent()).addView(pointerView); + ((ViewGroup)contextView.getParent()).addView(mPointerImageView); } - /** - * Send the new mouse position, computing the delta - * @param frameTimeNanos The time to render the frame, used to compute mouse delta - */ - public void tick(long frameTimeNanos){ - //update mouse position - if(lastHorizontalValue != 0 || lastVerticalValue != 0){ - GamepadJoystick currentJoystick = lastGrabbingState ? leftJoystick : rightJoystick; - - double acceleration = (mouseMagnitude - currentJoystick.getDeadzone()) / (1 - currentJoystick.getDeadzone()); - acceleration = Math.pow(acceleration, mouseMaxAcceleration); - if(acceleration > 1) acceleration = 1; - - // Compute delta since last tick time - float deltaX = (float) (Math.cos(mouseAngle) * acceleration * mouseSensitivity); - float deltaY = (float) (Math.sin(mouseAngle) * acceleration * mouseSensitivity); - float deltaTimeScale = ((frameTimeNanos - lastFrameTime) / 16666666f); // Scale of 1 = 60Hz - deltaX *= deltaTimeScale; - deltaY *= deltaTimeScale; - - CallbackBridge.mouseX += deltaX; - CallbackBridge.mouseY -= deltaY; - - if(!lastGrabbingState){ - CallbackBridge.mouseX = MathUtils.clamp(CallbackBridge.mouseX, 0, CallbackBridge.windowWidth); - CallbackBridge.mouseY = MathUtils.clamp(CallbackBridge.mouseY, 0, CallbackBridge.windowHeight); - placePointerView((int) (CallbackBridge.mouseX / scaleFactor), (int) (CallbackBridge.mouseY/ scaleFactor)); - } - - mouse_x = CallbackBridge.mouseX; - mouse_y = CallbackBridge.mouseY; - - //Send the mouse to the game - CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); - } - - // Update last nano time - lastFrameTime = frameTimeNanos; - } - - /** Update the grabbing state, and change the currentMap, mouse position and sensibility */ - private void updateGrabbingState() { - boolean lastGrabbingValue = lastGrabbingState; - lastGrabbingState = CallbackBridge.isGrabbing(); - if(lastGrabbingValue == lastGrabbingState) return; - - // Switch grabbing state then - currentMap.resetPressedState(); - if(lastGrabbingState){ - currentMap = gameMap; - pointerView.setVisibility(View.INVISIBLE); - mouseSensitivity = 18; - return; - } - - currentMap = menuMap; - sendDirectionalKeycode(currentJoystickDirection, false, gameMap); // removing what we were doing - - mouse_x = CallbackBridge.windowWidth/2; - mouse_y = CallbackBridge.windowHeight/2; - CallbackBridge.sendCursorPos(mouse_x, mouse_y); - placePointerView(CallbackBridge.physicalWidth/2, CallbackBridge.physicalHeight/2); - pointerView.setVisibility(View.VISIBLE); - // Sensitivity in menu is MC and HARDWARE resolution dependent - mouseSensitivity = 19 * scaleFactor / sensitivityFactor; - - } public void update(KeyEvent event){ sendButton(event); @@ -208,125 +141,17 @@ public class Gamepad { updateMouseJoystick(event); updateAnalogTriggers(event); - int[] dpadEvent = gamepadDpad.convertEvent(event); + int[] dpadEvent = mGamepadDpad.convertEvent(event); sendButton(dpadEvent[0], dpadEvent[1]); } - private void updateMouseJoystick(MotionEvent event){ - GamepadJoystick currentJoystick = lastGrabbingState ? rightJoystick : leftJoystick; - float horizontalValue = currentJoystick.getHorizontalAxis(event); - float verticalValue = currentJoystick.getVerticalAxis(event); - if(horizontalValue != lastHorizontalValue || verticalValue != lastVerticalValue){ - lastHorizontalValue = horizontalValue; - lastVerticalValue = verticalValue; - - mouseMagnitude = currentJoystick.getMagnitude(event); - mouseAngle = currentJoystick.getAngleRadian(event); - - tick(System.nanoTime()); - return; - } - lastHorizontalValue = horizontalValue; - lastVerticalValue = verticalValue; - - mouseMagnitude = currentJoystick.getMagnitude(event); - mouseAngle = currentJoystick.getAngleRadian(event); - - } - - private void updateDirectionalJoystick(MotionEvent event){ - GamepadJoystick currentJoystick = lastGrabbingState ? leftJoystick : rightJoystick; - - int lastJoystickDirection = currentJoystickDirection; - currentJoystickDirection = currentJoystick.getHeightDirection(event); - - if(currentJoystickDirection == lastJoystickDirection) return; - - sendDirectionalKeycode(lastJoystickDirection, false, getCurrentMap()); - sendDirectionalKeycode(currentJoystickDirection, true, getCurrentMap()); - } - - private void updateAnalogTriggers(MotionEvent event){ - if(mModifierAnalogTriggers){ - getCurrentMap().TRIGGER_LEFT.update( - (event.getAxisValue(MotionEvent.AXIS_LTRIGGER) > 0.5) - || (event.getAxisValue(MotionEvent.AXIS_BRAKE) > 0.5) - || (mModifierSwappedAxis &&(event.getAxisValue(MotionEvent.AXIS_Z) > 0.5)) ); - getCurrentMap().TRIGGER_RIGHT.update( - (event.getAxisValue( MotionEvent.AXIS_RTRIGGER) > 0.5) - || (event.getAxisValue(MotionEvent.AXIS_GAS) > 0.5) - || (mModifierSwappedAxis && event.getAxisValue(MotionEvent.AXIS_RZ) > 0.5) ); - } - } - public void notifyGUISizeChange(int newSize){ //Change the pointer size to match UI - int size = (int) ((22 * newSize) / scaleFactor); - pointerView.post(() -> pointerView.setLayoutParams(new FrameLayout.LayoutParams(size, size))); + int size = (int) ((22 * newSize) / mScaleFactor); + mPointerImageView.post(() -> mPointerImageView.setLayoutParams(new FrameLayout.LayoutParams(size, size))); } - /** - * Detect if a gamepad supports analog triggers - * @param inputDevice The input device with all the MotionRange - * @return Whether the gamepad supports analog triggers - */ - private boolean supportAnalogTriggers(InputDevice inputDevice){ - for(InputDevice.MotionRange motionRange : inputDevice.getMotionRanges()){ - int axis = motionRange.getAxis(); - - if( axis == MotionEvent.AXIS_BRAKE || axis == MotionEvent.AXIS_GAS || - axis == MotionEvent.AXIS_LTRIGGER || axis == MotionEvent.AXIS_RTRIGGER || - (mModifierSwappedAxis && axis == MotionEvent.AXIS_Z) || - (mModifierSwappedAxis && axis == MotionEvent.AXIS_RZ)){ - return true; - } - } - return false; - } - - private GamepadMap getCurrentMap(){ - return currentMap; - } - - private static void sendDirectionalKeycode(int direction, boolean isDown, GamepadMap map){ - switch (direction){ - case DIRECTION_NORTH: - sendInput(map.DIRECTION_FORWARD, isDown); - break; - case DIRECTION_NORTH_EAST: - sendInput(map.DIRECTION_FORWARD, isDown); - sendInput(map.DIRECTION_RIGHT, isDown); - break; - case DIRECTION_EAST: - sendInput(map.DIRECTION_RIGHT, isDown); - break; - case DIRECTION_SOUTH_EAST: - sendInput(map.DIRECTION_RIGHT, isDown); - sendInput(map.DIRECTION_BACKWARD, isDown); - break; - case DIRECTION_SOUTH: - sendInput(map.DIRECTION_BACKWARD, isDown); - break; - case DIRECTION_SOUTH_WEST: - sendInput(map.DIRECTION_BACKWARD, isDown); - sendInput(map.DIRECTION_LEFT, isDown); - break; - case DIRECTION_WEST: - sendInput(map.DIRECTION_LEFT, isDown); - break; - case DIRECTION_NORTH_WEST: - sendInput(map.DIRECTION_FORWARD, isDown); - sendInput(map.DIRECTION_LEFT, isDown); - break; - } - } - - private void placePointerView(int x, int y){ - pointerView.setX(x - pointerView.getWidth()/2); - pointerView.setY(y - pointerView.getHeight()/2); - } - public void sendButton(KeyEvent event){ sendButton(event.getKeyCode(), event.getAction()); } @@ -443,4 +268,180 @@ public class Gamepad { return ((event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD || GamepadDpad.isDpadEvent(event) ); } + + /** + * Send the new mouse position, computing the delta + * @param frameTimeNanos The time to render the frame, used to compute mouse delta + */ + private void tick(long frameTimeNanos){ + //update mouse position + if(mLastHorizontalValue != 0 || mLastVerticalValue != 0){ + GamepadJoystick currentJoystick = mLastGrabbingState ? mLeftJoystick : mRightJoystick; + + double acceleration = (mMouseMagnitude - currentJoystick.getDeadzone()) / (1 - currentJoystick.getDeadzone()); + acceleration = Math.pow(acceleration, MOUSE_MAX_ACCELERATION); + if(acceleration > 1) acceleration = 1; + + // Compute delta since last tick time + float deltaX = (float) (Math.cos(mMouseAngle) * acceleration * mMouseSensitivity); + float deltaY = (float) (Math.sin(mMouseAngle) * acceleration * mMouseSensitivity); + float deltaTimeScale = ((frameTimeNanos - mLastFrameTime) / 16666666f); // Scale of 1 = 60Hz + deltaX *= deltaTimeScale; + deltaY *= deltaTimeScale; + + CallbackBridge.mouseX += deltaX; + CallbackBridge.mouseY -= deltaY; + + if(!mLastGrabbingState){ + CallbackBridge.mouseX = MathUtils.clamp(CallbackBridge.mouseX, 0, CallbackBridge.windowWidth); + CallbackBridge.mouseY = MathUtils.clamp(CallbackBridge.mouseY, 0, CallbackBridge.windowHeight); + placePointerView((int) (CallbackBridge.mouseX / mScaleFactor), (int) (CallbackBridge.mouseY/ mScaleFactor)); + } + + mMouse_x = CallbackBridge.mouseX; + mMouse_y = CallbackBridge.mouseY; + + //Send the mouse to the game + CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); + } + + // Update last nano time + mLastFrameTime = frameTimeNanos; + } + + /** Update the grabbing state, and change the currentMap, mouse position and sensibility */ + private void updateGrabbingState() { + boolean lastGrabbingValue = mLastGrabbingState; + mLastGrabbingState = CallbackBridge.isGrabbing(); + if(lastGrabbingValue == mLastGrabbingState) return; + + // Switch grabbing state then + mCurrentMap.resetPressedState(); + if(mLastGrabbingState){ + mCurrentMap = mGameMap; + mPointerImageView.setVisibility(View.INVISIBLE); + mMouseSensitivity = 18; + return; + } + + mCurrentMap = mMenuMap; + sendDirectionalKeycode(mCurrentJoystickDirection, false, mGameMap); // removing what we were doing + + mMouse_x = CallbackBridge.windowWidth/2; + mMouse_y = CallbackBridge.windowHeight/2; + CallbackBridge.sendCursorPos(mMouse_x, mMouse_y); + placePointerView(CallbackBridge.physicalWidth/2, CallbackBridge.physicalHeight/2); + mPointerImageView.setVisibility(View.VISIBLE); + // Sensitivity in menu is MC and HARDWARE resolution dependent + mMouseSensitivity = 19 * mScaleFactor / mSensitivityFactor; + + } + + private void updateMouseJoystick(MotionEvent event){ + GamepadJoystick currentJoystick = mLastGrabbingState ? mRightJoystick : mLeftJoystick; + float horizontalValue = currentJoystick.getHorizontalAxis(event); + float verticalValue = currentJoystick.getVerticalAxis(event); + if(horizontalValue != mLastHorizontalValue || verticalValue != mLastVerticalValue){ + mLastHorizontalValue = horizontalValue; + mLastVerticalValue = verticalValue; + + mMouseMagnitude = currentJoystick.getMagnitude(event); + mMouseAngle = currentJoystick.getAngleRadian(event); + + tick(System.nanoTime()); + return; + } + mLastHorizontalValue = horizontalValue; + mLastVerticalValue = verticalValue; + + mMouseMagnitude = currentJoystick.getMagnitude(event); + mMouseAngle = currentJoystick.getAngleRadian(event); + + } + + private void updateDirectionalJoystick(MotionEvent event){ + GamepadJoystick currentJoystick = mLastGrabbingState ? mLeftJoystick : mRightJoystick; + + int lastJoystickDirection = mCurrentJoystickDirection; + mCurrentJoystickDirection = currentJoystick.getHeightDirection(event); + + if(mCurrentJoystickDirection == lastJoystickDirection) return; + + sendDirectionalKeycode(lastJoystickDirection, false, getCurrentMap()); + sendDirectionalKeycode(mCurrentJoystickDirection, true, getCurrentMap()); + } + + private void updateAnalogTriggers(MotionEvent event){ + if(mModifierAnalogTriggers){ + getCurrentMap().TRIGGER_LEFT.update( + (event.getAxisValue(MotionEvent.AXIS_LTRIGGER) > 0.5) + || (event.getAxisValue(MotionEvent.AXIS_BRAKE) > 0.5) + || (mModifierSwappedAxis &&(event.getAxisValue(MotionEvent.AXIS_Z) > 0.5)) ); + getCurrentMap().TRIGGER_RIGHT.update( + (event.getAxisValue( MotionEvent.AXIS_RTRIGGER) > 0.5) + || (event.getAxisValue(MotionEvent.AXIS_GAS) > 0.5) + || (mModifierSwappedAxis && event.getAxisValue(MotionEvent.AXIS_RZ) > 0.5) ); + } + } + + /** + * Detect if a gamepad supports analog triggers + * @param inputDevice The input device with all the MotionRange + * @return Whether the gamepad supports analog triggers + */ + private boolean supportAnalogTriggers(InputDevice inputDevice){ + for(InputDevice.MotionRange motionRange : inputDevice.getMotionRanges()){ + int axis = motionRange.getAxis(); + + if( axis == MotionEvent.AXIS_BRAKE || axis == MotionEvent.AXIS_GAS || + axis == MotionEvent.AXIS_LTRIGGER || axis == MotionEvent.AXIS_RTRIGGER || + (mModifierSwappedAxis && axis == MotionEvent.AXIS_Z) || + (mModifierSwappedAxis && axis == MotionEvent.AXIS_RZ)){ + return true; + } + } + return false; + } + + private GamepadMap getCurrentMap(){ + return mCurrentMap; + } + + private static void sendDirectionalKeycode(int direction, boolean isDown, GamepadMap map){ + switch (direction){ + case DIRECTION_NORTH: + sendInput(map.DIRECTION_FORWARD, isDown); + break; + case DIRECTION_NORTH_EAST: + sendInput(map.DIRECTION_FORWARD, isDown); + sendInput(map.DIRECTION_RIGHT, isDown); + break; + case DIRECTION_EAST: + sendInput(map.DIRECTION_RIGHT, isDown); + break; + case DIRECTION_SOUTH_EAST: + sendInput(map.DIRECTION_RIGHT, isDown); + sendInput(map.DIRECTION_BACKWARD, isDown); + break; + case DIRECTION_SOUTH: + sendInput(map.DIRECTION_BACKWARD, isDown); + break; + case DIRECTION_SOUTH_WEST: + sendInput(map.DIRECTION_BACKWARD, isDown); + sendInput(map.DIRECTION_LEFT, isDown); + break; + case DIRECTION_WEST: + sendInput(map.DIRECTION_LEFT, isDown); + break; + case DIRECTION_NORTH_WEST: + sendInput(map.DIRECTION_FORWARD, isDown); + sendInput(map.DIRECTION_LEFT, isDown); + break; + } + } + + private void placePointerView(int x, int y){ + mPointerImageView.setX(x - mPointerImageView.getWidth()/2); + mPointerImageView.setY(y - mPointerImageView.getHeight()/2); + } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadButton.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadButton.java index f502ff60f..a6c7cc1e7 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadButton.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadButton.java @@ -2,15 +2,15 @@ package net.kdt.pojavlaunch.customcontrols.gamepad; import android.view.KeyEvent; +/** + * Simple button able to store its state and some properties + */ public class GamepadButton { - /* - Just a simple button, that auto deal with the great habit from android to just SPAAAMS input events - */ public int[] keycodes; public boolean isToggleable = false; - private boolean isDown = false; - private boolean isToggled = false; + private boolean mIsDown = false; + private boolean mIsToggled = false; public void update(KeyEvent event){ boolean isKeyDown = (event.getAction() == KeyEvent.ACTION_DOWN); @@ -18,29 +18,29 @@ public class GamepadButton { } public void update(boolean isKeyDown){ - if(isKeyDown != isDown){ - isDown = isKeyDown; + if(isKeyDown != mIsDown){ + mIsDown = isKeyDown; if(isToggleable){ if(isKeyDown){ - isToggled = !isToggled; - Gamepad.sendInput(keycodes, isToggled); + mIsToggled = !mIsToggled; + Gamepad.sendInput(keycodes, mIsToggled); } return; } - Gamepad.sendInput(keycodes, isDown); + Gamepad.sendInput(keycodes, mIsDown); } } public void resetButtonState(){ - if(isDown || isToggled){ + if(mIsDown || mIsToggled){ Gamepad.sendInput(keycodes, false); } - isDown = false; - isToggled = false; + mIsDown = false; + mIsToggled = false; } public boolean isDown(){ - return isToggleable ? isToggled : isDown; + return isToggleable ? mIsToggled : mIsDown; } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadDpad.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadDpad.java index bf365b731..cba9484bd 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadDpad.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadDpad.java @@ -5,7 +5,6 @@ import android.view.KeyEvent; import android.view.MotionEvent; import static android.view.InputDevice.KEYBOARD_TYPE_NON_ALPHABETIC; -import static android.view.InputDevice.SOURCE_DPAD; import static android.view.KeyEvent.KEYCODE_DPAD_CENTER; import static android.view.KeyEvent.KEYCODE_DPAD_DOWN; import static android.view.KeyEvent.KEYCODE_DPAD_LEFT; @@ -14,7 +13,7 @@ import static android.view.KeyEvent.KEYCODE_DPAD_UP; public class GamepadDpad { - private int lastKeycode = KEYCODE_DPAD_CENTER; + private int mLastKeycode = KEYCODE_DPAD_CENTER; /** * Convert the event to a 2 int array: keycode and keyAction, similar to a keyEvent @@ -30,22 +29,22 @@ public class GamepadDpad { // Check if the AXIS_HAT_X value is -1 or 1, and set the D-pad // LEFT and RIGHT direction accordingly. if (Float.compare(xaxis, -1.0f) == 0) { - lastKeycode = KEYCODE_DPAD_LEFT; + mLastKeycode = KEYCODE_DPAD_LEFT; } else if (Float.compare(xaxis, 1.0f) == 0) { - lastKeycode = KEYCODE_DPAD_RIGHT; + mLastKeycode = KEYCODE_DPAD_RIGHT; } // Check if the AXIS_HAT_Y value is -1 or 1, and set the D-pad // UP and DOWN direction accordingly. else if (Float.compare(yaxis, -1.0f) == 0) { - lastKeycode = KEYCODE_DPAD_UP; + mLastKeycode = KEYCODE_DPAD_UP; } else if (Float.compare(yaxis, 1.0f) == 0) { - lastKeycode = KEYCODE_DPAD_DOWN; + mLastKeycode = KEYCODE_DPAD_DOWN; }else { //No keycode change action = KeyEvent.ACTION_UP; } - return new int[]{lastKeycode, action}; + return new int[]{mLastKeycode, action}; } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadJoystick.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadJoystick.java index 22cb0b999..7f0487b49 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadJoystick.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/GamepadJoystick.java @@ -20,17 +20,14 @@ public class GamepadJoystick { public static final int DIRECTION_SOUTH = 6; public static final int DIRECTION_SOUTH_EAST = 7; - private final InputDevice device; - - private final int verticalAxis; - private final int horizontalAxis; + private final InputDevice mInputDevice; + private final int mVerticalAxis; + private final int mHorizontalAxis; public GamepadJoystick(int horizontalAxis, int verticalAxis, InputDevice device){ - this.verticalAxis = verticalAxis; - this.horizontalAxis = horizontalAxis; - this.device = device; - - + this.mVerticalAxis = verticalAxis; + this.mHorizontalAxis = horizontalAxis; + this.mInputDevice = device; } public double getAngleRadian(MotionEvent event){ @@ -48,29 +45,18 @@ public class GamepadJoystick { } public double getMagnitude(MotionEvent event){ - float x = Math.abs(event.getAxisValue(horizontalAxis)); - float y = Math.abs(event.getAxisValue(verticalAxis)); + float x = Math.abs(event.getAxisValue(mHorizontalAxis)); + float y = Math.abs(event.getAxisValue(mVerticalAxis)); return MathUtils.dist(0,0, x, y); } public float getVerticalAxis(MotionEvent event){ - return applyDeadzone(event, verticalAxis); + return applyDeadzone(event, mVerticalAxis); } public float getHorizontalAxis(MotionEvent event){ - return applyDeadzone(event, horizontalAxis); - } - - private float applyDeadzone(MotionEvent event, int axis){ - //This piece of code also modifies the value - //to make it seem like there was no deadzone in the first place - - double magnitude = getMagnitude(event); - float deadzone = getDeadzone(); - if (magnitude < deadzone) return 0; - - return (float) ( (event.getAxisValue(axis) / magnitude) * ((magnitude - deadzone) / (1 - deadzone)) ); + return applyDeadzone(event, mHorizontalAxis); } public static boolean isJoystickEvent(MotionEvent event){ @@ -91,9 +77,20 @@ public class GamepadJoystick { */ public float getDeadzone() { try{ - return Math.max(device.getMotionRange(horizontalAxis).getFlat() * 1.9f, 0.2f); + return Math.max(mInputDevice.getMotionRange(mHorizontalAxis).getFlat() * 1.9f, 0.2f); }catch (Exception e){ return 0.2f; } } + + private float applyDeadzone(MotionEvent event, int axis){ + //This piece of code also modifies the value + //to make it seem like there was no deadzone in the first place + + double magnitude = getMagnitude(event); + float deadzone = getDeadzone(); + if (magnitude < deadzone) return 0; + + return (float) ( (event.getAxisValue(axis) / magnitude) * ((magnitude - deadzone) / (1 - deadzone)) ); + } } From 2550070954c4fde460c05e38c8b36ac9d1438416 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 18:20:40 +0100 Subject: [PATCH 58/70] Refactor editing button dialogs --- .../handleview/ActionPopupWindow.java | 40 +-- .../handleview/EditControlButtonPopup.java | 294 +++++++++--------- .../handleview/EditControlDrawerPopup.java | 48 +-- .../handleview/EditControlSubButtonPopup.java | 14 +- 4 files changed, 197 insertions(+), 199 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/ActionPopupWindow.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/ActionPopupWindow.java index f64d3f8c6..8e48d08bf 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/ActionPopupWindow.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/ActionPopupWindow.java @@ -43,11 +43,11 @@ public class ActionPopupWindow extends PinnedPopupWindow implements OnClickListe private TextView mDeleteTextView; private TextView mCloneTextView; - private final ControlButton editedButton; + private final ControlButton mEditedButton; public ActionPopupWindow(HandleView handleView, ControlButton button){ super(handleView); - this.editedButton = button; + this.mEditedButton = button; } @Override @@ -97,18 +97,18 @@ public class ActionPopupWindow extends PinnedPopupWindow implements OnClickListe public void onClick(final View view) { if (view == mEditTextView) { - if(editedButton instanceof ControlSubButton){ - new EditControlSubButtonPopup((ControlSubButton) editedButton); + if(mEditedButton instanceof ControlSubButton){ + new EditControlSubButtonPopup((ControlSubButton) mEditedButton); return; } - if(editedButton instanceof ControlDrawer){ - new EditControlDrawerPopup((ControlDrawer) editedButton); + if(mEditedButton instanceof ControlDrawer){ + new EditControlDrawerPopup((ControlDrawer) mEditedButton); return; } - if(editedButton instanceof ControlButton){ - new EditControlButtonPopup((ControlButton) editedButton); + if(mEditedButton instanceof ControlButton){ + new EditControlButtonPopup((ControlButton) mEditedButton); return; } @@ -121,18 +121,18 @@ public class ActionPopupWindow extends PinnedPopupWindow implements OnClickListe alertBuilder.setPositiveButton(R.string.global_remove, (p1, p2) -> { ControlLayout layout = ((ControlLayout) mHandleView.mView.getParent()); - if(editedButton instanceof ControlSubButton){ - layout.removeControlSubButton((ControlSubButton) editedButton); + if(mEditedButton instanceof ControlSubButton){ + layout.removeControlSubButton((ControlSubButton) mEditedButton); return; } - if(editedButton instanceof ControlDrawer){ - layout.removeControlDrawer((ControlDrawer) editedButton); + if(mEditedButton instanceof ControlDrawer){ + layout.removeControlDrawer((ControlDrawer) mEditedButton); return; } - if(editedButton instanceof ControlButton){ - layout.removeControlButton((ControlButton) editedButton); + if(mEditedButton instanceof ControlButton){ + layout.removeControlButton((ControlButton) mEditedButton); } layout.removeControlButton(mHandleView.mView); @@ -140,18 +140,18 @@ public class ActionPopupWindow extends PinnedPopupWindow implements OnClickListe alertBuilder.setNegativeButton(android.R.string.cancel, null); alertBuilder.show(); }else if(view == mCloneTextView) { - if(editedButton instanceof ControlDrawer){ - ControlDrawerData cloneData = new ControlDrawerData(((ControlDrawer)editedButton).getDrawerData()); + if(mEditedButton instanceof ControlDrawer){ + ControlDrawerData cloneData = new ControlDrawerData(((ControlDrawer) mEditedButton).getDrawerData()); cloneData.properties.dynamicX = "0.5 * ${screen_width}"; cloneData.properties.dynamicY = "0.5 * ${screen_height}"; ((ControlLayout) mHandleView.mView.getParent()).addDrawer(cloneData); - }else if(editedButton instanceof ControlSubButton){ - ControlData cloneData = new ControlData(editedButton.getProperties()); + }else if(mEditedButton instanceof ControlSubButton){ + ControlData cloneData = new ControlData(mEditedButton.getProperties()); cloneData.dynamicX = "0.5 * ${screen_width}"; cloneData.dynamicY = "0.5 * ${screen_height}"; - ((ControlLayout) mHandleView.mView.getParent()).addSubButton(((ControlSubButton) editedButton).parentDrawer, cloneData); + ((ControlLayout) mHandleView.mView.getParent()).addSubButton(((ControlSubButton) mEditedButton).parentDrawer, cloneData); }else{ - ControlData cloneData = new ControlData(editedButton.getProperties()); + ControlData cloneData = new ControlData(mEditedButton.getProperties()); cloneData.dynamicX = "0.5 * ${screen_width}"; cloneData.dynamicY = "0.5 * ${screen_height}"; ((ControlLayout) mHandleView.mView.getParent()).addControlButton(cloneData); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlButtonPopup.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlButtonPopup.java index 6b4071bb3..28d63f3dc 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlButtonPopup.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlButtonPopup.java @@ -1,6 +1,5 @@ package net.kdt.pojavlaunch.customcontrols.handleview; -import android.app.Dialog; import android.content.Context; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; @@ -8,7 +7,6 @@ import android.view.LayoutInflater; import android.view.View; import android.widget.ArrayAdapter; import android.widget.CheckBox; -import android.widget.CompoundButton; import android.widget.EditText; import android.widget.ImageButton; import android.widget.SeekBar; @@ -29,103 +27,103 @@ import static net.kdt.pojavlaunch.customcontrols.handleview.ActionPopupWindow.se public class EditControlButtonPopup { - protected AlertDialog dialog; - protected View v; - protected AlertDialog.Builder builder; + protected AlertDialog mDialog; + protected View mRootView; + protected AlertDialog.Builder mBuilder; - protected EditText editName; - protected Spinner[] spinnersKeycode; + protected EditText mNameEditText; + protected Spinner[] mKeycodeSpinners; - protected CheckBox checkToggle; - protected CheckBox checkPassThrough; - protected CheckBox checkBoxSwipeable; - protected CheckBox checkDynamicPosition; + protected CheckBox mToggleCheckbox; + protected CheckBox mPassthroughCheckbox; + protected CheckBox mSwipeableCheckbox; + protected CheckBox mDynamicPositionCheckbox; - protected EditText editWidth; - protected EditText editHeight; - protected EditText editDynamicX; - protected EditText editDynamicY; + protected EditText mWidthEditText; + protected EditText mHeightEditText; + protected EditText mDynamicXEditText; + protected EditText mDynamicYEditText; - protected SeekBar seekBarOpacity; - protected SeekBar seekBarCornerRadius; - protected SeekBar seekBarStrokeWidth; + protected SeekBar mOpacitySeekbar; + protected SeekBar mCornerRadiusSeekbar; + protected SeekBar mStrokeWidthSeekbar; - protected ImageButton buttonBackgroundColor; - protected ImageButton buttonStrokeColor; + protected ImageButton mBackgroundColorButton; + protected ImageButton mStrokeColorButton; - protected TextView textOpacity; - protected TextView textCornerRadius; - protected TextView textStrokeWidth; - protected TextView textStrokeColor; + protected TextView mOpacityTextView; + protected TextView mCornerRadiusTextView; + protected TextView mStrokeWidthTextView; + protected TextView mStrokeColorTextView; - protected final ControlButton button; - protected final ControlData properties; + protected final ControlButton mControlButton; + protected final ControlData mProperties; - protected ArrayAdapter adapter; - protected String[] specialArr; + protected ArrayAdapter mAdapter; + protected String[] mSpecialArray; public EditControlButtonPopup(ControlButton button){ - this.button = button; - this.properties = button.getProperties(); + this.mControlButton = button; + this.mProperties = button.getProperties(); initializeEditDialog(button.getContext()); //Create the finalized dialog - dialog = builder.create(); - dialog.setOnShowListener(dialogInterface -> setEditDialogValues()); + mDialog = mBuilder.create(); + mDialog.setOnShowListener(dialogInterface -> setEditDialogValues()); - dialog.show(); + mDialog.show(); } protected void initializeEditDialog(Context ctx){ //Create the editing dialog LayoutInflater layoutInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - v = layoutInflater.inflate(R.layout.control_button_setting,null); + mRootView = layoutInflater.inflate(R.layout.control_button_setting,null); - builder = new AlertDialog.Builder(ctx); - builder.setTitle(ctx.getResources().getString(R.string.customctrl_edit, properties.name)); - builder.setView(v); + mBuilder = new AlertDialog.Builder(ctx); + mBuilder.setTitle(ctx.getResources().getString(R.string.customctrl_edit, mProperties.name)); + mBuilder.setView(mRootView); //Linking a lot of stuff - editName = v.findViewById(R.id.editName_editText); + mNameEditText = mRootView.findViewById(R.id.editName_editText); - spinnersKeycode = new Spinner[]{ - v.findViewById(R.id.editMapping_spinner_1), - v.findViewById(R.id.editMapping_spinner_2), - v.findViewById(R.id.editMapping_spinner_3), - v.findViewById(R.id.editMapping_spinner_4) + mKeycodeSpinners = new Spinner[]{ + mRootView.findViewById(R.id.editMapping_spinner_1), + mRootView.findViewById(R.id.editMapping_spinner_2), + mRootView.findViewById(R.id.editMapping_spinner_3), + mRootView.findViewById(R.id.editMapping_spinner_4) }; - checkToggle = v.findViewById(R.id.checkboxToggle); - checkPassThrough = v.findViewById(R.id.checkboxPassThrough); - checkBoxSwipeable = v.findViewById(R.id.checkboxSwipeable); + mToggleCheckbox = mRootView.findViewById(R.id.checkboxToggle); + mPassthroughCheckbox = mRootView.findViewById(R.id.checkboxPassThrough); + mSwipeableCheckbox = mRootView.findViewById(R.id.checkboxSwipeable); - editWidth = v.findViewById(R.id.editSize_editTextX); - editHeight = v.findViewById(R.id.editSize_editTextY); + mWidthEditText = mRootView.findViewById(R.id.editSize_editTextX); + mHeightEditText = mRootView.findViewById(R.id.editSize_editTextY); - editDynamicX = v.findViewById(R.id.editDynamicPositionX_editText); - editDynamicY = v.findViewById(R.id.editDynamicPositionY_editText); + mDynamicXEditText = mRootView.findViewById(R.id.editDynamicPositionX_editText); + mDynamicYEditText = mRootView.findViewById(R.id.editDynamicPositionY_editText); - seekBarOpacity = v.findViewById(R.id.editButtonOpacity_seekbar); - seekBarCornerRadius = v.findViewById(R.id.editCornerRadius_seekbar); - seekBarStrokeWidth = v.findViewById(R.id.editStrokeWidth_seekbar); + mOpacitySeekbar = mRootView.findViewById(R.id.editButtonOpacity_seekbar); + mCornerRadiusSeekbar = mRootView.findViewById(R.id.editCornerRadius_seekbar); + mStrokeWidthSeekbar = mRootView.findViewById(R.id.editStrokeWidth_seekbar); SeekBar.OnSeekBarChangeListener changeListener = new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int i, boolean b) { - if(seekBar.equals(seekBarCornerRadius)) { - setPercentageText(textCornerRadius, i); + if(seekBar.equals(mCornerRadiusSeekbar)) { + setPercentageText(mCornerRadiusTextView, i); return; } - if(seekBar.equals(seekBarOpacity)) { - setPercentageText(textOpacity, i); + if(seekBar.equals(mOpacitySeekbar)) { + setPercentageText(mOpacityTextView, i); return; } - if(seekBar.equals(seekBarStrokeWidth)) { - setPercentageText(textStrokeWidth, i); - textStrokeColor.setVisibility(i == 0 ? View.GONE : View.VISIBLE); + if(seekBar.equals(mStrokeWidthSeekbar)) { + setPercentageText(mStrokeWidthTextView, i); + mStrokeColorTextView.setVisibility(i == 0 ? View.GONE : View.VISIBLE); } } @@ -136,43 +134,43 @@ public class EditControlButtonPopup { }; //Add listeners, too bad I don't need all the methods - seekBarOpacity.setOnSeekBarChangeListener(changeListener); - seekBarCornerRadius.setOnSeekBarChangeListener(changeListener); - seekBarStrokeWidth.setOnSeekBarChangeListener(changeListener); + mOpacitySeekbar.setOnSeekBarChangeListener(changeListener); + mCornerRadiusSeekbar.setOnSeekBarChangeListener(changeListener); + mStrokeWidthSeekbar.setOnSeekBarChangeListener(changeListener); - buttonBackgroundColor = v.findViewById(R.id.editBackgroundColor_imageButton); - buttonStrokeColor = v.findViewById(R.id.editStrokeColor_imageButton); + mBackgroundColorButton = mRootView.findViewById(R.id.editBackgroundColor_imageButton); + mStrokeColorButton = mRootView.findViewById(R.id.editStrokeColor_imageButton); - textOpacity = v.findViewById(R.id.editButtonOpacity_textView_percent); - textCornerRadius = v.findViewById(R.id.editCornerRadius_textView_percent); - textStrokeWidth = v.findViewById(R.id.editStrokeWidth_textView_percent); - textStrokeColor = v.findViewById(R.id.editStrokeColor_textView); + mOpacityTextView = mRootView.findViewById(R.id.editButtonOpacity_textView_percent); + mCornerRadiusTextView = mRootView.findViewById(R.id.editCornerRadius_textView_percent); + mStrokeWidthTextView = mRootView.findViewById(R.id.editStrokeWidth_textView_percent); + mStrokeColorTextView = mRootView.findViewById(R.id.editStrokeColor_textView); - checkDynamicPosition = v.findViewById(R.id.checkboxDynamicPosition); - checkDynamicPosition.setOnCheckedChangeListener((btn, checked) -> { - editDynamicX.setEnabled(checked); - editDynamicY.setEnabled(checked); + mDynamicPositionCheckbox = mRootView.findViewById(R.id.checkboxDynamicPosition); + mDynamicPositionCheckbox.setOnCheckedChangeListener((btn, checked) -> { + mDynamicXEditText.setEnabled(checked); + mDynamicYEditText.setEnabled(checked); }); //Initialize adapter for keycodes - adapter = new ArrayAdapter<>(ctx, android.R.layout.simple_spinner_item); + mAdapter = new ArrayAdapter<>(ctx, android.R.layout.simple_spinner_item); String[] oldSpecialArr = ControlData.buildSpecialButtonArray(); - specialArr = new String[oldSpecialArr.length]; - for (int i = 0; i < specialArr.length; i++) { - specialArr[i] = "SPECIAL_" + oldSpecialArr[specialArr.length - i - 1]; + mSpecialArray = new String[oldSpecialArr.length]; + for (int i = 0; i < mSpecialArray.length; i++) { + mSpecialArray[i] = "SPECIAL_" + oldSpecialArr[mSpecialArray.length - i - 1]; } - adapter.addAll(specialArr); - adapter.addAll(EfficientAndroidLWJGLKeycode.generateKeyName()); - adapter.setDropDownViewResource(android.R.layout.simple_list_item_single_choice); + mAdapter.addAll(mSpecialArray); + mAdapter.addAll(EfficientAndroidLWJGLKeycode.generateKeyName()); + mAdapter.setDropDownViewResource(android.R.layout.simple_list_item_single_choice); - for (Spinner spinner : spinnersKeycode) { - spinner.setAdapter(adapter); + for (Spinner spinner : mKeycodeSpinners) { + spinner.setAdapter(mAdapter); } //Set color imageButton behavior - buttonBackgroundColor.setOnClickListener(view -> ActionPopupWindow.showColorPicker(ctx, "Edit background color", true, buttonBackgroundColor)); - buttonStrokeColor.setOnClickListener(view -> ActionPopupWindow.showColorPicker(ctx, "Edit stroke color", false, buttonStrokeColor)); + mBackgroundColorButton.setOnClickListener(view -> ActionPopupWindow.showColorPicker(ctx, "Edit background color", true, mBackgroundColorButton)); + mStrokeColorButton.setOnClickListener(view -> ActionPopupWindow.showColorPicker(ctx, "Edit stroke color", false, mStrokeColorButton)); //Set dialog buttons behavior @@ -187,34 +185,34 @@ public class EditControlButtonPopup { protected void setupDialogButtons(){ //Set dialog buttons behavior - builder.setPositiveButton(android.R.string.ok, (dialogInterface1, i) -> { - if(!hasPropertiesErrors(dialog.getContext())){ + mBuilder.setPositiveButton(android.R.string.ok, (dialogInterface1, i) -> { + if(!hasPropertiesErrors(mDialog.getContext())){ saveProperties(); } }); - builder.setNegativeButton(android.R.string.cancel, null); + mBuilder.setNegativeButton(android.R.string.cancel, null); } protected void hideUselessViews(){ - (v.findViewById(R.id.editOrientation_textView)).setVisibility(View.GONE); + (mRootView.findViewById(R.id.editOrientation_textView)).setVisibility(View.GONE); - (v.findViewById(R.id.editDynamicPositionX_textView)).setVisibility(View.GONE); - (v.findViewById(R.id.editDynamicPositionY_textView)).setVisibility(View.GONE); - editDynamicX.setVisibility(View.GONE); - editDynamicY.setVisibility(View.GONE); + (mRootView.findViewById(R.id.editDynamicPositionX_textView)).setVisibility(View.GONE); + (mRootView.findViewById(R.id.editDynamicPositionY_textView)).setVisibility(View.GONE); + mDynamicXEditText.setVisibility(View.GONE); + mDynamicYEditText.setVisibility(View.GONE); //Hide the color choice if the width is 0. - textStrokeColor.setVisibility(properties.strokeWidth == 0 ? View.GONE : View.VISIBLE); + mStrokeColorTextView.setVisibility(mProperties.strokeWidth == 0 ? View.GONE : View.VISIBLE); } protected void defineDynamicCheckChange(){ - checkDynamicPosition.setOnCheckedChangeListener((compoundButton, b) -> { + mDynamicPositionCheckbox.setOnCheckedChangeListener((compoundButton, b) -> { int visibility = b ? View.VISIBLE : View.GONE; - (v.findViewById(R.id.editDynamicPositionX_textView)).setVisibility(visibility); - (v.findViewById(R.id.editDynamicPositionY_textView)).setVisibility(visibility); - editDynamicX.setVisibility(visibility); - editDynamicY.setVisibility(visibility); + (mRootView.findViewById(R.id.editDynamicPositionX_textView)).setVisibility(visibility); + (mRootView.findViewById(R.id.editDynamicPositionY_textView)).setVisibility(visibility); + mDynamicXEditText.setVisibility(visibility); + mDynamicYEditText.setVisibility(visibility); }); } @@ -226,65 +224,65 @@ public class EditControlButtonPopup { .size((int) Tools.dpToPx(20)) .build(); - buttonBackgroundColor.setBackground(drawable); - buttonStrokeColor.setBackground(drawable); + mBackgroundColorButton.setBackground(drawable); + mStrokeColorButton.setBackground(drawable); } protected void setEditDialogValues(){ - editName.setText(properties.name); + mNameEditText.setText(mProperties.name); - checkToggle.setChecked(properties.isToggle); - checkPassThrough.setChecked(properties.passThruEnabled); - checkBoxSwipeable.setChecked(properties.isSwipeable); + mToggleCheckbox.setChecked(mProperties.isToggle); + mPassthroughCheckbox.setChecked(mProperties.passThruEnabled); + mSwipeableCheckbox.setChecked(mProperties.isSwipeable); - editWidth.setText(Float.toString(properties.getWidth())); - editHeight.setText(Float.toString(properties.getHeight())); + mWidthEditText.setText(Float.toString(mProperties.getWidth())); + mHeightEditText.setText(Float.toString(mProperties.getHeight())); - editDynamicX.setEnabled(properties.isDynamicBtn); - editDynamicY.setEnabled(properties.isDynamicBtn); - editDynamicX.setText(properties.dynamicX); + mDynamicXEditText.setEnabled(mProperties.isDynamicBtn); + mDynamicYEditText.setEnabled(mProperties.isDynamicBtn); + mDynamicXEditText.setText(mProperties.dynamicX); - editDynamicY.setText(properties.dynamicY); + mDynamicYEditText.setText(mProperties.dynamicY); - seekBarOpacity.setProgress((int) (properties.opacity*100)); - seekBarStrokeWidth.setProgress(properties.strokeWidth); - seekBarCornerRadius.setProgress((int)properties.cornerRadius); + mOpacitySeekbar.setProgress((int) (mProperties.opacity*100)); + mStrokeWidthSeekbar.setProgress(mProperties.strokeWidth); + mCornerRadiusSeekbar.setProgress((int) mProperties.cornerRadius); - buttonBackgroundColor.setImageDrawable(new ColorDrawable(properties.bgColor)); - buttonStrokeColor.setImageDrawable(new ColorDrawable(properties.strokeColor)); + mBackgroundColorButton.setImageDrawable(new ColorDrawable(mProperties.bgColor)); + mStrokeColorButton.setImageDrawable(new ColorDrawable(mProperties.strokeColor)); - setPercentageText(textCornerRadius,seekBarCornerRadius.getProgress()); - setPercentageText(textOpacity,seekBarOpacity.getProgress()); - setPercentageText(textStrokeWidth,seekBarStrokeWidth.getProgress()); + setPercentageText(mCornerRadiusTextView, mCornerRadiusSeekbar.getProgress()); + setPercentageText(mOpacityTextView, mOpacitySeekbar.getProgress()); + setPercentageText(mStrokeWidthTextView, mStrokeWidthSeekbar.getProgress()); - checkDynamicPosition.setChecked(properties.isDynamicBtn); + mDynamicPositionCheckbox.setChecked(mProperties.isDynamicBtn); - for(int i=0; i< properties.keycodes.length; i++){ - if (properties.keycodes[i] < 0) { - spinnersKeycode[i].setSelection(properties.keycodes[i] + specialArr.length); + for(int i = 0; i< mProperties.keycodes.length; i++){ + if (mProperties.keycodes[i] < 0) { + mKeycodeSpinners[i].setSelection(mProperties.keycodes[i] + mSpecialArray.length); } else { - spinnersKeycode[i].setSelection(EfficientAndroidLWJGLKeycode.getIndexByValue(properties.keycodes[i]) + specialArr.length); + mKeycodeSpinners[i].setSelection(EfficientAndroidLWJGLKeycode.getIndexByValue(mProperties.keycodes[i]) + mSpecialArray.length); } } } protected boolean hasPropertiesErrors(Context ctx){ - if (editName.getText().toString().isEmpty()) { - editName.setError(ctx.getResources().getString(R.string.global_error_field_empty)); + if (mNameEditText.getText().toString().isEmpty()) { + mNameEditText.setError(ctx.getResources().getString(R.string.global_error_field_empty)); return true; } - if (properties.isDynamicBtn) { + if (mProperties.isDynamicBtn) { int errorAt = 0; try { - properties.insertDynamicPos(editDynamicX.getText().toString()); + mProperties.insertDynamicPos(mDynamicXEditText.getText().toString()); errorAt = 1; - properties.insertDynamicPos(editDynamicY.getText().toString()); + mProperties.insertDynamicPos(mDynamicYEditText.getText().toString()); } catch (Throwable th) { - (errorAt == 0 ? editDynamicX : editDynamicY).setError(th.getMessage()); + (errorAt == 0 ? mDynamicXEditText : mDynamicYEditText).setError(th.getMessage()); return true; } @@ -295,36 +293,36 @@ public class EditControlButtonPopup { protected void saveProperties(){ //This method assumes there are no error. - properties.name = editName.getText().toString(); + mProperties.name = mNameEditText.getText().toString(); //Keycodes - for(int i=0; i adapter = new ArrayAdapter<>(ctx, android.R.layout.simple_spinner_item); adapter.addAll(ControlDrawerData.getOrientations()); adapter.setDropDownViewResource(android.R.layout.simple_list_item_single_choice); - spinnerOrientation.setAdapter(adapter); + mOrientationSpinner.setAdapter(adapter); } @Override protected void setEditDialogValues() { super.setEditDialogValues(); - spinnerOrientation.setSelection(ControlDrawerData.orientationToInt(drawerData.orientation)); + mOrientationSpinner.setSelection(ControlDrawerData.orientationToInt(mDrawerData.orientation)); //Using the dialog to replace the button behavior allows us not to dismiss the window - dialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener(v -> { - ControlLayout layout = (ControlLayout) drawer.getParent(); - ControlData controlData = new ControlData(drawerData.properties); + mDialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener(v -> { + ControlLayout layout = (ControlLayout) mDrawer.getParent(); + ControlData controlData = new ControlData(mDrawerData.properties); controlData.name = "new"; - layout.addSubButton(drawer, controlData); + layout.addSubButton(mDrawer, controlData); - Context ctx = dialog.getContext(); + Context ctx = mDialog.getContext(); Toast.makeText(ctx, ctx.getString(R.string.customctrl_add_subbutton_message, - drawer.getDrawerData().buttonProperties.size()), Toast.LENGTH_SHORT).show(); + mDrawer.getDrawerData().buttonProperties.size()), Toast.LENGTH_SHORT).show(); }); } @@ -78,13 +78,13 @@ public class EditControlDrawerPopup extends EditControlButtonPopup{ protected void setupDialogButtons() { super.setupDialogButtons(); - builder.setNeutralButton(v.getResources().getString(R.string.customctrl_addsubbutton), null); + mBuilder.setNeutralButton(mRootView.getResources().getString(R.string.customctrl_addsubbutton), null); } @Override protected void saveProperties() { - drawerData.orientation = ControlDrawerData.intToOrientation(spinnerOrientation.getSelectedItemPosition()); + mDrawerData.orientation = ControlDrawerData.intToOrientation(mOrientationSpinner.getSelectedItemPosition()); super.saveProperties(); } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlSubButtonPopup.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlSubButtonPopup.java index 064a5829e..0b0f90e0b 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlSubButtonPopup.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlSubButtonPopup.java @@ -14,15 +14,15 @@ public class EditControlSubButtonPopup extends EditControlButtonPopup{ @Override protected void hideUselessViews() { - (v.findViewById(R.id.editSize_textView)).setVisibility(View.GONE); - (v.findViewById(R.id.editOrientation_textView)).setVisibility(View.GONE); + (mRootView.findViewById(R.id.editSize_textView)).setVisibility(View.GONE); + (mRootView.findViewById(R.id.editOrientation_textView)).setVisibility(View.GONE); - checkDynamicPosition.setVisibility(View.GONE); + mDynamicPositionCheckbox.setVisibility(View.GONE); - (v.findViewById(R.id.editDynamicPositionX_textView)).setVisibility(View.GONE); - editDynamicX.setVisibility(View.GONE); + (mRootView.findViewById(R.id.editDynamicPositionX_textView)).setVisibility(View.GONE); + mDynamicXEditText.setVisibility(View.GONE); - (v.findViewById(R.id.editDynamicPositionY_textView)).setVisibility(View.GONE); - editDynamicY.setVisibility(View.GONE); + (mRootView.findViewById(R.id.editDynamicPositionY_textView)).setVisibility(View.GONE); + mDynamicYEditText.setVisibility(View.GONE); } } From 16bdc35739f14688e11aa6ab7f7d69972ecd342f Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 18:30:42 +0100 Subject: [PATCH 59/70] Refactor HandleView related files --- .../customcontrols/handleview/HandleView.java | 212 +++++++++--------- .../handleview/SelectionEndHandleView.java | 3 +- .../handleview/ViewPositionListener.java | 2 +- 3 files changed, 109 insertions(+), 108 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/HandleView.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/HandleView.java index 1378be5db..075274dc8 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/HandleView.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/HandleView.java @@ -29,8 +29,7 @@ import net.kdt.pojavlaunch.*; import net.kdt.pojavlaunch.customcontrols.buttons.ControlButton; -public abstract class HandleView extends View implements ViewPositionListener, View.OnLongClickListener - { +public abstract class HandleView extends View implements ViewPositionListener, View.OnLongClickListener { protected Drawable mDrawable; protected Drawable mDrawableLtr; protected Drawable mDrawableRtl; @@ -65,12 +64,19 @@ public abstract class HandleView extends View implements ViewPositionListener, V // int mWindowPosX, mWindowPosY; private PositionListener mPositionListener; - public PositionListener getPositionListener() { - if (mPositionListener == null) { - mPositionListener = new PositionListener(mView); - } - return mPositionListener; - } + + // Touch-up filter: number of previous positions remembered + private static final int HISTORY_SIZE = 5; + private static final int TOUCH_UP_FILTER_DELAY_AFTER = 150; + private static final int TOUCH_UP_FILTER_DELAY_BEFORE = 350; + private final long[] mPreviousOffsetsTimes = new long[HISTORY_SIZE]; + private final int[] mPreviousOffsets = new int[HISTORY_SIZE]; + private int mPreviousOffsetIndex = 0; + private int mNumberPreviousOffsets = 0; + + // Addition + private float mDownX, mDownY; + public HandleView(ControlButton view) { super(view.getContext()); @@ -99,6 +105,98 @@ public abstract class HandleView extends View implements ViewPositionListener, V mIdealVerticalOffset = 0.7f * handleHeight; } + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(getPreferredWidth(), getPreferredHeight()); + } + + @Override + protected void onDraw(Canvas c) { + final int drawWidth = mDrawable.getIntrinsicWidth(); + final int left = getHorizontalOffset(); + + mDrawable.setBounds(left, 0, left + drawWidth, mDrawable.getIntrinsicHeight()); + mDrawable.draw(c); + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + ViewGroup.LayoutParams params = mView.getLayoutParams(); + + switch (ev.getActionMasked()) { + case MotionEvent.ACTION_DOWN: { + startTouchUpFilter(getCurrentCursorOffset()); + mTouchToWindowOffsetX = ev.getRawX() - mPositionX; + mTouchToWindowOffsetY = ev.getRawY() - mPositionY; + + final PositionListener positionListener = getPositionListener(); + mLastParentX = positionListener.getPositionX(); + mLastParentY = positionListener.getPositionY(); + mIsDragging = true; + + // MOD: Addition + mDownX = ev.getRawX(); + mDownY = ev.getRawY(); + mDownWidth = params.width; + mDownHeight = params.height; + + break; + } + + case MotionEvent.ACTION_MOVE: { + final float rawX = ev.getRawX(); + final float rawY = ev.getRawY(); + + // Vertical hysteresis: vertical down movement tends to snap to ideal offset + final float previousVerticalOffset = mTouchToWindowOffsetY - mLastParentY; + final float currentVerticalOffset = rawY - mPositionY - mLastParentY; + float newVerticalOffset; + if (previousVerticalOffset < mIdealVerticalOffset) { + newVerticalOffset = Math.min(currentVerticalOffset, mIdealVerticalOffset); + newVerticalOffset = Math.max(newVerticalOffset, previousVerticalOffset); + } else { + newVerticalOffset = Math.max(currentVerticalOffset, mIdealVerticalOffset); + newVerticalOffset = Math.min(newVerticalOffset, previousVerticalOffset); + } + mTouchToWindowOffsetY = newVerticalOffset + mLastParentY; + + final float newPosX = rawX - mTouchToWindowOffsetX + mHotspotX; + final float newPosY = rawY - mTouchToWindowOffsetY + mTouchOffsetY; + + int newWidth = (int) (mDownWidth + (rawX - mDownX)); + int newHeight = (int) (mDownHeight + (rawY - mDownY)); + + // mDownX = rawX; + // mDownY = rawY; + + params.width = Math.max(50, newWidth); + params.height = Math.max(50, newHeight); + + mView.setLayoutParams(params); + + updatePosition(newPosX, newPosY); + // break; + return true; + } + + case MotionEvent.ACTION_UP: + filterOnTouchUp(); + mIsDragging = false; + break; + + case MotionEvent.ACTION_CANCEL: + mIsDragging = false; + break; + } + return true; + } + + public PositionListener getPositionListener() { + if (mPositionListener == null) { + mPositionListener = new PositionListener(mView); + } + return mPositionListener; + } protected void updateDrawable() { // final int offset = getCurrentCursorOffset(); @@ -111,14 +209,7 @@ public abstract class HandleView extends View implements ViewPositionListener, V protected abstract int getHotspotX(Drawable drawable, boolean isRtlRun); protected abstract int getHorizontalGravity(boolean isRtlRun); - // Touch-up filter: number of previous positions remembered - private static final int HISTORY_SIZE = 5; - private static final int TOUCH_UP_FILTER_DELAY_AFTER = 150; - private static final int TOUCH_UP_FILTER_DELAY_BEFORE = 350; - private final long[] mPreviousOffsetsTimes = new long[HISTORY_SIZE]; - private final int[] mPreviousOffsets = new int[HISTORY_SIZE]; - private int mPreviousOffsetIndex = 0; - private int mNumberPreviousOffsets = 0; + private void startTouchUpFilter(int offset) { mNumberPreviousOffsets = 0; @@ -152,11 +243,6 @@ public abstract class HandleView extends View implements ViewPositionListener, V return mNumberPreviousOffsets > 1; } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - setMeasuredDimension(getPreferredWidth(), getPreferredHeight()); - } - private int getPreferredWidth() { return Math.max(mDrawable.getIntrinsicWidth(), mMinSize); } @@ -283,15 +369,6 @@ public abstract class HandleView extends View implements ViewPositionListener, V } } - @Override - protected void onDraw(Canvas c) { - final int drawWidth = mDrawable.getIntrinsicWidth(); - final int left = getHorizontalOffset(); - - mDrawable.setBounds(left, 0, left + drawWidth, mDrawable.getIntrinsicHeight()); - mDrawable.draw(c); - } - private int getHorizontalOffset() { final int width = getPreferredWidth(); final int drawWidth = mDrawable.getIntrinsicWidth(); @@ -315,81 +392,6 @@ public abstract class HandleView extends View implements ViewPositionListener, V return 0; } - // Addition - private float mDownX, mDownY; - - @Override - public boolean onTouchEvent(MotionEvent ev) { - ViewGroup.LayoutParams params = mView.getLayoutParams(); - - switch (ev.getActionMasked()) { - case MotionEvent.ACTION_DOWN: { - startTouchUpFilter(getCurrentCursorOffset()); - mTouchToWindowOffsetX = ev.getRawX() - mPositionX; - mTouchToWindowOffsetY = ev.getRawY() - mPositionY; - - final PositionListener positionListener = getPositionListener(); - mLastParentX = positionListener.getPositionX(); - mLastParentY = positionListener.getPositionY(); - mIsDragging = true; - - // MOD: Addition - mDownX = ev.getRawX(); - mDownY = ev.getRawY(); - mDownWidth = params.width; - mDownHeight = params.height; - - break; - } - - case MotionEvent.ACTION_MOVE: { - final float rawX = ev.getRawX(); - final float rawY = ev.getRawY(); - - // Vertical hysteresis: vertical down movement tends to snap to ideal offset - final float previousVerticalOffset = mTouchToWindowOffsetY - mLastParentY; - final float currentVerticalOffset = rawY - mPositionY - mLastParentY; - float newVerticalOffset; - if (previousVerticalOffset < mIdealVerticalOffset) { - newVerticalOffset = Math.min(currentVerticalOffset, mIdealVerticalOffset); - newVerticalOffset = Math.max(newVerticalOffset, previousVerticalOffset); - } else { - newVerticalOffset = Math.max(currentVerticalOffset, mIdealVerticalOffset); - newVerticalOffset = Math.min(newVerticalOffset, previousVerticalOffset); - } - mTouchToWindowOffsetY = newVerticalOffset + mLastParentY; - - final float newPosX = rawX - mTouchToWindowOffsetX + mHotspotX; - final float newPosY = rawY - mTouchToWindowOffsetY + mTouchOffsetY; - - int newWidth = (int) (mDownWidth + (rawX - mDownX)); - int newHeight = (int) (mDownHeight + (rawY - mDownY)); - - // mDownX = rawX; - // mDownY = rawY; - - params.width = Math.max(50, newWidth); - params.height = Math.max(50, newHeight); - - mView.setLayoutParams(params); - - updatePosition(newPosX, newPosY); - // break; - return true; - } - - case MotionEvent.ACTION_UP: - filterOnTouchUp(); - mIsDragging = false; - break; - - case MotionEvent.ACTION_CANCEL: - mIsDragging = false; - break; - } - return true; - } - public boolean isDragging() { return mIsDragging; } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/SelectionEndHandleView.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/SelectionEndHandleView.java index 489c91bec..ebbb5e64c 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/SelectionEndHandleView.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/SelectionEndHandleView.java @@ -25,8 +25,7 @@ import android.view.*; import net.kdt.pojavlaunch.customcontrols.buttons.ControlButton; -public class SelectionEndHandleView extends HandleView -{ +public class SelectionEndHandleView extends HandleView { public SelectionEndHandleView(ControlButton view) { super(view); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/ViewPositionListener.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/ViewPositionListener.java index 0dd53f6c2..cf0dda3a2 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/ViewPositionListener.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/ViewPositionListener.java @@ -20,5 +20,5 @@ package net.kdt.pojavlaunch.customcontrols.handleview; public interface ViewPositionListener { - public void updatePosition(int parentPositionX, int parentPositionY, boolean parentPositionChanged, boolean parentScrolled); + void updatePosition(int parentPositionX, int parentPositionY, boolean parentPositionChanged, boolean parentScrolled); } From cad3f63433e3584c93b43a2fc2e47220fa20ce74 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sat, 26 Feb 2022 18:36:21 +0100 Subject: [PATCH 60/70] Refactor control button related files --- .../customcontrols/ControlLayout.java | 3 +- .../customcontrols/CustomControls.java | 2 +- .../customcontrols/buttons/ControlButton.java | 30 ++++++++----------- .../customcontrols/buttons/ControlDrawer.java | 7 ++--- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java index dfaf130d8..4975bb351 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlLayout.java @@ -16,8 +16,7 @@ import net.kdt.pojavlaunch.customcontrols.buttons.ControlSubButton; import net.kdt.pojavlaunch.customcontrols.handleview.HandleView; import net.kdt.pojavlaunch.prefs.*; -public class ControlLayout extends FrameLayout -{ +public class ControlLayout extends FrameLayout { protected CustomControls mLayout; private boolean mModifiable; private CustomControlsActivity mActivity; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java index 7fd3f1bc0..eade383fa 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/CustomControls.java @@ -57,7 +57,7 @@ public class CustomControls { public void save(String path) throws IOException { - //Current version is the V2.4 so the version as to be marked as 4 ! + //Current version is the V2.5 so the version as to be marked as 4 ! version = 4; Tools.write(path, Tools.GLOBAL_GSON.toJson(this)); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlButton.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlButton.java index 36949e11a..c11ab1484 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlButton.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlButton.java @@ -29,19 +29,15 @@ import static org.lwjgl.glfw.CallbackBridge.sendKeyPress; import static org.lwjgl.glfw.CallbackBridge.sendMouseButton; @SuppressLint("ViewConstructor") -public class ControlButton extends androidx.appcompat.widget.AppCompatButton implements OnLongClickListener -{ - private final Paint mRectPaint = new Paint();; - +public class ControlButton extends androidx.appcompat.widget.AppCompatButton implements OnLongClickListener { + private final Paint mRectPaint = new Paint(); protected GestureDetector mGestureDetector; protected ControlData mProperties; protected SelectionEndHandleView mHandleView; - protected boolean mModifiable = false; protected boolean mCanTriggerLongClick = true; - - protected boolean isToggled = false; - protected boolean isPointerOutOfBounds = false; + protected boolean mIsToggled = false; + protected boolean mIsPointerOutOfBounds = false; public ControlButton(ControlLayout layout, ControlData properties) { super(layout.getContext()); @@ -258,7 +254,7 @@ public class ControlButton extends androidx.appcompat.widget.AppCompatButton imp @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); - if (isToggled || (!mProperties.isToggle && isActivated())) + if (mIsToggled || (!mProperties.isToggle && isActivated())) canvas.drawRoundRect(0, 0, getWidth(), getHeight(), mProperties.cornerRadius, mProperties.cornerRadius, mRectPaint); } @@ -303,26 +299,26 @@ public class ControlButton extends androidx.appcompat.widget.AppCompatButton imp //If out of bounds if(event.getX() < getLeft() || event.getX() > getRight() || event.getY() < getTop() || event.getY() > getBottom()){ - if(mProperties.isSwipeable && !isPointerOutOfBounds){ + if(mProperties.isSwipeable && !mIsPointerOutOfBounds){ //Remove keys if(!triggerToggle()) { sendKeyPresses(false); } } - isPointerOutOfBounds = true; + mIsPointerOutOfBounds = true; ((ControlLayout) getParent()).onTouch(this, event); break; } //Else if we now are in bounds - if(isPointerOutOfBounds) { + if(mIsPointerOutOfBounds) { ((ControlLayout) getParent()).onTouch(this, event); //RE-press the button if(mProperties.isSwipeable && !mProperties.isToggle){ sendKeyPresses(true); } } - isPointerOutOfBounds = false; + mIsPointerOutOfBounds = false; break; case MotionEvent.ACTION_DOWN: // 0 @@ -339,8 +335,8 @@ public class ControlButton extends androidx.appcompat.widget.AppCompatButton imp MinecraftGLView v = ((ControlLayout) this.getParent()).findViewById(R.id.main_game_render_view); if (v != null) v.dispatchTouchEvent(event); } - if(isPointerOutOfBounds) ((ControlLayout) getParent()).onTouch(this, event); - isPointerOutOfBounds = false; + if(mIsPointerOutOfBounds) ((ControlLayout) getParent()).onTouch(this, event); + mIsPointerOutOfBounds = false; if(!triggerToggle()) { sendKeyPresses(false); @@ -500,9 +496,9 @@ public class ControlButton extends androidx.appcompat.widget.AppCompatButton imp public boolean triggerToggle(){ //returns true a the toggle system is triggered if(mProperties.isToggle){ - isToggled = !isToggled; + mIsToggled = !mIsToggled; invalidate(); - sendKeyPresses(isToggled); + sendKeyPresses(mIsToggled); return true; } return false; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlDrawer.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlDrawer.java index a7fbb154c..d048ab99f 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlDrawer.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/buttons/ControlDrawer.java @@ -2,7 +2,6 @@ package net.kdt.pojavlaunch.customcontrols.buttons; import android.annotation.SuppressLint; import android.view.MotionEvent; -import android.view.View; import android.view.ViewGroup; import net.kdt.pojavlaunch.Tools; @@ -20,7 +19,7 @@ public class ControlDrawer extends ControlButton { public ArrayList buttons; public ControlDrawerData drawerData; - public ControlLayout mLayout; + public ControlLayout layout; public boolean areButtonsVisible; @@ -28,14 +27,14 @@ public class ControlDrawer extends ControlButton { super(layout, drawerData.properties); buttons = new ArrayList<>(drawerData.buttonProperties.size()); - mLayout = layout; + this.layout = layout; this.drawerData = drawerData; areButtonsVisible = layout.getModifiable(); } public void addButton(ControlData properties){ - addButton(new ControlSubButton(mLayout, properties, this)); + addButton(new ControlSubButton(layout, properties, this)); } public void addButton(ControlSubButton button){ From fdaa98bc4dff07a899609bf7941de8f5b9bdade9 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sun, 6 Mar 2022 22:18:06 +0100 Subject: [PATCH 61/70] Fix some naming; Rename many resources --- .../src/main/AndroidManifest.xml | 4 ++-- .../java/net/kdt/pojavlaunch/JAssets.java | 4 +++- .../customcontrols/handleview/HandleView.java | 6 ++---- .../prefs/PerVersionConfigDialog.java | 6 +++++- .../src/main/res/anim/translate_left_side.xml | 5 ----- .../main/res/anim/translate_right_side.xml | 5 ----- .../main/res/drawable-hdpi/ic_flatstyle.png | Bin 1052 -> 0 bytes .../src/main/res/drawable-hdpi/ic_map_rmb.png | Bin 9797 -> 0 bytes ...es.png => ic_setting_disable_gestures.png} | Bin ...eeform_opt.png => ic_setting_freeform.png} | Bin ...lib_check.png => ic_setting_lib_check.png} | Bin .../{ic_auto_ram.png => ic_setting_ram.png} | Bin ...{tap_len.png => ic_setting_tap_length.png} | Bin .../text_select_handle_left_mtrl_alpha.png | Bin 478 -> 0 bytes .../text_select_handle_right_mtrl_alpha.png | Bin 486 -> 0 bytes ...btn_scale.png => ic_setting_btn_scale.png} | Bin .../{jre_args.png => ic_setting_jre_args.png} | Bin ...ter_1.png => ic_setting_mouse_pointer.png} | Bin .../src/main/res/drawable-mdpi/rm_jre.png | Bin 13728 -> 0 bytes .../text_select_handle_left_mtrl_alpha.png | Bin 346 -> 0 bytes .../text_select_handle_right_mtrl_alpha.png | Bin 347 -> 0 bytes ...idebar.png => ic_setting_hide_sidebar.png} | Bin .../text_select_handle_left_mtrl_alpha.png | Bin 751 -> 0 bytes .../text_select_handle_right_mtrl_alpha.png | Bin 752 -> 0 bytes .../text_select_handle_left_mtrl_alpha.png | Bin 1148 -> 0 bytes .../text_select_handle_right_mtrl_alpha.png | Bin 1155 -> 0 bytes ..._notch.png => ic_setting_ignore_notch.png} | Bin ...d.png => ic_setting_mouse_pointer_spd.png} | Bin ...r.png => ic_setting_resolution_scaler.png} | Bin ....png => ic_setting_sign_in_background.png} | Bin .../src/main/res/drawable/mouse_pointer_1.png | Bin 9015 -> 0 bytes .../text_select_handle_left_material.xml | 19 ------------------ .../text_select_handle_right_material.xml | 19 ------------------ .../src/main/res/drawable/view_handle.xml | 4 ++++ .../main/res/layout/import_control_layout.xml | 2 +- .../src/main/res/layout/launcher_login_v3.xml | 2 +- .../src/main/res/values/styles.xml | 19 ------------------ .../src/main/res/xml/pref_control.xml | 10 ++++----- .../src/main/res/xml/pref_java.xml | 4 ++-- .../src/main/res/xml/pref_misc.xml | 4 ++-- .../src/main/res/xml/pref_video.xml | 4 ++-- 41 files changed, 29 insertions(+), 88 deletions(-) delete mode 100644 app_pojavlauncher/src/main/res/anim/translate_left_side.xml delete mode 100644 app_pojavlauncher/src/main/res/anim/translate_right_side.xml delete mode 100644 app_pojavlauncher/src/main/res/drawable-hdpi/ic_flatstyle.png delete mode 100644 app_pojavlauncher/src/main/res/drawable-hdpi/ic_map_rmb.png rename app_pojavlauncher/src/main/res/drawable-hdpi/{ic_disable_gestures.png => ic_setting_disable_gestures.png} (100%) rename app_pojavlauncher/src/main/res/drawable-hdpi/{freeform_opt.png => ic_setting_freeform.png} (100%) rename app_pojavlauncher/src/main/res/drawable-hdpi/{ic_lib_check.png => ic_setting_lib_check.png} (100%) rename app_pojavlauncher/src/main/res/drawable-hdpi/{ic_auto_ram.png => ic_setting_ram.png} (100%) rename app_pojavlauncher/src/main/res/drawable-hdpi/{tap_len.png => ic_setting_tap_length.png} (100%) mode change 100755 => 100644 delete mode 100644 app_pojavlauncher/src/main/res/drawable-hdpi/text_select_handle_left_mtrl_alpha.png delete mode 100644 app_pojavlauncher/src/main/res/drawable-hdpi/text_select_handle_right_mtrl_alpha.png rename app_pojavlauncher/src/main/res/drawable-mdpi/{btn_scale.png => ic_setting_btn_scale.png} (100%) mode change 100755 => 100644 rename app_pojavlauncher/src/main/res/drawable-mdpi/{jre_args.png => ic_setting_jre_args.png} (100%) mode change 100755 => 100644 rename app_pojavlauncher/src/main/res/drawable-mdpi/{mouse_pointer_1.png => ic_setting_mouse_pointer.png} (100%) mode change 100755 => 100644 delete mode 100755 app_pojavlauncher/src/main/res/drawable-mdpi/rm_jre.png delete mode 100644 app_pojavlauncher/src/main/res/drawable-mdpi/text_select_handle_left_mtrl_alpha.png delete mode 100644 app_pojavlauncher/src/main/res/drawable-mdpi/text_select_handle_right_mtrl_alpha.png rename app_pojavlauncher/src/main/res/drawable-xhdpi/{hide_sidebar.png => ic_setting_hide_sidebar.png} (100%) mode change 100755 => 100644 delete mode 100644 app_pojavlauncher/src/main/res/drawable-xhdpi/text_select_handle_left_mtrl_alpha.png delete mode 100644 app_pojavlauncher/src/main/res/drawable-xhdpi/text_select_handle_right_mtrl_alpha.png delete mode 100644 app_pojavlauncher/src/main/res/drawable-xxhdpi/text_select_handle_left_mtrl_alpha.png delete mode 100644 app_pojavlauncher/src/main/res/drawable-xxhdpi/text_select_handle_right_mtrl_alpha.png rename app_pojavlauncher/src/main/res/drawable/{ignore_notch.png => ic_setting_ignore_notch.png} (100%) mode change 100755 => 100644 rename app_pojavlauncher/src/main/res/drawable/{mouse_pointer_spd.png => ic_setting_mouse_pointer_spd.png} (100%) rename app_pojavlauncher/src/main/res/drawable/{resolution_scaler.png => ic_setting_resolution_scaler.png} (100%) mode change 100755 => 100644 rename app_pojavlauncher/src/main/res/drawable/{sign_in_background.png => ic_setting_sign_in_background.png} (100%) delete mode 100755 app_pojavlauncher/src/main/res/drawable/mouse_pointer_1.png delete mode 100644 app_pojavlauncher/src/main/res/drawable/text_select_handle_left_material.xml delete mode 100644 app_pojavlauncher/src/main/res/drawable/text_select_handle_right_material.xml create mode 100644 app_pojavlauncher/src/main/res/drawable/view_handle.xml diff --git a/app_pojavlauncher/src/main/AndroidManifest.xml b/app_pojavlauncher/src/main/AndroidManifest.xml index d8fe8db22..28c2ea9e0 100644 --- a/app_pojavlauncher/src/main/AndroidManifest.xml +++ b/app_pojavlauncher/src/main/AndroidManifest.xml @@ -59,12 +59,12 @@ diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JAssets.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JAssets.java index 684bd6bcc..2f166583d 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JAssets.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JAssets.java @@ -1,9 +1,11 @@ package net.kdt.pojavlaunch; +import com.google.gson.annotations.SerializedName; + import java.util.Map; public class JAssets { - public boolean mapToResources; + @SerializedName("map_to_resources") public boolean mapToResources; public Map objects; } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/HandleView.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/HandleView.java index 075274dc8..4f7a7b4b3 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/HandleView.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/HandleView.java @@ -31,7 +31,6 @@ import net.kdt.pojavlaunch.customcontrols.buttons.ControlButton; public abstract class HandleView extends View implements ViewPositionListener, View.OnLongClickListener { protected Drawable mDrawable; - protected Drawable mDrawableLtr; protected Drawable mDrawableRtl; private final PopupWindow mContainer; // Position with respect to the parent TextView @@ -92,8 +91,7 @@ public abstract class HandleView extends View implements ViewPositionListener, V mContainer.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL); mContainer.setContentView(this); - mDrawableLtr = view.getContext().getDrawable(R.drawable.text_select_handle_left_material); - mDrawableRtl = view.getContext().getDrawable(R.drawable.text_select_handle_right_material); + mDrawableRtl = view.getContext().getDrawable(R.drawable.view_handle); mMinSize = view.getContext().getResources().getDimensionPixelSize(R.dimen.text_handle_min_size); setOnLongClickListener(this); @@ -201,7 +199,7 @@ public abstract class HandleView extends View implements ViewPositionListener, V protected void updateDrawable() { // final int offset = getCurrentCursorOffset(); final boolean isRtlCharAtOffset = true; // mView.getLayout().isRtlCharAt(offset); - mDrawable = isRtlCharAtOffset ? mDrawableRtl : mDrawableLtr; + mDrawable = mDrawableRtl; //isRtlCharAtOffset ? mDrawableRtl : mDrawableLtr; mHotspotX = getHotspotX(mDrawable, isRtlCharAtOffset); mHorizontalGravity = getHorizontalGravity(isRtlCharAtOffset); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/PerVersionConfigDialog.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/PerVersionConfigDialog.java index eb14119fc..d98c03407 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/PerVersionConfigDialog.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/PerVersionConfigDialog.java @@ -17,7 +17,10 @@ import net.kdt.pojavlaunch.multirt.Runtime; import net.kdt.pojavlaunch.value.PerVersionConfig; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.List; public class PerVersionConfigDialog{ @@ -38,7 +41,8 @@ public class PerVersionConfigDialog{ mJvmSpinner = mRootView.findViewById(R.id.pvc_javaVm); mRendererSpinner = mRootView.findViewById(R.id.pvc_renderer); - List renderList = Arrays.asList(mContext.getResources().getStringArray(R.array.renderer)); + ArrayList renderList = new ArrayList<>(5); + Collections.addAll(renderList, mContext.getResources().getStringArray(R.array.renderer)); renderList.add("Default"); mRendererNames = Arrays.asList(mContext.getResources().getStringArray(R.array.renderer_values)); mRendererSpinner.setAdapter(new ArrayAdapter<>(mContext, android.R.layout.simple_spinner_dropdown_item, renderList)); diff --git a/app_pojavlauncher/src/main/res/anim/translate_left_side.xml b/app_pojavlauncher/src/main/res/anim/translate_left_side.xml deleted file mode 100644 index 962be1cc6..000000000 --- a/app_pojavlauncher/src/main/res/anim/translate_left_side.xml +++ /dev/null @@ -1,5 +0,0 @@ - - diff --git a/app_pojavlauncher/src/main/res/anim/translate_right_side.xml b/app_pojavlauncher/src/main/res/anim/translate_right_side.xml deleted file mode 100644 index 607d4f8d0..000000000 --- a/app_pojavlauncher/src/main/res/anim/translate_right_side.xml +++ /dev/null @@ -1,5 +0,0 @@ - - diff --git a/app_pojavlauncher/src/main/res/drawable-hdpi/ic_flatstyle.png b/app_pojavlauncher/src/main/res/drawable-hdpi/ic_flatstyle.png deleted file mode 100644 index 777730532cf04e20569e94f0514893b81db87cb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1052 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yu@pObhHwBu4M$1`0|WDAPZ!6K ziaBrZ+Gorul{x3#moEU?f;d&b}TDMpQP;h&dcb2#k9<=^PW6c zdA_as!?w9~*%HS)aoY9WY0LCPZ^V*9^34*+J5pJk59MC z_}@vKFz89n&d!dEj+Q>3VVqT0XLtJa>ByLv99ypBZOIC=uU)@h{PNOL&of5GVq#*O zwrsgl#iN$6?kj`ASr#VNMh8cQ009mWl9`FueB(J{`zn>1cV%y7Iw-uI>n(obSgHMc)t&YywQol4m+ShPy@=(~J^PnTKetw#d-m&V z=9+lnr&`x4Y^FW=sq($|$DgMq@nxH5pZ)s!VM*ZL`R~qrx-6HL!onokfB5AiiR;t( zzfO|z{r>C8P8E4|%bD*?Pyd?n?|Ea&(OGigZO8wYe!aT>{N=stlm6~N-1hrN-p}(d zvN{>l-sKzbaz5uz zdOvB;%qNQ@7OVLwyp=uMEAO^v#@f|^*H*LvRZVZJLeueu(tTSb$QsG`+CcFUw_|v=T7*Zx9O`r|7F>dnsE+%`^W6~ Wtl`-qqofj0hVyjwb6Mw<&;$VHBDHTic_uciocdh#m+^m(AH8bzbylu}s&%5*3+|+>mG~a0u2*i#y z)Wd>6;JiOyW+tHLOEK#Q;OA734%(6#_(U?_i3fo$fY5r{mf=||Q(>=st?uspT9d}8 zY>G19$BXM1Tol*l;(pq}_w4%Ft*EmWQt$3RIrX!(o_ClxD*p=jX-B;Fb(mi18-_vc z=eNNU*uK2#X{~MftdHRfSrYeFYPY9nC?Vxu4IJ`2wg-0?#@okzq@SZ4p&$b=52PM! z4e10|LKS6|Wzd6o4ekamLrD)KysiaQk()(Ga`(-8+l!|ElH3))m(wjhc4q>ws= zZZZ4Nys-b=WXv1Me3)oF-BtcAVjx7+W~OLgvf%P8TVOI1fso zE5@6qZ%U%itQAnXFk}+>W79WfGZi}>3nm`l#8_9r1fAnC-5Ix%MVGw@g-@T7QAr(c`3;Tg$c8Y8S zrBFk@1|P!Pe-z_y4Rob$QIE--1WKwvyvTeV-2ckd!+r!gG~3(e-Im;)286P*-(I}-PZ~H*=*WYKVX$7n2eW#;M{KWFb$_=wvdZxNVW9c zot3U^N1NMk@81%NMzR z{3rH<%XKIlvP2;5PI046T!w=(Jp4@D01Xa^ol6tA`j9Q30H_k-oszd;e&1*Ovg*5^ z=EH^1Q~`X!!Jp0%xMymx+`689w{zPqf>D-H#(Tz^7`v6+&?d&IpzFm1B^i}OmX$WhMPOR?CTaiG&Pf>)#Rr~ecASdl48Lf6@=_29Q*4TxH5uA6Pa z6+y&(qzDdf2dYmNi*4(l4c*iS#oUbGdI;A^UVRy4HPRW}fLKae()j{ETd-Qrz^_~V z%7J6?rTaDCl90IP!>tqsGs?{qUAPzUaC>so#D8bsH$qXE$_Gc7O2SIj5Q~!mSfx>h zM5dgq#$2TVbxvXQ84wlBlf1($4%VW3J{YzeL9n2^mu*lz5s1dEYJ}pRql6wY z>*r*x#;vlDdXVk9qoiKnQRdwJR0(706Sl zz}2vz4^zzQMVY-5Twx_^NpD=VZj%-a*!g@DRZIp9oJ$B_P9R{m)c=7h6K6c6sGrF$*Hzk zc?-uVrHkIFd3D40;-1%7R;Z1ILZXe+6&@Fq?qxk6{>J-F-Q~yxml)p%_RXou#4i&Z z8LUm)j@9RQ3zm3w_+CC5_!@V4M1aMc#e3@d31@aq%AWK(D{YKCLUu)QHsu(cy)ozn z2);1@QHPA*SI^0vOr@ParI=GQZ^L%TwhQZhF#;!ZBc2&~IuHf$H6Sl=QhJSp#|P2Q zkA=0(Ov(>MiKY-!Sv7vEpXwP}Ul&}8x+wMCT-e+)R({Y=R&|bVjX(WMw;>r$s?S8T ze8mC5H%(l>gR?yAp}l28W`!&Qy?vT573Udfr)V(*mxQN=z(paPp+DcoW^bUB(DST( z>e^X7S;o=aDe4-8lKUBir1m~{Ok}~p!P$&-5|2f6kymEpQJmZF5$V(u#nPfuR^(cu1&<=b zEz=-&p~bROo--QcF@hOLEER#_wry7{bK!*E$XuixtF3=O*D2%*D9+AAIw`HM9g1c; zRG7Q5uOU9(M*XlX=DKs0ChL)7CUKPaZXP!V@^e|RLBy49dO7|L*D0M4qB&)Fv5>T+ z>Q*Nn;Y{lj_32~HcjRL&NecKe$Qbrm_qODaFL)ZAqYw77*sqltXG2;oj__*Mkyauy zGR^+1WdFA-3zDaH$iAGRCDv_WAxXY(nZdS=9d9-yMXSFz`>r@jX;Ivh87GsYUtQ7L zK3MiqSemkm(hgRhQ`RqHyc~-l*oef? z3B_rO;A6bX1rTeb_{s>MIo5Ovzapf`tJ6E7fSvwsS;Xljc{D}1n9;w-w7$=# zwsR}CKk)OB3T=$LMXB27L|=a6njkT{98)KS{DI||tAnhY(40w7IRke{XCaZJYaFfD zlDKf~{wNAQkR7l5SGZQNOC!i>E6x}ym0jkTL-LZnqOHa&g^3l|WPf!P8SWE%&9Eq4? z7jZc%4I5#H!95a93Rm*KJBu`_zv$1j9{XX={1IDTfDOAc!|qKwp^R)p)_%EuH<13G z%?d;BCk~FjysCPpp?dv!VVSPHT4xZ3Q*Y{W>}MAX+Fu#VkXjpt$j~$D&4olw`-rP9 z$=HZ!49+S8ik7{kA&{Y!+J>nXX<_Q);(KI*%jrLPFbGLsc;jkXe-uT3|I`6P*Oefx zh#D9ar3rBM>JC*(XfV&aGPBQoCO;_Dx|?6rfZ>3iWhGz|!gr(k;<`F5zvt9Y7i?hs$KMhp zC}fRZ+CIN4ROR^oIOQ=CW&C!?_-muxY(N%@CAWx2pp$Eby#<$U-gH5TgEH=np$m!` z=xco$r<~?DaVSa|VbJw>mH1{Hof5bw5-H&5&*oAMS^tf`Fm(=glKnQHIH>vZ^1efb zrdt(9ub_3U)=Z(w<=D8zAhP`F?UQZ5{fr0J@|@J_G!=}hsDYRSX$vpASlr5xRIn#( z1aW3&@5#isOAPPSiyCP8Ne{QXZ9hfxP6@!uO?A?-5wkyvJpwXAtiMZa`fdC4lDYU2 zwIG(S(6spm@5Fxc%COyH3(E?=F{}h8y$N3?C|tJ)~8j$610@6g*k< zJN!`OX`h`(9&u3nzr_%quML$dmIM`xx~SxW{W~9SzAck&(*djGaF-)I_xl`(|VsK}FLkAM@ovy38a9*9G%`_AR z6Fj?49As5n^7`qif~Z$-*6WboIGROs&9~Xi4y7+kLUfB`&VdDg7FUK95$$gpTa4z| zOYRRxMu!Jh>zJy|?(4R?FmF+`7&1fpDa}~SqtO1O{Y62c+qV*?O?+qi=v+-P_S&pY z%v(L@uJXKJ|3pk4dgGzL{WRW@vf(~6vt+pHca|n7H)`F(mKS~32pSbBM%s)~{m0;F z=XreNOn(|ym3Pi3oCUx9o9;dRS5w_p3)bn_*NRe4;@>X(hDeZjKuUM`D3Wp`RtbQTU-q0;$GZ$i z-bf35hX(Bth=WY&pMM))Sd`GJC3BU|Y!K|dwkMOZ6KWPd&&D)izaFa`e=V`O_MMG7 zA|Jby=JWYJad4v1(`)mVMw*|g#7YW|U$)!QTKY=tQXRa?uW(|f$I^PknkqHHdIr{> zF_)B;>CD^QzY<}WA*@^ME8AtIOxi54uT}6lP3XbS*g`!xl?Q$LQ4O-)wIwuCY_-TGV^LIw7tzdvW(}~x4=+(u3MM$ zPAKFZ=ylix?QWlRT|Tv_S4Koy7S(9N22m?YM%nj+Cp)THw^t%; zxaDG(su5KYJqmtajXA%04_|PtzgCG{yC}VrJqH(&evY)vMaT^wqT@0=XLu816!OXLJMx0lT0G;7;3Seo4?j0>5j-L%iJNLMM^**S8#DS+FBjhxT|+F+N7nI;0Kh#{>aNql#r%J|-U7_G8|XrR`op9nZ`Ph~>*Kxx zFyyDdoktiVvn6jcqm!TfS0K6IHeg=(`{2oI2ge2-+KA9asR=-O={w_4!1;}X_UK1Z zjWciK{o)Gvf&r)*j}$3kit9H7n5w4}^D`n+WW=RLNfhK2_HFEy<03!}uo|BuU3Ajk zUtSn%R0Ry>n{?0bB}CVw05Cz}a_qHkuF?b^<4&KiYbOZA_WVW`BE23bl#qOgA!PY;2O;Jv zapn%{N}9ed_fBG1_;aumMRU=uY83!yE~uDfI`qRlMpM;Eo4*GiU~PatdtXo@cpAl$ zt$@XtNot6Xd;$!nJT9j6fu`%fzUX6;Ah{P1r>!HLhIUonet`h7$I4DI9dhkzW9U^~ z?HZwj1vY>_y`QbfbaDw`4ucoyz%&Ep2P{rM2XSX8Dk5^^98%A{++O^2jimiMqo1tb z(GD108g{O?e9&SnaMW00rP&yS9_Q5w>H3xRB|+$Ze1njXW^!KJ{@gVhinc-4?uqTI zP?)}ifaN}ppK%q}s9Stjy5JxbVspNs@j-Mn_%IAZ4?%2>*uj3O((-*qjd2S{j(YZ| zyvKBu+8Ja(eI^pEg%2aLAIFD5WKY#~f9q8xOT(AFIDn)o)87$Hw8PI~F_e{tnI&%K zJS9*wD3gIRW0tzgB7w7&C7dpo7wn+N?+{_W^eBEeLQg6uwr`kzjjkE@e8E$grqUBTI1dX5r)!sR zz5b4eXivWz=si6 z@0dIv6&&SN=dG_Cv$;`1-{S=#Zzl%?0 z$SP>ZL$4*n?Yy9IQ0Cz^DfSF{{ndM?gFYQ*S#_`mhm<%^2+W6^u9`SK@g`9BJbTef zNj%arEyP2#kVvFN0MEcRg`)E!=sBPm^naaANHq2e@aWmbL?cP4+Kj~_LJze<)^$6R zO<}Fq++yPn^D{jR-Bp5AE=C9z_jj8`qI+KAhwu+XW3Ku%{Vn(k`sV~y$!n@Pu38ca zz9BAj%owiT8+jYcq6KPeYH`&}m0$j(vsdM*52Wm0EO~UH@3{o6!t{KT?)g{%PFio9 z#PwGJ=W>ZqY+*vYFka061fE7}Y&yLgilO^0{MP;Nu-w1HxErIBrCZBHxu!Kx0t z6fQnR-C~(mbws^6?AJM`PBgV~-T(8d8!eKio^f$Fq0)Gn-rx)%EV+M#^BSMTk3rNx zRI`aVR|AxIdp=9%24TbPrcK>x0T%X5AUxLvSbDAXTF!qv6E0r$>BsVtKGZ6Wiqlz; zqa_mukq5enBeRQ*P`bnD%Dfng=Vg5NX zc9b-)wT+4aB0BnJzPbS}j_|)H^W3H*|dOuA_DC;Uw`B89~mLk8DLW zgbezo*JKhtNsu__CqHX;ap`yswJen4fuu}|Ex@&iqP+V=CDE5Yb0v##|34Gxxkw4G zu3@s}Q>4iM|6-PDmJy&q=1IE;jKs!EV00jCx>i=k0Ar^w`NnNfz+8YFr*%t0VwpL$y>}6BUwVtgCpT?Yj z_eudwVgF_YV4VXXNrUw1U_;1u!XTvo=+6|5SfTIFe8z}@3Gwx=;s?NMgMVRUU{)ek zMb|{4-odsaOetrzA`t+r7i(gE4Rc`yYY{rua~TdJ0HO&F=-CSO1hC~pA3)H#XKR>2 zx7gIZ-k!2!bH5tHd9|IAZIK;)0|2FHSisG=zoRQI0m!pti_=Jte<0LEBEMCBSY1rl zMA{rESf+ZJOgIkCrb&=`?J6W(VX%4zuiBfxWt>82)8_!7F2FK^yRtHqUALD-8mU~g|-0beY?eJq8C}al7VG{-YLF|0dO{9EOu#2oHm*2 zC1Wa4J|1XNVg(D}titrTDt&O}F9p;cMps8Z=Ed#DgzXyvVp*59X z709~&$mY_!B9`q`yo=nh0^agv9fX-?$o6^(VDsxK{Q9lh+6wXUF7hdwmn{296N7Py)Z#%V2`(V^v6J%b@mqUaFJoodaz@UdDwNm771Mk+zp}c@;~-mc8%bk zmmo>8`z~6vX86+aB~pz|T+<*%zhecJ&|B+skM@QwWJC@Sn7c>jhA;75y#&A`y&TZK zCX=}zK>uIh&F01VVeMVlt!*D$yOl1pD`^1LgB~7yv)u3$N{HjDxwUOYS9ZEe;(cF` zeakxofcrKkM%HI9+{D^sboI!OXz(`x9M=^f_Y|ny$dt0s^vjaE;M{m+RSUWrA<4b8 z+_*)pA~zA5L(E%6NRUQ=8vW`^=f*gRlhcPj72mr*3g<=dn-?~{)$fS8Qz{LExw~G< z{t}jY6@FJ_*m02|sr&jj{WYS|=ls`|5K6a|{T|>B$2E$TvXD%dmE9aStp1MF+Sb<` zx!C>X9x^H2Q%guly*6)Duj3baBE382ys|K$-~zoN`reiGPxhZQq>JkAsIx=Y4ajsA zHFHe?mMy!!e5BC#4*;DONH_b4cmy8yiZgGYVr`LkIa(3^o+~#x27pia4>fkEzyIfn zC4AA`zO2V8k$S}%nv*&d31mC@o_y#pD_SFb`7Hz}E~$f+kuFDGSWM=fvPy7wB!byV z^7mJ%N{+j#zPzTV0!oTjr9%{gLu|HfcQ=&#m3D!qr8fLWQ8uWN|4(7 zZaPA^U|Ni!J>Nc65_||3;Rogh>Sy>8CBGv8T2D7h|k5qxOAmuDB^@aO)O%RB2{m*{^7$~>^46gTU zRI$5i18kPV2}=7ti6~LaNj#r(7B4Kn^Uh7rKBbX!%TRA}T3gAl6U4_4sEMjxFn42Ly96Yy`GPZUj^hD2;`0hL4n#Ag0! zV+N0WjwaOyZmHgjiG1R^9=qG5Mw`5Zo&7T6UO9{>0|G+SM|lJF#cX21jlKICTVr`;7nad5u233EM3+;5g55jO}n+*~jtygnji zM}XF!xR2EqV0rej6=gAf(vp8%m!9?a07$Qc01J?vV(kA#b_VKdAAnG#AqesWg{Gzc z+W38GAx-v{vX3&djK^FJB_B1do*U@Q1!}Ih$f!MK7W%&7uw4?W*O4B4{%SqQ3~(fO zQtW5?GxCAj>d-iMgouzYwg-WGp830*_ZLKUG)TlSPi0EPk8)_?RnY_68r$Rsl6 zpo26F0W!)$%OjVN&pq5f@xkEcbfS{5dXcA;t7u$p?CK<^lhRmZfdsXmAEwbj<2A)d zXtX(<y?+wFX0jS7 z3BOv@Z!G8vVp%sdZ1*#wHIs!;C(SJpv0d5oPI?_;xYY=|+I90bZTYBS#KX?KC*dLm z^ojzTcGBjP63*<&zNmoNfXy3vEn&aCN8gGIUNrzwK7a;M0xUSuWzfv2?MoWZA17E~ zlB6`^HRIzsAu*g~4iQpkb5GrJh~P@zr?=y7)RvJPAT1Z^J0JtA^ z+gwKFZYQRkOc-LDr-4;wbf^mCUt|MSw#)~F7-%&1{kCk41E;#rf+Gy~Dbm!CwU%d{ z+o^gGf*VgEUnKYT)SSnKwn$cs_6FUs@Da`!dX@0^)0!;5fij~Ili2`6zQz!ICHA;7 z&`xPZF>==u`!I*o-e@noK-y7_aV`3#<+~7^Ox29h9-^?kHB@+APW_>5iP(0*UALmm zzM;DH&{MQG50WDm38j@urnIW;TNa%t?kqh;gi4{Ni-j^mQX+NwZT3Ds=g2kUeDrg zw@OCYa~7tDeHG64rP9f)?!S%=2gTKy!@>S?^I`qEK1Lqr#3w^i*B*;J8hI@tC zt(>8SkRyWbo)y9U9A&zt9h0UcKE7Izesgp&Qly0O9{5DBnixh$ME0(9l9vf4i#u{g z$v1uw$Y3%LF4bDRb*M7Wfw_hITPV2ltq3mh28pG>Os?XQ(;9;*Xd3jhfo6UE(ieDu zf{5DS*Y0(_45;jwv|82;2jgmnpN~-qT~qeKD6A11l6`y?)~kQyLnz1h z5==Z+FK6yIc?g75GFGJ5%z&)T+HRdb%vy+JzzrX3m2FPYEYKVW!2iNPXnj+?3LU5W F{|n#aibntd diff --git a/app_pojavlauncher/src/main/res/drawable-hdpi/ic_disable_gestures.png b/app_pojavlauncher/src/main/res/drawable-hdpi/ic_setting_disable_gestures.png similarity index 100% rename from app_pojavlauncher/src/main/res/drawable-hdpi/ic_disable_gestures.png rename to app_pojavlauncher/src/main/res/drawable-hdpi/ic_setting_disable_gestures.png diff --git a/app_pojavlauncher/src/main/res/drawable-hdpi/freeform_opt.png b/app_pojavlauncher/src/main/res/drawable-hdpi/ic_setting_freeform.png similarity index 100% rename from app_pojavlauncher/src/main/res/drawable-hdpi/freeform_opt.png rename to app_pojavlauncher/src/main/res/drawable-hdpi/ic_setting_freeform.png diff --git a/app_pojavlauncher/src/main/res/drawable-hdpi/ic_lib_check.png b/app_pojavlauncher/src/main/res/drawable-hdpi/ic_setting_lib_check.png similarity index 100% rename from app_pojavlauncher/src/main/res/drawable-hdpi/ic_lib_check.png rename to app_pojavlauncher/src/main/res/drawable-hdpi/ic_setting_lib_check.png diff --git a/app_pojavlauncher/src/main/res/drawable-hdpi/ic_auto_ram.png b/app_pojavlauncher/src/main/res/drawable-hdpi/ic_setting_ram.png similarity index 100% rename from app_pojavlauncher/src/main/res/drawable-hdpi/ic_auto_ram.png rename to app_pojavlauncher/src/main/res/drawable-hdpi/ic_setting_ram.png diff --git a/app_pojavlauncher/src/main/res/drawable-hdpi/tap_len.png b/app_pojavlauncher/src/main/res/drawable-hdpi/ic_setting_tap_length.png old mode 100755 new mode 100644 similarity index 100% rename from app_pojavlauncher/src/main/res/drawable-hdpi/tap_len.png rename to app_pojavlauncher/src/main/res/drawable-hdpi/ic_setting_tap_length.png diff --git a/app_pojavlauncher/src/main/res/drawable-hdpi/text_select_handle_left_mtrl_alpha.png b/app_pojavlauncher/src/main/res/drawable-hdpi/text_select_handle_left_mtrl_alpha.png deleted file mode 100644 index 9cdc25b4581dba8cf1d440f233ad79458e1ad24b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 478 zcmV<40U`d0P)T2qefINpU!KQvos*e*=z3A6l{P8Y1o7eWMK<(u+4U0 z7e<}IDT6xb<{$b3J_I4iT8piQUO0yLkRpG|Sc;9q3_L{;T9mdFyAok&k!R&Lrk7D( zAb8zEa38!1#G1IJ8{tAIHsIwo&d)TR~QgoBqggNH)gL6twyHFPV=ygrTl@TPsQNSu?WfP6#zJs8jKN2Qv2;e(Vd?OWp5^_B zV(Hjup8v3>rUA}FexCDuI3IIHr-={V!??Ylc^esb#)rN*jKjk}uQnYQT|qyehL*%s zKnu*m9ba+(mnDbZ^rw)7gvDp}uj@2@Nb7+qSNJ$~1ed(b9J<2Cv|(uDmtUmw4FG)L U{GPf85dZ)H07*qoM6N<$g0b%0j{pDw diff --git a/app_pojavlauncher/src/main/res/drawable-hdpi/text_select_handle_right_mtrl_alpha.png b/app_pojavlauncher/src/main/res/drawable-hdpi/text_select_handle_right_mtrl_alpha.png deleted file mode 100644 index 276d4809159289a7c65f44d9a6e0dd81b6f07984..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 486 zcmV@P)4l((?8 zv5~wi$e8hay3f>PqqygJ&gIl+J@dWyo_kN{81uU^3fr&+n=A_(unrkmgEXXI6_SvE zIK*HCx}eSkU{F-S2YGnn3)c;`Q08KA#;4#?uW$&x5Oys%Z6Ubm0cIfLQgF&*aM7|$ z(JKPMIexi?|N0|c>KURg1Sf=o$r&_g2PXxC-(f&II4&4WuAovgcu6?;1zP`8Fs;aj zG=t}bgA4raR~w58!F!s)3kt!Pn!z!iSCYZkn!ytaclby%xF0@*gLgE8+l7N^`b=sD z)7ti4FqkfGr)F>!?_)^?-$IS{dO9lfrl#MRhLCn}HJk{oqnlmX`RL$1C|j{_Fb3tW z1k)dxIRF3v diff --git a/app_pojavlauncher/src/main/res/drawable-mdpi/btn_scale.png b/app_pojavlauncher/src/main/res/drawable-mdpi/ic_setting_btn_scale.png old mode 100755 new mode 100644 similarity index 100% rename from app_pojavlauncher/src/main/res/drawable-mdpi/btn_scale.png rename to app_pojavlauncher/src/main/res/drawable-mdpi/ic_setting_btn_scale.png diff --git a/app_pojavlauncher/src/main/res/drawable-mdpi/jre_args.png b/app_pojavlauncher/src/main/res/drawable-mdpi/ic_setting_jre_args.png old mode 100755 new mode 100644 similarity index 100% rename from app_pojavlauncher/src/main/res/drawable-mdpi/jre_args.png rename to app_pojavlauncher/src/main/res/drawable-mdpi/ic_setting_jre_args.png diff --git a/app_pojavlauncher/src/main/res/drawable-mdpi/mouse_pointer_1.png b/app_pojavlauncher/src/main/res/drawable-mdpi/ic_setting_mouse_pointer.png old mode 100755 new mode 100644 similarity index 100% rename from app_pojavlauncher/src/main/res/drawable-mdpi/mouse_pointer_1.png rename to app_pojavlauncher/src/main/res/drawable-mdpi/ic_setting_mouse_pointer.png diff --git a/app_pojavlauncher/src/main/res/drawable-mdpi/rm_jre.png b/app_pojavlauncher/src/main/res/drawable-mdpi/rm_jre.png deleted file mode 100755 index dec16982a9887b73dc167b3854a85172058832ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13728 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 diff --git a/app_pojavlauncher/src/main/res/drawable-mdpi/text_select_handle_left_mtrl_alpha.png b/app_pojavlauncher/src/main/res/drawable-mdpi/text_select_handle_left_mtrl_alpha.png deleted file mode 100644 index 95c0168cdc36bb16e2050e9cb18e32f4400b55be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 346 zcmV-g0j2(lP)2%5q#;Np}YBC1J4MMNxLqM~Rn68s1?m>J>i z|G*Ji9PYj6c;GkRKbPmg@x1U8LkhbnqJkDW=;8)F^fAC4?(u+2&v=qJl7LUl;Rn#S zjN8H)z5+)5cWe3QE-;G_=gSjNANS^t@f|VFm-neYX*?;!`LamrvyZ7#VA~?_G{m+p z)3OL0D8)Gqi@=d$VACRStQc6c2z*ftEL#L#DaE-(D_8^`;zuFy1A7*MJ9twFbQjIG zMPM8y{6>g#2gU)`td50s)I&zjD=g7$w6bt*2Kj^1MTbf#tEdT%j07*qoM6N<$f;4`YrvLx| diff --git a/app_pojavlauncher/src/main/res/drawable-mdpi/text_select_handle_right_mtrl_alpha.png b/app_pojavlauncher/src/main/res/drawable-mdpi/text_select_handle_right_mtrl_alpha.png deleted file mode 100644 index 569332abfeaaf6e7e259a2d9fd68bd0df3065a09..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 347 zcmV-h0i^zkP)!J0%fkvj||0Pq~3@ zEL#U&2Mqjej6>us13M7{y%~-ypJX>;pf|;i)jQc%2=tz?ViDL<3Y=iwBCx3x=)dl& zMc|cE;6nbP>eEmRe76X^Pz?OA2s~B{e6a|u$P2C!cxn+?#!w;d3tJX}1=(bx1`bfP z2uxs84*sxl-#9?Z>O4-!fj;*6_M7v(&w0*sM#M&p1odDZSPa&J z&0q)E1$KiLum`k)edHiHOxnOv&;gEv6QGlv1j{97F%B#PXTU@70=x$WPy#7P_*#x$ zEAP{vd=`Hv{%(;{-N$gy$PBvy-bJ#i#q=koJP4cw)_`tiT2ez{xf9p`+Ck3%i>pxJ z^U-CD0N23h8ZXm732gV8c^5Lux@v((yveI)`S3Agc@=?&yzRE@Seld#2-M%O*OS2M z;I;vAX;cU9_abi;PYRz53GDMEa2B|4Wa*~SiKf+qygHs+Q)47NQ=5+|toh2u1orU{ zYd&U!Ck8W6%b1-W1U4JnJmNBDs|SI)(|t22@T->$JR7yA{tNtzxN6|s`zyA25O~w5 zJUxkQ_aN}DQGs8;77qfuj4ojL#+(gTM}hrx4{8SmZ(A1|tpB>LU6n znBzg@LPjxXA9!uypAGtH4l?0*6Sr+U&}xKd56Q zr@=6B9$LIU%V6nVmM|INK6Lpk0QY#Hul2IkQ;^Q$Op_diN}S7PYi|v+?zx0noCe8Z z=reJK{Fo6e_G8xR^G?S|*5_r}{!Zcq&;-u2*e?8oIBiiq00+QKo`MEVOa@E9F>njK zk#HSaidP$^XB%@`JMja3Mjm*l866TmMvi#`=*ZKaOgnwyR h&7FO!gvr-T<2y|(8@#<}Ci4IQ002ovPDHLkV1gD8WLf|K diff --git a/app_pojavlauncher/src/main/res/drawable-xhdpi/text_select_handle_right_mtrl_alpha.png b/app_pojavlauncher/src/main/res/drawable-xhdpi/text_select_handle_right_mtrl_alpha.png deleted file mode 100644 index d3602d9888ec5b8fcf1061180588fbbbb7ff0fbe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 752 zcmV-+A-&_LhII_c`aWQ=i_|cCkL4^E~Hwe&-b_eQW@o;Jk7U zoCO`A9h?RymE+10r4_V*X3zu$(X=AJYQFM5ZG+2g!5U*-f*r5 zfd`GWF@?MUOFRhNYov`S_A*)HB?G@06!=X$gmHm?2q#3BJqX-qP+tCg+~Yyueq$$* zICnh=+yg!v75LDDz)eQm7?$u&4+7U2eTk489t5reZw<<0Z`$EO;8O6?U^C4D>kbbB zXY2ICS_ZxYD?JFT0vDvbSDU}WGcUsgj*K>f4~FD%I>a>-H|ro=w|H(y;2RwzRCp1{ ze{>i4WTgMQ2BwR%;Pd8zf$20`s^#J^CW6fp)-951X$B=+^v@KhF$r9hux^pW{EtUB zUTIDc$HC2j>j{+dYi;UN5w#L_Rfft?&KzVs0xR?}lA7S64|i4i{$Vx_>dSU0ytFo)4@fe$FuKGJsZ5Mn&Msn0000x}*Pp3fyNZ+t3oE5Oe% z#2AOkvWpZ@02*WfA3+>grVsE*0MI7>=-QPK4}dZv%D_V$;yBMUM%aPrN(SK3Sn{#i z#8zBoXUsz)fX$s}BL?h|WrA_07^MWnh;=6X{~}ggAHNel&pbTCYfTAY|kRrB{EvTFYp$}c#gCo*pM(vz!QAHBm-)WWliMB0O$CeJw#eO zt=c`!E;S2#A`Q!E0Pp2Pj;-*?=757J0FUwxM@bsTRo>k602i6!2sy0=vYO(uozNY%PD|oZbLq4y)YJ|>)*WX_ zu2OLaT;+GmOIk4JvH(zF+G>Hv=OT5N*;2^YR)Hlqskp66*EvhW8g7+K+;_R8;U8vL zvgD}+3BFRxmDGV7e8;p}?6VFF{zT0~>j0MA;3q3~>@&@E%O%5AWPo3g7G59en5>Rd zzmR)8%b?Leb&>OYtagm16L^Ut!<}|f6VhUi)BLEzbo89--p6MrTa8t?mN?I+))SRA z>v zB8MPGw~wydP1n7HHV@RGCMZ%&+bAH)qMSjcshF#Aec@Nzfu-nHme+rA&n?fsW*0E%_H>)6KwGczPZH O0000f_d(Np_ zki;IfRasj>EYemGi4bdv6+8E0O$9|Qk%CwYMGZ|&b82cDX4I9mWo|u*e!a~rhC!rw z&Ha|1zppfvaakW)VrA6bgL9a3M9r5D8#kuQ?KM+ku}CcHwE6!0^~T=KTSLo1d+o9^ z+aZ?{{rWK@Dkz}PX*&J+>y5peS*)aJz*<|4sH&LK6n7u+)(&t|D|E(E((eK5Z8T^` z(_FU!Z%GOGTJ)mDsy11r?7Zo2ThdRc+;Xwr?Wii&7&hRv)7=ET*@%T107KcJhurUk z@iZS>?BYG3SJiHBTGBnhaW+bN-5VbEj?LWy+|C@hplGL8J<=^px{&$8F6gzx3m)u- z&~n<+0KQzb#FKt?Aq~YYCX|()0CP;)de0b2<6TLC&t&e!S2MHc4CM`62!_idPkYLO ze1W5Yz$I0WTb^`TCj*{U4dTOBY`}KwlK#cXfaip@jh?kAPvE5{0xoLUkhBbx47eE> zH?rDp3-gS$!X_U@6>E~IMzR4<1c|h+-<;N2kzZ)pr!O#Y*%p`co8f*Z1A8$8M)CtL z2FInQ`u~WuuEy`n^7G-E)q!zim1IKs--@)Zlmk}e2R!6taO7B&A8;c;RqLN~JeVhN zD==`ZZ6ZJ5!vm$)Uz_ z6MOxZ#|qPGM-6mKfI8%T7c<5^;`ua+!s+;4!vezwGxX%sKCv(VBM(>Q&v|@JuPruX+##dBa4PMC|6zcy98J7W)h5F>SY?H>J{7S@ zS*#%zsjHiI-1kNub=Ji!OTS@K_k~KTRvNb4GE4O->D4rA)_IdonJ{5mjjY4RzW{r9 VK~u{Msc8TJ002ovPDHLkV1gvREKdLc diff --git a/app_pojavlauncher/src/main/res/drawable/ignore_notch.png b/app_pojavlauncher/src/main/res/drawable/ic_setting_ignore_notch.png old mode 100755 new mode 100644 similarity index 100% rename from app_pojavlauncher/src/main/res/drawable/ignore_notch.png rename to app_pojavlauncher/src/main/res/drawable/ic_setting_ignore_notch.png diff --git a/app_pojavlauncher/src/main/res/drawable/mouse_pointer_spd.png b/app_pojavlauncher/src/main/res/drawable/ic_setting_mouse_pointer_spd.png similarity index 100% rename from app_pojavlauncher/src/main/res/drawable/mouse_pointer_spd.png rename to app_pojavlauncher/src/main/res/drawable/ic_setting_mouse_pointer_spd.png diff --git a/app_pojavlauncher/src/main/res/drawable/resolution_scaler.png b/app_pojavlauncher/src/main/res/drawable/ic_setting_resolution_scaler.png old mode 100755 new mode 100644 similarity index 100% rename from app_pojavlauncher/src/main/res/drawable/resolution_scaler.png rename to app_pojavlauncher/src/main/res/drawable/ic_setting_resolution_scaler.png diff --git a/app_pojavlauncher/src/main/res/drawable/sign_in_background.png b/app_pojavlauncher/src/main/res/drawable/ic_setting_sign_in_background.png similarity index 100% rename from app_pojavlauncher/src/main/res/drawable/sign_in_background.png rename to app_pojavlauncher/src/main/res/drawable/ic_setting_sign_in_background.png diff --git a/app_pojavlauncher/src/main/res/drawable/mouse_pointer_1.png b/app_pojavlauncher/src/main/res/drawable/mouse_pointer_1.png deleted file mode 100755 index e5bb2041d07966a63bcc936e4cacab3edad7b698..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9015 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 A#sB~S diff --git a/app_pojavlauncher/src/main/res/drawable/text_select_handle_left_material.xml b/app_pojavlauncher/src/main/res/drawable/text_select_handle_left_material.xml deleted file mode 100644 index b228d3f5a..000000000 --- a/app_pojavlauncher/src/main/res/drawable/text_select_handle_left_material.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - diff --git a/app_pojavlauncher/src/main/res/drawable/text_select_handle_right_material.xml b/app_pojavlauncher/src/main/res/drawable/text_select_handle_right_material.xml deleted file mode 100644 index acacbf678..000000000 --- a/app_pojavlauncher/src/main/res/drawable/text_select_handle_right_material.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - diff --git a/app_pojavlauncher/src/main/res/drawable/view_handle.xml b/app_pojavlauncher/src/main/res/drawable/view_handle.xml new file mode 100644 index 000000000..f85c50284 --- /dev/null +++ b/app_pojavlauncher/src/main/res/drawable/view_handle.xml @@ -0,0 +1,4 @@ + + + diff --git a/app_pojavlauncher/src/main/res/layout/import_control_layout.xml b/app_pojavlauncher/src/main/res/layout/import_control_layout.xml index 4e5704f38..5aac9e3d1 100644 --- a/app_pojavlauncher/src/main/res/layout/import_control_layout.xml +++ b/app_pojavlauncher/src/main/res/layout/import_control_layout.xml @@ -12,7 +12,7 @@ android:layout_height="match_parent" android:elevation="-10dp" android:scaleType="centerCrop" - android:src="@drawable/sign_in_background" /> + android:src="@drawable/ic_setting_sign_in_background" /> diff --git a/app_pojavlauncher/src/main/res/values/styles.xml b/app_pojavlauncher/src/main/res/values/styles.xml index 0c537ead5..5067d8708 100644 --- a/app_pojavlauncher/src/main/res/values/styles.xml +++ b/app_pojavlauncher/src/main/res/values/styles.xml @@ -9,23 +9,4 @@ true @style/PreferenceThemeOverlay.v14.Material - - - - - diff --git a/app_pojavlauncher/src/main/res/xml/pref_control.xml b/app_pojavlauncher/src/main/res/xml/pref_control.xml index 982daf915..f5cc23764 100644 --- a/app_pojavlauncher/src/main/res/xml/pref_control.xml +++ b/app_pojavlauncher/src/main/res/xml/pref_control.xml @@ -9,7 +9,7 @@ @@ -21,7 +21,7 @@ app2:showSeekBarValue="true" app2:selectable="false" app2:seekBarIncrement="10" - app2:icon="@drawable/tap_len" /> + app2:icon="@drawable/ic_setting_tap_length" /> @@ -35,7 +35,7 @@ app2:showSeekBarValue="true" app2:selectable="false" app2:seekBarIncrement="5" - app2:icon="@drawable/btn_scale"/> + app2:icon="@drawable/ic_setting_btn_scale"/> @@ -48,7 +48,7 @@ android:key="mousescale" android:summary="@string/mcl_setting_subtitle_mousescale" android:title="@string/mcl_setting_title_mousescale" - app2:icon="@drawable/mouse_pointer_1" + app2:icon="@drawable/ic_setting_mouse_pointer" app2:selectable="false" app2:seekBarIncrement="5" app2:showSeekBarValue="true" /> @@ -56,7 +56,7 @@ android:key="mousespeed" android:summary="@string/mcl_setting_subtitle_mousespeed" android:title="@string/mcl_setting_title_mousespeed" - app2:icon="@drawable/mouse_pointer_spd" + app2:icon="@drawable/ic_setting_mouse_pointer_spd" app2:selectable="false" app2:seekBarIncrement="5" app2:showSeekBarValue="true" /> diff --git a/app_pojavlauncher/src/main/res/xml/pref_java.xml b/app_pojavlauncher/src/main/res/xml/pref_java.xml index a45405076..64d9a5164 100644 --- a/app_pojavlauncher/src/main/res/xml/pref_java.xml +++ b/app_pojavlauncher/src/main/res/xml/pref_java.xml @@ -11,7 +11,7 @@ + app2:icon="@drawable/ic_setting_hide_sidebar" /> diff --git a/app_pojavlauncher/src/main/res/xml/pref_video.xml b/app_pojavlauncher/src/main/res/xml/pref_video.xml index 8832a5838..255609284 100644 --- a/app_pojavlauncher/src/main/res/xml/pref_video.xml +++ b/app_pojavlauncher/src/main/res/xml/pref_video.xml @@ -18,7 +18,7 @@ android:key="ignoreNotch" android:summary="@string/mcl_setting_subtitle_ignore_notch" android:title="@string/mcl_setting_title_ignore_notch" - app2:icon="@drawable/ignore_notch" /> + app2:icon="@drawable/ic_setting_ignore_notch" /> + app2:icon="@drawable/ic_setting_resolution_scaler"/> \ No newline at end of file From 22f6b8369ad15a17511ec43fddde9befde6f4658 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sun, 6 Mar 2022 22:33:23 +0100 Subject: [PATCH 62/70] Rename more resources --- .../pojavlaunch/customcontrols/gamepad/Gamepad.java | 2 +- .../drawable/{pointer.png => gamepad_pointer.png} | Bin 2 files changed, 1 insertion(+), 1 deletion(-) rename app_pojavlauncher/src/main/res/drawable/{pointer.png => gamepad_pointer.png} (100%) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java index e0ab49553..6e473d0fe 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java @@ -117,7 +117,7 @@ public class Gamepad { Context ctx = contextView.getContext(); mPointerImageView = new ImageView(contextView.getContext()); - mPointerImageView.setImageDrawable(ResourcesCompat.getDrawable(ctx.getResources(), R.drawable.pointer, ctx.getTheme())); + mPointerImageView.setImageDrawable(ResourcesCompat.getDrawable(ctx.getResources(), R.drawable.gamepad_pointer, ctx.getTheme())); mPointerImageView.getDrawable().setFilterBitmap(false); int size = (int) ((22 * getMcScale()) / mScaleFactor); diff --git a/app_pojavlauncher/src/main/res/drawable/pointer.png b/app_pojavlauncher/src/main/res/drawable/gamepad_pointer.png similarity index 100% rename from app_pojavlauncher/src/main/res/drawable/pointer.png rename to app_pojavlauncher/src/main/res/drawable/gamepad_pointer.png From b6c250cadd9f09e1b8775841df737ddcb3115828 Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Sun, 6 Mar 2022 23:12:33 +0100 Subject: [PATCH 63/70] Fix improper array filling --- .../net/kdt/pojavlaunch/EfficientAndroidLWJGLKeycode.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/EfficientAndroidLWJGLKeycode.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/EfficientAndroidLWJGLKeycode.java index b8eb1a8dc..dfc650ad1 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/EfficientAndroidLWJGLKeycode.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/EfficientAndroidLWJGLKeycode.java @@ -17,6 +17,7 @@ public class EfficientAndroidLWJGLKeycode { private static final int[] sAndroidKeycodes = new int[KEYCODE_COUNT]; private static final short[] sLwjglKeycodes = new short[KEYCODE_COUNT]; private static String[] androidKeyNameArray; /* = new String[androidKeycodes.length]; */ + private static int mTmpCount = 0; static { @@ -219,7 +220,8 @@ public class EfficientAndroidLWJGLKeycode { } private static void add(int androidKeycode, short LWJGLKeycode){ - sAndroidKeycodes[sAndroidKeycodes.length - 1] = androidKeycode; - sLwjglKeycodes[sLwjglKeycodes.length - 1] = LWJGLKeycode; + sAndroidKeycodes[mTmpCount] = androidKeycode; + sLwjglKeycodes[mTmpCount] = LWJGLKeycode; + mTmpCount ++; } } From e61b81154586839e86eec5bc9ed059106950611a Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Tue, 8 Mar 2022 18:11:22 +0100 Subject: [PATCH 64/70] Update layout names --- .../src/main/java/com/kdt/LoggerView.java | 2 +- .../java/net/kdt/pojavlaunch/BaseMainActivity.java | 2 +- .../net/kdt/pojavlaunch/CustomControlsActivity.java | 2 +- .../net/kdt/pojavlaunch/ImportControlActivity.java | 2 +- .../net/kdt/pojavlaunch/JavaGUILauncherActivity.java | 3 +-- .../main/java/net/kdt/pojavlaunch/MainActivity.java | 5 +---- .../net/kdt/pojavlaunch/PojavLauncherActivity.java | 2 +- .../java/net/kdt/pojavlaunch/PojavLoginActivity.java | 10 +++------- .../handleview/EditControlButtonPopup.java | 2 +- .../net/kdt/pojavlaunch/fragments/ConsoleFragment.java | 2 +- .../net/kdt/pojavlaunch/fragments/CrashFragment.java | 2 +- .../kdt/pojavlaunch/fragments/LauncherFragment.java | 2 +- .../kdt/pojavlaunch/multirt/RTRecyclerViewAdapter.java | 2 +- .../net/kdt/pojavlaunch/multirt/RTSpinnerAdapter.java | 2 +- .../kdt/pojavlaunch/prefs/ControlOffsetPreference.java | 2 +- .../kdt/pojavlaunch/prefs/PerVersionConfigDialog.java | 3 +-- ...{main_with_customctrl.xml => activity_basemain.xml} | 0 ...ontrol_mapping.xml => activity_custom_controls.xml} | 0 ..._control_layout.xml => activity_import_control.xml} | 0 ...{install_mod.xml => activity_java_gui_launcher.xml} | 0 ...auncher_main_v4.xml => activity_pojav_launcher.xml} | 0 ...{launcher_login_v3.xml => activity_pojav_login.xml} | 0 ...n_setting.xml => dialog_control_button_setting.xml} | 0 ...dialog.xml => dialog_control_offset_preference.xml} | 0 ...d_editor.xml => dialog_live_mouse_speed_editor.xml} | 0 .../{pvc_popup.xml => dialog_per_version_control.xml} | 0 ...count_list_holder.xml => dialog_select_account.xml} | 0 ...maintab_consolelog.xml => fragment_console_log.xml} | 0 .../{lmaintab_crashlog.xml => fragment_crash_log.xml} | 0 .../layout/{lmaintab_news.xml => fragment_news.xml} | 0 ...ccount_list_item.xml => item_minecraft_account.xml} | 0 ...rt_recyclable_view.xml => item_multirt_runtime.xml} | 0 .../layout/{loggerview_layout.xml => view_logger.xml} | 0 33 files changed, 18 insertions(+), 27 deletions(-) rename app_pojavlauncher/src/main/res/layout/{main_with_customctrl.xml => activity_basemain.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{control_mapping.xml => activity_custom_controls.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{import_control_layout.xml => activity_import_control.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{install_mod.xml => activity_java_gui_launcher.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{launcher_main_v4.xml => activity_pojav_launcher.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{launcher_login_v3.xml => activity_pojav_login.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{control_button_setting.xml => dialog_control_button_setting.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{control_offset_preference_dialog.xml => dialog_control_offset_preference.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{live_mouse_speed_editor.xml => dialog_live_mouse_speed_editor.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{pvc_popup.xml => dialog_per_version_control.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{simple_account_list_holder.xml => dialog_select_account.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{lmaintab_consolelog.xml => fragment_console_log.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{lmaintab_crashlog.xml => fragment_crash_log.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{lmaintab_news.xml => fragment_news.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{simple_account_list_item.xml => item_minecraft_account.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{multirt_recyclable_view.xml => item_multirt_runtime.xml} (100%) rename app_pojavlauncher/src/main/res/layout/{loggerview_layout.xml => view_logger.xml} (100%) diff --git a/app_pojavlauncher/src/main/java/com/kdt/LoggerView.java b/app_pojavlauncher/src/main/java/com/kdt/LoggerView.java index 98b91f8ca..b77ffeb68 100644 --- a/app_pojavlauncher/src/main/java/com/kdt/LoggerView.java +++ b/app_pojavlauncher/src/main/java/com/kdt/LoggerView.java @@ -47,7 +47,7 @@ public class LoggerView extends ConstraintLayout { * Inflate the layout, and add component behaviors */ private void init(){ - inflate(getContext(), R.layout.loggerview_layout, this); + inflate(getContext(), R.layout.view_logger, this); mLogTextView = findViewById(R.id.content_log_view); mLogTextView.setTypeface(Typeface.MONOSPACE); //TODO clamp the max text so it doesn't go oob diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java index be39a141a..a2ee37ac8 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java @@ -342,7 +342,7 @@ public class BaseMainActivity extends BaseActivity { public void adjustMouseSpeedLive() { AlertDialog.Builder b = new AlertDialog.Builder(this); b.setTitle(R.string.mcl_setting_title_mousespeed); - View v = LayoutInflater.from(this).inflate(R.layout.live_mouse_speed_editor,null); + View v = LayoutInflater.from(this).inflate(R.layout.dialog_live_mouse_speed_editor,null); final SeekBar sb = v.findViewById(R.id.mouseSpeed); final TextView tv = v.findViewById(R.id.mouseSpeedTV); sb.setMax(275); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomControlsActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomControlsActivity.java index 1dba07e59..c694b9307 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomControlsActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/CustomControlsActivity.java @@ -36,7 +36,7 @@ public class CustomControlsActivity extends BaseActivity { // setTheme(androidx.appcompat.R.style.Theme_AppCompat_Translucent); } - setContentView(R.layout.control_mapping); + setContentView(R.layout.activity_custom_controls); mControlLayout = (ControlLayout) findViewById(R.id.customctrl_controllayout); mDrawerLayout = (DrawerLayout) findViewById(R.id.customctrl_drawerlayout); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ImportControlActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ImportControlActivity.java index e1ae0ad5d..15fe8abd6 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ImportControlActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ImportControlActivity.java @@ -43,7 +43,7 @@ public class ImportControlActivity extends Activity { super.onCreate(savedInstanceState); Tools.initContextConstants(getApplicationContext()); - setContentView(R.layout.import_control_layout); + setContentView(R.layout.activity_import_control); mEditText = findViewById(R.id.editText_import_control_file_name); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java index 16fb5727d..c04b61906 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JavaGUILauncherActivity.java @@ -4,7 +4,6 @@ import android.annotation.SuppressLint; import android.os.*; import android.util.*; import android.view.*; -import android.view.View.*; import android.widget.*; import java.io.*; @@ -38,7 +37,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.install_mod); + setContentView(R.layout.activity_java_gui_launcher); Logger.getInstance().reset(); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java index d9e9e2641..69c8fbd27 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java @@ -5,8 +5,6 @@ import android.content.Intent; import android.os.*; -import androidx.annotation.Nullable; - import net.kdt.pojavlaunch.customcontrols.*; import net.kdt.pojavlaunch.prefs.*; import net.kdt.pojavlaunch.utils.MCOptionUtils; @@ -15,7 +13,6 @@ import java.io.*; import static net.kdt.pojavlaunch.prefs.LauncherPreferences.DEFAULT_PREF; import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_SUSTAINED_PERFORMANCE; -import static net.kdt.pojavlaunch.utils.MCOptionUtils.getMcScale; public class MainActivity extends BaseMainActivity { public static ControlLayout mControlLayout; @@ -25,7 +22,7 @@ public class MainActivity extends BaseMainActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - initLayout(R.layout.main_with_customctrl); + initLayout(R.layout.activity_basemain); // Set the sustained performance mode for available APIs if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLauncherActivity.java index 026d46d38..b6676422c 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLauncherActivity.java @@ -84,7 +84,7 @@ public class PojavLauncherActivity extends BaseLauncherActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.launcher_main_v4); + setContentView(R.layout.activity_pojav_launcher); //Boilerplate linking/initialisation viewPager = findViewById(R.id.launchermainTabPager); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java index 30d060bac..fd5b52f6f 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java @@ -10,10 +10,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.AssetManager; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.graphics.Color; -import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.ColorDrawable; import android.net.Uri; import android.os.Build; @@ -22,7 +19,6 @@ import android.text.Html; import android.text.SpannableString; import android.text.Spanned; import android.text.style.StyleSpan; -import android.util.Base64; import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -171,7 +167,7 @@ public class PojavLoginActivity extends BaseActivity { } } private void uiInit() { - setContentView(R.layout.launcher_login_v3); + setContentView(R.layout.activity_pojav_login); Spinner spinnerChgLang = findViewById(R.id.login_spinner_language); @@ -494,14 +490,14 @@ public class PojavLoginActivity extends BaseActivity { final Dialog accountDialog = new Dialog(PojavLoginActivity.this); - accountDialog.setContentView(R.layout.simple_account_list_holder); + accountDialog.setContentView(R.layout.dialog_select_account); LinearLayout accountListLayout = accountDialog.findViewById(R.id.accountListLayout); LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE); for (int accountIndex = 0; accountIndex < accountArr.length; accountIndex++) { String s = accountArr[accountIndex]; - View child = inflater.inflate(R.layout.simple_account_list_item, accountListLayout,false); + View child = inflater.inflate(R.layout.item_minecraft_account, accountListLayout,false); TextView accountName = child.findViewById(R.id.accountitem_text_name); ImageButton removeButton = child.findViewById(R.id.accountitem_button_remove); ImageView imageView = child.findViewById(R.id.account_head); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlButtonPopup.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlButtonPopup.java index 28d63f3dc..18c7d7c1a 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlButtonPopup.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/EditControlButtonPopup.java @@ -79,7 +79,7 @@ public class EditControlButtonPopup { protected void initializeEditDialog(Context ctx){ //Create the editing dialog LayoutInflater layoutInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - mRootView = layoutInflater.inflate(R.layout.control_button_setting,null); + mRootView = layoutInflater.inflate(R.layout.dialog_control_button_setting,null); mBuilder = new AlertDialog.Builder(ctx); mBuilder.setTitle(ctx.getResources().getString(R.string.customctrl_edit, mProperties.name)); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ConsoleFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ConsoleFragment.java index 40b7bcfae..4dc026e47 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ConsoleFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ConsoleFragment.java @@ -19,7 +19,7 @@ public class ConsoleFragment extends Fragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); - View view = inflater.inflate(R.layout.lmaintab_consolelog, container, false); + View view = inflater.inflate(R.layout.fragment_console_log, container, false); mConsoleView = (TextView) view.findViewById(R.id.lmaintabconsoleLogTextView); mConsoleView.setTypeface(Typeface.MONOSPACE); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/CrashFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/CrashFragment.java index b6cb32e63..c555f747f 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/CrashFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/CrashFragment.java @@ -23,7 +23,7 @@ public class CrashFragment extends Fragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); - return inflater.inflate(R.layout.lmaintab_crashlog, container, false); + return inflater.inflate(R.layout.fragment_crash_log, container, false); } @Override diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LauncherFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LauncherFragment.java index 758b56f74..c0871d3c8 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LauncherFragment.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LauncherFragment.java @@ -39,7 +39,7 @@ public class LauncherFragment extends Fragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); - mRootView = inflater.inflate(R.layout.lmaintab_news, container, false); + mRootView = inflater.inflate(R.layout.fragment_news, container, false); return mRootView; } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTRecyclerViewAdapter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTRecyclerViewAdapter.java index e2765f967..cec96f6a0 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTRecyclerViewAdapter.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/RTRecyclerViewAdapter.java @@ -32,7 +32,7 @@ public class RTRecyclerViewAdapter extends RecyclerView.Adapter Date: Tue, 8 Mar 2022 18:14:49 +0100 Subject: [PATCH 65/70] Update drawable names --- .../kdt/pojavlaunch/MinecraftLEGLView.java | 604 ++++++++++++++++++ .../java/net/kdt/pojavlaunch/Touchpad.java | 2 +- .../customcontrols/gamepad/Gamepad.java | 2 +- .../customcontrols/handleview/HandleView.java | 2 +- ...pad_pointer.png => ic_gamepad_pointer.png} | Bin .../res/drawable/{logo.png => ic_logo.png} | Bin ...mouse_pointer.png => ic_mouse_pointer.png} | Bin .../{view_handle.xml => ic_view_handle.xml} | 0 .../res/layout/activity_java_gui_launcher.xml | 2 +- .../main/res/layout/activity_pojav_login.xml | 2 +- 10 files changed, 609 insertions(+), 5 deletions(-) create mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftLEGLView.java rename app_pojavlauncher/src/main/res/drawable/{gamepad_pointer.png => ic_gamepad_pointer.png} (100%) rename app_pojavlauncher/src/main/res/drawable/{logo.png => ic_logo.png} (100%) rename app_pojavlauncher/src/main/res/drawable/{mouse_pointer.png => ic_mouse_pointer.png} (100%) rename app_pojavlauncher/src/main/res/drawable/{view_handle.xml => ic_view_handle.xml} (100%) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftLEGLView.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftLEGLView.java new file mode 100644 index 000000000..fd532295b --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftLEGLView.java @@ -0,0 +1,604 @@ +package net.kdt.pojavlaunch; + +import static net.kdt.pojavlaunch.BaseMainActivity.touchCharInput; +import static net.kdt.pojavlaunch.utils.MCOptionUtils.getMcScale; +import static org.lwjgl.glfw.CallbackBridge.sendKeyPress; +import static org.lwjgl.glfw.CallbackBridge.sendMouseButton; +import static org.lwjgl.glfw.CallbackBridge.windowHeight; +import static org.lwjgl.glfw.CallbackBridge.windowWidth; + +import android.app.Activity; +import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.InputDevice; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; + +import com.google.android.material.math.MathUtils; + +import net.kdt.pojavlaunch.customcontrols.gamepad.Gamepad; +import net.kdt.pojavlaunch.prefs.LauncherPreferences; +import net.kdt.pojavlaunch.utils.JREUtils; +import net.kdt.pojavlaunch.utils.MCOptionUtils; + +import org.lwjgl.glfw.CallbackBridge; + +/** + * Class dealing with showing minecraft surface and taking inputs to dispatch them to minecraft + */ +public class MinecraftLEGLView extends SurfaceView { + /* Gamepad object for gamepad inputs, instantiated on need */ + private Gamepad gamepad = null; + /* Pointer Debug textview, used to show info about the pointer state */ + private TextView pointerDebugText; + /* Resolution scaler option, allow downsizing a window */ + private final float scaleFactor = LauncherPreferences.DEFAULT_PREF.getInt("resolutionRatio",100)/100f; + /* Display properties, such as resolution and DPI */ + private final DisplayMetrics displayMetrics = Tools.getDisplayMetrics((Activity) getContext()); + /* Sensitivity, adjusted according to screen size */ + private final double sensitivityFactor = (1.4 * (1080f/ displayMetrics.heightPixels)); + /* Use to detect simple and double taps */ + private final TapDetector singleTapDetector = new TapDetector(1, TapDetector.DETECTION_METHOD_BOTH); + private final TapDetector doubleTapDetector = new TapDetector(2, TapDetector.DETECTION_METHOD_DOWN); + /* MC GUI scale, listened by MCOptionUtils */ + private int GUIScale = getMcScale(); + private MCOptionUtils.MCOptionListener GUIScaleListener = () -> GUIScale = getMcScale(); + /* Surface ready listener, used by the activity to launch minecraft */ + SurfaceReadyListener surfaceReadyListener = null; + + /* List of hotbarKeys, used when clicking on the hotbar */ + private static final int[] hotbarKeys = { + LwjglGlfwKeycode.GLFW_KEY_1, LwjglGlfwKeycode.GLFW_KEY_2, LwjglGlfwKeycode.GLFW_KEY_3, + LwjglGlfwKeycode.GLFW_KEY_4, LwjglGlfwKeycode.GLFW_KEY_5, LwjglGlfwKeycode.GLFW_KEY_6, + LwjglGlfwKeycode.GLFW_KEY_7, LwjglGlfwKeycode.GLFW_KEY_8, LwjglGlfwKeycode.GLFW_KEY_9}; + /* Last hotbar button (0-9) registered */ + private int lastHotbarKey = -1; + /* Events can start with only a move instead of an pointerDown due to mouse passthrough */ + private boolean shouldBeDown = false; + /* When fingers are really near to each other, it tends to either swap or remove a pointer ! */ + private int lastPointerCount = 0; + /* Previous MotionEvent position, not scale */ + private float prevX, prevY; + /* PointerID used for the moving camera */ + private int currentPointerID = -1000; + /* Initial first pointer positions non-scaled, used to test touch sloppiness */ + private float initialX, initialY; + /* Last first pointer positions non-scaled, used to scroll distance */ + private float scrollLastInitialX, scrollLastInitialY; + /* How much distance a finger has to go for touch sloppiness to be disabled */ + public static final int FINGER_STILL_THRESHOLD = (int) Tools.dpToPx(9); + /* How much distance a finger has to go to scroll */ + public static final int FINGER_SCROLL_THRESHOLD = (int) Tools.dpToPx(6); + /* Handle hotbar throw button and mouse mining button */ + public static final int MSG_LEFT_MOUSE_BUTTON_CHECK = 1028; + public static final int MSG_DROP_ITEM_BUTTON_CHECK = 1029; + private final Handler theHandler = new Handler(Looper.getMainLooper()) { + public void handleMessage(Message msg) { + if(msg.what == MSG_LEFT_MOUSE_BUTTON_CHECK) { + if (LauncherPreferences.PREF_DISABLE_GESTURES) return; + float x = CallbackBridge.mouseX; + float y = CallbackBridge.mouseY; + if (CallbackBridge.isGrabbing() && + MathUtils.dist(x, y, initialX, initialY) < FINGER_STILL_THRESHOLD) { + triggeredLeftMouseButton = true; + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, true); + } + return; + } + if(msg.what == MSG_DROP_ITEM_BUTTON_CHECK) { + if(CallbackBridge.isGrabbing()){ + sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_Q); + theHandler.sendEmptyMessageDelayed(MSG_DROP_ITEM_BUTTON_CHECK, 600); + } + return; + } + + } + }; + /* Whether the button was triggered, used by the handler */ + private static boolean triggeredLeftMouseButton = false; + + + public MinecraftLEGLView(Context context) { + this(context, null); + } + + public MinecraftLEGLView(Context context, AttributeSet attributeSet) { + super(context, attributeSet); + //Fixes freeform and dex mode having transparent glass, + //since it forces android to used the background color of the view/layout behind it. + //setOpaque(false); + setFocusable(true); + + MCOptionUtils.addMCOptionListener(GUIScaleListener); + } + + /** Initialize the view and all its settings */ + public void start(){ + // Add the pointer debug textview + pointerDebugText = new TextView(getContext()); + pointerDebugText.setX(0); + pointerDebugText.setY(0); + pointerDebugText.setVisibility(GONE); + ((ViewGroup)getParent()).addView(pointerDebugText); + + + getHolder().addCallback(new SurfaceHolder.Callback() { + private boolean isCalled = false; + @Override + public void surfaceCreated(@NonNull SurfaceHolder holder) { + + //Load Minecraft options: + MCOptionUtils.load(); + MCOptionUtils.set("overrideWidth", String.valueOf(windowWidth)); + MCOptionUtils.set("overrideHeight", String.valueOf(windowHeight)); + MCOptionUtils.save(); + getMcScale(); + // Should we do that? + if(isCalled) return; + isCalled = true; + + getHolder().setFixedSize(windowWidth, windowHeight); + + + JREUtils.setupBridgeWindow(getHolder().getSurface()); + + new Thread(() -> { + try { + Thread.sleep(200); + if(surfaceReadyListener != null){ + surfaceReadyListener.isReady(); + } + } catch (Throwable e) { + Tools.showError(getContext(), e, true); + } + }, "JVM Main thread").start(); + } + + @Override + public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) { + windowWidth = Tools.getDisplayFriendlyRes(displayMetrics.widthPixels, scaleFactor); + windowHeight = Tools.getDisplayFriendlyRes(displayMetrics.heightPixels, scaleFactor); + CallbackBridge.sendUpdateWindowSize(windowWidth, windowHeight); + getMcScale(); + Toast.makeText(getContext(), "width: " + width, Toast.LENGTH_SHORT).show(); + Toast.makeText(getContext(), "height: " + height, Toast.LENGTH_SHORT).show(); + getHolder().setFixedSize(windowWidth, windowHeight); + } + + @Override + public void surfaceDestroyed(@NonNull SurfaceHolder holder) { + + } + }); + } + + + + + /** + * The touch event for both grabbed an non-grabbed mouse state on the touch screen + * Does not cover the virtual mouse touchpad + */ + @Override + public boolean onTouchEvent(MotionEvent e) { + // Looking for a mouse to handle, won't have an effect if no mouse exists. + for (int i = 0; i < e.getPointerCount(); i++) { + if (e.getToolType(i) != MotionEvent.TOOL_TYPE_MOUSE) continue; + + // Mouse found + if(CallbackBridge.isGrabbing()) return false; + CallbackBridge.sendCursorPos( e.getX(i) * scaleFactor, e.getY(i) * scaleFactor); + return true; //mouse event handled successfully + } + + // System.out.println("Pre touch, isTouchInHotbar=" + Boolean.toString(isTouchInHotbar) + ", action=" + MotionEvent.actionToString(e.getActionMasked())); + + //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() * scaleFactor); + CallbackBridge.mouseY = (e.getY() * scaleFactor); + //One android click = one MC click + if(singleTapDetector.onTouchEvent(e)){ + CallbackBridge.putMouseEventWithCoords(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, CallbackBridge.mouseX, CallbackBridge.mouseY); + return true; + } + } + + // Check double tap state, used for the hotbar + boolean hasDoubleTapped = doubleTapDetector.onTouchEvent(e); + + switch (e.getActionMasked()) { + case MotionEvent.ACTION_MOVE: + int pointerCount = e.getPointerCount(); + + // In-menu interactions + if(!CallbackBridge.isGrabbing()){ + + // Touch hover + if(pointerCount == 1){ + CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); + prevX = e.getX(); + prevY = e.getY(); + break; + } + + // Scrolling feature + if(LauncherPreferences.PREF_DISABLE_GESTURES) break; + // The pointer count can never be 0, and it is not 1, therefore it is >= 2 + int hScroll = ((int) (e.getX() - scrollLastInitialX)) / FINGER_SCROLL_THRESHOLD; + int vScroll = ((int) (e.getY() - scrollLastInitialY)) / FINGER_SCROLL_THRESHOLD; + + if(vScroll != 0 || hScroll != 0){ + CallbackBridge.sendScroll(hScroll, vScroll); + scrollLastInitialX = e.getX(); + scrollLastInitialY = e.getY(); + } + break; + } + + // Camera movement + int pointerIndex = e.findPointerIndex(currentPointerID); + int hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY()); + // Start movement, due to new pointer or loss of pointer + if (pointerIndex == -1 || lastPointerCount != pointerCount || !shouldBeDown) { + if(hudKeyHandled != -1) break; //No pointer attribution on hotbar + + shouldBeDown = true; + currentPointerID = e.getPointerId(0); + prevX = e.getX(); + prevY = e.getY(); + break; + } + // Continue movement as usual + if(hudKeyHandled == -1){ //No camera on hotbar + CallbackBridge.mouseX += (e.getX(pointerIndex) - prevX) * sensitivityFactor; + CallbackBridge.mouseY += (e.getY(pointerIndex) - prevY) * sensitivityFactor; + } + + prevX = e.getX(pointerIndex); + prevY = e.getY(pointerIndex); + + CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); + break; + + case MotionEvent.ACTION_DOWN: // 0 + CallbackBridge.sendPrepareGrabInitialPos(); + + hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY()); + boolean isTouchInHotbar = hudKeyHandled != -1; + if (isTouchInHotbar) { + sendKeyPress(hudKeyHandled); + if(hasDoubleTapped && hudKeyHandled == lastHotbarKey){ + //Prevent double tapping Event on two different slots + sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_F); + } + + theHandler.sendEmptyMessageDelayed(MSG_DROP_ITEM_BUTTON_CHECK, 350); + CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); + lastHotbarKey = hudKeyHandled; + break; + } + + CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); + prevX = e.getX(); + prevY = e.getY(); + + if (CallbackBridge.isGrabbing()) { + currentPointerID = e.getPointerId(0); + // It cause hold left mouse while moving camera + initialX = CallbackBridge.mouseX; + initialY = CallbackBridge.mouseY; + theHandler.sendEmptyMessageDelayed(MSG_LEFT_MOUSE_BUTTON_CHECK, LauncherPreferences.PREF_LONGPRESS_TRIGGER); + } + lastHotbarKey = hudKeyHandled; + break; + + case MotionEvent.ACTION_UP: // 1 + case MotionEvent.ACTION_CANCEL: // 3 + shouldBeDown = false; + currentPointerID = -1; + + hudKeyHandled = handleGuiBar((int)e.getX(), (int) e.getY()); + isTouchInHotbar = hudKeyHandled != -1; + // We only treat in world events + if (!CallbackBridge.isGrabbing()) break; + + // Stop the dropping of items + if (isTouchInHotbar) { + sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_Q, 0, false); + theHandler.removeMessages(MSG_DROP_ITEM_BUTTON_CHECK); + break; + } + + // Remove the mouse left button + if(triggeredLeftMouseButton){ + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, false); + triggeredLeftMouseButton = false; + break; + } + theHandler.removeMessages(MSG_LEFT_MOUSE_BUTTON_CHECK); + + // In case of a short click, just send a quick right click + if(!LauncherPreferences.PREF_DISABLE_GESTURES && + MathUtils.dist(initialX, initialY, CallbackBridge.mouseX, CallbackBridge.mouseY) < FINGER_STILL_THRESHOLD){ + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, true); + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, false); + } + break; + + case MotionEvent.ACTION_POINTER_DOWN: // 5 + //TODO Hey we could have some sort of middle click detection ? + + scrollLastInitialX = e.getX(); + scrollLastInitialY = e.getY(); + //Checking if we are pressing the hotbar to select the item + hudKeyHandled = handleGuiBar((int)e.getX(e.getPointerCount()-1), (int) e.getY(e.getPointerCount()-1)); + if(hudKeyHandled != -1){ + sendKeyPress(hudKeyHandled); + if(hasDoubleTapped && hudKeyHandled == lastHotbarKey){ + //Prevent double tapping Event on two different slots + sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_F); + } + } + + lastHotbarKey = hudKeyHandled; + break; + + } + + // Actualise the pointer count + lastPointerCount = e.getPointerCount(); + + //debugText.setText(CallbackBridge.DEBUG_STRING.toString()); + CallbackBridge.DEBUG_STRING.setLength(0); + + return true; + } + + /** + * The event for mouse/joystick movements + * We don't do the gamepad right now. + */ + @Override + public boolean dispatchGenericMotionEvent(MotionEvent event) { + int mouseCursorIndex = -1; + + if(Gamepad.isGamepadEvent(event)){ + if(gamepad == null){ + gamepad = new Gamepad(this, event.getDevice()); + } + + gamepad.update(event); + return true; + } + + for(int i = 0; i < event.getPointerCount(); i++) { + if(event.getToolType(i) != MotionEvent.TOOL_TYPE_MOUSE) continue; + // Mouse found + mouseCursorIndex = i; + break; + } + if(mouseCursorIndex == -1) return false; // we cant consoom that, theres no mice! + if(CallbackBridge.isGrabbing()) { + if(BaseMainActivity.isAndroid8OrHigher()){ + requestFocus(); + requestPointerCapture(); + } + } + switch(event.getActionMasked()) { + case MotionEvent.ACTION_HOVER_MOVE: + CallbackBridge.mouseX = (event.getX(mouseCursorIndex) * scaleFactor); + CallbackBridge.mouseY = (event.getY(mouseCursorIndex) * scaleFactor); + CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); + //debugText.setText(CallbackBridge.DEBUG_STRING.toString()); + CallbackBridge.DEBUG_STRING.setLength(0); + return true; + case MotionEvent.ACTION_SCROLL: + CallbackBridge.sendScroll((double) event.getAxisValue(MotionEvent.AXIS_VSCROLL), (double) event.getAxisValue(MotionEvent.AXIS_HSCROLL)); + return true; + case MotionEvent.ACTION_BUTTON_PRESS: + return sendMouseButtonUnconverted(event.getActionButton(),true); + case MotionEvent.ACTION_BUTTON_RELEASE: + return sendMouseButtonUnconverted(event.getActionButton(),false); + default: + return false; + } + } + + //TODO MOVE THIS SOMEWHERE ELSE + private boolean debugErrored = false; + /** The input event for mouse with a captured pointer */ + @RequiresApi(26) + @Override + public boolean dispatchCapturedPointerEvent(MotionEvent e) { + CallbackBridge.mouseX += (e.getX()*scaleFactor); + CallbackBridge.mouseY += (e.getY()*scaleFactor); + if(!CallbackBridge.isGrabbing()){ + releasePointerCapture(); + clearFocus(); + } + + if (pointerDebugText.getVisibility() == View.VISIBLE && !debugErrored) { + StringBuilder builder = new StringBuilder(); + try { + builder.append("PointerCapture debug\n"); + builder.append("MotionEvent=").append(e.getActionMasked()).append("\n"); + builder.append("PressingBtn=").append(MotionEvent.class.getDeclaredMethod("buttonStateToString").invoke(null, e.getButtonState())).append("\n\n"); + + builder.append("PointerX=").append(e.getX()).append("\n"); + builder.append("PointerY=").append(e.getY()).append("\n"); + builder.append("RawX=").append(e.getRawX()).append("\n"); + builder.append("RawY=").append(e.getRawY()).append("\n\n"); + + builder.append("XPos=").append(CallbackBridge.mouseX).append("\n"); + builder.append("YPos=").append(CallbackBridge.mouseY).append("\n\n"); + builder.append("MovingX=").append(getMoving(e.getX(), true)).append("\n"); + builder.append("MovingY=").append(getMoving(e.getY(), false)).append("\n"); + } catch (Throwable th) { + debugErrored = true; + builder.append("Error getting debug. The debug will be stopped!\n").append(Log.getStackTraceString(th)); + } finally { + pointerDebugText.setText(builder.toString()); + builder.setLength(0); + } + } + + pointerDebugText.setText(CallbackBridge.DEBUG_STRING.toString()); + CallbackBridge.DEBUG_STRING.setLength(0); + switch (e.getActionMasked()) { + case MotionEvent.ACTION_MOVE: + CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY); + return true; + case MotionEvent.ACTION_BUTTON_PRESS: + return sendMouseButtonUnconverted(e.getActionButton(), true); + case MotionEvent.ACTION_BUTTON_RELEASE: + return sendMouseButtonUnconverted(e.getActionButton(), false); + case MotionEvent.ACTION_SCROLL: + CallbackBridge.sendScroll(e.getAxisValue(MotionEvent.AXIS_HSCROLL), e.getAxisValue(MotionEvent.AXIS_VSCROLL)); + return true; + default: + return false; + } + } + + /** The event for keyboard/ gamepad button inputs */ + @Override + public boolean onKeyPreIme(int keyCode, KeyEvent event) { + //Toast.makeText(this, event.toString(),Toast.LENGTH_SHORT).show(); + //Toast.makeText(this, event.getDevice().toString(), Toast.LENGTH_SHORT).show(); + + //Filtering useless events by order of probability + if((event.getFlags() & KeyEvent.FLAG_FALLBACK) == KeyEvent.FLAG_FALLBACK) return true; + int eventKeycode = event.getKeyCode(); + if(eventKeycode == KeyEvent.KEYCODE_UNKNOWN) return true; + if(eventKeycode == KeyEvent.KEYCODE_VOLUME_DOWN) return false; + if(eventKeycode == KeyEvent.KEYCODE_VOLUME_UP) return false; + if(event.getRepeatCount() != 0) return true; + if(event.getAction() == KeyEvent.ACTION_MULTIPLE) return true; + + //Toast.makeText(this, "FIRST VERIF PASSED", Toast.LENGTH_SHORT).show(); + + //Sometimes, key events comes from SOME keys of the software keyboard + //Even weirder, is is unknown why a key or another is selected to trigger a keyEvent + if((event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) == KeyEvent.FLAG_SOFT_KEYBOARD){ + if(eventKeycode == KeyEvent.KEYCODE_ENTER) return true; //We already listen to it. + touchCharInput.dispatchKeyEvent(event); + return true; + } + //Toast.makeText(this, "SECOND VERIF PASSED", Toast.LENGTH_SHORT).show(); + + + //Sometimes, key events may come from the mouse + if(event.getDevice() != null + && ( (event.getSource() & InputDevice.SOURCE_MOUSE_RELATIVE) == InputDevice.SOURCE_MOUSE_RELATIVE + || (event.getSource() & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) ){ + //Toast.makeText(this, "THE EVENT COMES FROM A MOUSE", Toast.LENGTH_SHORT).show(); + + + if(eventKeycode == KeyEvent.KEYCODE_BACK){ + sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, event.getAction() == KeyEvent.ACTION_DOWN); + return true; + } + } + System.out.println(event); + + if(Gamepad.isGamepadEvent(event)){ + + if(gamepad == null){ + gamepad = new Gamepad(this, event.getDevice()); + } + + gamepad.update(event); + return true; + } + + int index = EfficientAndroidLWJGLKeycode.getIndexByKey(eventKeycode); + if(index >= 0) { + //Toast.makeText(this,"THIS IS A KEYBOARD EVENT !", Toast.LENGTH_SHORT).show(); + EfficientAndroidLWJGLKeycode.execKey(event, index); + return true; + } + + return false; + } + + /** Get the mouse direction as a string */ + private String getMoving(float pos, boolean xOrY) { + if (pos == 0) return "STOPPED"; + if (pos > 0) return xOrY ? "RIGHT" : "DOWN"; + return xOrY ? "LEFT" : "UP"; + } + + /** Convert the mouse button, then send it + * @return Whether the event was processed + */ + public static boolean sendMouseButtonUnconverted(int button, boolean status) { + int glfwButton = -256; + switch (button) { + case MotionEvent.BUTTON_PRIMARY: + glfwButton = LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT; + break; + case MotionEvent.BUTTON_TERTIARY: + glfwButton = LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_MIDDLE; + break; + case MotionEvent.BUTTON_SECONDARY: + glfwButton = LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT; + break; + } + if(glfwButton == -256) return false; + sendMouseButton(glfwButton, status); + return true; + } + + + + /** @return the hotbar key, given the position. -1 if no key are pressed */ + public int handleGuiBar(int x, int y) { + if (!CallbackBridge.isGrabbing()) return -1; + + int barHeight = mcscale(20); + int barY = CallbackBridge.physicalHeight - barHeight; + if(y < barY) return -1; + + int barWidth = mcscale(180); + int barX = (CallbackBridge.physicalWidth / 2) - (barWidth / 2); + if(x < barX || x >= barX + barWidth) return -1; + + return hotbarKeys[(int) net.kdt.pojavlaunch.utils.MathUtils.map(x, barX, barX + barWidth, 0, 9)]; + } + + /** Return the size, given the UI scale size */ + private int mcscale(int input) { + return (int)((GUIScale * input)/scaleFactor); + } + + /** Toggle the pointerDebugText visibility state */ + public void togglepointerDebugging() { + pointerDebugText.setVisibility(pointerDebugText.getVisibility() == View.GONE ? View.VISIBLE : View.GONE); + } + + /** A small interface called when the listener is ready for the first time */ + public interface SurfaceReadyListener { + void isReady(); + } + + public void setSurfaceReadyListener(SurfaceReadyListener listener){ + surfaceReadyListener = listener; + } +} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java index 32c422bb0..80dec94dd 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Touchpad.java @@ -155,7 +155,7 @@ public class Touchpad extends FrameLayout { private void init(){ // Setup mouse pointer - mMousePointerImageView.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.mouse_pointer, getContext().getTheme())); + mMousePointerImageView.setImageDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.ic_mouse_pointer, getContext().getTheme())); mMousePointerImageView.post(() -> { ViewGroup.LayoutParams params = mMousePointerImageView.getLayoutParams(); params.width = (int) (36 / 100f * LauncherPreferences.PREF_MOUSESCALE); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java index 6e473d0fe..c13ed6e76 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/gamepad/Gamepad.java @@ -117,7 +117,7 @@ public class Gamepad { Context ctx = contextView.getContext(); mPointerImageView = new ImageView(contextView.getContext()); - mPointerImageView.setImageDrawable(ResourcesCompat.getDrawable(ctx.getResources(), R.drawable.gamepad_pointer, ctx.getTheme())); + mPointerImageView.setImageDrawable(ResourcesCompat.getDrawable(ctx.getResources(), R.drawable.ic_gamepad_pointer, ctx.getTheme())); mPointerImageView.getDrawable().setFilterBitmap(false); int size = (int) ((22 * getMcScale()) / mScaleFactor); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/HandleView.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/HandleView.java index 4f7a7b4b3..c8278cadf 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/HandleView.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/handleview/HandleView.java @@ -91,7 +91,7 @@ public abstract class HandleView extends View implements ViewPositionListener, V mContainer.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL); mContainer.setContentView(this); - mDrawableRtl = view.getContext().getDrawable(R.drawable.view_handle); + mDrawableRtl = view.getContext().getDrawable(R.drawable.ic_view_handle); mMinSize = view.getContext().getResources().getDimensionPixelSize(R.dimen.text_handle_min_size); setOnLongClickListener(this); diff --git a/app_pojavlauncher/src/main/res/drawable/gamepad_pointer.png b/app_pojavlauncher/src/main/res/drawable/ic_gamepad_pointer.png similarity index 100% rename from app_pojavlauncher/src/main/res/drawable/gamepad_pointer.png rename to app_pojavlauncher/src/main/res/drawable/ic_gamepad_pointer.png diff --git a/app_pojavlauncher/src/main/res/drawable/logo.png b/app_pojavlauncher/src/main/res/drawable/ic_logo.png similarity index 100% rename from app_pojavlauncher/src/main/res/drawable/logo.png rename to app_pojavlauncher/src/main/res/drawable/ic_logo.png diff --git a/app_pojavlauncher/src/main/res/drawable/mouse_pointer.png b/app_pojavlauncher/src/main/res/drawable/ic_mouse_pointer.png similarity index 100% rename from app_pojavlauncher/src/main/res/drawable/mouse_pointer.png rename to app_pojavlauncher/src/main/res/drawable/ic_mouse_pointer.png diff --git a/app_pojavlauncher/src/main/res/drawable/view_handle.xml b/app_pojavlauncher/src/main/res/drawable/ic_view_handle.xml similarity index 100% rename from app_pojavlauncher/src/main/res/drawable/view_handle.xml rename to app_pojavlauncher/src/main/res/drawable/ic_view_handle.xml diff --git a/app_pojavlauncher/src/main/res/layout/activity_java_gui_launcher.xml b/app_pojavlauncher/src/main/res/layout/activity_java_gui_launcher.xml index 04d6cfc30..1c405721e 100644 --- a/app_pojavlauncher/src/main/res/layout/activity_java_gui_launcher.xml +++ b/app_pojavlauncher/src/main/res/layout/activity_java_gui_launcher.xml @@ -23,7 +23,7 @@ android:id="@+id/main_mouse_pointer" android:layout_width="18dp" android:layout_height="27dp" - android:src="@drawable/mouse_pointer" /> + android:src="@drawable/ic_mouse_pointer" /> diff --git a/app_pojavlauncher/src/main/res/layout/activity_pojav_login.xml b/app_pojavlauncher/src/main/res/layout/activity_pojav_login.xml index 5cb4076cf..f20ea7b18 100644 --- a/app_pojavlauncher/src/main/res/layout/activity_pojav_login.xml +++ b/app_pojavlauncher/src/main/res/layout/activity_pojav_login.xml @@ -39,7 +39,7 @@ android:id="@+id/login_image_logo" android:layout_width="300dp" android:layout_height="48dp" - android:src="@drawable/logo" + android:src="@drawable/ic_logo" app:layout_constraintBottom_toTopOf="@+id/login_menu" app:layout_constraintEnd_toStartOf="@+id/guidelineLeft" From de8a16e5c5bd3b2e898919e33ade44fcff4cca41 Mon Sep 17 00:00:00 2001 From: artdeell Date: Thu, 10 Mar 2022 21:21:46 +0300 Subject: [PATCH 66/70] We do a little renaming --- .../main/java/net/kdt/pojavlaunch/BaseMainActivity.java | 8 ++++---- .../{LWJGLGLFWKeycode.java => LwjglGlfwKeycode.java} | 0 2 files changed, 4 insertions(+), 4 deletions(-) rename app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/{LWJGLGLFWKeycode.java => LwjglGlfwKeycode.java} (100%) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java index a2ee37ac8..800ef48cf 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseMainActivity.java @@ -151,7 +151,7 @@ public class BaseMainActivity extends BaseActivity { final int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; final View decorView = getWindow().getDecorView(); decorView.setSystemUiVisibility(uiOptions); - CallbackBridge.nativeSetWindowAttrib(LWJGLGLFWKeycode.GLFW_HOVERED, 1); + CallbackBridge.nativeSetWindowAttrib(LwjglGlfwKeycode.GLFW_HOVERED, 1); } @Override @@ -159,7 +159,7 @@ public class BaseMainActivity extends BaseActivity { if (CallbackBridge.isGrabbing()){ sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_ESCAPE); } - CallbackBridge.nativeSetWindowAttrib(LWJGLGLFWKeycode.GLFW_HOVERED, 0); + CallbackBridge.nativeSetWindowAttrib(LwjglGlfwKeycode.GLFW_HOVERED, 0); mIsResuming = false; super.onPause(); } @@ -167,12 +167,12 @@ public class BaseMainActivity extends BaseActivity { @Override protected void onStart() { super.onStart(); - CallbackBridge.nativeSetWindowAttrib(LWJGLGLFWKeycode.GLFW_VISIBLE, 1); + CallbackBridge.nativeSetWindowAttrib(LwjglGlfwKeycode.GLFW_VISIBLE, 1); } @Override protected void onStop() { - CallbackBridge.nativeSetWindowAttrib(LWJGLGLFWKeycode.GLFW_VISIBLE, 0); + CallbackBridge.nativeSetWindowAttrib(LwjglGlfwKeycode.GLFW_VISIBLE, 0); super.onStop(); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LWJGLGLFWKeycode.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LwjglGlfwKeycode.java similarity index 100% rename from app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LWJGLGLFWKeycode.java rename to app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LwjglGlfwKeycode.java From deef6223d3e04426d0d5fd089c0960314a91f49b Mon Sep 17 00:00:00 2001 From: khanhduytran0 Date: Fri, 11 Mar 2022 20:05:59 +0700 Subject: [PATCH 67/70] Mojang + Offline account removal Offline account is now Local account --- README.md | 1 + .../kdt/pojavlaunch/BaseLauncherActivity.java | 17 +++- .../pojavlaunch/PojavLauncherActivity.java | 2 +- .../kdt/pojavlaunch/PojavLoginActivity.java | 61 ++------------ .../net/kdt/pojavlaunch/PojavProfile.java | 6 -- .../main/java/net/kdt/pojavlaunch/Tools.java | 2 +- .../authenticator/mojang/LoginListener.java | 7 -- .../authenticator/mojang/LoginTask.java | 71 ----------------- .../mojang/RefreshTokenTask.java | 79 ------------------- .../mojang/yggdrasil/AuthenticateRequest.java | 24 ------ .../yggdrasil/AuthenticateResponse.java | 11 --- .../mojang/yggdrasil/RefreshResponse.java | 10 --- .../yggdrasil/YggdrasilAuthenticator.java | 25 ------ .../tasks/MinecraftDownloaderTask.java | 2 +- .../main/res/layout/activity_pojav_login.xml | 55 ++----------- .../src/main/res/values/strings.xml | 9 +-- 16 files changed, 35 insertions(+), 347 deletions(-) delete mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/LoginListener.java delete mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/LoginTask.java delete mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/RefreshTokenTask.java delete mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/AuthenticateRequest.java delete mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/AuthenticateResponse.java delete mode 100644 app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/RefreshResponse.java diff --git a/README.md b/README.md index bd9839bc5..990448364 100644 --- a/README.md +++ b/README.md @@ -108,3 +108,4 @@ Any code change should be submitted as a pull request. The description should ex - [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. diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseLauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseLauncherActivity.java index 7fc551a02..cc35505cb 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseLauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/BaseLauncherActivity.java @@ -99,7 +99,22 @@ public abstract class BaseLauncherActivity extends BaseActivity { } else if (canBack) { v.setEnabled(false); mTask = new MinecraftDownloaderTask(this); - mTask.execute(mProfile.selectedVersion); + // TODO: better check!!! + if (mProfile.accessToken.equals("0")) { + File verJsonFile = new File(Tools.DIR_HOME_VERSION, + mProfile.selectedVersion + "/" + mProfile.selectedVersion + ".json"); + if (verJsonFile.exists()) { + mTask.onPostExecute(null); + } else { + new AlertDialog.Builder(this) + .setTitle(R.string.global_error) + .setMessage(R.string.mcl_launch_error_localmode) + .setPositiveButton(android.R.string.ok, null) + .show(); + } + } else { + mTask.execute(mProfile.selectedVersion); + } } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLauncherActivity.java index b6676422c..9607983a0 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLauncherActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLauncherActivity.java @@ -228,7 +228,7 @@ public class PojavLauncherActivity extends BaseLauncherActivity accountFaceImageView.setImageBitmap(mProfile.getSkinFace()); //TODO FULL BACKGROUND LOGIN - tvConnectStatus.setText(mProfile.accessToken.equals("0") ? R.string.mcl_account_offline : R.string.mcl_account_connected); + tvConnectStatus.setText(mProfile.accessToken.equals("0") ? R.string.mcl_account_local : R.string.mcl_account_connected); } catch(Exception e) { mProfile = new MinecraftAccount(); Tools.showError(this, e, true); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java index fd5b52f6f..e5708d388 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java @@ -43,9 +43,6 @@ import androidx.core.content.ContextCompat; import net.kdt.pojavlaunch.authenticator.microsoft.MicrosoftAuthTask; import net.kdt.pojavlaunch.authenticator.microsoft.ui.MicrosoftLoginGUIActivity; -import net.kdt.pojavlaunch.authenticator.mojang.InvalidateTokenTask; -import net.kdt.pojavlaunch.authenticator.mojang.LoginListener; -import net.kdt.pojavlaunch.authenticator.mojang.LoginTask; import net.kdt.pojavlaunch.authenticator.mojang.RefreshListener; import net.kdt.pojavlaunch.customcontrols.CustomControls; import net.kdt.pojavlaunch.multirt.MultiRTConfigDialog; @@ -69,9 +66,9 @@ public class PojavLoginActivity extends BaseActivity { private final Object mLockStoragePerm = new Object(); private final Object mLockSelectJRE = new Object(); - private EditText edit2, edit3; + private EditText edit2; private final int REQUEST_STORAGE_REQUEST_CODE = 1; - private CheckBox sRemember, sOffline; + private CheckBox sRemember; private TextView startupTextView; private SharedPreferences firstLaunchPrefs; private MinecraftAccount mProfile = null; @@ -237,15 +234,8 @@ public class PojavLoginActivity extends BaseActivity { }); edit2 = (EditText) findViewById(R.id.login_edit_email); - edit3 = (EditText) findViewById(R.id.login_edit_password); sRemember = findViewById(R.id.login_switch_remember); - sOffline = findViewById(R.id.login_switch_offline); - sOffline.setOnCheckedChangeListener((p1, p2) -> { - // May delete later - edit3.setEnabled(!p2); - }); - isSkipInit = true; } @@ -529,11 +519,9 @@ public class PojavLoginActivity extends BaseActivity { }; MinecraftAccount acc = MinecraftAccount.load(selectedAccName); - if (acc.isMicrosoft){ + if (acc.accessToken.length() >= 5){ new MicrosoftAuthTask(PojavLoginActivity.this, authListener) .execute("true", acc.msaRefreshToken); - } else if (acc.accessToken.length() >= 5) { - PojavProfile.updateTokens(PojavLoginActivity.this, selectedAccName, authListener); } else { accountDialog.dismiss(); PojavProfile.launch(PojavLoginActivity.this, selectedAccName); @@ -574,7 +562,7 @@ public class PojavLoginActivity extends BaseActivity { accountDialog.show(); } - private MinecraftAccount loginOffline() { + private MinecraftAccount loginLocal() { new File(Tools.DIR_ACCOUNT_OLD).mkdir(); String text = edit2.getText().toString(); @@ -584,8 +572,6 @@ public class PojavLoginActivity extends BaseActivity { edit2.setError(getString(R.string.login_error_invalid_username)); } else if (new File(Tools.DIR_ACCOUNT_NEW + "/" + text + ".json").exists()) { edit2.setError(getString(R.string.login_error_exist_username)); - } else if (!edit3.getText().toString().isEmpty()) { - edit3.setError(getString(R.string.login_error_offline_password)); } else { MinecraftAccount builder = new MinecraftAccount(); builder.isMicrosoft = false; @@ -599,43 +585,8 @@ public class PojavLoginActivity extends BaseActivity { public void loginMC(final View v) { - - if (sOffline.isChecked()) { - mProfile = loginOffline(); - playProfile(false); - } else { - ProgressBar prb = findViewById(R.id.launcherAccProgress); - new LoginTask().setLoginListener(new LoginListener(){ - - - @Override - public void onBeforeLogin() { - v.setEnabled(false); - prb.setVisibility(View.VISIBLE); - } - - @Override - public void onLoginDone(String[] result) { - if(result[0].equals("ERROR")){ - Tools.dialogOnUiThread(PojavLoginActivity.this, - getResources().getString(R.string.global_error), strArrToString(result)); - } else{ - MinecraftAccount builder = new MinecraftAccount(); - builder.accessToken = result[1]; - builder.clientToken = result[2]; - builder.profileId = result[3]; - builder.username = result[4]; - builder.updateSkinFace(); - mProfile = builder; - } - runOnUiThread(() -> { - v.setEnabled(true); - prb.setVisibility(View.GONE); - playProfile(false); - }); - } - }).execute(edit2.getText().toString(), edit3.getText().toString()); - } + mProfile = loginLocal(); + playProfile(false); } private void playProfile(boolean notOnLogin) { diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java index d1a6709a9..53252682b 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java @@ -8,8 +8,6 @@ import android.util.Log; import com.google.gson.JsonSyntaxException; import java.io.File; import java.io.IOException; -import net.kdt.pojavlaunch.authenticator.mojang.RefreshListener; -import net.kdt.pojavlaunch.authenticator.mojang.RefreshTokenTask; import net.kdt.pojavlaunch.value.MinecraftAccount; public class PojavProfile { @@ -103,8 +101,4 @@ public class PojavProfile { Intent intent = new Intent(ctx, PojavLauncherActivity.class); //MCLauncherActivity.class); ctx.startActivity(intent); } - - public static void updateTokens(final Activity ctx, final String name, RefreshListener listen) throws Exception { - new RefreshTokenTask(ctx, listen).execute(name); - } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java index ad69b5707..b3c9c0bfb 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -197,7 +197,7 @@ public final class Tools { versionName = versionInfo.inheritsFrom; } - String userType = "mojang"; + String userType = "msa"; File gameDir = new File(strGameDir); gameDir.mkdirs(); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/LoginListener.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/LoginListener.java deleted file mode 100644 index 444dffc6d..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/LoginListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.kdt.pojavlaunch.authenticator.mojang; - -public interface LoginListener -{ - public void onBeforeLogin(); - public void onLoginDone(String[] result); -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/LoginTask.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/LoginTask.java deleted file mode 100644 index b61478e4e..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/LoginTask.java +++ /dev/null @@ -1,71 +0,0 @@ -package net.kdt.pojavlaunch.authenticator.mojang; - -import android.os.*; -import net.kdt.pojavlaunch.authenticator.mojang.yggdrasil.*; -import java.io.*; -import java.util.*; -import net.kdt.pojavlaunch.*; - -public class LoginTask extends AsyncTask -{ - private YggdrasilAuthenticator authenticator = new YggdrasilAuthenticator(); - //private String TAG = "MojangAuth-login"; - private LoginListener listener; - - public LoginTask setLoginListener(LoginListener listener) { - this.listener = listener; - return this; - } - - private UUID getRandomUUID() { - return UUID.randomUUID(); - } - - @Override - protected void onPreExecute() { - listener.onBeforeLogin(); - - super.onPreExecute(); - } - - @Override - protected Void doInBackground(String[] args) { - ArrayList str = new ArrayList(); - str.add("ERROR"); - try{ - try{ - AuthenticateResponse response = authenticator.authenticate(args[0], args[1], getRandomUUID()); - if (response.selectedProfile == null) { - str.add("Can't login a demo account!\n"); - } else { - if (new File(Tools.DIR_ACCOUNT_NEW + "/" + response.selectedProfile.name + ".json").exists()) { - str.add("This account already exist!\n"); - } else { - str.add(response.accessToken); // Access token - str.add(response.clientToken.toString()); // Client token - str.add(response.selectedProfile.id); // Profile ID - str.add(response.selectedProfile.name); // Username - str.set(0, "NORMAL"); - } - } - } - //MainActivity.updateStatus(804); - catch(Throwable e){ - str.add(e.getMessage()); - } - } - catch(Exception e){ - str.add(e.getMessage()); - } - - listener.onLoginDone(str.toArray(new String[0])); - - return null; - } - - @Override - protected void onPostExecute(Void result) { - // listener.onLoginDone(result); - super.onPostExecute(result); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/RefreshTokenTask.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/RefreshTokenTask.java deleted file mode 100644 index b7fb145e0..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/RefreshTokenTask.java +++ /dev/null @@ -1,79 +0,0 @@ -package net.kdt.pojavlaunch.authenticator.mojang; - -import android.content.*; -import android.os.*; -import com.google.gson.*; - -import java.io.IOException; -import java.lang.ref.WeakReference; -import java.util.*; -import net.kdt.pojavlaunch.*; -import net.kdt.pojavlaunch.authenticator.mojang.yggdrasil.*; -import android.app.*; -import net.kdt.pojavlaunch.value.*; - -public class RefreshTokenTask extends AsyncTask { - private YggdrasilAuthenticator authenticator = new YggdrasilAuthenticator(); - //private Gson gson = new Gson(); - private RefreshListener listener; - private MinecraftAccount profilePath; - - private final WeakReference ctx; - private ProgressDialog build; - - public RefreshTokenTask(Context ctx, RefreshListener listener) { - this.ctx = new WeakReference<>(ctx); - this.listener = listener; - } - - @Override - public void onPreExecute() { - build = new ProgressDialog(ctx.get()); - build.setMessage(ctx.get().getString(R.string.global_waiting)); - build.setProgressStyle(ProgressDialog.STYLE_SPINNER); - build.setCancelable(false); - build.show(); - } - - @Override - public Throwable doInBackground(String... args) { - try { - this.profilePath = MinecraftAccount.load(args[0]); - int responseCode = 400; - try { - responseCode = this.authenticator.validate(profilePath.accessToken).statusCode; - }catch(RuntimeException e) {} - - if (responseCode == 403) { - RefreshResponse response = this.authenticator.refresh(profilePath.accessToken, UUID.fromString(profilePath.clientToken)); - if (response == null) { - // Refresh when offline? - return null; - } else if (response.selectedProfile == null) { - throw new IllegalArgumentException("Can't refresh a demo account!"); - } - - profilePath.clientToken = response.clientToken.toString(); - profilePath.accessToken = response.accessToken; - profilePath.username = response.selectedProfile.name; - profilePath.profileId = response.selectedProfile.id; - } - profilePath.updateSkinFace(); - profilePath.save(); - return null; - } catch (Throwable e) { - return e; - } - } - - @Override - public void onPostExecute(Throwable result) { - build.dismiss(); - if (result == null) { - listener.onSuccess(profilePath); - } else { - listener.onFailed(result); - } - } -} - diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/AuthenticateRequest.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/AuthenticateRequest.java deleted file mode 100644 index f9dce5790..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/AuthenticateRequest.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.kdt.pojavlaunch.authenticator.mojang.yggdrasil; - -import java.util.UUID; - -public class AuthenticateRequest { - public AgentInfo agent = new AgentInfo(); - public UUID clientToken; - public String password; - public String username; - - public static class AgentInfo { - public String name; - public int version; - } - - public AuthenticateRequest(String username, String password, UUID clientToken, String clientName, int clientVersion) { - this.username = username; - this.password = password; - this.clientToken = clientToken; - this.agent.name = clientName; - this.agent.version = clientVersion; - } -} - diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/AuthenticateResponse.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/AuthenticateResponse.java deleted file mode 100644 index 8989acd15..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/AuthenticateResponse.java +++ /dev/null @@ -1,11 +0,0 @@ -package net.kdt.pojavlaunch.authenticator.mojang.yggdrasil; - -import java.util.UUID; - -public class AuthenticateResponse { - public String accessToken; - public Profile[] availableProfiles; - public UUID clientToken; - public Profile selectedProfile; -} - diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/RefreshResponse.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/RefreshResponse.java deleted file mode 100644 index b9a597955..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/RefreshResponse.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.kdt.pojavlaunch.authenticator.mojang.yggdrasil; - -import java.util.UUID; - -public class RefreshResponse { - public String accessToken; - public UUID clientToken; - public Profile selectedProfile; -} - diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/YggdrasilAuthenticator.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/YggdrasilAuthenticator.java index fb3029608..8cf004610 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/YggdrasilAuthenticator.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/mojang/yggdrasil/YggdrasilAuthenticator.java @@ -90,31 +90,6 @@ public class YggdrasilAuthenticator { } } - public AuthenticateResponse authenticate(String username, String password, UUID clientId) throws IOException, Throwable { - NetworkResponse obj = makeRequest("authenticate", new AuthenticateRequest(username, password, clientId, this.clientName, this.clientVersion), AuthenticateResponse.class); - /* - if (obj.statusCode != 200) { - throw new RuntimeException("Invalid username or password, status code: " + obj.statusCode); - } - */ - obj.throwExceptionIfNeed(); - return (AuthenticateResponse) obj.response; - } - - public RefreshResponse refresh(String authToken, UUID clientId) throws IOException, Throwable { - NetworkResponse obj = makeRequest("refresh", new RefreshRequest(authToken, clientId), RefreshResponse.class); - if (obj == null) { - return null; - } else { - obj.throwExceptionIfNeed(); // "Invalid username or password, status code: " + obj.statusCode); - return (RefreshResponse) obj.response; - } - } - - public NetworkResponse validate(String authToken) throws Throwable { - return makeRequest("validate", new RefreshRequest(authToken, null), null); - } - public NetworkResponse invalidate(String authToken, UUID clientId) throws Throwable { return makeRequest("invalidate", new RefreshRequest(authToken, clientId), null); } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java index 41aa16824..42b7463f6 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/MinecraftDownloaderTask.java @@ -358,7 +358,7 @@ public class MinecraftDownloaderTask extends AsyncTask - - - - - - - - - - - + app:layout_constraintStart_toStartOf="@+id/login_edit_email" + app:layout_constraintTop_toBottomOf="@+id/login_edit_email" /> + app:layout_constraintStart_toStartOf="@+id/login_switch_local" + app:layout_constraintTop_toBottomOf="@+id/login_switch_local" /> @@ -190,4 +147,4 @@ app:layout_constraintStart_toStartOf="@+id/mineButton" app:layout_constraintTop_toBottomOf="@+id/mineButton" /> - \ No newline at end of file + diff --git a/app_pojavlauncher/src/main/res/values/strings.xml b/app_pojavlauncher/src/main/res/values/strings.xml index c56acc483..43a560083 100644 --- a/app_pojavlauncher/src/main/res/values/strings.xml +++ b/app_pojavlauncher/src/main/res/values/strings.xml @@ -10,16 +10,12 @@ - Email or username - Password + Local username Keep me logged in Login - Login as offline account - Invalid username. Username must be in range of 3-16 characters, should only contains A-Z, a-z, 0-9 and underscore. This username already exist - Offline account can\'t include password! Microsoft login @@ -58,7 +54,7 @@ Connected - Offline + Local Ready to play Minecraft %s @@ -66,6 +62,7 @@ Downloading %s "Downloading %s (%.2f MB / %.2f MB)" Preparing to download resources + Minecraft can\'t be legally installed when logged in with a local account. Please switch to an online account to continue. Options Launch a mod installer (Forge, LabyMod, Fabric, etc...) From 2f4f71e27febf4376586538697d1b2cac1b25a2f Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh <40482367+khanhduytran0@users.noreply.github.com> Date: Fri, 11 Mar 2022 20:11:33 +0700 Subject: [PATCH 68/70] Re-add an necessary import --- .../src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java index e5708d388..dd91ed26a 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavLoginActivity.java @@ -43,6 +43,7 @@ import androidx.core.content.ContextCompat; import net.kdt.pojavlaunch.authenticator.microsoft.MicrosoftAuthTask; import net.kdt.pojavlaunch.authenticator.microsoft.ui.MicrosoftLoginGUIActivity; +import net.kdt.pojavlaunch.authenticator.mojang.InvalidateTokenTask; import net.kdt.pojavlaunch.authenticator.mojang.RefreshListener; import net.kdt.pojavlaunch.customcontrols.CustomControls; import net.kdt.pojavlaunch.multirt.MultiRTConfigDialog; From ddae3ecf1521fbe5f41575f2362db530f381abe1 Mon Sep 17 00:00:00 2001 From: Duy Tran Khanh <40482367+khanhduytran0@users.noreply.github.com> Date: Fri, 11 Mar 2022 20:28:47 +0700 Subject: [PATCH 69/70] Possible fix for broken UI --- .../src/main/res/layout/activity_pojav_login.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app_pojavlauncher/src/main/res/layout/activity_pojav_login.xml b/app_pojavlauncher/src/main/res/layout/activity_pojav_login.xml index 86c7400bf..e1ae586c3 100644 --- a/app_pojavlauncher/src/main/res/layout/activity_pojav_login.xml +++ b/app_pojavlauncher/src/main/res/layout/activity_pojav_login.xml @@ -102,8 +102,8 @@ android:textColor="@android:color/white" app:layout_constraintEnd_toStartOf="@+id/guidelineLeft" - app:layout_constraintStart_toStartOf="@+id/login_switch_local" - app:layout_constraintTop_toBottomOf="@+id/login_switch_local" /> + app:layout_constraintStart_toStartOf="@id/login_switch_remember" + app:layout_constraintTop_toBottomOf="@id/login_switch_remember" /> Date: Tue, 15 Mar 2022 08:27:49 +0700 Subject: [PATCH 70/70] MultiRT config dialog list: fix orientation --- .../java/net/kdt/pojavlaunch/multirt/MultiRTConfigDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTConfigDialog.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTConfigDialog.java index 24731a15f..7e0bdbfc2 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTConfigDialog.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/multirt/MultiRTConfigDialog.java @@ -19,7 +19,7 @@ public class MultiRTConfigDialog { public void prepare(BaseLauncherActivity activity) { mDialogView = new RecyclerView(activity); - mDialogView.setLayoutManager(new LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)); + mDialogView.setLayoutManager(new LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)); mDialogView.setAdapter(new RTRecyclerViewAdapter(this)); AlertDialog.Builder builder = new AlertDialog.Builder(activity);