added a apply recommended graphics settings button to options

This commit is contained in:
aomizu
2025-06-14 14:28:50 +09:00
parent 68cfe61064
commit c0daa300bf
7 changed files with 263 additions and 1 deletions

135
pkg/launcher/recommended.go Normal file
View File

@@ -0,0 +1,135 @@
package launcher
import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"turtlesilicon/pkg/debug"
"turtlesilicon/pkg/paths"
)
// RecommendedSettings contains the recommended graphics settings for optimal performance
var RecommendedSettings = map[string]string{
"farclip": "177",
"M2UseShaders": "1",
"gxColorBits": "24",
"gxDepthBits": "24",
"gxMultisampleQuality": "0.000000",
"gxMultisample": "2",
"shadowLOD": "0",
}
// CheckRecommendedSettings reads the Config.wtf file and checks if all recommended settings are applied
// Returns true if all settings are correctly applied, false otherwise
func CheckRecommendedSettings() bool {
if paths.TurtlewowPath == "" {
debug.Printf("TurtleWoW path not set, cannot check Config.wtf")
return false
}
configPath := filepath.Join(paths.TurtlewowPath, "WTF", "Config.wtf")
if _, err := os.Stat(configPath); os.IsNotExist(err) {
debug.Printf("Config.wtf not found at %s", configPath)
return false
}
content, err := os.ReadFile(configPath)
if err != nil {
debug.Printf("Failed to read Config.wtf: %v", err)
return false
}
configText := string(content)
// Check each recommended setting
for setting, expectedValue := range RecommendedSettings {
if !isSettingCorrect(configText, setting, expectedValue) {
debug.Printf("Setting %s not found or incorrect in Config.wtf", setting)
return false
}
}
debug.Printf("All recommended settings are correctly applied")
return true
}
// isSettingCorrect checks if a specific setting has the correct value in the config text
func isSettingCorrect(configText, setting, expectedValue string) bool {
// Create regex pattern to match the setting
pattern := fmt.Sprintf(`SET\s+%s\s+"([^"]*)"`, regexp.QuoteMeta(setting))
re := regexp.MustCompile(pattern)
matches := re.FindStringSubmatch(configText)
if len(matches) < 2 {
return false
}
currentValue := matches[1]
return currentValue == expectedValue
}
// ApplyRecommendedSettings applies all recommended graphics settings to Config.wtf
func ApplyRecommendedSettings() error {
if paths.TurtlewowPath == "" {
return fmt.Errorf("TurtleWoW path not set")
}
configPath := filepath.Join(paths.TurtlewowPath, "WTF", "Config.wtf")
// Create WTF directory if it doesn't exist
wtfDir := filepath.Dir(configPath)
if err := os.MkdirAll(wtfDir, 0755); err != nil {
return fmt.Errorf("failed to create WTF directory: %v", err)
}
var configText string
// Read existing config if it exists
if content, err := os.ReadFile(configPath); err == nil {
configText = string(content)
} else {
debug.Printf("Config.wtf not found, creating new file")
configText = ""
}
// Apply each recommended setting
for setting, value := range RecommendedSettings {
configText = updateOrAddSetting(configText, setting, value)
}
// Write the updated config back to file
if err := os.WriteFile(configPath, []byte(configText), 0644); err != nil {
return fmt.Errorf("failed to write Config.wtf: %v", err)
}
debug.Printf("Successfully applied recommended settings to Config.wtf")
return nil
}
// updateOrAddSetting updates an existing setting or adds a new one if it doesn't exist
func updateOrAddSetting(configText, setting, value string) string {
// Create regex pattern to match the setting
pattern := fmt.Sprintf(`SET\s+%s\s+"[^"]*"`, regexp.QuoteMeta(setting))
re := regexp.MustCompile(pattern)
newSetting := fmt.Sprintf(`SET %s "%s"`, setting, value)
if re.MatchString(configText) {
// Replace existing setting
configText = re.ReplaceAllString(configText, newSetting)
debug.Printf("Updated setting %s to %s", setting, value)
} else {
// Add new setting
if configText != "" && !strings.HasSuffix(configText, "\n") {
configText += "\n"
}
configText += newSetting + "\n"
debug.Printf("Added new setting %s with value %s", setting, value)
}
return configText
}

View File

@@ -1,6 +1,7 @@
package ui
import (
"fmt"
"net/url"
"strings"
"time"
@@ -13,6 +14,7 @@ import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/dialog"
"fyne.io/fyne/v2/widget"
)
@@ -47,6 +49,35 @@ func createOptionsComponents() {
vanillaTweaksCheckbox.SetChecked(prefs.EnableVanillaTweaks)
launcher.EnableVanillaTweaks = prefs.EnableVanillaTweaks
// Create recommended settings button with help icon
applyRecommendedSettingsButton = widget.NewButton("Apply recommended settings", func() {
err := launcher.ApplyRecommendedSettings()
if err != nil {
debug.Printf("Failed to apply recommended settings: %v", err)
// Show error dialog if we have a window reference
if currentWindow != nil {
dialog.ShowError(fmt.Errorf("failed to apply recommended settings: %v", err), currentWindow)
}
} else {
debug.Printf("Successfully applied recommended settings")
// Show success dialog if we have a window reference
if currentWindow != nil {
dialog.ShowInformation("Success", "Recommended graphics settings have been applied to Config.wtf", currentWindow)
}
// Update button state
updateRecommendedSettingsButton()
}
})
applyRecommendedSettingsButton.Importance = widget.MediumImportance
// Create help button for recommended settings
recommendedSettingsHelpButton = widget.NewButton("?", func() {
showRecommendedSettingsHelpPopup()
})
recommendedSettingsHelpButton.Importance = widget.MediumImportance
// Initialize button state
updateRecommendedSettingsButton()
// Create Wine registry Option-as-Alt buttons and status
createWineRegistryComponents()
@@ -350,3 +381,84 @@ func stopPulsingEffect() {
pulsingTicker = nil
}
}
// updateRecommendedSettingsButton updates the state of the recommended settings button
func updateRecommendedSettingsButton() {
if applyRecommendedSettingsButton == nil {
return
}
// Check if all recommended settings are already applied
if launcher.CheckRecommendedSettings() {
applyRecommendedSettingsButton.Disable()
applyRecommendedSettingsButton.SetText("Settings applied")
} else {
applyRecommendedSettingsButton.Enable()
applyRecommendedSettingsButton.SetText("Apply recommended settings")
}
// Help button should always be enabled
if recommendedSettingsHelpButton != nil {
recommendedSettingsHelpButton.Enable()
}
}
// showRecommendedSettingsHelpPopup shows a popup explaining the recommended graphics settings
func showRecommendedSettingsHelpPopup() {
if currentWindow == nil {
return
}
// Create help content
helpTitle := widget.NewRichTextFromMarkdown("# 📋 Recommended Graphics Settings")
// Create individual setting labels for better formatting
settingsTitle := widget.NewLabel("The following settings will be applied to your Config.wtf file:")
settingsTitle.TextStyle = fyne.TextStyle{Bold: true}
setting1 := widget.NewLabel("• Terrain Distance (farclip): 177 - Reduces CPU overhead - more fps")
setting2 := widget.NewLabel("• Vertex Animation Shaders (M2UseShaders): Enabled - Prevents graphic glitches")
setting3 := widget.NewLabel("• Multisampling (gxMultisample): 2x - Makes portraits load properly")
setting4 := widget.NewLabel("• Shadow LOD (shadowLOD): 0 - 10% fps increase")
settingsContainer := container.NewVBox(
settingsTitle,
widget.NewSeparator(),
setting1,
setting2,
setting3,
setting4,
widget.NewSeparator(),
)
// Create OK button
okButton := widget.NewButton("OK", func() {
// This will be set when the popup is created
})
okButton.Importance = widget.MediumImportance
// Create help content container
helpContentContainer := container.NewVBox(
container.NewCenter(helpTitle),
widget.NewSeparator(),
settingsContainer,
widget.NewSeparator(),
container.NewCenter(okButton),
)
// Calculate popup size
windowSize := currentWindow.Content().Size()
popupWidth := windowSize.Width * 3 / 4
popupHeight := windowSize.Height * 3 / 4
// Create the help popup
helpPopup := widget.NewModalPopUp(container.NewPadded(helpContentContainer), currentWindow.Canvas())
helpPopup.Resize(fyne.NewSize(popupWidth, popupHeight))
// Set the OK button action to hide the help popup
okButton.OnTapped = func() {
helpPopup.Hide()
}
helpPopup.Show()
}

View File

@@ -15,6 +15,9 @@ func showOptionsPopup() {
// Create options content with better organization and smaller titles
optionsTitle := widget.NewLabel("Options")
optionsTitle.TextStyle = fyne.TextStyle{Bold: true}
// Create label for recommended settings
recommendedSettingsLabel := widget.NewLabel("Graphics settings:")
gameOptionsContainer := container.NewVBox(
optionsTitle,
widget.NewSeparator(),
@@ -22,6 +25,8 @@ func showOptionsPopup() {
showTerminalCheckbox,
vanillaTweaksCheckbox,
widget.NewSeparator(),
container.NewBorder(nil, nil, recommendedSettingsLabel, container.NewHBox(applyRecommendedSettingsButton, recommendedSettingsHelpButton), nil),
widget.NewSeparator(),
container.NewBorder(nil, nil, nil, container.NewHBox(enableOptionAsAltButton, disableOptionAsAltButton), optionAsAltStatusLabel),
)

View File

@@ -30,6 +30,11 @@ func UpdateAllStatuses() {
if optionAsAltStatusLabel != nil {
updateWineRegistryStatus()
}
// Update recommended settings button if component is initialized
if applyRecommendedSettingsButton != nil {
updateRecommendedSettingsButton()
}
}
// updateCrossoverStatus updates CrossOver path and patch status

View File

@@ -32,6 +32,10 @@ var (
showTerminalCheckbox *widget.Check
vanillaTweaksCheckbox *widget.Check
// Recommended settings button
applyRecommendedSettingsButton *widget.Button
recommendedSettingsHelpButton *widget.Button
// Wine registry buttons and status
enableOptionAsAltButton *widget.Button
disableOptionAsAltButton *widget.Button