120 lines
2.0 KiB
Go
120 lines
2.0 KiB
Go
package sets
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"ur.gs/chaos-gate/internal/util/asciiscan"
|
|
)
|
|
|
|
type MapSet struct {
|
|
Description string
|
|
Defs [4]byte // TODO: work out what these are for
|
|
|
|
// TODO: is there any more structure than this? Should I preserve empty lines?
|
|
Palette []string
|
|
}
|
|
|
|
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-.obj 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
|
|
}
|
|
|
|
out.Defs, err = consumeDefs(s)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for {
|
|
str, err := s.ConsumeString()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
return out, nil
|
|
}
|
|
|
|
return nil, err
|
|
}
|
|
|
|
out.Palette = append(out.Palette, str)
|
|
}
|
|
|
|
return out, nil
|
|
}
|
|
|
|
func consumeDefs(scanner *asciiscan.Scanner) ([4]byte, error) {
|
|
var out [4]byte
|
|
|
|
expectDefs, err := scanner.ConsumeString()
|
|
if err != nil {
|
|
return out, err
|
|
}
|
|
|
|
if expectDefs != "Defs" {
|
|
return out, fmt.Errorf("Couldn't find Defs section")
|
|
}
|
|
|
|
defs, err := scanner.ConsumeString()
|
|
if err != nil {
|
|
return out, err
|
|
}
|
|
|
|
parts := strings.SplitN(defs, " ", -1)
|
|
if len(parts) != 4 {
|
|
return out, fmt.Errorf("Defs section did not have 4 components")
|
|
}
|
|
|
|
for i, part := range parts {
|
|
n, err := strconv.ParseInt(part, 10, 8)
|
|
if err != nil {
|
|
return out, err
|
|
}
|
|
|
|
out[i] = byte(n) // safe as we specify 8 bits to ParseInt
|
|
}
|
|
|
|
return out, nil
|
|
}
|