diff --git a/cmd/vinegar/binary.go b/cmd/vinegar/binary.go index 21fa983..7b56544 100644 --- a/cmd/vinegar/binary.go +++ b/cmd/vinegar/binary.go @@ -367,8 +367,7 @@ func (b *Binary) ExtractPackages(pm *bootstrapper.PackageManifest) error { } func (b *Binary) SetupDxvk() error { - if b.State.DxvkVersion != "" && b.GlobalConfig.Player.Dxvk && b.GlobalConfig.Studio.Dxvk { - b.Splash.SetMessage("Uninstalling DXVK") + if b.State.DxvkVersion != "" && !b.GlobalConfig.Player.Dxvk && !b.GlobalConfig.Studio.Dxvk { if err := dxvk.Remove(b.Prefix); err != nil { return err } @@ -381,8 +380,7 @@ func (b *Binary) SetupDxvk() error { return nil } - b.Splash.SetProgress(0.0) - dxvk.Setenv() + dxvk.Setenv(b.Prefix) if b.GlobalConfig.DxvkVersion == b.State.DxvkVersion { return nil @@ -391,23 +389,12 @@ func (b *Binary) SetupDxvk() error { if err := dirs.Mkdirs(dirs.Cache); err != nil { return err } - path := filepath.Join(dirs.Cache, "dxvk-"+b.GlobalConfig.DxvkVersion+".tar.gz") - - b.Splash.SetProgress(0.3) - b.Splash.SetMessage("Downloading DXVK") - if err := dxvk.Fetch(path, b.GlobalConfig.DxvkVersion); err != nil { - return err - } - - b.Splash.SetProgress(0.7) - b.Splash.SetMessage("Extracting DXVK") - if err := dxvk.Extract(path, b.Prefix); err != nil { - return err - } - b.Splash.SetProgress(1.0) + b.Splash.SetMessage("Installing DXVK") + // This would only get saved if Install succeeded b.State.DxvkVersion = b.GlobalConfig.DxvkVersion - return nil + + return dxvk.Install(b.GlobalConfig.DxvkVersion, b.Prefix) } func (b *Binary) Command(args ...string) (*wine.Cmd, error) { diff --git a/wine/dxvk/dxvk.go b/wine/dxvk/dxvk.go index 319c145..8db94fe 100644 --- a/wine/dxvk/dxvk.go +++ b/wine/dxvk/dxvk.go @@ -14,42 +14,54 @@ import ( "github.com/vinegarhq/vinegar/wine" ) -const Repo = "https://github.com/doitsujin/dxvk" +var pfxDll32Path = filepath.Join("drive_c", "Program Files (x86)", "DXVK") +var pfxDll64Path = filepath.Join("drive_c", "Program Files", "DXVK") -func Setenv() { +func Setenv(pfx *wine.Prefix) { log.Printf("Enabling WINE DXVK DLL overrides") - os.Setenv("WINEDLLOVERRIDES", os.Getenv("WINEDLLOVERRIDES")+";d3d10core=n;d3d11=n;d3d9=n;dxgi=n") + os.Setenv("WINEDLLPATH", os.Getenv("WINEDLLPATH")+ + filepath.Join(pfx.Dir(), pfxDll32Path)+":"+filepath.Join(pfx.Dir(), pfxDll64Path), + ) + os.Setenv("WINEDLLOVERRIDES", os.Getenv("WINEDLLOVERRIDES")+";d3d10core,d3d11,d3d9,dxgi=n") } -func Fetch(name string, ver string) error { - url := fmt.Sprintf("%s/releases/download/v%[2]s/dxvk-%[2]s.tar.gz", Repo, ver) +// Remove will remove the directories the DXVK DLLs have been extracted to by Extract() +func Remove(pfx *wine.Prefix) error { + log.Println("Removing DXVK DLLs") - log.Printf("Downloading DXVK %s (%s as %s)", ver, url, name) + if err := os.RemoveAll(filepath.Join(pfx.Dir(), pfxDll32Path)); err != nil { + return err + } - return util.Download(url, name) + return os.RemoveAll(filepath.Join(pfx.Dir(), pfxDll64Path)) } -func Remove(pfx *wine.Prefix) error { - log.Println("Deleting all overridden DXVK DLLs") - - for _, dir := range []string{"syswow64", "system32"} { - for _, dll := range []string{"d3d9", "d3d10core", "d3d11", "dxgi"} { - p := filepath.Join(pfx.Dir(), "drive_c", "windows", dir, dll+".dll") - - log.Println("Removing DXVK DLL:", p) +// Install will download the DXVK tarball with the given version to a temporary +// file dictated by os.CreateTemp. Afterwards, it will proceed by calling Extract +// with the DXVK tarball, and then removing it. +func Install(ver string, pfx *wine.Prefix) error { + url := fmt.Sprintf( + "%s/releases/download/v%[2]s/dxvk-%[2]s.tar.gz", + "https://github.com/doitsujin/dxvk", ver, + ) - if err := os.Remove(p); err != nil { - return err - } - } + f, err := os.CreateTemp("", "dxvktarball.*.tar.gz") + if err != nil { + return err } + defer os.Remove(f.Name()) - log.Println("Restoring Wineprefix DLLs") + log.Println("Downloading DXVK", ver) + if err := util.Download(url, f.Name()); err != nil { + return fmt.Errorf("download dxvk %s: %w", ver, err) + } - return pfx.Wine("wineboot", "-u").Run() + return Extract(f.Name(), pfx) } +// Extract extracts the given DXVK tarball named file +// to a folder within the wineprefix. func Extract(name string, pfx *wine.Prefix) error { log.Printf("Extracting DXVK (%s)", name) @@ -83,13 +95,12 @@ func Extract(name string, pfx *wine.Prefix) error { } dir, ok := map[string]string{ - "x64": filepath.Join(pfx.Dir(), "drive_c", "windows", "system32"), - "x32": filepath.Join(pfx.Dir(), "drive_c", "windows", "syswow64"), + "x64": filepath.Join(pfx.Dir(), pfxDll64Path), + "x32": filepath.Join(pfx.Dir(), pfxDll32Path), }[filepath.Base(filepath.Dir(hdr.Name))] if !ok { - log.Printf("Skipping DXVK unhandled file: %s", hdr.Name) - continue + return fmt.Errorf("unhandled dxvk tarball file: %s", hdr.Name) } p := filepath.Join(dir, path.Base(hdr.Name)) @@ -113,6 +124,5 @@ func Extract(name string, pfx *wine.Prefix) error { f.Close() } - log.Printf("Deleting DXVK tarball (%s)", name) - return os.RemoveAll(name) + return nil }