mirror of
https://github.com/geode-sdk/android-launcher.git
synced 2026-10-21 16:32:39 +00:00
Compare commits
7
Commits
1.9.0
...
latency-test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df513983d1 | ||
|
|
a71071e3ac | ||
|
|
8578200db1 | ||
|
|
adb9dcc1e9 | ||
|
|
a32589b06c | ||
|
|
1773e54c84 | ||
|
|
5718b73470 |
No files matched your search
@@ -318,6 +318,7 @@ android {
|
|||||||
buildFeatures {
|
buildFeatures {
|
||||||
compose = true
|
compose = true
|
||||||
buildConfig = true
|
buildConfig = true
|
||||||
|
prefab = true
|
||||||
}
|
}
|
||||||
packaging {
|
packaging {
|
||||||
resources {
|
resources {
|
||||||
@@ -359,6 +360,7 @@ dependencies {
|
|||||||
implementation ("androidx.activity:activity-ktx:1.13.0")
|
implementation ("androidx.activity:activity-ktx:1.13.0")
|
||||||
implementation ("androidx.appcompat:appcompat:1.8.0")
|
implementation ("androidx.appcompat:appcompat:1.8.0")
|
||||||
implementation ("androidx.documentfile:documentfile:1.1.0")
|
implementation ("androidx.documentfile:documentfile:1.1.0")
|
||||||
|
implementation ("androidx.games:games-frame-pacing:2.1.3")
|
||||||
|
|
||||||
implementation ("com.squareup.okio:okio:3.18.2")
|
implementation ("com.squareup.okio:okio:3.18.2")
|
||||||
implementation ("com.squareup.okhttp3:okhttp:5.5.0")
|
implementation ("com.squareup.okhttp3:okhttp:5.5.0")
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ cmake_minimum_required(VERSION 3.21)
|
|||||||
|
|
||||||
project(launcherfix)
|
project(launcherfix)
|
||||||
|
|
||||||
add_library(launcherfix SHARED launcher-fix.cpp patcher.cpp)
|
find_package(games-frame-pacing REQUIRED CONFIG)
|
||||||
|
|
||||||
|
add_library(launcherfix SHARED launcher-fix.cpp patcher.cpp pacing.cpp)
|
||||||
|
|
||||||
target_compile_features(launcherfix PUBLIC cxx_std_20)
|
target_compile_features(launcherfix PUBLIC cxx_std_20)
|
||||||
set_target_properties(launcherfix PROPERTIES CXX_EXTENSIONS OFF)
|
set_target_properties(launcherfix PROPERTIES CXX_EXTENSIONS OFF)
|
||||||
@@ -14,4 +16,5 @@ set_target_properties(launcherfix PROPERTIES
|
|||||||
CXX_VISIBILITY_PRESET hidden
|
CXX_VISIBILITY_PRESET hidden
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(launcherfix PRIVATE log)
|
target_link_libraries(launcherfix PRIVATE log android)
|
||||||
|
target_link_libraries(launcherfix PRIVATE games-frame-pacing::swappy_static)
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
#include <swappy/swappyGL.h>
|
||||||
|
#include <swappy/swappyGL_extra.h>
|
||||||
|
#include <android/native_window_jni.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT void JNICALL Java_com_geode_launcher_LauncherFix_initFramePacing(
|
||||||
|
JNIEnv *env,
|
||||||
|
jobject,
|
||||||
|
jobject activity
|
||||||
|
) {
|
||||||
|
SwappyGL_init(env, activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NativeWindowDeleter {
|
||||||
|
void operator()(ANativeWindow* p) const {
|
||||||
|
if (p != nullptr) ANativeWindow_release(p);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<ANativeWindow, NativeWindowDeleter> native_window = nullptr;
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT void JNICALL Java_com_geode_launcher_LauncherFix_destroyFramePacing(JNIEnv*, jobject) {
|
||||||
|
SwappyGL_destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jboolean JNICALL Java_com_geode_launcher_LauncherFix_swapFrame(
|
||||||
|
JNIEnv*,
|
||||||
|
jobject,
|
||||||
|
jlong display,
|
||||||
|
jlong surface
|
||||||
|
) {
|
||||||
|
return SwappyGL_swap(
|
||||||
|
reinterpret_cast<EGLDisplay>(display),
|
||||||
|
reinterpret_cast<EGLSurface>(surface)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT void JNICALL Java_com_geode_launcher_LauncherFix_setSurface(
|
||||||
|
JNIEnv* env,
|
||||||
|
jobject,
|
||||||
|
jobject surface
|
||||||
|
) {
|
||||||
|
if (surface == nullptr) {
|
||||||
|
native_window.reset();
|
||||||
|
SwappyGL_setWindow(nullptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
native_window.reset(ANativeWindow_fromSurface(env, surface));
|
||||||
|
SwappyGL_setWindow(native_window.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT void JNICALL Java_com_geode_launcher_LauncherFix_setSwapInterval(
|
||||||
|
JNIEnv* env,
|
||||||
|
jobject,
|
||||||
|
jlong interval_ns
|
||||||
|
) {
|
||||||
|
SwappyGL_setAutoSwapInterval(false);
|
||||||
|
SwappyGL_setSwapIntervalNS(interval_ns);
|
||||||
|
}
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -5,7 +5,9 @@ import android.content.Intent
|
|||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
import android.content.pm.PackageInfo
|
import android.content.pm.PackageInfo
|
||||||
import android.opengl.GLSurfaceView
|
import android.opengl.EGL14
|
||||||
|
import android.opengl.EGLConfig
|
||||||
|
import android.opengl.EGLDisplay
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
@@ -43,9 +45,6 @@ import java.io.File
|
|||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import javax.microedition.khronos.egl.EGL10
|
|
||||||
import javax.microedition.khronos.egl.EGLConfig
|
|
||||||
import javax.microedition.khronos.egl.EGLDisplay
|
|
||||||
|
|
||||||
enum class DisplayMode {
|
enum class DisplayMode {
|
||||||
DEFAULT, LIMITED, FULLSCREEN;
|
DEFAULT, LIMITED, FULLSCREEN;
|
||||||
@@ -78,6 +77,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
private var mAspectRatio = 0.0f
|
private var mAspectRatio = 0.0f
|
||||||
private var mScreenZoom = 1.0f
|
private var mScreenZoom = 1.0f
|
||||||
private var mScreenZoomFit = false
|
private var mScreenZoomFit = false
|
||||||
|
private var mNativeFramePacing = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setupUIState()
|
setupUIState()
|
||||||
@@ -131,6 +131,10 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
mGLSurfaceView?.manualBackEvents = true
|
mGLSurfaceView?.manualBackEvents = true
|
||||||
|
|
||||||
|
if (mNativeFramePacing) {
|
||||||
|
LauncherFix.initFramePacing(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createVersionFile() {
|
private fun createVersionFile() {
|
||||||
@@ -491,9 +495,11 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
|
|
||||||
val frameRate = mLimitedRefreshRate
|
val frameRate = mLimitedRefreshRate
|
||||||
if (frameRate != null) {
|
if (frameRate != null) {
|
||||||
renderer.limitFrameRate(frameRate)
|
glSurfaceView.setMaxFrameRate(frameRate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glSurfaceView.nativeFramePacing = mNativeFramePacing
|
||||||
|
|
||||||
editText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
|
editText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
|
||||||
glSurfaceView.cocos2dxEditText = editText
|
glSurfaceView.cocos2dxEditText = editText
|
||||||
|
|
||||||
@@ -529,6 +535,8 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mNativeFramePacing = preferenceUtils.getBoolean(PreferenceUtils.Key.NATIVE_FRAME_PACING)
|
||||||
|
|
||||||
if (displayMode == DisplayMode.FULLSCREEN && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (displayMode == DisplayMode.FULLSCREEN && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
||||||
GeodeUtils.handleSafeArea = true
|
GeodeUtils.handleSafeArea = true
|
||||||
@@ -562,6 +570,10 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
FMOD.close()
|
FMOD.close()
|
||||||
|
|
||||||
|
if (mNativeFramePacing) {
|
||||||
|
LauncherFix.destroyFramePacing()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resumeGame() {
|
private fun resumeGame() {
|
||||||
@@ -733,11 +745,7 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class EGLConfigChooser : GLSurfaceView.EGLConfigChooser {
|
class EGLConfigChooser : ExplicitGLSurfaceView.EGLConfigChooser {
|
||||||
// this comes from EGL14, but is unavailable on EGL10
|
|
||||||
// also EGL14 is incompatible with EGL10. so whatever
|
|
||||||
private var EGL_OPENGL_ES2_BIT: Int = 0x04
|
|
||||||
|
|
||||||
private data class ConfigValues(
|
private data class ConfigValues(
|
||||||
val redSize: Int,
|
val redSize: Int,
|
||||||
val greenSize: Int,
|
val greenSize: Int,
|
||||||
@@ -747,29 +755,29 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
val stencilSize: Int,
|
val stencilSize: Int,
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun getAttribValue(egl: EGL10, display: EGLDisplay, config: EGLConfig, attrib: Int): Int {
|
private fun getAttribValue(display: EGLDisplay, config: EGLConfig, attrib: Int): Int {
|
||||||
val value = IntArray(1)
|
val value = IntArray(1)
|
||||||
egl.eglGetConfigAttrib(display, config, attrib, value)
|
EGL14.eglGetConfigAttrib(display, config, attrib, value, 0)
|
||||||
|
|
||||||
return value[0]
|
return value[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun testConfig(egl: EGL10, display: EGLDisplay, attrib: ConfigValues): EGLConfig? {
|
private fun testConfig(display: EGLDisplay, attrib: ConfigValues): EGLConfig? {
|
||||||
val attribList = intArrayOf(
|
val attribList = intArrayOf(
|
||||||
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
|
||||||
EGL10.EGL_RED_SIZE, attrib.redSize,
|
EGL14.EGL_RED_SIZE, attrib.redSize,
|
||||||
EGL10.EGL_GREEN_SIZE, attrib.greenSize,
|
EGL14.EGL_GREEN_SIZE, attrib.greenSize,
|
||||||
EGL10.EGL_BLUE_SIZE, attrib.blueSize,
|
EGL14.EGL_BLUE_SIZE, attrib.blueSize,
|
||||||
EGL10.EGL_ALPHA_SIZE, attrib.alphaSize,
|
EGL14.EGL_ALPHA_SIZE, attrib.alphaSize,
|
||||||
EGL10.EGL_DEPTH_SIZE, attrib.depthSize,
|
EGL14.EGL_DEPTH_SIZE, attrib.depthSize,
|
||||||
EGL10.EGL_STENCIL_SIZE, attrib.stencilSize,
|
EGL14.EGL_STENCIL_SIZE, attrib.stencilSize,
|
||||||
EGL10.EGL_NONE
|
EGL14.EGL_NONE
|
||||||
)
|
)
|
||||||
|
|
||||||
val configs = arrayOfNulls<EGLConfig>(1)
|
val configs = arrayOfNulls<EGLConfig>(1)
|
||||||
val numConfigs = IntArray(1)
|
val numConfigs = IntArray(1)
|
||||||
|
|
||||||
val res = egl.eglChooseConfig(display, attribList, configs, configs.size, numConfigs)
|
val res = EGL14.eglChooseConfig(display, attribList, 0, configs, 0, configs.size, numConfigs, 0)
|
||||||
if (res && numConfigs[0] > 0 && configs[0] != null) {
|
if (res && numConfigs[0] > 0 && configs[0] != null) {
|
||||||
return configs[0]
|
return configs[0]
|
||||||
}
|
}
|
||||||
@@ -777,18 +785,18 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun printConfig(egl: EGL10, display: EGLDisplay, config: EGLConfig) {
|
private fun printConfig(display: EGLDisplay, config: EGLConfig) {
|
||||||
val id = getAttribValue(egl, display, config, EGL10.EGL_CONFIG_ID)
|
val id = getAttribValue(display, config, EGL14.EGL_CONFIG_ID)
|
||||||
val red = getAttribValue(egl, display, config, EGL10.EGL_RED_SIZE)
|
val red = getAttribValue(display, config, EGL14.EGL_RED_SIZE)
|
||||||
val green = getAttribValue(egl, display, config, EGL10.EGL_GREEN_SIZE)
|
val green = getAttribValue(display, config, EGL14.EGL_GREEN_SIZE)
|
||||||
val blue = getAttribValue(egl, display, config, EGL10.EGL_BLUE_SIZE)
|
val blue = getAttribValue(display, config, EGL14.EGL_BLUE_SIZE)
|
||||||
val alpha = getAttribValue(egl, display, config, EGL10.EGL_ALPHA_SIZE)
|
val alpha = getAttribValue(display, config, EGL14.EGL_ALPHA_SIZE)
|
||||||
val depth = getAttribValue(egl, display, config, EGL10.EGL_DEPTH_SIZE)
|
val depth = getAttribValue(display, config, EGL14.EGL_DEPTH_SIZE)
|
||||||
val stencil = getAttribValue(egl, display, config, EGL10.EGL_STENCIL_SIZE)
|
val stencil = getAttribValue(display, config, EGL14.EGL_STENCIL_SIZE)
|
||||||
println("EGLConfig $id: (red = $red, green = $green, blue = $blue, alpha = $alpha, depth = $depth, stencil = $stencil)")
|
println("EGLConfig $id: (red = $red, green = $green, blue = $blue, alpha = $alpha, depth = $depth, stencil = $stencil)")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun chooseConfig(egl: EGL10, display: EGLDisplay): EGLConfig {
|
override fun chooseConfig(display: EGLDisplay): EGLConfig {
|
||||||
val configs = listOf(
|
val configs = listOf(
|
||||||
ConfigValues(8, 8, 8, 8, 16, 8),
|
ConfigValues(8, 8, 8, 8, 16, 8),
|
||||||
ConfigValues(8, 8, 8, 0, 16, 8),
|
ConfigValues(8, 8, 8, 0, 16, 8),
|
||||||
@@ -797,9 +805,9 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL
|
|||||||
)
|
)
|
||||||
|
|
||||||
return configs.firstNotNullOf {
|
return configs.firstNotNullOf {
|
||||||
val config = testConfig(egl, display, it)
|
val config = testConfig(display, it)
|
||||||
if (config != null) {
|
if (config != null) {
|
||||||
printConfig(egl, display, config)
|
printConfig(display, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
config
|
config
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package com.geode.launcher
|
package com.geode.launcher
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.view.Surface
|
||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
import com.geode.launcher.utils.Constants
|
import com.geode.launcher.utils.Constants
|
||||||
|
|
||||||
@@ -16,4 +18,10 @@ object LauncherFix {
|
|||||||
external fun enableExceptionsRenaming()
|
external fun enableExceptionsRenaming()
|
||||||
|
|
||||||
external fun performPatches()
|
external fun performPatches()
|
||||||
|
|
||||||
|
external fun initFramePacing(activity: Activity)
|
||||||
|
external fun destroyFramePacing()
|
||||||
|
external fun swapFrame(display: Long, surface: Long): Boolean
|
||||||
|
external fun setSurface(surface: Surface?)
|
||||||
|
external fun setSwapInterval(intervalNs: Long)
|
||||||
}
|
}
|
||||||
@@ -169,6 +169,12 @@ fun DeveloperSettingsScreen(onBackPressedDispatcher: OnBackPressedDispatcher?) {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SettingsCard(
|
||||||
|
title = stringResource(R.string.preference_native_pacing),
|
||||||
|
description = stringResource(R.string.preference_native_pacing_description),
|
||||||
|
preferenceKey = PreferenceUtils.Key.NATIVE_FRAME_PACING,
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
SettingsCard(
|
SettingsCard(
|
||||||
|
|||||||
@@ -150,6 +150,7 @@ class PreferenceUtils(private val sharedPreferences: SharedPreferences) {
|
|||||||
LAST_LAUNCHER_UPDATE,
|
LAST_LAUNCHER_UPDATE,
|
||||||
DISABLE_UPDATE_CACHE,
|
DISABLE_UPDATE_CACHE,
|
||||||
PREBUNDLED_GEODE_MIGRATION_PERFORMED,
|
PREBUNDLED_GEODE_MIGRATION_PERFORMED,
|
||||||
|
NATIVE_FRAME_PACING,
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun defaultValueForBooleanKey(key: Key): Boolean {
|
private fun defaultValueForBooleanKey(key: Key): Boolean {
|
||||||
@@ -201,6 +202,7 @@ class PreferenceUtils(private val sharedPreferences: SharedPreferences) {
|
|||||||
Key.LAST_LAUNCHER_UPDATE -> "PreferenceLastLauncherUpdate"
|
Key.LAST_LAUNCHER_UPDATE -> "PreferenceLastLauncherUpdate"
|
||||||
Key.DISABLE_UPDATE_CACHE -> "PreferenceDisableUpdateCache"
|
Key.DISABLE_UPDATE_CACHE -> "PreferenceDisableUpdateCache"
|
||||||
Key.PREBUNDLED_GEODE_MIGRATION_PERFORMED -> "PreferencePrebundledGeodeMigrationPerformed"
|
Key.PREBUNDLED_GEODE_MIGRATION_PERFORMED -> "PreferencePrebundledGeodeMigrationPerformed"
|
||||||
|
Key.NATIVE_FRAME_PACING -> "PreferenceNativeFramePacing"
|
||||||
// Key.RELEASE_CHANNEL -> "PreferenceReleaseChannel"
|
// Key.RELEASE_CHANNEL -> "PreferenceReleaseChannel"
|
||||||
// Key.LAST_DISMISSED_UPDATE -> "PreferenceLastDismissedUpdate"
|
// Key.LAST_DISMISSED_UPDATE -> "PreferenceLastDismissedUpdate"
|
||||||
// Key.FORCE_HRR -> "PreferenceForceHighRefreshRate"
|
// Key.FORCE_HRR -> "PreferenceForceHighRefreshRate"
|
||||||
|
|||||||
@@ -17,15 +17,18 @@ import android.view.inputmethod.InputMethodManager
|
|||||||
import androidx.annotation.RequiresApi
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.appcompat.widget.AppCompatEditText
|
import androidx.appcompat.widget.AppCompatEditText
|
||||||
import com.customRobTop.BaseRobTopActivity
|
import com.customRobTop.BaseRobTopActivity
|
||||||
|
import com.geode.launcher.ExplicitGLSurfaceView
|
||||||
|
import com.geode.launcher.LauncherFix
|
||||||
import com.geode.launcher.utils.GeodeUtils
|
import com.geode.launcher.utils.GeodeUtils
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.roundToLong
|
||||||
|
|
||||||
private const val HANDLER_OPEN_IME_KEYBOARD = 2
|
private const val HANDLER_OPEN_IME_KEYBOARD = 2
|
||||||
private const val HANDLER_CLOSE_IME_KEYBOARD = 3
|
private const val HANDLER_CLOSE_IME_KEYBOARD = 3
|
||||||
private const val MS_TO_NS = 1_000_000
|
private const val MS_TO_NS = 1_000_000
|
||||||
private const val SEC_TO_NS = 1_000_000_000.0
|
private const val SEC_TO_NS = 1_000_000_000.0
|
||||||
|
|
||||||
class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
class Cocos2dxGLSurfaceView(context: Context) : ExplicitGLSurfaceView(context) {
|
||||||
companion object {
|
companion object {
|
||||||
lateinit var cocos2dxGLSurfaceView: Cocos2dxGLSurfaceView
|
lateinit var cocos2dxGLSurfaceView: Cocos2dxGLSurfaceView
|
||||||
private lateinit var handler: Handler
|
private lateinit var handler: Handler
|
||||||
@@ -64,6 +67,7 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
var controllerEventsEnabled = false
|
var controllerEventsEnabled = false
|
||||||
private set
|
private set
|
||||||
var supportsResizeEvents = false
|
var supportsResizeEvents = false
|
||||||
|
var saveNativeFramePacing = false
|
||||||
|
|
||||||
var cocos2dxEditText: AppCompatEditText? = null
|
var cocos2dxEditText: AppCompatEditText? = null
|
||||||
set(value) {
|
set(value) {
|
||||||
@@ -139,6 +143,10 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
|
|
||||||
println("updateRefreshRate: selecting refresh rate of ${chosenDisplay.refreshRate} (display ${chosenDisplay.modeId})")
|
println("updateRefreshRate: selecting refresh rate of ${chosenDisplay.refreshRate} (display ${chosenDisplay.modeId})")
|
||||||
|
|
||||||
|
if (saveNativeFramePacing) {
|
||||||
|
LauncherFix.setSwapInterval((1_000_000_000L / chosenRefreshRate).roundToLong())
|
||||||
|
}
|
||||||
|
|
||||||
holder.surface.setFrameRate(chosenRefreshRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT)
|
holder.surface.setFrameRate(chosenRefreshRate, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT)
|
||||||
if (isAttachedToWindow) {
|
if (isAttachedToWindow) {
|
||||||
(context as Activity).window.attributes.preferredRefreshRate = chosenRefreshRate
|
(context as Activity).window.attributes.preferredRefreshRate = chosenRefreshRate
|
||||||
@@ -153,6 +161,7 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
|
||||||
renderMode = RENDERMODE_CONTINUOUSLY
|
renderMode = RENDERMODE_CONTINUOUSLY
|
||||||
queueEvent { cocos2dxRenderer.handleOnResume() }
|
queueEvent { cocos2dxRenderer.handleOnResume() }
|
||||||
}
|
}
|
||||||
@@ -533,6 +542,11 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
setRenderer(this.cocos2dxRenderer)
|
setRenderer(this.cocos2dxRenderer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setNativeFramePacing(nativeFramePacing: Boolean) {
|
||||||
|
super.setNativeFramePacing(nativeFramePacing)
|
||||||
|
saveNativeFramePacing = nativeFramePacing
|
||||||
|
}
|
||||||
|
|
||||||
private fun getContentText(): String {
|
private fun getContentText(): String {
|
||||||
return cocos2dxRenderer.getContentText()
|
return cocos2dxRenderer.getContentText()
|
||||||
}
|
}
|
||||||
@@ -567,6 +581,10 @@ class Cocos2dxGLSurfaceView(context: Context) : GLSurfaceView(context) {
|
|||||||
inputManager.unregisterInputDeviceListener(InputListener)
|
inputManager.unregisterInputDeviceListener(InputListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setMaxFrameRate(rate: Int) {
|
||||||
|
cocos2dxRenderer.limitFrameRate(rate)
|
||||||
|
}
|
||||||
|
|
||||||
object InputListener : InputManager.InputDeviceListener {
|
object InputListener : InputManager.InputDeviceListener {
|
||||||
override fun onInputDeviceAdded(deviceId: Int) {
|
override fun onInputDeviceAdded(deviceId: Int) {
|
||||||
GeodeUtils.inputDeviceAdded(deviceId)
|
GeodeUtils.inputDeviceAdded(deviceId)
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
package org.cocos2dx.lib
|
package org.cocos2dx.lib
|
||||||
|
|
||||||
import android.opengl.GLSurfaceView
|
import android.opengl.EGLConfig
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import javax.microedition.khronos.egl.EGLConfig
|
import com.geode.launcher.ExplicitGLSurfaceView
|
||||||
import javax.microedition.khronos.opengles.GL10
|
|
||||||
|
|
||||||
private const val NANOSECONDS_PER_SECOND = 1000000000L
|
private const val NANOSECONDS_PER_SECOND = 1000000000L
|
||||||
private const val NANOSECONDS_PER_MICROSECOND = 1000000L
|
private const val NANOSECONDS_PER_MICROSECOND = 1000000L
|
||||||
|
|
||||||
@Suppress("unused", "KotlinJniMissingFunction")
|
@Suppress("unused", "KotlinJniMissingFunction")
|
||||||
class Cocos2dxRenderer(private var handler: Cocos2dxGLSurfaceView) : GLSurfaceView.Renderer {
|
class Cocos2dxRenderer(private var handler: Cocos2dxGLSurfaceView) : ExplicitGLSurfaceView.Renderer {
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun setAnimationInterval(@Suppress("UNUSED_PARAMETER") animationInterval: Double) {
|
fun setAnimationInterval(@Suppress("UNUSED_PARAMETER") animationInterval: Double) {
|
||||||
@@ -80,12 +79,12 @@ class Cocos2dxRenderer(private var handler: Cocos2dxGLSurfaceView) : GLSurfaceVi
|
|||||||
screenHeight = surfaceHeight
|
screenHeight = surfaceHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSurfaceCreated(gl10: GL10?, eglConfig: EGLConfig?) {
|
override fun onSurfaceCreated(eglConfig: EGLConfig?) {
|
||||||
nativeInit(screenWidth, screenHeight)
|
nativeInit(screenWidth, screenHeight)
|
||||||
lastTickInNanoSeconds = System.nanoTime()
|
lastTickInNanoSeconds = System.nanoTime()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSurfaceChanged(gl10: GL10?, width: Int, height: Int) {
|
override fun onSurfaceChanged(width: Int, height: Int) {
|
||||||
if (setFrameRate && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
if (setFrameRate && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
handler.updateRefreshRate()
|
handler.updateRefreshRate()
|
||||||
}
|
}
|
||||||
@@ -93,7 +92,7 @@ class Cocos2dxRenderer(private var handler: Cocos2dxGLSurfaceView) : GLSurfaceVi
|
|||||||
println("renderer surfaceChanged: ${width}x${height}@${handler.display.refreshRate}fps")
|
println("renderer surfaceChanged: ${width}x${height}@${handler.display.refreshRate}fps")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDrawFrame(gl: GL10?) {
|
override fun onDrawFrame() {
|
||||||
val animationInterval = mAnimationInterval
|
val animationInterval = mAnimationInterval
|
||||||
if (animationInterval == null) {
|
if (animationInterval == null) {
|
||||||
nativeRender()
|
nativeRender()
|
||||||
|
|||||||
@@ -298,6 +298,9 @@
|
|||||||
<string name="preference_profiles_delete_alt">Delete</string>
|
<string name="preference_profiles_delete_alt">Delete</string>
|
||||||
<string name="preference_profiles_delete_undo_alt">Undo</string>
|
<string name="preference_profiles_delete_undo_alt">Undo</string>
|
||||||
|
|
||||||
|
<string name="preference_native_pacing">Native frame pacing</string>
|
||||||
|
<string name="preference_native_pacing_description">Reduces latency, but may worsen frame drops.</string>
|
||||||
|
|
||||||
<!-- ApplicationLogsActivity strings -->
|
<!-- ApplicationLogsActivity strings -->
|
||||||
<string name="title_activity_application_logs">Application logs</string>
|
<string name="title_activity_application_logs">Application logs</string>
|
||||||
<string name="application_logs_no_logs">No logs available.</string>
|
<string name="application_logs_no_logs">No logs available.</string>
|
||||||
|
|||||||
Reference in new issue
Block a user