diff --git a/Config/Supermodel.ini b/Config/Supermodel.ini index 56355b9..7986237 100644 --- a/Config/Supermodel.ini +++ b/Config/Supermodel.ini @@ -40,7 +40,6 @@ WideBackground = false ; Refresh rate (milliHertz accuracy). Actual Model 3 refresh rate is 57.524 Hz ; but this can cause judder so we use 60 Hz by default. -Throttle = 1 RefreshRate = 60.000 ; Legacy SCSP DSP implementation for games that do not play well with the newer diff --git a/README.md b/README.md index cfa7f4c..8df50c5 100644 --- a/README.md +++ b/README.md @@ -24,15 +24,6 @@ From the main game list, open the side menu (toolbar "menu" icon) and look under - **Wide background:** Stretches the 2D background layers when using widescreen (Supermodel `-wide-bg`). - **Enhanced Real3D (experimental):** Enables more desktop-like Real3D rendering (multi-pass transparency compositing + scroll fog). This can improve visuals in some games/areas, but may reduce performance on lower-end devices. -## Frame rate (High refresh devices) - -If games run too fast on 90/120Hz devices, enable frame limiting in `.../Android/data//files/super3/Config/Supermodel.ini`: - -- `Throttle = 1` -- `RefreshRate = 60.000` (or `57.524` for true Model 3 speed) - -Note: the app overwrites `Supermodel.ini` with the APK defaults after app updates. - ## Files & Storage - Save states and thumbnails are stored under the app's user data directory in `Saves/` (for example: `.../Android/data//files/super3/Saves/`). diff --git a/android/app/src/main/assets/Config/Supermodel.ini b/android/app/src/main/assets/Config/Supermodel.ini index 031f872..19c0017 100644 --- a/android/app/src/main/assets/Config/Supermodel.ini +++ b/android/app/src/main/assets/Config/Supermodel.ini @@ -28,11 +28,6 @@ QuadRendering = 0 XResolution = 496 YResolution = 384 VSync = 1 -; Frame limiting (recommended on 90/120Hz devices to prevent speedups) -Throttle = 1 -; Refresh rate (milliHertz accuracy). Actual Model 3 refresh rate is 57.524 Hz -; but this can cause judder so we use 60 Hz by default. -RefreshRate = 60.000 WideScreen = 0 WideBackground = 0 ; Enhanced Real3D compositing (FBO transparency + scroll fog). More accurate but may be slower. diff --git a/android/app/src/main/cpp/native-lib.cpp b/android/app/src/main/cpp/native-lib.cpp index 589fc7a..8706f2e 100644 --- a/android/app/src/main/cpp/native-lib.cpp +++ b/android/app/src/main/cpp/native-lib.cpp @@ -10,7 +10,6 @@ #include #include #include -#include #include @@ -260,13 +259,6 @@ struct Super3Host { // Supermodel.ini commonly uses 200 as "100%". config.Set("SoundVolume", "100"); config.Set("MusicVolume", "150"); - - // Match desktop defaults: cap emulation to the requested refresh rate. - // Without this, vsync on high-refresh devices (e.g., 120 Hz) can drive the - // emulation loop too fast. - config.Set("Throttle", true); - config.Set("RefreshRate", "60.0"); - config.Set("LegacySoundDSP", false); config.Set("New3DEngine", true); config.Set("New3DAccurate", false); @@ -744,45 +736,6 @@ static std::optional FindFirstExisting(const std::vector(60.0f)); - } catch (...) { - refreshRateHz = 60.0f; - } - - if (!std::isfinite(refreshRateHz) || refreshRateHz <= 0.0f) { - return 0; - } - - return uint64_t(1000.0f * refreshRateHz); -} - -static void SuperSleepUntil(uint64_t target, uint64_t perfCounterFrequency) -{ - const uint64_t time = SDL_GetPerformanceCounter(); - if (time > target) { - return; - } - - // Sleep the whole number of milliseconds minus one, then spin for the tail. - int32_t numWholeMillisToSleep = int32_t((target - time) * 1000 / perfCounterFrequency); - numWholeMillisToSleep -= 1; - if (numWholeMillisToSleep > 0) { - SDL_Delay((uint32_t)numWholeMillisToSleep); - } - - volatile uint64_t now; - int32_t remain; - do { - now = SDL_GetPerformanceCounter(); - remain = int32_t(target - now); - } while (remain > 0); -} - // SDL entry point; currently a stub until the emulator core is hooked up. extern "C" int SDL_main(int argc, char* argv[]) { (void)argc; @@ -943,10 +896,6 @@ extern "C" int SDL_main(int argc, char* argv[]) { bool loggedControls = false; bool audioOpened = false; bool new3dAttached = false; - - const uint64_t perfCounterFrequency = SDL_GetPerformanceFrequency(); - uint64_t perfCountPerFrame = 0; - uint64_t nextTime = 0; while (running) { SDL_Event ev; while (SDL_PollEvent(&ev)) { @@ -1078,20 +1027,6 @@ extern "C" int SDL_main(int argc, char* argv[]) { SDL_GL_SwapWindow(window); - // Frame limiting: cap emulation on high refresh rate displays (e.g., 120 Hz). - // Mirrors the desktop SDL OSD behavior (Throttle + RefreshRate). - const bool throttle = host.config["Throttle"].ValueAsDefault(true); - if (throttle || host.threadsPausedByMenu) { - const uint64_t refreshRateMilliHz = GetDesiredRefreshRateMilliHz(host.config); - if (refreshRateMilliHz > 0 && perfCounterFrequency > 0) { - perfCountPerFrame = (perfCounterFrequency * 1000) / refreshRateMilliHz; - if (perfCountPerFrame == 0) perfCountPerFrame = 1; - - SuperSleepUntil(nextTime, perfCounterFrequency); - nextTime = SDL_GetPerformanceCounter() + perfCountPerFrame; - } - } - uint32_t t = SDL_GetTicks(); if (t - lastStatusLog > 2000) { lastStatusLog = t; diff --git a/android/app/src/main/java/com/izzy2lost/super3/AssetInstaller.kt b/android/app/src/main/java/com/izzy2lost/super3/AssetInstaller.kt index 8fa9fef..ac73646 100644 --- a/android/app/src/main/java/com/izzy2lost/super3/AssetInstaller.kt +++ b/android/app/src/main/java/com/izzy2lost/super3/AssetInstaller.kt @@ -1,43 +1,19 @@ package com.izzy2lost.super3 import android.content.Context -import android.os.Build import java.io.File object AssetInstaller { - private const val PREFS_NAME = "super3_prefs" - private const val KEY_ASSET_VERSION_CODE = "asset_installed_version_code" - fun ensureInstalled(context: Context, internalUserRoot: File) { internalUserRoot.mkdirs() // Copy the standard Supermodel folder layout from APK assets into the internal user root. - // We generally avoid overwriting existing files so user data persists. + // We never overwrite existing files so user edits persist. val topLevel = listOf("Assets", "Config", "GraphicsAnalysis", "NVRAM", "Saves") for (dir in topLevel) { copyAssetTree(context, dir, File(internalUserRoot, dir)) } - val prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) - val lastInstalledVersionCode = (prefs.all[KEY_ASSET_VERSION_CODE] as? Number)?.toLong() ?: -1L - val currentVersionCode = - runCatching { - val info = context.packageManager.getPackageInfo(context.packageName, 0) - if (Build.VERSION.SDK_INT >= 28) info.longVersionCode else info.versionCode.toLong() - }.getOrDefault(-1L) - - // If the app was updated, overwrite Supermodel.ini with the new defaults from the APK. - // (Other files are still preserved by default.) - if (lastInstalledVersionCode != currentVersionCode) { - copyAssetFile( - context, - "Config/Supermodel.ini", - File(File(internalUserRoot, "Config"), "Supermodel.ini"), - overwrite = true, - ) - prefs.edit().putLong(KEY_ASSET_VERSION_CODE, currentVersionCode).apply() - } - migrateSupermodelIni(File(File(internalUserRoot, "Config"), "Supermodel.ini")) } @@ -64,16 +40,6 @@ object AssetInstaller { } } - private fun copyAssetFile(context: Context, assetPath: String, dest: File, overwrite: Boolean) { - if (!overwrite && dest.exists()) return - dest.parentFile?.mkdirs() - context.assets.open(assetPath).use { input -> - dest.outputStream().use { output -> - input.copyTo(output) - } - } - } - private fun migrateSupermodelIni(ini: File) { if (!ini.exists()) return