mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-01-13 12:56:35 -05:00
abstracted d2config to an interface (still have a singleton, though) (#538)
This commit is contained in:
parent
3757ff1ac5
commit
cf35285b48
@ -130,7 +130,7 @@ func (p *App) initialize() error {
|
||||
}
|
||||
|
||||
config := d2config.Get()
|
||||
d2resource.LanguageCode = config.Language
|
||||
d2resource.LanguageCode = config.Language()
|
||||
|
||||
p.renderer.SetWindowIcon("d2logo.png")
|
||||
p.terminal.BindLogger()
|
||||
@ -164,7 +164,7 @@ func (p *App) initialize() error {
|
||||
return err
|
||||
}
|
||||
|
||||
p.audio.SetVolumes(config.BgmVolume, config.SfxVolume)
|
||||
p.audio.SetVolumes(config.BgmVolume(), config.SfxVolume())
|
||||
|
||||
if err := p.loadDataDict(); err != nil {
|
||||
return err
|
||||
@ -583,7 +583,8 @@ func updateInitError(target d2interface.Surface) error {
|
||||
width, height := target.GetSize()
|
||||
|
||||
target.PushTranslation(width/5, height/2)
|
||||
target.DrawText("Could not find the MPQ files in the directory: %s\nPlease put the files and re-run the game.", d2config.Get().MpqPath)
|
||||
target.DrawText(`Could not find the MPQ files in the directory:
|
||||
%s\nPlease put the files and re-run the game.`, d2config.Get().MpqPath())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
21
d2common/d2interface/configuration.go
Normal file
21
d2common/d2interface/configuration.go
Normal file
@ -0,0 +1,21 @@
|
||||
package d2interface
|
||||
|
||||
// Configuration saves, loads, and returns the OpenDiablo2
|
||||
// configuration. This is either loaded from disk, or generated
|
||||
// when one is not found.
|
||||
type Configuration interface {
|
||||
Load() error
|
||||
Save() error
|
||||
// Get() Configuration
|
||||
MpqLoadOrder() []string
|
||||
Language() string
|
||||
MpqPath() string
|
||||
TicksPerSecond() int
|
||||
FpsCap() int
|
||||
SfxVolume() float64
|
||||
BgmVolume() float64
|
||||
FullScreen() bool
|
||||
RunInBackground() bool
|
||||
VsyncEnabled() bool
|
||||
Backend() string
|
||||
}
|
@ -2,13 +2,12 @@ package d2asset
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"path"
|
||||
"sync"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2mpq"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2config"
|
||||
)
|
||||
|
||||
type archiveEntry struct {
|
||||
@ -18,7 +17,7 @@ type archiveEntry struct {
|
||||
|
||||
type archiveManager struct {
|
||||
cache d2interface.Cache
|
||||
config *d2config.Configuration
|
||||
config d2interface.Configuration
|
||||
entries []archiveEntry
|
||||
mutex sync.Mutex
|
||||
}
|
||||
@ -27,7 +26,7 @@ const (
|
||||
archiveBudget = 1024 * 1024 * 512
|
||||
)
|
||||
|
||||
func createArchiveManager(config *d2config.Configuration) *archiveManager {
|
||||
func createArchiveManager(config d2interface.Configuration) *archiveManager {
|
||||
return &archiveManager{cache: d2common.CreateCache(archiveBudget), config: config}
|
||||
}
|
||||
|
||||
@ -86,14 +85,14 @@ func (am *archiveManager) loadArchive(archivePath string) (*d2mpq.MPQ, error) {
|
||||
}
|
||||
|
||||
func (am *archiveManager) cacheArchiveEntries() error {
|
||||
if len(am.entries) == len(am.config.MpqLoadOrder) {
|
||||
if len(am.entries) == len(am.config.MpqLoadOrder()) {
|
||||
return nil
|
||||
}
|
||||
|
||||
am.entries = nil
|
||||
|
||||
for _, archiveName := range am.config.MpqLoadOrder {
|
||||
archivePath := path.Join(am.config.MpqPath, archiveName)
|
||||
for _, archiveName := range am.config.MpqLoadOrder() {
|
||||
archivePath := path.Join(am.config.MpqPath(), archiveName)
|
||||
|
||||
archive, err := am.loadArchive(archivePath)
|
||||
if err != nil {
|
||||
|
@ -1,24 +1,24 @@
|
||||
package d2asset
|
||||
|
||||
import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2config"
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dat"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2mpq"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2config"
|
||||
)
|
||||
|
||||
var singleton *assetManager
|
||||
|
||||
// Initialize creates and assigns all necessary dependencies for the assetManager top-level functions to work correctly
|
||||
func Initialize(renderer d2interface.Renderer, term d2interface.Terminal) error {
|
||||
func Initialize(renderer d2interface.Renderer,
|
||||
term d2interface.Terminal) error {
|
||||
var (
|
||||
config = d2config.Get()
|
||||
archiveManager = createArchiveManager(&config)
|
||||
fileManager = createFileManager(&config, archiveManager)
|
||||
archiveManager = createArchiveManager(config)
|
||||
fileManager = createFileManager(config, archiveManager)
|
||||
paletteManager = createPaletteManager()
|
||||
paletteTransformManager = createPaletteTransformManager()
|
||||
animationManager = createAnimationManager(renderer)
|
||||
@ -51,12 +51,8 @@ func Initialize(renderer d2interface.Renderer, term d2interface.Terminal) error
|
||||
}
|
||||
|
||||
if err := term.BindAction("assetstat", "display asset manager cache statistics", func() {
|
||||
type cache interface {
|
||||
GetWeight() int
|
||||
GetBudget() int
|
||||
}
|
||||
|
||||
var cacheStatistics = func(c cache) float64 {
|
||||
var cacheStatistics = func(c d2interface.Cache) float64 {
|
||||
const percent = 100.0
|
||||
return float64(c.GetWeight()) / float64(c.GetBudget()) * percent
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2config"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -17,11 +16,16 @@ const (
|
||||
type fileManager struct {
|
||||
cache d2interface.Cache
|
||||
archiveManager *archiveManager
|
||||
config *d2config.Configuration
|
||||
config d2interface.Configuration
|
||||
}
|
||||
|
||||
func createFileManager(config *d2config.Configuration, archiveManager *archiveManager) *fileManager {
|
||||
return &fileManager{d2common.CreateCache(fileBudget), archiveManager, config}
|
||||
func createFileManager(config d2interface.Configuration,
|
||||
archiveManager *archiveManager) *fileManager {
|
||||
return &fileManager{
|
||||
d2common.CreateCache(fileBudget),
|
||||
archiveManager,
|
||||
config,
|
||||
}
|
||||
}
|
||||
|
||||
func (fm *fileManager) loadFileStream(filePath string) (*d2mpq.MpqDataStream, error) {
|
||||
@ -76,7 +80,7 @@ func (fm *fileManager) removeLocaleTokens(filePath string) string {
|
||||
tableToken := d2resource.LanguageTableToken
|
||||
fontToken := d2resource.LanguageFontToken
|
||||
|
||||
filePath = strings.ReplaceAll(filePath, tableToken, fm.config.Language)
|
||||
filePath = strings.ReplaceAll(filePath, tableToken, fm.config.Language())
|
||||
|
||||
// fixme: not all languages==latin
|
||||
filePath = strings.ReplaceAll(filePath, fontToken, "latin")
|
||||
|
@ -14,16 +14,16 @@ const defaultBgmVolume = 0.3
|
||||
|
||||
func getDefaultConfig() *Configuration {
|
||||
config := &Configuration{
|
||||
Language: "ENG",
|
||||
FullScreen: false,
|
||||
TicksPerSecond: -1,
|
||||
RunInBackground: true,
|
||||
VsyncEnabled: true,
|
||||
SfxVolume: defaultSfxVolume,
|
||||
BgmVolume: defaultBgmVolume,
|
||||
MpqPath: "C:/Program Files (x86)/Diablo II",
|
||||
Backend: "Ebiten",
|
||||
MpqLoadOrder: []string{
|
||||
language: "ENG",
|
||||
fullScreen: false,
|
||||
ticksPerSecond: -1,
|
||||
runInBackground: true,
|
||||
vsyncEnabled: true,
|
||||
sfxVolume: defaultSfxVolume,
|
||||
bgmVolume: defaultBgmVolume,
|
||||
mpqPath: "C:/Program Files (x86)/Diablo II",
|
||||
backend: "Ebiten",
|
||||
mpqLoadOrder: []string{
|
||||
"Patch_D2.mpq",
|
||||
"d2exp.mpq",
|
||||
"d2xmusic.mpq",
|
||||
@ -41,11 +41,11 @@ func getDefaultConfig() *Configuration {
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
if runtime.GOARCH == "386" {
|
||||
config.MpqPath = "C:/Program Files/Diablo II"
|
||||
config.mpqPath = "C:/Program Files/Diablo II"
|
||||
}
|
||||
case "darwin":
|
||||
config.MpqPath = "/Applications/Diablo II/"
|
||||
config.MpqLoadOrder = []string{
|
||||
config.mpqPath = "/Applications/Diablo II/"
|
||||
config.mpqLoadOrder = []string{
|
||||
"Diablo II Patch",
|
||||
"Diablo II Expansion Data",
|
||||
"Diablo II Expansion Movies",
|
||||
@ -60,7 +60,7 @@ func getDefaultConfig() *Configuration {
|
||||
}
|
||||
case "linux":
|
||||
if usr, err := user.Current(); err == nil {
|
||||
config.MpqPath = path.Join(usr.HomeDir, ".wine/drive_c/Program Files (x86)/Diablo II")
|
||||
config.mpqPath = path.Join(usr.HomeDir, ".wine/drive_c/Program Files (x86)/Diablo II")
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ func load(configPath string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(data, &singleton); err != nil {
|
||||
if err := unmarshalIntoInterface(data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -105,6 +105,60 @@ func load(configPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func unmarshalIntoInterface(d []byte) error {
|
||||
tmp := &hack{} // an empty concrete implementation
|
||||
if err := json.Unmarshal(d, tmp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tmp2cfg(tmp, singleton) // transfer tmp values to singleton
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO figure out a way to unmarshal into an interface
|
||||
type hack struct{
|
||||
MpqLoadOrder []string
|
||||
Language string
|
||||
MpqPath string
|
||||
TicksPerSecond int
|
||||
FpsCap int
|
||||
SfxVolume float64
|
||||
BgmVolume float64
|
||||
FullScreen bool
|
||||
RunInBackground bool
|
||||
VsyncEnabled bool
|
||||
Backend string
|
||||
}
|
||||
|
||||
func cfg2tmp (a *Configuration, b *hack) {
|
||||
b.MpqLoadOrder = a.mpqLoadOrder
|
||||
b.Language = a.language
|
||||
b.MpqPath = a.mpqPath
|
||||
b.TicksPerSecond = a.ticksPerSecond
|
||||
b.FpsCap = a.fpsCap
|
||||
b.SfxVolume = a.sfxVolume
|
||||
b.BgmVolume = a.bgmVolume
|
||||
b.FullScreen = a.fullScreen
|
||||
b.RunInBackground = a.runInBackground
|
||||
b.VsyncEnabled = a.vsyncEnabled
|
||||
b.Backend = a.backend
|
||||
}
|
||||
|
||||
func tmp2cfg (b *hack, a *Configuration) {
|
||||
a.mpqLoadOrder = b.MpqLoadOrder
|
||||
a.language = b.Language
|
||||
a.mpqPath = b.MpqPath
|
||||
a.ticksPerSecond = b.TicksPerSecond
|
||||
a.fpsCap = b.FpsCap
|
||||
a.sfxVolume = b.SfxVolume
|
||||
a.bgmVolume = b.BgmVolume
|
||||
a.fullScreen = b.FullScreen
|
||||
a.runInBackground = b.RunInBackground
|
||||
a.vsyncEnabled = b.VsyncEnabled
|
||||
a.backend = b.Backend
|
||||
}
|
||||
|
||||
func save(configPath string) error {
|
||||
configDir := path.Dir(configPath)
|
||||
|
||||
@ -118,14 +172,16 @@ func save(configPath string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := json.MarshalIndent(singleton, "", " ")
|
||||
tmp := &hack{}
|
||||
cfg2tmp(singleton, tmp)
|
||||
data, err := json.MarshalIndent(tmp, "", " ")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := configFile.Write(data); err != nil {
|
||||
return err
|
||||
if _, writeErr := configFile.Write(data); writeErr != nil {
|
||||
return writeErr
|
||||
}
|
||||
|
||||
err = configFile.Close()
|
||||
|
@ -6,25 +6,68 @@ import (
|
||||
|
||||
// Configuration defines the configuration for the engine, loaded from config.json
|
||||
type Configuration struct {
|
||||
MpqLoadOrder []string
|
||||
Language string
|
||||
MpqPath string
|
||||
TicksPerSecond int
|
||||
FpsCap int
|
||||
SfxVolume float64
|
||||
BgmVolume float64
|
||||
FullScreen bool
|
||||
RunInBackground bool
|
||||
VsyncEnabled bool
|
||||
Backend string
|
||||
mpqLoadOrder []string
|
||||
language string
|
||||
mpqPath string
|
||||
ticksPerSecond int
|
||||
fpsCap int
|
||||
sfxVolume float64
|
||||
bgmVolume float64
|
||||
fullScreen bool
|
||||
runInBackground bool
|
||||
vsyncEnabled bool
|
||||
backend string
|
||||
}
|
||||
|
||||
var singleton = getDefaultConfig()
|
||||
func (c *Configuration) MpqLoadOrder() []string {
|
||||
return c.mpqLoadOrder
|
||||
}
|
||||
|
||||
func Load() error {
|
||||
func (c *Configuration) Language() string {
|
||||
return c.language
|
||||
}
|
||||
|
||||
func (c *Configuration) MpqPath() string {
|
||||
return c.mpqPath
|
||||
}
|
||||
|
||||
func (c *Configuration) TicksPerSecond() int {
|
||||
return c.ticksPerSecond
|
||||
}
|
||||
|
||||
func (c *Configuration) FpsCap() int {
|
||||
return c.fpsCap
|
||||
}
|
||||
|
||||
func (c *Configuration) SfxVolume() float64 {
|
||||
return c.sfxVolume
|
||||
}
|
||||
|
||||
func (c *Configuration) BgmVolume() float64 {
|
||||
return c.bgmVolume
|
||||
}
|
||||
|
||||
func (c *Configuration) FullScreen() bool {
|
||||
return c.fullScreen
|
||||
}
|
||||
|
||||
func (c *Configuration) RunInBackground() bool {
|
||||
return c.runInBackground
|
||||
}
|
||||
|
||||
func (c *Configuration) VsyncEnabled() bool {
|
||||
return c.vsyncEnabled
|
||||
}
|
||||
|
||||
func (c *Configuration) Backend() string {
|
||||
return c.backend
|
||||
}
|
||||
|
||||
// Load loads a configuration object from disk
|
||||
func (c *Configuration) Load() error {
|
||||
configPaths := []string{
|
||||
getLocalConfigPath(),
|
||||
getDefaultConfigPath(),
|
||||
getLocalConfigPath(),
|
||||
}
|
||||
|
||||
var loaded bool
|
||||
@ -49,7 +92,8 @@ func Load() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func Save() error {
|
||||
// Save saves the configuration object to disk
|
||||
func (c *Configuration) Save() error {
|
||||
configPath := getDefaultConfigPath()
|
||||
log.Printf("saving configuration file to %s...", configPath)
|
||||
|
||||
@ -60,11 +104,3 @@ func Save() error {
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func Get() Configuration {
|
||||
if singleton == nil {
|
||||
panic("configuration is not initialized")
|
||||
}
|
||||
|
||||
return *singleton
|
||||
}
|
||||
|
22
d2core/d2config/singleton_stuff.go
Normal file
22
d2core/d2config/singleton_stuff.go
Normal file
@ -0,0 +1,22 @@
|
||||
package d2config
|
||||
|
||||
import "github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
// TODO remove this shit
|
||||
|
||||
var singleton = getDefaultConfig()
|
||||
|
||||
// Load loads a configuration object from disk
|
||||
func Load() error {
|
||||
return singleton.Load()
|
||||
}
|
||||
|
||||
// Save saves the configuration object to disk
|
||||
func Save() error {
|
||||
return singleton.Save()
|
||||
}
|
||||
|
||||
// Get returns a configuration object
|
||||
func Get() d2interface.Configuration {
|
||||
return singleton
|
||||
}
|
@ -33,10 +33,10 @@ func CreateRenderer() (*Renderer, error) {
|
||||
config := d2config.Get()
|
||||
|
||||
ebiten.SetCursorMode(ebiten.CursorModeHidden)
|
||||
ebiten.SetFullscreen(config.FullScreen)
|
||||
ebiten.SetRunnableOnUnfocused(config.RunInBackground)
|
||||
ebiten.SetVsyncEnabled(config.VsyncEnabled)
|
||||
ebiten.SetMaxTPS(config.TicksPerSecond)
|
||||
ebiten.SetFullscreen(config.FullScreen())
|
||||
ebiten.SetRunnableOnUnfocused(config.RunInBackground())
|
||||
ebiten.SetVsyncEnabled(config.VsyncEnabled())
|
||||
ebiten.SetMaxTPS(config.TicksPerSecond())
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user