Start reorganising for multiple games

This commit is contained in:
2020-06-01 01:08:53 +01:00
parent 59baf20c35
commit c1268e8d57
15 changed files with 257 additions and 145 deletions

18
.gitignore vendored
View File

@@ -1,14 +1,8 @@
/config.toml
/loader
/orig
/palette-idx
/view-ani
/view-font
/view-obj
/view-map
/view-minimap
/view-menu
/view-set
/ordoor
/investigation/Maps
/investigation/Obj
/isos
/CG
/SL
/SaW
/WoW
/bin

View File

@@ -4,37 +4,40 @@ GOBUILD ?= go build -tags ebitengl
all: loader ordoor palette-idx view-ani view-font view-obj view-map view-menu view-minimap view-set
loader: $(srcfiles)
$(GOBUILD) -o loader ./cmd/loader
bin:
mkdir bin
palette-idx: $(srcfiles)
$(GOBUILD) -o palette-idx ./cmd/palette-idx
loader: bin $(srcfiles)
$(GOBUILD) -o bin/loader ./cmd/loader
view-ani: $(srcfiles)
$(GOBUILD) -o view-ani ./cmd/view-ani
palette-idx: bin $(srcfiles)
$(GOBUILD) -o bin/palette-idx ./cmd/palette-idx
view-font: $(srcfiles)
$(GOBUILD) -o view-font ./cmd/view-font
view-ani: bin $(srcfiles)
$(GOBUILD) -o bin/view-ani ./cmd/view-ani
view-obj: $(srcfiles)
$(GOBUILD) -o view-obj ./cmd/view-obj
view-font: bin $(srcfiles)
$(GOBUILD) -o bin/view-font ./cmd/view-font
view-map: $(srcfiles)
$(GOBUILD) -o view-map ./cmd/view-map
view-obj: bin $(srcfiles)
$(GOBUILD) -o bin/view-obj ./cmd/view-obj
view-menu: $(srcfiles)
$(GOBUILD) -o view-menu ./cmd/view-menu
view-map: bin $(srcfiles)
$(GOBUILD) -o bin/view-map ./cmd/view-map
view-minimap: $(srcfiles)
$(GOBUILD) -o view-minimap ./cmd/view-minimap
view-menu: bin $(srcfiles)
$(GOBUILD) -o bin/view-menu ./cmd/view-menu
view-set: $(srcfiles)
$(GOBUILD) -o view-set ./cmd/view-set
view-minimap: bin $(srcfiles)
$(GOBUILD) -o bin/view-minimap ./cmd/view-minimap
ordoor: $(srcfiles)
$(GOBUILD) -o ordoor ./cmd/ordoor
view-set: bin $(srcfiles)
$(GOBUILD) -o bin/view-set ./cmd/view-set
ordoor: bin $(srcfiles)
$(GOBUILD) -o bin/ordoor ./cmd/ordoor
clean:
rm -f loader ordoor view-ani view-obj view-map view-minimap view-set palette-idx view-font
rm -rf bin
.PHONY: all clean

View File

@@ -1,20 +1,34 @@
# Ordoor
Ordoor is an **unofficial** [game engine recreation](https://en.wikipedia.org/wiki/Game_engine_recreation)
of the classic game from 1998, [Warhammer 40,000: Chaos Gate](https://en.wikipedia.org/wiki/Warhammer_40,000:_Chaos_Gate)
of the Random Games, Inc., [Strategy Engine](https://www.mobygames.com/game-group/game-engine-random-games-1996-2000-strategy-engine),
which was in use from 1996 - 2000.
**You must have a copy of the original game data to use this project**. GOG is
the current publisher of this game; [you can purchase it here](https://www.gog.com/game/warhammer_40000_chaos_gate).
Four games are known to have been published for this engine:
"Warhammer 40,000" is a trademark of Games Workshop, and the game data used by
Ordoor contains Games Workshop intellectual property. I am confident that this
project uses all those things in accordance with the
[Intellectual Property Policy](https://www.games-workshop.com/en-GB/Intellectual-Property-Policy)
and the license granted when purchasing a copy of the game in question. Do let
me know if you see or suspect any violation, and I'll address it immediately.
* [Wages of War: The Business of Battle](https://en.wikipedia.org/wiki/Wages_of_War) (1996)
* [Soldiers At War](https://en.wikipedia.org/wiki/Soldiers_at_War) (1998)
* [Warhammer 40,000: Chaos Gate](https://en.wikipedia.org/wiki/Warhammer_40,000:_Chaos_Gate) (1998) [GOG](https://www.gog.com/game/warhammer_40000_chaos_gate)
* [Avalon Hill's Squad Leader](https://en.wikipedia.org/wiki/Avalon_Hill%27s_Squad_Leader) (2000)
The aim of Ordoor is to be a complete reimplementation that allows all four
of these games to be played on modern hardware. It should also permit new games
of the same style to be built.
For each of the games above, **You must have a copy of the original game data to play**.
Links are provided above if we're aware of an active publisher; otherwise, check
your back catalogue, or perhaps a local charity shop.
Trademarks and intellectual property are the property of their respective
owners, and the games mentioned above (including the game data) are protected by
copyright. As a mere game engine recreation, we're confident that this project
operates legally, and that its goal is a noble one. Do get in touch if you
believe otherwise!
Ordoor is a portmanteau of Order Door, which is, of course, the opposite of a
Chaos Gate.
Chaos Gate. The project began with a Chaos Gate recreation, then more games were
discovered, so scope expanded. A rename and/or rewrite may be on the cards as a
result.
## Current status
@@ -31,6 +45,27 @@ I've just been informed that another game from 1998, [Soldiers At War](https://e
seems to use the same engine. Maybe at some point Ordoor will be able to play
both. Will that need a rename? Hmm. Watch this space.
## Long-term goals
Once full playthrough of the official single-player campaign for all four games
has been achieved, thoughts turn to other things we could do. Here are some
ideas, mostly at random.
Multi-player support.
Graphics enhancements - 3D models instead of sprites, high-resolution tile sets,
32-bit colour, etc. Hopefully we'd be able to drop these in one at a time.
Vastly improved AI.
Mash-ups? How do mercenaries fare against cultists fare against Nazis? Only one
way to find out!
New campaigns with existing assets. Tell new stories, or elaborate on / modify
existing ones.
Completely new fantasy game using the same engine.
## Building from source
I'm writing code in Go at the moment, so you'll need to have a Go runtime
@@ -119,30 +154,3 @@ $ ./scripts/convert-wav ./orig/Wav
As with video playback, the ambition is to *eventually* remove this dependency
and operate on the unmodified files instead.
## Miscellany
"Mission Setup" includes information about available squad types
From EquipDef.cpp Dumo: CEquipment we learn the following object types:
0. DELETED
1. WEAPON
2. GRENADE
3. MEDIPACK
4. SCANNER
5. GENESEED
6. CLIP
7. DOOR KEY
8. DOOR KEY
9. DOOR KEY
10. DOOR KEY
And we learn they can be "on"....
0. CHARACTER
1. VEHICLE
2. CANISTER
I'm starting to see some parallels with [this](https://github.com/shlainn/game-file-formats/wiki/)
in the data formats, and the timeline (1997) seems about right. Worth keeping an
eye on!

View File

@@ -7,6 +7,7 @@ import (
"path/filepath"
"strings"
"code.ur.gs/lupine/ordoor/internal/config"
"code.ur.gs/lupine/ordoor/internal/data"
"code.ur.gs/lupine/ordoor/internal/fonts"
"code.ur.gs/lupine/ordoor/internal/idx"
@@ -16,29 +17,38 @@ import (
)
var (
gamePath = flag.String("game-path", "./orig", "Path to a WH40K: Chaos Gate installation")
skipObj = flag.Bool("skip-obj", true, "Skip loading .obj files")
configFile = flag.String("config", "config.toml", "Config file")
engine = flag.String("engine", "", "Override engine to use")
skipObj = flag.Bool("skip-obj", true, "Skip loading .obj files")
)
// FIXME: all these paths are hardcoded with Chaos Gate in mind
func main() {
flag.Parse()
loadData()
cfg, err := config.Load(*configFile, *engine)
if err != nil {
log.Fatalf("Failed to load config: %v", err)
}
engine := cfg.DefaultEngine()
gamePath := engine.DataDir
loadData(filepath.Join(gamePath, "Data"))
if !*skipObj {
loadObj()
loadObj(filepath.Join(gamePath, "Obj"))
}
loadMapsFrom("Maps")
loadMapsFrom("MultiMaps")
loadSets()
loadMenus()
loadFonts()
loadIdx()
loadMapsFrom(filepath.Join(gamePath, "Maps"))
loadMapsFrom(filepath.Join(gamePath, "MultiMaps"))
loadSets(filepath.Join(gamePath, "Sets"))
loadMenus(filepath.Join(gamePath, "Menu"))
loadFonts(filepath.Join(gamePath, "Fonts"))
loadIdx(filepath.Join(gamePath, "Idx", "WarHammer.idx"))
}
func loadData() {
dataPath := filepath.Join(*gamePath, "Data")
func loadData(dataPath string) {
accountingPath := filepath.Join(dataPath, "Accounting.dat")
aniObDefPath := filepath.Join(dataPath, "AniObDef.dat")
genericDataPath := filepath.Join(dataPath, "GenericData.dat")
@@ -84,9 +94,7 @@ func loadData() {
ha.Print()
}
func loadObj() {
objDataPath := filepath.Join(*gamePath, "Obj")
func loadObj(objDataPath string) {
// TODO: Obj/cpiece.rec isn't loaded by this. Do we need it? How do we know?
log.Printf("Loading %s...", objDataPath)
objects, err := data.LoadObjects(objDataPath)
@@ -116,8 +124,7 @@ func loadObj() {
}
}
func loadMapsFrom(part string) {
mapsPath := filepath.Join(*gamePath, part)
func loadMapsFrom(mapsPath string) {
log.Printf("Loading maps from %s", mapsPath)
gameMaps, err := maps.LoadGameMaps(mapsPath)
@@ -140,8 +147,7 @@ func loadMapsFrom(part string) {
}
}
func loadSets() {
setsPath := filepath.Join(*gamePath, "Sets")
func loadSets(setsPath string) {
log.Printf("Loading sets from %s", setsPath)
mapSets, err := sets.LoadSets(setsPath)
@@ -157,8 +163,8 @@ func loadSets() {
}
}
func loadMenus() {
menusPath := filepath.Join(*gamePath, "Menu")
func loadMenus(menusPath string) {
log.Printf("Loading menus from %s", menusPath)
menus, err := menus.LoadMenus(menusPath)
if err != nil {
@@ -187,8 +193,8 @@ func displayRecord(record *menus.Record, depth int) {
fmt.Printf("%s* %s\n", strings.Repeat(" ", depth), content)
}
func loadFonts() {
fontsPath := filepath.Join(*gamePath, "Fonts")
func loadFonts(fontsPath string) {
log.Printf("Loading fonts from %s", fontsPath)
fonts, err := fonts.LoadFonts(fontsPath)
if err != nil {
@@ -200,8 +206,9 @@ func loadFonts() {
}
}
func loadIdx() {
idxPath := filepath.Join(*gamePath, "Idx", "WarHammer.idx")
func loadIdx(idxPath string) {
log.Printf("Loading idx from %s", idxPath)
idx, err := idx.Load(idxPath)
if err != nil {
log.Fatalf("Failed to parse %s as idx: %v", idxPath, err)

View File

@@ -11,11 +11,14 @@ import (
"golang.org/x/image/colornames"
"code.ur.gs/lupine/ordoor/internal/assetstore"
"code.ur.gs/lupine/ordoor/internal/config"
"code.ur.gs/lupine/ordoor/internal/ui"
)
var (
gamePath = flag.String("game-path", "./orig", "Path to a WH40K: Chaos Gate installation")
configFile = flag.String("config", "config.toml", "Config file")
engine = flag.String("engine", "", "Override engine to use")
groupIdx = flag.Int("group", 1, "Group index to start at")
recIdx = flag.Int("record", 0, "Record index to start at")
@@ -43,12 +46,17 @@ type state struct {
func main() {
flag.Parse()
if *gamePath == "" {
if *configFile == "" {
flag.Usage()
os.Exit(1)
}
assets, err := assetstore.New(*gamePath)
cfg, err := config.Load(*configFile, *engine)
if err != nil {
log.Fatalf("Failed to load config: %v", err)
}
assets, err := assetstore.New(cfg.DefaultEngine())
if err != nil {
log.Fatal("Failed to set up asset store: %v", err)
}

View File

@@ -10,11 +10,14 @@ import (
"github.com/hajimehoshi/ebiten"
"code.ur.gs/lupine/ordoor/internal/assetstore"
"code.ur.gs/lupine/ordoor/internal/config"
"code.ur.gs/lupine/ordoor/internal/ui"
)
var (
gamePath = flag.String("game-path", "./orig", "Path to a WH40K: Chaos Gate installation")
configFile = flag.String("config", "config.toml", "Config file")
engine = flag.String("engine", "", "Override engine to use")
fontName = flag.String("font", "", "Name of a font, e.g., basfont12")
txt = flag.String("text", "Test string", "Text to render")
@@ -37,12 +40,17 @@ type state struct {
func main() {
flag.Parse()
if *gamePath == "" || *fontName == "" {
if *configFile == "" || *fontName == "" {
flag.Usage()
os.Exit(1)
}
assets, err := assetstore.New(*gamePath)
cfg, err := config.Load(*configFile, *engine)
if err != nil {
log.Fatalf("Failed to load config: %v", err)
}
assets, err := assetstore.New(cfg.DefaultEngine())
if err != nil {
log.Fatal(err)
}

View File

@@ -9,13 +9,16 @@ import (
"github.com/hajimehoshi/ebiten"
"code.ur.gs/lupine/ordoor/internal/assetstore"
"code.ur.gs/lupine/ordoor/internal/config"
"code.ur.gs/lupine/ordoor/internal/scenario"
"code.ur.gs/lupine/ordoor/internal/ui"
)
var (
gamePath = flag.String("game-path", "./orig", "Path to a WH40K: Chaos Gate installation")
gameMap = flag.String("map", "", "Name of a map, e.g., Chapter01")
configFile = flag.String("config", "config.toml", "Config file")
engine = flag.String("engine", "", "Override engine to use")
gameMap = flag.String("map", "", "Name of a map, e.g., Chapter01")
winX = flag.Int("win-x", 1280, "Pre-scaled window X dimension")
winY = flag.Int("win-y", 1024, "Pre-scaled window Y dimension")
@@ -28,14 +31,19 @@ type env struct {
func main() {
flag.Parse()
if *gamePath == "" || *gameMap == "" {
if *configFile == "" || *gameMap == "" {
flag.Usage()
os.Exit(1)
}
assets, err := assetstore.New(*gamePath)
cfg, err := config.Load(*configFile, *engine)
if err != nil {
log.Fatalf("Failed to scan root directory %v: %v", *gamePath, err)
log.Fatalf("Failed to load config: %v", err)
}
assets, err := assetstore.New(cfg.DefaultEngine())
if err != nil {
log.Fatalf("Failed to scan root directory: %v", err)
}
scenario, err := scenario.NewScenario(assets, *gameMap)

View File

@@ -8,11 +8,14 @@ import (
"github.com/hajimehoshi/ebiten"
"code.ur.gs/lupine/ordoor/internal/assetstore"
"code.ur.gs/lupine/ordoor/internal/config"
"code.ur.gs/lupine/ordoor/internal/ui"
)
var (
gamePath = flag.String("game-path", "./orig", "Path to a WH40K: Chaos Gate installation")
configFile = flag.String("config", "config.toml", "Config file")
engine = flag.String("engine", "", "Override engine to use")
menuName = flag.String("menu", "", "Name of a menu, e.g. Main")
winX = flag.Int("win-x", 1280, "Pre-scaled window X dimension")
@@ -28,12 +31,17 @@ type dlg struct {
func main() {
flag.Parse()
if *gamePath == "" || *menuName == "" {
if *configFile == "" || *menuName == "" {
flag.Usage()
os.Exit(1)
}
assets, err := assetstore.New(*gamePath)
cfg, err := config.Load(*configFile, *engine)
if err != nil {
log.Fatalf("Failed to load config: %v", err)
}
assets, err := assetstore.New(cfg.DefaultEngine())
if err != nil {
log.Fatal(err)
}

View File

@@ -10,14 +10,17 @@ import (
"github.com/hajimehoshi/ebiten"
"code.ur.gs/lupine/ordoor/internal/assetstore"
"code.ur.gs/lupine/ordoor/internal/config"
"code.ur.gs/lupine/ordoor/internal/ui"
)
var (
gamePath = flag.String("game-path", "./orig", "Path to a WH40K: Chaos Gate installation")
objFile = flag.String("obj-file", "", "Path of an .obj file, e.g. ./orig/Obj/TZEENTCH.OBJ")
objName = flag.String("obj-name", "", "Name of an .obj file, e.g. TZEENTCH")
sprIdx = flag.Int("spr-idx", 0, "Sprite index to start at")
configFile = flag.String("config", "config.toml", "Config file")
engine = flag.String("engine", "", "Override engine to use")
objFile = flag.String("obj-file", "", "Path of an .obj file, e.g. ./orig/Obj/TZEENTCH.OBJ")
objName = flag.String("obj-name", "", "Name of an .obj file, e.g. TZEENTCH")
sprIdx = flag.Int("spr-idx", 0, "Sprite index to start at")
winX = flag.Int("win-x", 1280, "Pre-scaled window X dimension")
winY = flag.Int("win-y", 1024, "Pre-scaled window Y dimension")
@@ -42,12 +45,17 @@ type state struct {
func main() {
flag.Parse()
if *gamePath == "" || (*objName == "" && *objFile == "") {
if *configFile == "" || (*objName == "" && *objFile == "") {
flag.Usage()
os.Exit(1)
}
assets, err := assetstore.New(*gamePath)
cfg, err := config.Load(*configFile, *engine)
if err != nil {
log.Fatalf("Failed to load config: %v", err)
}
assets, err := assetstore.New(cfg.DefaultEngine())
if err != nil {
log.Fatal("Failed to set up asset store: %v", err)
}

View File

@@ -10,12 +10,15 @@ import (
"github.com/hajimehoshi/ebiten"
"code.ur.gs/lupine/ordoor/internal/assetstore"
"code.ur.gs/lupine/ordoor/internal/config"
"code.ur.gs/lupine/ordoor/internal/ui"
)
var (
gamePath = flag.String("game-path", "./orig", "Path to a WH40K: Chaos Gate installation")
setName = flag.String("set", "", "Name of a set, e.g., map01")
configFile = flag.String("config", "config.toml", "Config file")
engine = flag.String("engine", "", "Override engine to use")
setName = flag.String("set", "", "Name of a set, e.g., map01")
winX = flag.Int("win-x", 1280, "Pre-scaled window X dimension")
winY = flag.Int("win-y", 1024, "Pre-scaled window Y dimension")
@@ -39,12 +42,17 @@ type state struct {
func main() {
flag.Parse()
if *gamePath == "" || *setName == "" {
if *configFile == "" || *setName == "" {
flag.Usage()
os.Exit(1)
}
assets, err := assetstore.New(*gamePath)
cfg, err := config.Load(*configFile, *engine)
if err != nil {
log.Fatalf("Failed to load config: %v", err)
}
assets, err := assetstore.New(cfg.DefaultEngine())
if err != nil {
log.Fatal(err)
}

View File

@@ -1,6 +1,21 @@
[ordoor]
data_dir = "./orig"
video_player = ["mpv", "--no-config", "--keep-open=no", "--force-window=no", "--no-border", "--no-osc", "--fullscreen", "--no-input-default-bindings"]
video_player = ["mpv", "--no-config", "--keep-open=no", "--force-window=no", "--no-border", "--no-osc", "--fullscreen", "--no-input-default-bindings"]
default_engine = "ordoor"
[engines.geas] # Wages of War -> Gifts of Peace -> Geas
data_dir = "./WoW"
[engines.ordoor] # Chaos Gate -> Order Door -> Ordoor
data_dir = "./CG"
palette = "ChaosGate"
[engines.baps] # Soldiers At War -> Boys at Play -> Baps
data_dir = "./SaW"
palette = "SoldiersAtWar"
# [engines.] Squad Leader -> ??? -> ???
# data_dir = "./SL"
# palette = "SquadLeader" # may not be relevant?
[options]
play_movies = true

View File

@@ -7,19 +7,16 @@ import (
"path/filepath"
"strings"
"code.ur.gs/lupine/ordoor/internal/config"
"code.ur.gs/lupine/ordoor/internal/data"
"code.ur.gs/lupine/ordoor/internal/idx"
)
const (
RootDir = "" // Used in the entryMap for entries pertaining to the root dir
)
type entryMap map[string]map[string]string
// type AssetStore is responsible for lazily loading game data when it is
// required. Applications shouldn't need to do anything except set one of these
// up, pointing at the game dir root, to access all assets.
// up, pointing at the game dir root, to access all assets for that game.
//
// Assets should be loaded on-demand to keep memory costs as low as possible.
// Cross-platform differences such as filename case sensitivity are also dealt
@@ -27,8 +24,12 @@ type entryMap map[string]map[string]string
//
// We assume the directory is read-only. You can run Refresh() if you make a
// change.
//
// To mix assets from different games, either construct a synthetic directory
// or instantiate two separate asset stores.
type AssetStore struct {
RootDir string
// Palette
// Case-insensitive file lookup.
// {"":{"anim":"Anim", "obj":"Obj", ...}, "anim":{ "warhammer.ani":"WarHammer.ani" }, ...}
@@ -50,9 +51,13 @@ type AssetStore struct {
}
// New returns a new AssetStore
func New(dir string) (*AssetStore, error) {
func New(engine *config.Engine) (*AssetStore, error) {
if engine == nil {
return nil, fmt.Errorf("Unconfigured engine passed to assetstore")
}
store := &AssetStore{
RootDir: dir,
RootDir: engine.DataDir,
}
// fill entryMap
@@ -70,7 +75,7 @@ func (a *AssetStore) Refresh() error {
}
newEntryMap := make(entryMap, len(rootEntries))
newEntryMap[RootDir] = rootEntries
newEntryMap[""] = rootEntries
for lower, natural := range rootEntries {
path := filepath.Join(a.RootDir, natural)
@@ -118,7 +123,7 @@ func (a *AssetStore) lookup(name, ext string, dirs ...string) (string, error) {
dir = canonical(dir)
if base, ok := a.entries[dir]; ok {
if file, ok := base[filename]; ok {
actualDir := a.entries[RootDir][dir]
actualDir := a.entries[""][dir]
return filepath.Join(a.RootDir, actualDir, file), nil
}
}

View File

@@ -2,15 +2,16 @@ package config
import (
"errors"
"fmt"
"os"
"path/filepath"
"github.com/BurntSushi/toml"
)
type Ordoor struct {
DataDir string `toml:"data_dir"`
VideoPlayer []string `toml:"video_player"`
type Engine struct {
DataDir string `toml:"data_dir"`
Palette string `toml:"palette"`
}
// Things set in the options hash
@@ -38,12 +39,40 @@ type Options struct {
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:"-"`
Ordoor `toml:"ordoor"`
Options `toml:"options"`
}
func Load(filename string) (*Config, error) {
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)
@@ -53,7 +82,15 @@ func Load(filename string) (*Config, error) {
out.filename = filename
return &out, err
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 {
@@ -72,11 +109,6 @@ func (c *Config) Save() error {
return toml.NewEncoder(f).Encode(c)
}
// TODO: case-insensitive lookup
func (c *Config) DataFile(path string) string {
return filepath.Join(c.DataDir, path)
}
func (c *Config) ResetDefaults() error {
if c.Defaults == nil {
return errors.New("Defaults not available")

View File

@@ -34,12 +34,12 @@ type Ordoor struct {
}
func Run(configFile string, overrideX, overrideY int) error {
cfg, err := config.Load(configFile)
cfg, err := config.Load(configFile, "ordoor")
if err != nil {
return fmt.Errorf("Couldn't load config file: %v", err)
}
assets, err := assetstore.New(cfg.Ordoor.DataDir)
assets, err := assetstore.New(cfg.DefaultEngine())
if err != nil {
return fmt.Errorf("Failed to initialize asset store: %v", err)
}

View File

@@ -6,7 +6,7 @@ import (
)
func (o *Ordoor) PlayVideo(name string, skippable bool) {
filename := o.config.DataFile("SMK/" + name + ".smk")
filename := o.config.DataFile("ordoor", "SMK/"+name+".smk")
if len(o.config.VideoPlayer) == 0 {
log.Printf("Video player not configured, skipping video %v", filename)