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 }