added a apply recommended graphics settings button to options
This commit is contained in:
@@ -3,4 +3,4 @@
|
||||
Name = "TurtleSilicon"
|
||||
ID = "com.tairasu.turtlesilicon"
|
||||
Version = "1.2.2"
|
||||
Build = 52
|
||||
Build = 57
|
||||
|
@@ -91,6 +91,7 @@ If you prefer to run the application directly from source code:
|
||||
1. Set "Terrain distance" as low as possible. This reduces the overhead stress on the CPU
|
||||
2. Turn Vertex Animation Shaders on. Otherwise you get graphic glitches on custom models.
|
||||
3. Set Multisampling to 24-bit color 24-bit depth **2x** to make portraits load
|
||||
4. Add `SET shadowLOD "0"` to your Config.wtf inside the WTF directory
|
||||
|
||||
## Build Instructions
|
||||
|
||||
|
135
pkg/launcher/recommended.go
Normal file
135
pkg/launcher/recommended.go
Normal 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
|
||||
}
|
@@ -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()
|
||||
}
|
||||
|
@@ -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),
|
||||
)
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user