|
|
|
@ -10,8 +10,6 @@ import android.graphics.Color |
|
|
|
import android.os.Bundle |
|
|
|
import android.os.Handler |
|
|
|
import android.view.* |
|
|
|
import android.widget.Button |
|
|
|
import android.widget.TextView |
|
|
|
import android.widget.Toast |
|
|
|
import androidx.fragment.app.Fragment |
|
|
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager |
|
|
|
@ -20,8 +18,8 @@ import org.yuzu.yuzu_emu.NativeLibrary |
|
|
|
import org.yuzu.yuzu_emu.R |
|
|
|
import org.yuzu.yuzu_emu.YuzuApplication |
|
|
|
import org.yuzu.yuzu_emu.activities.EmulationActivity |
|
|
|
import org.yuzu.yuzu_emu.databinding.FragmentEmulationBinding |
|
|
|
import org.yuzu.yuzu_emu.features.settings.model.Settings |
|
|
|
import org.yuzu.yuzu_emu.overlay.InputOverlay |
|
|
|
import org.yuzu.yuzu_emu.utils.DirectoryInitialization |
|
|
|
import org.yuzu.yuzu_emu.utils.DirectoryInitialization.DirectoryInitializationState |
|
|
|
import org.yuzu.yuzu_emu.utils.DirectoryStateReceiver |
|
|
|
@ -29,13 +27,14 @@ import org.yuzu.yuzu_emu.utils.Log |
|
|
|
|
|
|
|
class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.FrameCallback { |
|
|
|
private lateinit var preferences: SharedPreferences |
|
|
|
private var inputOverlay: InputOverlay? = null |
|
|
|
private lateinit var emulationState: EmulationState |
|
|
|
private var directoryStateReceiver: DirectoryStateReceiver? = null |
|
|
|
private var emulationActivity: EmulationActivity? = null |
|
|
|
private lateinit var perfStats: TextView |
|
|
|
private var perfStatsUpdater: (() -> Unit)? = null |
|
|
|
|
|
|
|
private var _binding: FragmentEmulationBinding? = null |
|
|
|
private val binding get() = _binding!! |
|
|
|
|
|
|
|
override fun onAttach(context: Context) { |
|
|
|
super.onAttach(context) |
|
|
|
if (context is EmulationActivity) { |
|
|
|
@ -66,22 +65,19 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram |
|
|
|
inflater: LayoutInflater, |
|
|
|
container: ViewGroup?, |
|
|
|
savedInstanceState: Bundle? |
|
|
|
): View? { |
|
|
|
val contents = inflater.inflate(R.layout.fragment_emulation, container, false) |
|
|
|
val surfaceView = contents.findViewById<SurfaceView>(R.id.surface_emulation) |
|
|
|
surfaceView.holder.addCallback(this) |
|
|
|
inputOverlay = contents.findViewById(R.id.surface_input_overlay) |
|
|
|
perfStats = contents.findViewById(R.id.show_fps_text) |
|
|
|
perfStats.setTextColor(Color.YELLOW) |
|
|
|
val doneButton = contents.findViewById<Button>(R.id.done_control_config) |
|
|
|
doneButton?.setOnClickListener { stopConfiguringControls() } |
|
|
|
): View { |
|
|
|
_binding = FragmentEmulationBinding.inflate(layoutInflater) |
|
|
|
return binding.root |
|
|
|
} |
|
|
|
|
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
|
|
|
binding.surfaceEmulation.holder.addCallback(this) |
|
|
|
binding.showFpsText.setTextColor(Color.YELLOW) |
|
|
|
binding.doneControlConfig.setOnClickListener { stopConfiguringControls() } |
|
|
|
|
|
|
|
// Setup overlay. |
|
|
|
resetInputOverlay() |
|
|
|
updateShowFpsOverlay() |
|
|
|
|
|
|
|
// The new Surface created here will get passed to the native code via onSurfaceChanged. |
|
|
|
return contents |
|
|
|
} |
|
|
|
|
|
|
|
override fun onResume() { |
|
|
|
@ -108,6 +104,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram |
|
|
|
super.onPause() |
|
|
|
} |
|
|
|
|
|
|
|
override fun onDestroyView() { |
|
|
|
super.onDestroyView() |
|
|
|
_binding = null |
|
|
|
} |
|
|
|
|
|
|
|
override fun onDetach() { |
|
|
|
NativeLibrary.clearEmulationActivity() |
|
|
|
super.onDetach() |
|
|
|
@ -144,7 +145,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram |
|
|
|
} |
|
|
|
|
|
|
|
fun refreshInputOverlay() { |
|
|
|
inputOverlay!!.refreshControls() |
|
|
|
binding.surfaceInputOverlay.refreshControls() |
|
|
|
} |
|
|
|
|
|
|
|
fun resetInputOverlay() { |
|
|
|
@ -152,7 +153,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram |
|
|
|
preferences.edit() |
|
|
|
.putInt(Settings.PREF_CONTROL_SCALE, 50) |
|
|
|
.apply() |
|
|
|
inputOverlay!!.resetButtonPlacement() |
|
|
|
binding.surfaceInputOverlay.resetButtonPlacement() |
|
|
|
} |
|
|
|
|
|
|
|
private fun updateShowFpsOverlay() { |
|
|
|
@ -165,17 +166,17 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram |
|
|
|
perfStatsUpdater = { |
|
|
|
val perfStats = NativeLibrary.GetPerfStats() |
|
|
|
if (perfStats[FPS] > 0) { |
|
|
|
this.perfStats.text = String.format("FPS: %.1f", perfStats[FPS]) |
|
|
|
binding.showFpsText.text = String.format("FPS: %.1f", perfStats[FPS]) |
|
|
|
} |
|
|
|
perfStatsUpdateHandler.postDelayed(perfStatsUpdater!!, 100) |
|
|
|
} |
|
|
|
perfStatsUpdateHandler.post(perfStatsUpdater!!) |
|
|
|
perfStats.visibility = View.VISIBLE |
|
|
|
binding.showFpsText.visibility = View.VISIBLE |
|
|
|
} else { |
|
|
|
if (perfStatsUpdater != null) { |
|
|
|
perfStatsUpdateHandler.removeCallbacks(perfStatsUpdater!!) |
|
|
|
} |
|
|
|
perfStats.visibility = View.GONE |
|
|
|
binding.showFpsText.visibility = View.GONE |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -203,18 +204,17 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram |
|
|
|
} |
|
|
|
|
|
|
|
fun startConfiguringControls() { |
|
|
|
requireView().findViewById<View>(R.id.done_control_config).visibility = |
|
|
|
View.VISIBLE |
|
|
|
inputOverlay!!.setIsInEditMode(true) |
|
|
|
binding.doneControlConfig.visibility = View.VISIBLE |
|
|
|
binding.surfaceInputOverlay.setIsInEditMode(true) |
|
|
|
} |
|
|
|
|
|
|
|
fun stopConfiguringControls() { |
|
|
|
requireView().findViewById<View>(R.id.done_control_config).visibility = View.GONE |
|
|
|
inputOverlay!!.setIsInEditMode(false) |
|
|
|
binding.doneControlConfig.visibility = View.GONE |
|
|
|
binding.surfaceInputOverlay.setIsInEditMode(false) |
|
|
|
} |
|
|
|
|
|
|
|
val isConfiguringControls: Boolean |
|
|
|
get() = inputOverlay!!.isInEditMode |
|
|
|
get() = binding.surfaceInputOverlay.isInEditMode |
|
|
|
|
|
|
|
private class EmulationState(private val mGamePath: String?) { |
|
|
|
private var state: State |
|
|
|
|