mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2026-06-04 06:05:00 -06:00
Merge e210aa8a79 into c650473fdc
This commit is contained in:
commit
aa01e60b58
@ -6,6 +6,7 @@ package org.citra.citra_emu.activities
|
|||||||
|
|
||||||
import android.Manifest.permission
|
import android.Manifest.permission
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
@ -116,24 +117,29 @@ class EmulationActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
EmulationLifecycleUtil.addShutdownHook(onShutdown)
|
EmulationLifecycleUtil.addShutdownHook(onShutdown)
|
||||||
|
|
||||||
isEmulationRunning = true
|
if (!intent.getBooleanExtra(NO_GAME_EDIT_MODE, false)) {
|
||||||
instance = this
|
isEmulationRunning = true
|
||||||
|
instance = this
|
||||||
|
}
|
||||||
|
|
||||||
applyOrientationSettings() // Check for orientation settings at startup
|
applyOrientationSettings() // Check for orientation settings at startup
|
||||||
|
|
||||||
val game = try {
|
if (!intent.getBooleanExtra(NO_GAME_EDIT_MODE, false)) {
|
||||||
intent.extras?.let { extras ->
|
val game = try {
|
||||||
BundleCompat.getParcelable(extras, "game", Game::class.java)
|
intent.extras?.let { extras ->
|
||||||
} ?: run {
|
BundleCompat.getParcelable(extras, "game", Game::class.java)
|
||||||
Log.error("[EmulationActivity] Missing game data in intent extras")
|
} ?: run {
|
||||||
|
Log.error("[EmulationActivity] Missing game data in intent extras")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.error("[EmulationActivity] Failed to retrieve game data: ${e.message}")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.error("[EmulationActivity] Failed to retrieve game data: ${e.message}")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
NativeLibrary.playTimeManagerStart(game.titleId)
|
|
||||||
|
NativeLibrary.playTimeManagerStart(game.titleId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// On some devices, the system bars will not disappear on first boot or after some
|
// On some devices, the system bars will not disappear on first boot or after some
|
||||||
@ -174,8 +180,10 @@ class EmulationActivity : AppCompatActivity() {
|
|||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
EmulationLifecycleUtil.removeHook(onShutdown)
|
EmulationLifecycleUtil.removeHook(onShutdown)
|
||||||
NativeLibrary.playTimeManagerStop()
|
NativeLibrary.playTimeManagerStop()
|
||||||
isEmulationRunning = false
|
if (!intent.getBooleanExtra(NO_GAME_EDIT_MODE, false)) {
|
||||||
instance = null
|
isEmulationRunning = false
|
||||||
|
instance = null
|
||||||
|
}
|
||||||
secondaryDisplay.releasePresentation()
|
secondaryDisplay.releasePresentation()
|
||||||
secondaryDisplay.releaseVD()
|
secondaryDisplay.releaseVD()
|
||||||
|
|
||||||
@ -544,6 +552,13 @@ class EmulationActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private var instance: EmulationActivity? = null
|
private var instance: EmulationActivity? = null
|
||||||
|
const val NO_GAME_EDIT_MODE = "noGameEditMode"
|
||||||
|
|
||||||
|
fun launchForOverlayEdit(context: Context): Intent {
|
||||||
|
return Intent(context, EmulationActivity::class.java).apply {
|
||||||
|
putExtra(NO_GAME_EDIT_MODE, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun isRunning(): Boolean {
|
fun isRunning(): Boolean {
|
||||||
return instance?.isEmulationRunning ?: false
|
return instance?.isEmulationRunning ?: false
|
||||||
|
|||||||
@ -104,6 +104,7 @@ class Settings {
|
|||||||
const val SECTION_CAMERA = "Camera"
|
const val SECTION_CAMERA = "Camera"
|
||||||
const val SECTION_CONTROLS = "Controls"
|
const val SECTION_CONTROLS = "Controls"
|
||||||
const val SECTION_RENDERER = "Renderer"
|
const val SECTION_RENDERER = "Renderer"
|
||||||
|
const val SECTION_INPUT_OVERLAY = "Input Overlay"
|
||||||
const val SECTION_LAYOUT = "Layout"
|
const val SECTION_LAYOUT = "Layout"
|
||||||
const val SECTION_UTILITY = "Utility"
|
const val SECTION_UTILITY = "Utility"
|
||||||
const val SECTION_AUDIO = "Audio"
|
const val SECTION_AUDIO = "Audio"
|
||||||
@ -242,6 +243,7 @@ class Settings {
|
|||||||
SECTION_CAMERA,
|
SECTION_CAMERA,
|
||||||
SECTION_CONTROLS,
|
SECTION_CONTROLS,
|
||||||
SECTION_RENDERER,
|
SECTION_RENDERER,
|
||||||
|
SECTION_INPUT_OVERLAY,
|
||||||
SECTION_LAYOUT,
|
SECTION_LAYOUT,
|
||||||
SECTION_STORAGE,
|
SECTION_STORAGE,
|
||||||
SECTION_UTILITY,
|
SECTION_UTILITY,
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
package org.citra.citra_emu.features.settings.ui
|
package org.citra.citra_emu.features.settings.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.hardware.camera2.CameraAccessException
|
import android.hardware.camera2.CameraAccessException
|
||||||
@ -17,6 +18,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|||||||
import kotlinx.serialization.builtins.IntArraySerializer
|
import kotlinx.serialization.builtins.IntArraySerializer
|
||||||
import org.citra.citra_emu.CitraApplication
|
import org.citra.citra_emu.CitraApplication
|
||||||
import org.citra.citra_emu.R
|
import org.citra.citra_emu.R
|
||||||
|
import org.citra.citra_emu.activities.EmulationActivity
|
||||||
import org.citra.citra_emu.display.ScreenLayout
|
import org.citra.citra_emu.display.ScreenLayout
|
||||||
import org.citra.citra_emu.display.StereoMode
|
import org.citra.citra_emu.display.StereoMode
|
||||||
import org.citra.citra_emu.display.StereoWhichDisplay
|
import org.citra.citra_emu.display.StereoWhichDisplay
|
||||||
@ -99,6 +101,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||||||
Settings.SECTION_CAMERA -> addCameraSettings(sl)
|
Settings.SECTION_CAMERA -> addCameraSettings(sl)
|
||||||
Settings.SECTION_CONTROLS -> addControlsSettings(sl)
|
Settings.SECTION_CONTROLS -> addControlsSettings(sl)
|
||||||
Settings.SECTION_RENDERER -> addGraphicsSettings(sl)
|
Settings.SECTION_RENDERER -> addGraphicsSettings(sl)
|
||||||
|
Settings.SECTION_INPUT_OVERLAY -> addInputOverlaySettings(sl)
|
||||||
Settings.SECTION_LAYOUT -> addLayoutSettings(sl)
|
Settings.SECTION_LAYOUT -> addLayoutSettings(sl)
|
||||||
Settings.SECTION_AUDIO -> addAudioSettings(sl)
|
Settings.SECTION_AUDIO -> addAudioSettings(sl)
|
||||||
Settings.SECTION_DEBUG -> addDebugSettings(sl)
|
Settings.SECTION_DEBUG -> addDebugSettings(sl)
|
||||||
@ -179,6 +182,14 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||||||
Settings.SECTION_RENDERER
|
Settings.SECTION_RENDERER
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
add(
|
||||||
|
SubmenuSetting(
|
||||||
|
R.string.preferences_input_overlay,
|
||||||
|
0,
|
||||||
|
R.drawable.dpad,
|
||||||
|
Settings.SECTION_INPUT_OVERLAY
|
||||||
|
)
|
||||||
|
)
|
||||||
add(
|
add(
|
||||||
SubmenuSetting(
|
SubmenuSetting(
|
||||||
R.string.preferences_layout,
|
R.string.preferences_layout,
|
||||||
@ -1127,6 +1138,58 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addInputOverlaySettings(sl: ArrayList<SettingsItem>) {
|
||||||
|
settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_input_overlay))
|
||||||
|
sl.apply {
|
||||||
|
val inputOverlayOpacitySetting = object : AbstractBooleanSetting {
|
||||||
|
private val preferences =
|
||||||
|
PreferenceManager.getDefaultSharedPreferences(CitraApplication.appContext)
|
||||||
|
|
||||||
|
override var boolean: Boolean
|
||||||
|
get() = preferences.getBoolean("EmulationMenuSettings_ShowOverlay", true)
|
||||||
|
set(value) {
|
||||||
|
preferences.edit()
|
||||||
|
.putBoolean("EmulationMenuSettings_ShowOverlay", value)
|
||||||
|
.apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val key: String? = null
|
||||||
|
override val section: String? = null
|
||||||
|
override val isRuntimeEditable: Boolean = true
|
||||||
|
override val valueAsString: String
|
||||||
|
get() = preferences.getBoolean("EmulationMenuSettings_ShowOverlay", true)
|
||||||
|
.toString()
|
||||||
|
override val defaultValue = true
|
||||||
|
}
|
||||||
|
|
||||||
|
add(
|
||||||
|
SwitchSetting(
|
||||||
|
inputOverlayOpacitySetting,
|
||||||
|
R.string.enable_input_overlay,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
add(
|
||||||
|
HeaderSetting(
|
||||||
|
R.string.realtime_edit,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
add(
|
||||||
|
RunnableSetting(
|
||||||
|
R.string.edit_overlay_layout,
|
||||||
|
R.string.edit_overlay_layout_description,
|
||||||
|
false,
|
||||||
|
R.drawable.dpad,
|
||||||
|
runnable = {
|
||||||
|
val intent = EmulationActivity.launchForOverlayEdit(CitraApplication.appContext)
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
CitraApplication.appContext.startActivity(intent)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun addLayoutSettings(sl: ArrayList<SettingsItem>) {
|
private fun addLayoutSettings(sl: ArrayList<SettingsItem>) {
|
||||||
settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_layout))
|
settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_layout))
|
||||||
sl.apply {
|
sl.apply {
|
||||||
|
|||||||
@ -129,6 +129,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
if (args.noGameEditMode) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val intent = requireActivity().intent
|
val intent = requireActivity().intent
|
||||||
var intentUri: Uri? = intent.data
|
var intentUri: Uri? = intent.data
|
||||||
val oldIntentInfo = Pair(
|
val oldIntentInfo = Pair(
|
||||||
@ -212,6 +216,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args.noGameEditMode) {
|
||||||
|
setupNoGameEditMode()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
binding.surfaceEmulation.holder.addCallback(this)
|
binding.surfaceEmulation.holder.addCallback(this)
|
||||||
binding.doneControlConfig.setOnClickListener {
|
binding.doneControlConfig.setOnClickListener {
|
||||||
binding.doneControlConfig.visibility = View.GONE
|
binding.doneControlConfig.visibility = View.GONE
|
||||||
@ -503,6 +512,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
|
||||||
|
if (args.noGameEditMode) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
Choreographer.getInstance().postFrameCallback(this)
|
Choreographer.getInstance().postFrameCallback(this)
|
||||||
if (NativeLibrary.isRunning()) {
|
if (NativeLibrary.isRunning()) {
|
||||||
emulationState.unpause()
|
emulationState.unpause()
|
||||||
@ -530,7 +544,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
if (NativeLibrary.isRunning()) {
|
if (!args.noGameEditMode && NativeLibrary.isRunning()) {
|
||||||
emulationState.pause()
|
emulationState.pause()
|
||||||
}
|
}
|
||||||
Choreographer.getInstance().removeFrameCallback(this)
|
Choreographer.getInstance().removeFrameCallback(this)
|
||||||
@ -574,6 +588,27 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupNoGameEditMode() {
|
||||||
|
binding.surfaceInputOverlay.post {
|
||||||
|
binding.surfaceInputOverlay.refreshControls(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.doneControlConfig.setOnClickListener {
|
||||||
|
finishNoGameEditMode()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.doneControlConfig.visibility = View.VISIBLE
|
||||||
|
binding.surfaceInputOverlay.setIsInEditMode(true)
|
||||||
|
binding.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
||||||
|
binding.surfaceInputOverlay.visibility = View.VISIBLE
|
||||||
|
binding.loadingIndicator.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun finishNoGameEditMode() {
|
||||||
|
binding.surfaceInputOverlay.setIsInEditMode(false)
|
||||||
|
emulationActivity.finish()
|
||||||
|
}
|
||||||
|
|
||||||
private fun showSavestateMenu() {
|
private fun showSavestateMenu() {
|
||||||
val popupMenu = PopupMenu(
|
val popupMenu = PopupMenu(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
@ -1236,7 +1271,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
|
|||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resetInputOverlay() {
|
fun resetInputOverlay() {
|
||||||
resetAllScales()
|
resetAllScales()
|
||||||
preferences.edit()
|
preferences.edit()
|
||||||
.putInt("controlOpacity", 50)
|
.putInt("controlOpacity", 50)
|
||||||
|
|||||||
@ -570,7 +570,7 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun refreshControls() {
|
fun refreshControls(noGameEdit: Boolean = false) {
|
||||||
// Remove all the overlay buttons from the HashSet.
|
// Remove all the overlay buttons from the HashSet.
|
||||||
overlayButtons.clear()
|
overlayButtons.clear()
|
||||||
overlayDpads.clear()
|
overlayDpads.clear()
|
||||||
@ -583,7 +583,7 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add all the enabled overlay items back to the HashSet.
|
// Add all the enabled overlay items back to the HashSet.
|
||||||
if (EmulationMenuSettings.showOverlay) {
|
if (noGameEdit || EmulationMenuSettings.showOverlay) {
|
||||||
addOverlayControls(orientation)
|
addOverlayControls(orientation)
|
||||||
}
|
}
|
||||||
invalidate()
|
invalidate()
|
||||||
|
|||||||
@ -15,6 +15,10 @@
|
|||||||
app:argType="org.citra.citra_emu.model.Game"
|
app:argType="org.citra.citra_emu.model.Game"
|
||||||
app:nullable="true"
|
app:nullable="true"
|
||||||
android:defaultValue="@null" />
|
android:defaultValue="@null" />
|
||||||
|
<argument
|
||||||
|
android:name="noGameEditMode"
|
||||||
|
app:argType="boolean"
|
||||||
|
android:defaultValue="false" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
|
|||||||
@ -948,4 +948,11 @@
|
|||||||
<string name="decompress_failed">Decompression failed.</string>
|
<string name="decompress_failed">Decompression failed.</string>
|
||||||
<string name="compress_decompress_installed_app">Already installed applications cannot be compressed or decompressed.</string>
|
<string name="compress_decompress_installed_app">Already installed applications cannot be compressed or decompressed.</string>
|
||||||
|
|
||||||
|
<!-- Input Overlay Settings -->
|
||||||
|
<string name="preferences_input_overlay">Input Overlay</string>
|
||||||
|
<string name="enable_input_overlay">Enable Touch Input Overlay</string>
|
||||||
|
<string name="edit_overlay_layout">Edit Touch Input Overlay</string>
|
||||||
|
<string name="realtime_edit">Edit in realtime</string>
|
||||||
|
<string name="edit_overlay_layout_description">Edit the touch overlay without having to open a game.</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user