package sets import ( "fmt" "io/ioutil" "path/filepath" "strconv" "strings" "ur.gs/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-.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 } 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 }