Files
ordoor/internal/sets/sets.go
2019-12-31 01:55:58 +00:00

156 lines
3.0 KiB
Go

package sets
import (
"fmt"
"io/ioutil"
"path/filepath"
"strconv"
"strings"
"code.ur.gs/lupine/ordoor/internal/util/asciiscan"
)
type MapSet struct {
Description string
SurfaceCount int
LeftCount int
RightCount int
CenterCount int
Palette []string
// TODO: is there any more structure than this? Should I preserve empty lines?
SurfacePalette []string
LeftPalette []string
RightPalette []string
CenterPalette []string
}
func (m *MapSet) Count() int {
return m.SurfaceCount + m.LeftCount + m.RightCount + m.CenterCount
}
func LoadSets(dir string) (map[string]*MapSet, error) {
fis, err := ioutil.ReadDir(dir)
if err != nil {
return nil, err
}
out := make(map[string]*MapSet, len(fis))
for _, fi := range fis {
filename := filepath.Join(dir, fi.Name())
basename := filepath.Base(filename)
extname := filepath.Ext(filename)
// Don't try to load non-.set files
if !strings.EqualFold(extname, ".set") {
continue
}
obj, err := LoadSet(filename)
if err != nil {
return nil, fmt.Errorf("%s: %v", filename, err)
}
out[basename] = obj
}
return out, nil
}
func LoadSet(filename string) (*MapSet, error) {
out := &MapSet{}
s, err := asciiscan.New(filename)
if err != nil {
return nil, err
}
defer s.Close()
out.Description, err = s.ConsumeString()
if err != nil {
return nil, err
}
if err := consumeDefs(s, out); err != nil {
return nil, err
}
fmt.Println(filename)
out.Palette = make([]string, out.Count())
offset := 0
out.SurfacePalette = out.Palette[offset : offset+out.SurfaceCount : offset+out.SurfaceCount]
offset += out.SurfaceCount
out.LeftPalette = out.Palette[offset : offset+out.LeftCount : offset+out.LeftCount]
offset += out.LeftCount
out.RightPalette = out.Palette[offset : offset+out.RightCount : offset+out.RightCount]
offset += out.RightCount
out.CenterPalette = out.Palette[offset : offset+out.CenterCount : offset+out.CenterCount]
offset += out.CenterCount
if err := consumePalette(s, out.Palette); err != nil {
return nil, fmt.Errorf("Failed to read palette: %v", err)
}
return out, nil
}
func consumeDefs(scanner *asciiscan.Scanner, in *MapSet) error {
expectDefs, err := scanner.ConsumeString()
if err != nil {
return err
}
if expectDefs != "Defs" {
return fmt.Errorf("Couldn't find Defs section")
}
defs, err := scanner.ConsumeString()
if err != nil {
return err
}
parts := strings.SplitN(defs, " ", -1)
if len(parts) != 4 {
return fmt.Errorf("Defs section did not have 4 components")
}
ints := make([]int, 4)
for i, part := range parts {
n, err := strconv.ParseInt(part, 10, 8)
if err != nil {
return err
}
ints[i] = int(n) // safe as we specify 8 bits to ParseInt
}
in.SurfaceCount = ints[0]
in.LeftCount = ints[1]
in.RightCount = ints[2]
in.CenterCount = ints[3]
return nil
}
func consumePalette(scanner *asciiscan.Scanner, into []string) error {
for i := 0; i < len(into); i++ {
str, err := scanner.ConsumeString()
if err != nil {
return err // EOF is bad: the number of entries is explicit
}
into[i] = str
}
return nil
}