package config import ( "errors" "fmt" "os" "path/filepath" "github.com/BurntSushi/toml" ) type Engine struct { DataDir string `toml:"data_dir"` Palette string `toml:"palette"` } // Things set in the options hash // TODO: load defaults from Data/GenericData.dat if they're not set type Options struct { PlayMovies bool `toml:"play_movies"` Animations bool `toml:"animations"` PlayMusic bool `toml:"play_music"` CombatVoices bool `toml:"combat_voices"` ShowGrid bool `toml:"show_grid"` ShowPaths bool `toml:"show_paths"` PointSaving bool `toml:"point_saving"` AutoCutLevel bool `toml:"auto_cut_level"` XRes int `toml:"x_resolution"` YRes int `toml:"y_resolution"` MusicVolume int `toml:"music_volume"` SFXVolume int `toml:"sfx_volume"` UnitSpeed int `toml:"unit_speed"` AnimSpeed int `toml:"animation_speed"` } type Config struct { filename string `toml:"-"` VideoPlayer []string `toml:"video_player"` Engines map[string]Engine `toml:"engines"` DefaultEngineName string `toml:"default_engine"` // FIXME: options may well end up being per-engine too Defaults *Options `toml:"-"` Options `toml:"options"` } func (c *Config) Engine(name string) *Engine { engine, ok := c.Engines[name] if !ok { return nil } return &engine } func (c *Config) DefaultEngine() *Engine { return c.Engine(c.DefaultEngineName) } // TODO: case-insensitive lookup func (c *Config) DataFile(engine string, path string) string { cfg, ok := c.Engines[engine] if !ok { return "" } return filepath.Join(cfg.DataDir, path) } func Load(filename string, overrideDefaultEngine string) (*Config, error) { var out Config _, err := toml.DecodeFile(filename, &out) if err != nil { return nil, err } out.filename = filename if overrideDefaultEngine != "" { out.DefaultEngineName = overrideDefaultEngine } if out.DefaultEngine() == nil { return nil, fmt.Errorf("Default engine %q not configured", out.DefaultEngineName) } return &out, nil } func (c *Config) HasUnsetOptions() bool { var empty Options return c.Options == empty } func (c *Config) Save() error { f, err := os.OpenFile(c.filename, os.O_WRONLY, 0644) if err != nil { return err } defer f.Close() return toml.NewEncoder(f).Encode(c) } func (c *Config) ResetDefaults() error { if c.Defaults == nil { return errors.New("Defaults not available") } c.Options = *c.Defaults return c.Save() } func (o *Options) ResolutionIndex() int { if o.XRes == 640 && o.YRes == 480 { return 1 } if o.XRes == 800 && o.YRes == 600 { return 2 } if o.XRes == 1024 && o.YRes == 768 { return 3 } return 4 // Magic value } func (o *Options) SetResolutionIndex(value int) { switch value { case 1: o.XRes = 640 o.YRes = 480 case 2: o.XRes = 800 o.YRes = 600 case 3: o.XRes = 1024 o.YRes = 768 } // If the value isn't recognised, silently ignore the request to avoid // overwriting options the resolution slider doesn't know about }