mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
Two-stage No-JIT warning and red in-game indicator.
This commit is contained in:
@@ -227,6 +227,7 @@ struct GameScreenView: View {
|
||||
@State private var menuButtonHidden = false
|
||||
@State private var vmMenuAvailable = false
|
||||
@State private var gameMenuAvailable = false
|
||||
@State private var noJITFallbackActive = false
|
||||
// MARK: Overlay Route
|
||||
// The pause card + every screen launched from it are driven by one FSM. Opening a child
|
||||
// transitions `.paused -> .pausedPresenting(child)` without tearing the card down; the child
|
||||
@@ -402,7 +403,7 @@ struct GameScreenView: View {
|
||||
}
|
||||
.overlay(alignment: .topTrailing) {
|
||||
if !menuButtonHidden {
|
||||
menuButton()
|
||||
menuButtonCluster()
|
||||
.padding(.top, 8)
|
||||
.padding(.trailing, 4)
|
||||
.gameplayLaunchChrome(visible: appState.gameplayLaunchControlsVisible)
|
||||
@@ -614,7 +615,7 @@ struct GameScreenView: View {
|
||||
VStack {
|
||||
HStack {
|
||||
Spacer()
|
||||
menuButton()
|
||||
menuButtonCluster()
|
||||
}
|
||||
.padding(.top, isLandscape ? 8 : 4)
|
||||
.padding(.trailing, isLandscape ? 8 : 4)
|
||||
@@ -634,6 +635,21 @@ struct GameScreenView: View {
|
||||
.accessibilityHint(settings.localized("Opens the pause menu"))
|
||||
}
|
||||
|
||||
private func menuButtonCluster() -> some View {
|
||||
HStack(spacing: 6) {
|
||||
if noJITFallbackActive {
|
||||
Text(settings.localized("No JIT"))
|
||||
.font(.caption.weight(.semibold))
|
||||
.foregroundStyle(.red)
|
||||
.padding(.horizontal, 9)
|
||||
.padding(.vertical, 6)
|
||||
.background(.black.opacity(0.40), in: Capsule())
|
||||
.accessibilityLabel(settings.localized("No JIT mode"))
|
||||
}
|
||||
menuButton()
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func enterEmulationOnlyModeIfReady() {
|
||||
guard settings.emulationOnlyModeEnabled,
|
||||
@@ -1072,12 +1088,16 @@ struct GameScreenView: View {
|
||||
private func refreshRuntimeMenuState() {
|
||||
let vmRunning = ARMSX2Bridge.isVMRunning()
|
||||
let gameReady = ARMSX2Bridge.hasValidSaveStateGame()
|
||||
let noJITActive = ARMSX2Bridge.isNoJITFallbackActive()
|
||||
if vmMenuAvailable != vmRunning {
|
||||
vmMenuAvailable = vmRunning
|
||||
}
|
||||
if gameMenuAvailable != gameReady {
|
||||
gameMenuAvailable = gameReady
|
||||
}
|
||||
if noJITFallbackActive != noJITActive {
|
||||
noJITFallbackActive = noJITActive
|
||||
}
|
||||
let identity = gameReady ? runtimePadLayoutIdentityForCurrentGame() : nil
|
||||
if runtimePadLayoutIdentity != identity {
|
||||
runtimePadLayoutIdentity = identity
|
||||
|
||||
@@ -47,6 +47,7 @@ struct RootView: View {
|
||||
@State private var settings = SettingsStore.shared
|
||||
@State private var fileImporter = FileImportHandler.shared
|
||||
@State private var showBootSplash = true
|
||||
@State private var showNoJITFinalConfirmation = false
|
||||
// The background layer observes renderer state directly. Keeping only the
|
||||
// host reference here prevents snapshot/visibility publications from
|
||||
// invalidating the complete menu hierarchy.
|
||||
@@ -176,21 +177,55 @@ struct RootView: View {
|
||||
.alert(
|
||||
"⚠️ \(settings.localized("JIT Access Not Detected"))",
|
||||
isPresented: Binding(
|
||||
get: { appState.pendingJITGameBoot != nil },
|
||||
set: { if !$0 { appState.cancelPendingJITGameBoot() } }
|
||||
get: {
|
||||
appState.pendingJITGameBoot != nil && !showNoJITFinalConfirmation
|
||||
},
|
||||
set: { isPresented in
|
||||
if !isPresented && !showNoJITFinalConfirmation {
|
||||
appState.cancelPendingJITGameBoot()
|
||||
}
|
||||
}
|
||||
)
|
||||
) {
|
||||
Button(settings.localized("Cancel"), role: .cancel) {
|
||||
appState.cancelPendingJITGameBoot()
|
||||
}
|
||||
Button(settings.localized("Continue")) {
|
||||
appState.continuePendingJITGameBoot()
|
||||
Button(settings.localized("Continue"), role: .destructive) {
|
||||
showNoJITFinalConfirmation = true
|
||||
}
|
||||
} message: {
|
||||
Text(settings.localized(
|
||||
"JIT access is not available. Match the StikDebug script to the JIT Script setting in Emulator settings."
|
||||
))
|
||||
}
|
||||
.alert(
|
||||
"⚠️ \(settings.localized("JIT Access Not Detected"))",
|
||||
isPresented: Binding(
|
||||
get: {
|
||||
showNoJITFinalConfirmation && appState.pendingJITGameBoot != nil
|
||||
},
|
||||
set: { isPresented in
|
||||
guard !isPresented else { return }
|
||||
showNoJITFinalConfirmation = false
|
||||
if appState.pendingJITGameBoot != nil {
|
||||
appState.cancelPendingJITGameBoot()
|
||||
}
|
||||
}
|
||||
)
|
||||
) {
|
||||
Button(settings.localized("Cancel"), role: .cancel) {
|
||||
showNoJITFinalConfirmation = false
|
||||
appState.cancelPendingJITGameBoot()
|
||||
}
|
||||
Button(settings.localized("Continue"), role: .destructive) {
|
||||
appState.continuePendingJITGameBoot()
|
||||
showNoJITFinalConfirmation = false
|
||||
}
|
||||
} message: {
|
||||
Text(settings.localized(
|
||||
"Are you sure you want to continue?\nJIT access is required for 60 FPS.\n\nEXPECT TOO LOW PERFORMANCE.\nPROCEED AT YOUR OWN RISK!"
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user