Skip to content
Closed
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
427 changes: 427 additions & 0 deletions app/src/main/app/shell/LaunchOptionsScreen.kt

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions app/src/main/app/shell/LibraryGameLaunchScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import androidx.compose.material.icons.outlined.DesktopWindows
import androidx.compose.material.icons.outlined.EmojiEvents
import androidx.compose.material.icons.outlined.History
import androidx.compose.material.icons.outlined.Refresh
import androidx.compose.material.icons.outlined.RocketLaunch
import androidx.compose.material.icons.outlined.Home
import androidx.compose.material.icons.outlined.PlayArrow
import androidx.compose.material.icons.outlined.Save
Expand Down Expand Up @@ -140,6 +141,8 @@ internal fun LibraryGameLaunchScreen(
showVerifyFiles: Boolean = true,
showCheckForUpdate: Boolean = true,
showWorkshop: Boolean = true,
showLaunchOptions: Boolean = false,
onLaunchOptions: () -> Unit = {},
playEnabled: Boolean = true,
playDisabledLabel: String? = null,
onBack: () -> Unit,
Expand Down Expand Up @@ -278,11 +281,13 @@ internal fun LibraryGameLaunchScreen(
showCheckForUpdate = showCheckForUpdate,
showWorkshop = showWorkshop,
showAchievements = onAchievements != null,
showLaunchOptions = showLaunchOptions,
areSteamActionsEnabled = areSteamActionsEnabled,
onVerifyFiles = onVerifyFiles,
onCheckForUpdate = onCheckForUpdate,
onWorkshop = onWorkshop,
onAchievements = { onAchievements?.invoke() },
onLaunchOptions = onLaunchOptions,
)
}

Expand Down Expand Up @@ -821,11 +826,13 @@ private fun SourceTag(
showCheckForUpdate: Boolean = true,
showWorkshop: Boolean = true,
showAchievements: Boolean = false,
showLaunchOptions: Boolean = false,
areSteamActionsEnabled: Boolean = true,
onVerifyFiles: () -> Unit = {},
onCheckForUpdate: () -> Unit = {},
onWorkshop: () -> Unit = {},
onAchievements: () -> Unit = {},
onLaunchOptions: () -> Unit = {},
) {
var menuOpen by remember { mutableStateOf(false) }
var anchorHeightPx by remember { mutableStateOf(0) }
Expand Down Expand Up @@ -902,6 +909,13 @@ private fun SourceTag(
label = stringResource(R.string.steam_achievements_title),
) { menuOpen = false; onAchievements() }
}
if (showLaunchOptions) {
LaunchSourceMenuItem(
icon = Icons.Outlined.RocketLaunch,
label = stringResource(R.string.store_game_launch_options),
enabled = areSteamActionsEnabled,
) { menuOpen = false; onLaunchOptions() }
}
}
}
}
Expand Down
18 changes: 17 additions & 1 deletion app/src/main/app/shell/StoreGameDetailScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import androidx.compose.material.icons.outlined.ExpandMore
import androidx.compose.material.icons.outlined.Extension
import androidx.compose.material.icons.outlined.Folder
import androidx.compose.material.icons.outlined.Refresh
import androidx.compose.material.icons.outlined.RocketLaunch
import androidx.compose.material.icons.outlined.SportsEsports
import androidx.compose.material.icons.outlined.Storage
import androidx.compose.material.icons.outlined.SystemUpdate
Expand Down Expand Up @@ -155,6 +156,8 @@ internal fun StoreGameDetailScreen(
showWorkshop: Boolean = false,
showVerifyFiles: Boolean = false,
areSteamActionsEnabled: Boolean = true,
showLaunchOptions: Boolean = false,
onLaunchOptions: () -> Unit = {},
dlcs: List<StoreDlcItem> = emptyList(),
selectedDlcIds: Set<Int> = emptySet(),
isDlcSelectionEnabled: Boolean = true,
Expand Down Expand Up @@ -202,7 +205,9 @@ internal fun StoreGameDetailScreen(
val showUpdateCta = updateCheckAvailable && isUpdateAvailable
val verifyFilesAvailable = showVerifyFiles && isInstalled
val workshopAvailable = showWorkshop && isInstalled
val sourceMenuEnabled = updateCheckAvailable || verifyFilesAvailable || workshopAvailable
val launchOptionsAvailable = showLaunchOptions && isInstalled
val sourceMenuEnabled =
updateCheckAvailable || verifyFilesAvailable || workshopAvailable || launchOptionsAvailable
val showDlcCard = dlcs.isNotEmpty()
val showActionColumn =
showDownloadCta || showUpdateCta ||
Expand Down Expand Up @@ -313,6 +318,7 @@ internal fun StoreGameDetailScreen(
showCheckForUpdate = updateCheckAvailable,
showVerifyFiles = verifyFilesAvailable,
showWorkshop = workshopAvailable,
showLaunchOptions = launchOptionsAvailable,
isCheckingForUpdate = isCheckingForUpdate,
areSteamActionsEnabled = areSteamActionsEnabled,
isUpdateCheckEnabled =
Expand All @@ -323,6 +329,7 @@ internal fun StoreGameDetailScreen(
onVerifyFiles = onVerifyFiles,
onCheckForUpdate = onCheckForUpdate,
onWorkshop = onWorkshop,
onLaunchOptions = onLaunchOptions,
)
}

Expand Down Expand Up @@ -824,12 +831,14 @@ private fun StoreSourceTag(
showCheckForUpdate: Boolean = false,
showVerifyFiles: Boolean = false,
showWorkshop: Boolean = false,
showLaunchOptions: Boolean = false,
isCheckingForUpdate: Boolean = false,
areSteamActionsEnabled: Boolean = true,
isUpdateCheckEnabled: Boolean = true,
onVerifyFiles: () -> Unit = {},
onCheckForUpdate: () -> Unit = {},
onWorkshop: () -> Unit = {},
onLaunchOptions: () -> Unit = {},
) {
var anchorHeightPx by remember { mutableIntStateOf(0) }
Box {
Expand Down Expand Up @@ -913,6 +922,13 @@ private fun StoreSourceTag(
enabled = areSteamActionsEnabled,
) { onMenuOpenChange(false); onWorkshop() }
}
if (showLaunchOptions) {
StoreSourceMenuItem(
icon = Icons.Outlined.RocketLaunch,
label = stringResource(R.string.store_game_launch_options),
enabled = areSteamActionsEnabled,
) { onMenuOpenChange(false); onLaunchOptions() }
}
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/app/shell/UnifiedActivityDownloads.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1356,6 +1356,7 @@ internal fun UnifiedActivity.GameManagerDialog(
var isCheckingForUpdate by remember(app.id) { mutableStateOf(false) }
var isUpdateCheckCoolingDown by remember(app.id) { mutableStateOf(false) }
var showWorkshopDialog by remember(app.id) { mutableStateOf(false) }
val launchOptionsState = rememberSteamLaunchOptionsState(app.id, enabled = installed == true)
var updateInfo by remember(app.id) { mutableStateOf<SteamService.SteamUpdateInfo?>(null) }
var updateStatusText by remember(app.id) { mutableStateOf<String?>(null) }
val downloadRecords by com.winlator.cmod.app.service.download.DownloadCoordinator.records.collectAsState(
Expand Down Expand Up @@ -1547,6 +1548,8 @@ internal fun UnifiedActivity.GameManagerDialog(
showWorkshop = isReallyInstalled,
showVerifyFiles = isReallyInstalled,
areSteamActionsEnabled = !hasBlockingSteamDownload,
showLaunchOptions = launchOptionsState.options.size >= 2,
onLaunchOptions = launchOptionsState::show,
dlcs = dlcItems,
selectedDlcIds = selectedDlcIds.toSet(),
isDlcSelectionEnabled = steamDownloadRecord == null,
Expand Down Expand Up @@ -1686,6 +1689,8 @@ internal fun UnifiedActivity.GameManagerDialog(
onDismissRequest = { showWorkshopDialog = false },
)
}

SteamLaunchOptionsDialogHost(app.id, app.name, launchOptionsState)
}

@Composable
Expand Down
7 changes: 7 additions & 0 deletions app/src/main/app/shell/UnifiedActivityGameDialogs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1678,6 +1678,9 @@ internal fun UnifiedActivity.LibraryGameDetailDialog(
val isEpic = app.id >= 2000000000
val isGog = gogGame != null
val epicId = if (isEpic) app.id - 2000000000 else 0
val isSteamLibraryGame = !isCustom && !isEpic && !isGog

val launchOptionsState = rememberSteamLaunchOptionsState(app.id, enabled = isSteamLibraryGame)

val libraryDownloadRecords by com.winlator.cmod.app.service.download.DownloadCoordinator.records.collectAsState(
initial = com.winlator.cmod.app.service.download.DownloadCoordinator.snapshotRecords(),
Expand Down Expand Up @@ -2412,6 +2415,8 @@ internal fun UnifiedActivity.LibraryGameDetailDialog(
(!isEpic || epicGame?.isInstalled == true) &&
(!isGog || gogGame?.isInstalled == true),
showWorkshop = !isEpic && !isGog,
showLaunchOptions = launchOptionsState.options.size >= 2,
onLaunchOptions = launchOptionsState::show,
areSteamActionsEnabled =
when {
isEpic -> !hasBlockingEpicDownloadForLibrary
Expand Down Expand Up @@ -2910,6 +2915,8 @@ internal fun UnifiedActivity.LibraryGameDetailDialog(
onDismissRequest = { showWorkshopDialog = false },
)
}

SteamLaunchOptionsDialogHost(app.id, app.name, launchOptionsState)
}
}
}
7 changes: 3 additions & 4 deletions app/src/main/app/shell/UnifiedActivityLaunch.kt
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,9 @@ internal fun UnifiedActivity.launchSteamGame(
return@launch
}

val shortcut =
containerManager.loadShortcuts().find {
it.getExtra("game_source") == "STEAM" && it.getExtra("app_id") == app.id.toString()
}
// Shared resolver: same canonical shortcut the picker writes to (and no
// per-shortcut icon decode the way loadShortcuts() does).
val shortcut = SteamService.locateSteamShortcut(context, app.id, containerManager)
val detectedLaunchExecutable = SteamService.getInstalledExe(app.id)

if (shortcut != null) {
Expand Down
Binary file modified app/src/main/assets/wnsteam/bionic/steam.exe
Binary file not shown.
Loading