Files
ordoor/cmd/loader/main.go

229 lines
6.3 KiB
Go
Raw Normal View History

package main
import (
"flag"
2018-03-17 04:15:40 +00:00
"fmt"
2020-06-01 01:24:44 +01:00
"image/color"
"log"
"path/filepath"
2018-12-30 23:23:08 +00:00
"strings"
2020-06-01 01:08:53 +01:00
"code.ur.gs/lupine/ordoor/internal/config"
2019-12-31 01:55:58 +00:00
"code.ur.gs/lupine/ordoor/internal/data"
"code.ur.gs/lupine/ordoor/internal/fonts"
2020-04-15 21:11:01 +01:00
"code.ur.gs/lupine/ordoor/internal/idx"
2019-12-31 01:55:58 +00:00
"code.ur.gs/lupine/ordoor/internal/maps"
"code.ur.gs/lupine/ordoor/internal/menus"
2020-06-01 01:24:44 +01:00
"code.ur.gs/lupine/ordoor/internal/palettes"
2019-12-31 01:55:58 +00:00
"code.ur.gs/lupine/ordoor/internal/sets"
)
var (
2020-06-01 01:08:53 +01:00
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")
)
2020-06-01 01:08:53 +01:00
// FIXME: all these paths are hardcoded with Chaos Gate in mind
func main() {
flag.Parse()
2020-06-01 01:08:53 +01:00
cfg, err := config.Load(*configFile, *engine)
if err != nil {
log.Fatalf("Failed to load config: %v", err)
}
engine := cfg.DefaultEngine()
gamePath := engine.DataDir
2020-06-01 01:24:44 +01:00
palette, ok := palettes.Get(engine.Palette)
if !ok {
log.Fatalf("Unknown palette name: %v", engine.Palette)
}
2020-06-01 01:08:53 +01:00
loadData(filepath.Join(gamePath, "Data"))
2018-12-30 23:23:08 +00:00
if !*skipObj {
2020-06-01 01:08:53 +01:00
loadObj(filepath.Join(gamePath, "Obj"))
2018-12-30 23:23:08 +00:00
}
2018-03-17 04:15:40 +00:00
2020-06-01 01:08:53 +01:00
loadMapsFrom(filepath.Join(gamePath, "Maps"))
loadMapsFrom(filepath.Join(gamePath, "MultiMaps"))
loadSets(filepath.Join(gamePath, "Sets"))
2020-06-01 01:24:44 +01:00
loadMenus(filepath.Join(gamePath, "Menu"), palette)
2020-06-01 01:08:53 +01:00
loadFonts(filepath.Join(gamePath, "Fonts"))
loadIdx(filepath.Join(gamePath, "Idx", "WarHammer.idx"))
2018-03-17 04:15:40 +00:00
}
2020-06-01 01:08:53 +01:00
func loadData(dataPath string) {
accountingPath := filepath.Join(dataPath, "Accounting.dat")
aniObDefPath := filepath.Join(dataPath, "AniObDef.dat")
2020-04-15 21:11:01 +01:00
genericDataPath := filepath.Join(dataPath, "GenericData.dat")
hasActionPath := filepath.Join(dataPath, "HasAction.dat")
i18nPath := filepath.Join(dataPath, data.I18nFile)
log.Printf("Loading %s...", accountingPath)
accounting, err := data.LoadAccounting(accountingPath)
if err != nil {
log.Fatalf("Failed to parse %s: %s", accountingPath, err)
}
log.Printf("%s: %+v", accountingPath, accounting)
log.Printf("Loading %s...", aniObDefPath)
animated, err := data.LoadAnimatedObjectDefinitions(aniObDefPath)
if err != nil {
log.Fatalf("Failed to parse %s: %s", genericDataPath, err)
}
log.Printf("%s: %+v", aniObDefPath, animated)
log.Printf("Loading %s...", genericDataPath)
genericData, err := data.LoadGeneric(genericDataPath)
if err != nil {
log.Fatalf("Failed to parse %s: %s", genericDataPath, err)
}
log.Printf("%s: %+v", genericDataPath, genericData)
log.Printf("Loading %s...", i18nPath)
i18n, err := data.LoadI18n(i18nPath)
if err != nil {
log.Fatalf("Failed to parse %s: %s", i18nPath, err)
}
log.Printf("%s: len=%v", i18nPath, i18n.Len())
2020-04-15 21:11:01 +01:00
ha, err := data.LoadHasAction(hasActionPath)
if err != nil {
log.Fatalf("Failed to parse %s: %v", hasActionPath, err)
}
ha.Print()
2018-03-17 04:15:40 +00:00
}
2020-06-01 01:08:53 +01:00
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)
if err != nil {
log.Fatalf("Failed to parse %s: %s", objDataPath, err)
}
2018-03-17 04:15:40 +00:00
inspect := "c_webs"
inspect_obj := inspect + ".obj"
log.Printf("Objects in %s:", objDataPath)
for key, obj := range objects {
2018-03-17 04:15:40 +00:00
if key != inspect_obj {
continue
}
log.Printf(
"\t%s\t%d sprites\t%d bytes",
key, obj.ObjectHeader.NumSprites, obj.ObjectHeader.DataSize,
2018-03-17 04:15:40 +00:00
)
}
2018-03-17 04:15:40 +00:00
log.Printf("%s: %#v", inspect, objects[inspect_obj])
for i, sprite := range objects[inspect_obj].Sprites {
numPixels := sprite.Width * sprite.Height
log.Printf("sprite %d: w=%d h=%d sz=%d w*h=%d bits/pixel=%v", i, sprite.Width, sprite.Height, sprite.PixelSize, numPixels, float64(sprite.PixelSize*8)/float64(numPixels))
2018-03-17 04:15:40 +00:00
}
}
2020-06-01 01:08:53 +01:00
func loadMapsFrom(mapsPath string) {
2018-03-17 04:15:40 +00:00
log.Printf("Loading maps from %s", mapsPath)
gameMaps, err := maps.LoadGameMaps(mapsPath)
if err != nil {
log.Fatalf("Failed to parse %s/*.{MAP,txt} as game maps: %v", mapsPath, err)
}
log.Printf("Maps in %s:", mapsPath)
for key, gm := range gameMaps {
rect := gm.Rect()
2018-03-17 04:15:40 +00:00
fmt.Printf(
" * `%s`: IsCampaignMap=%v W=%v:%v L=%v:%v SetName=%s\n",
key,
gm.IsCampaignMap,
2020-05-31 14:58:46 +01:00
rect.Min.X, rect.Max.X,
rect.Min.Y, rect.Max.Y,
string(gm.SetName),
2018-03-17 04:15:40 +00:00
)
}
}
2018-03-18 05:34:14 +00:00
2020-06-01 01:08:53 +01:00
func loadSets(setsPath string) {
2018-03-18 05:34:14 +00:00
log.Printf("Loading sets from %s", setsPath)
mapSets, err := sets.LoadSets(setsPath)
if err != nil {
log.Fatalf("Failed to parse %s/*.set as map sets: %v", setsPath, err)
}
for key, mapSet := range mapSets {
2018-03-18 17:27:32 +00:00
fmt.Printf(" * `%s`: surface expected=%d actual=%d\n", key, mapSet.SurfaceCount, len(mapSet.SurfacePalette))
fmt.Printf(" * `%s`: left expected=%d actual=%d\n", key, mapSet.LeftCount, len(mapSet.LeftPalette))
fmt.Printf(" * `%s`: right expected=%d actual=%d\n", key, mapSet.RightCount, len(mapSet.RightPalette))
fmt.Printf(" * `%s`: center expected=%d actual=%d\n", key, mapSet.CenterCount, len(mapSet.CenterPalette))
2018-03-18 05:34:14 +00:00
}
}
2018-12-30 23:23:08 +00:00
2020-06-01 01:24:44 +01:00
func loadMenus(menusPath string, palette color.Palette) {
2020-06-01 01:08:53 +01:00
log.Printf("Loading menus from %s", menusPath)
2018-12-30 23:23:08 +00:00
2020-06-01 01:24:44 +01:00
menus, err := menus.LoadMenus(menusPath, palette)
2018-12-30 23:23:08 +00:00
if err != nil {
log.Fatalf("Failed to parse %s/*.mnu as menus: %v", menusPath, err)
}
for _, menu := range menus {
fmt.Printf(" * `%s`: objects=%v fonts=%v\n", menu.Name, menu.ObjectFiles, menu.FontNames)
for _, group := range menu.Groups {
// TODO: display group
for _, record := range group.Records {
displayRecord(record, 2)
}
2018-12-30 23:23:08 +00:00
}
}
}
func displayRecord(record *menus.Record, depth int) {
content := fmt.Sprintf("id=%v type=%v sprite=%v", record.ID, record.Type, record.SpriteId)
2018-12-30 23:23:08 +00:00
if !record.Active {
content = "(" + content + ")"
}
fmt.Printf("%s* %s\n", strings.Repeat(" ", depth), content)
}
2020-06-01 01:08:53 +01:00
func loadFonts(fontsPath string) {
log.Printf("Loading fonts from %s", fontsPath)
fonts, err := fonts.LoadFonts(fontsPath)
if err != nil {
log.Fatalf("Failed to parse %s/*.fnt as fonts: %v", fontsPath, err)
}
for _, font := range fonts {
fmt.Printf(" * `%s`: obj=%v entries=%v\n", font.Name, font.ObjectFile, font.Entries())
}
}
2020-04-15 21:11:01 +01:00
2020-06-01 01:08:53 +01:00
func loadIdx(idxPath string) {
log.Printf("Loading idx from %s", idxPath)
idx, err := idx.Load(idxPath)
2020-04-15 21:11:01 +01:00
if err != nil {
log.Fatalf("Failed to parse %s as idx: %v", idxPath, err)
}
for i, group := range idx.Groups {
log.Printf("Group %2d: %4d records, start sprite is %6d", i, len(group.Records), group.Spec.SpriteIdx)
2020-06-13 23:10:21 +01:00
for i, rec := range group.Records {
log.Printf("\t%3d: %#+v", i, rec)
}
}
2020-04-15 21:11:01 +01:00
}