Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions app/src/main/feature/library/GameSettings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,16 @@ class GameSettingsStateHolder {
val numControllersEntries = mutableStateOf<List<String>>(emptyList())
val selectedNumControllers = mutableIntStateOf(0)
val disableXInput = mutableStateOf(false)
val peekMessageLimiterDelayValues = listOf(0, 1, 2, 4, 8, 16)
val peekMessageLimiterEntries = mutableStateOf(listOf(
"Off",
"1ms (Light, ~150fps)",
"2ms (Moderate, ~120fps)",
"4ms (Noticeable, ~80fps)",
"8ms (Strong, ~50fps)",
"16ms (Very Strong, ~30fps)"
))
val peekMessageLimiterIndex = mutableIntStateOf(0)
val simTouchScreen = mutableStateOf(false)
val screenTouchMode = mutableIntStateOf(0)
val gestureProfileEntries = mutableStateOf<List<String>>(emptyList())
Expand Down Expand Up @@ -2615,6 +2625,22 @@ private fun WineD3DConfigCard(state: GameSettingsStateHolder) {
)
}
}

val isContainer = state.isContainerEditMode.value

if (!isContainer) {
Spacer(Modifier.height(SettingItemGap))
SettingPairRow {
Box(Modifier.weight(1f)) {
SettingDropdown(
label = stringResource(R.string.shortcuts_properties_peekmessage_limiter),
entries = state.peekMessageLimiterEntries.value,
selectedIndex = state.peekMessageLimiterIndex.intValue,
onSelected = { state.peekMessageLimiterIndex.intValue = it }
)
}
}
}
}
}
}
Expand Down Expand Up @@ -4969,6 +4995,7 @@ private fun InputSection(state: GameSettingsStateHolder) {
}
)
}

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@ class ShortcutSettingsComposeDialog private constructor(
state.selectedDInputMapperType.intValue =
if ((inputType and WinHandler.FLAG_DINPUT_MAPPER_STANDARD.toInt()) == WinHandler.FLAG_DINPUT_MAPPER_STANDARD.toInt()) 0 else 1
state.disableXInput.value = shortcut.getExtra("disableXinput", "0") == "1"
val peekDelay = shortcut.getExtra("peekMessageLimiter", "0").toIntOrNull() ?: 0
state.peekMessageLimiterIndex.intValue = state.peekMessageLimiterDelayValues.indexOf(peekDelay).coerceAtLeast(0)
state.shortcutExclusiveXInput.value = shortcut.getExtra("exclusiveXInput", "").let {
if (it.isEmpty()) container.isExclusiveXInput() else it == "1"
}
Expand Down Expand Up @@ -1267,7 +1269,8 @@ class ShortcutSettingsComposeDialog private constructor(
val disableXinputValue = if (state.disableXInput.value) "1" else null
shortcut.putExtra("disableXinput", disableXinputValue)
if (disableXinputValue != null) hasContainerOverride = true

val peekDelay = state.peekMessageLimiterDelayValues.getOrElse(state.peekMessageLimiterIndex.intValue) { 0 }
shortcut.putExtra("peekMessageLimiter", peekDelay.toString())
shortcut.putExtra("exclusiveXInput", if (state.shortcutExclusiveXInput.value) "1" else "0")
if (state.shortcutExclusiveXInput.value != container.isExclusiveXInput()) hasContainerOverride = true

Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@
<string name="shortcuts_properties_exec_arguments">Exec Arguments</string>
<string name="shortcuts_properties_target_path">Target Path</string>
<string name="shortcuts_properties_disable_xinput">Disable Xinput (For Exclusive M/KB Control)</string>
<string name="shortcuts_properties_peekmessage_limiter">CPU Limiter</string>
<string name="num_controllers">Number of Controllers</string>
<string name="shortcuts_properties_exclusive_input">Exclusive Input</string>
<string name="shortcuts_properties_custom_game_settings">Custom Game Settings</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,17 @@ private void mergeExternalEnvVars(
} else if (overrideFakeUdevDataDir != null && !overrideFakeUdevDataDir.isEmpty()) {
envVars.put("FAKE_UDEV_DATA_DIR", overrideFakeUdevDataDir);
}

// PeekMessage idle-spin limiter (Wine patch, per-shortcut opt-in)
String peekDelay = shortcut != null ? shortcut.getExtra("peekMessageLimiter", "0") : "0";
if (!"0".equals(peekDelay)) {
// Only apply when using WineD3D (not DXVK/VKD3D)
String dxWrapper = shortcut.getExtra("dxwrapper", "");
if (dxWrapper.toLowerCase().contains("wined3d")) {
envVars.put("WINE_PEEK_LIMITER", peekDelay);
Log.d("GuestLauncher", "PeekMessage limiter enabled, delay=" + peekDelay + "ms");
}
}
}

private void prepareFakeInputUdevMetadata(ImageFs imageFs, File devInputDir, EnvVars envVars) {
Expand Down
Loading