2018-03-18 05:34:14 +00:00
|
|
|
package sets
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"path/filepath"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
|
2019-12-31 01:55:58 +00:00
|
|
|
"code.ur.gs/lupine/ordoor/internal/util/asciiscan"
|
2018-03-18 05:34:14 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type MapSet struct {
|
|
|
|
Description string
|
2018-03-18 17:27:32 +00:00
|
|
|
|
|
|
|
SurfaceCount int
|
|
|
|
LeftCount int
|
|
|
|
RightCount int
|
|
|
|
CenterCount int
|
2018-03-18 05:34:14 +00:00
|
|
|
|
2018-03-18 18:19:05 +00:00
|
|
|
Palette []string
|
|
|
|
|
2018-03-18 05:34:14 +00:00
|
|
|
// TODO: is there any more structure than this? Should I preserve empty lines?
|
2018-03-18 17:27:32 +00:00
|
|
|
SurfacePalette []string
|
|
|
|
LeftPalette []string
|
|
|
|
RightPalette []string
|
|
|
|
CenterPalette []string
|
2018-03-18 05:34:14 +00:00
|
|
|
}
|
|
|
|
|
2018-03-18 18:19:05 +00:00
|
|
|
func (m *MapSet) Count() int {
|
|
|
|
return m.SurfaceCount + m.LeftCount + m.RightCount + m.CenterCount
|
|
|
|
}
|
|
|
|
|
2018-03-18 15:39:50 +00:00
|
|
|
func LoadSets(dir string) (map[string]*MapSet, error) {
|
2018-03-18 05:34:14 +00:00
|
|
|
fis, err := ioutil.ReadDir(dir)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-03-18 15:39:50 +00:00
|
|
|
out := make(map[string]*MapSet, len(fis))
|
2018-03-18 05:34:14 +00:00
|
|
|
|
|
|
|
for _, fi := range fis {
|
|
|
|
filename := filepath.Join(dir, fi.Name())
|
|
|
|
basename := filepath.Base(filename)
|
|
|
|
extname := filepath.Ext(filename)
|
|
|
|
|
2018-12-30 23:22:20 +00:00
|
|
|
// Don't try to load non-.set files
|
2018-03-18 05:34:14 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2018-03-18 15:39:50 +00:00
|
|
|
func LoadSet(filename string) (*MapSet, error) {
|
|
|
|
out := &MapSet{}
|
2018-03-18 05:34:14 +00:00
|
|
|
|
|
|
|
s, err := asciiscan.New(filename)
|
|
|
|
if err != nil {
|
2018-03-18 15:39:50 +00:00
|
|
|
return nil, err
|
2018-03-18 05:34:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
defer s.Close()
|
|
|
|
|
|
|
|
out.Description, err = s.ConsumeString()
|
|
|
|
if err != nil {
|
2018-03-18 15:39:50 +00:00
|
|
|
return nil, err
|
2018-03-18 05:34:14 +00:00
|
|
|
}
|
|
|
|
|
2018-03-18 17:27:32 +00:00
|
|
|
if err := consumeDefs(s, out); err != nil {
|
2018-03-18 15:39:50 +00:00
|
|
|
return nil, err
|
2018-03-18 05:34:14 +00:00
|
|
|
}
|
|
|
|
|
2018-03-18 18:19:05 +00:00
|
|
|
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)
|
2018-03-18 05:34:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return out, nil
|
|
|
|
}
|
|
|
|
|
2018-03-18 17:27:32 +00:00
|
|
|
func consumeDefs(scanner *asciiscan.Scanner, in *MapSet) error {
|
2018-03-18 05:34:14 +00:00
|
|
|
expectDefs, err := scanner.ConsumeString()
|
|
|
|
if err != nil {
|
2018-03-18 17:27:32 +00:00
|
|
|
return err
|
2018-03-18 05:34:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if expectDefs != "Defs" {
|
2018-03-18 17:27:32 +00:00
|
|
|
return fmt.Errorf("Couldn't find Defs section")
|
2018-03-18 05:34:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
defs, err := scanner.ConsumeString()
|
|
|
|
if err != nil {
|
2018-03-18 17:27:32 +00:00
|
|
|
return err
|
2018-03-18 05:34:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
parts := strings.SplitN(defs, " ", -1)
|
|
|
|
if len(parts) != 4 {
|
2018-03-18 17:27:32 +00:00
|
|
|
return fmt.Errorf("Defs section did not have 4 components")
|
2018-03-18 05:34:14 +00:00
|
|
|
}
|
|
|
|
|
2018-03-18 17:27:32 +00:00
|
|
|
ints := make([]int, 4)
|
|
|
|
|
2018-03-18 05:34:14 +00:00
|
|
|
for i, part := range parts {
|
|
|
|
n, err := strconv.ParseInt(part, 10, 8)
|
|
|
|
if err != nil {
|
2018-03-18 17:27:32 +00:00
|
|
|
return err
|
2018-03-18 05:34:14 +00:00
|
|
|
}
|
|
|
|
|
2018-03-18 17:27:32 +00:00
|
|
|
ints[i] = int(n) // safe as we specify 8 bits to ParseInt
|
2018-03-18 05:34:14 +00:00
|
|
|
}
|
|
|
|
|
2018-03-18 17:27:32 +00:00
|
|
|
in.SurfaceCount = ints[0]
|
|
|
|
in.LeftCount = ints[1]
|
|
|
|
in.RightCount = ints[2]
|
|
|
|
in.CenterCount = ints[3]
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-03-18 18:19:05 +00:00
|
|
|
func consumePalette(scanner *asciiscan.Scanner, into []string) error {
|
|
|
|
for i := 0; i < len(into); i++ {
|
2018-03-18 17:27:32 +00:00
|
|
|
str, err := scanner.ConsumeString()
|
|
|
|
if err != nil {
|
|
|
|
return err // EOF is bad: the number of entries is explicit
|
|
|
|
}
|
|
|
|
|
2018-03-18 18:19:05 +00:00
|
|
|
into[i] = str
|
2018-03-18 17:27:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2018-03-18 05:34:14 +00:00
|
|
|
}
|