From ba34490aaed5f7c242c2b0453130fefc07d0d5d0 Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Mon, 29 Jun 2026 04:03:38 -0400 Subject: restructured project --- io.go | 222 ------------------------------------------------------------------ 1 file changed, 222 deletions(-) delete mode 100644 io.go (limited to 'io.go') diff --git a/io.go b/io.go deleted file mode 100644 index 1b2fd5d..0000000 --- a/io.go +++ /dev/null @@ -1,222 +0,0 @@ -package main - -import ( - "bytes" - "fmt" - "os" - "path/filepath" - "strings" - - "gopkg.in/yaml.v3" -) - -// Save format is YAML header with metadata, then the text grid below. -// Format: -// --- -// -// ... -// - -type SaveData struct { - Name string `yaml:"name"` - Width int `yaml:"width"` - Height int `yaml:"height"` - Palette []Terrain `yaml:"palette"` - GridBody string `yaml:"grid_body,omitempty"` - GridColors []string `yaml:"grid_colors,omitempty"` - TextLabels []TextLabel `yaml:"text_labels,omitempty"` - Submaps []SubmapRef `yaml:"submaps,omitempty"` -} - -type SubmapRef struct { - X int `yaml:"x"` - Y int `yaml:"y"` - Data SaveData `yaml:"data"` -} - -// SerializeMap serializes the map to the save format. -func SerializeMap(m *Map, path string) error { - data := buildSaveData(m) - - yamlBytes, err := yaml.Marshal(data) - if err != nil { - return err - } - - var buf bytes.Buffer - buf.WriteString("---\n") - buf.Write(yamlBytes) - buf.WriteString("...\n") - - for _, row := range m.Grid { - for _, cell := range row { - if cell.Terrain < 0 || cell.Terrain >= len(m.Palette) { - buf.WriteByte(' ') - } else { - buf.WriteString(m.Palette[cell.Terrain].ASCII) - } - } - buf.WriteByte('\n') - } - - dir := filepath.Dir(path) - if err := os.MkdirAll(dir, 0755); err != nil { - return err - } - return os.WriteFile(path, buf.Bytes(), 0644) -} - -func buildSaveData(m *Map) SaveData { - sd := SaveData{ - Name: m.Name, - Width: m.Width, - Height: m.Height, - Palette: m.Palette, - } - // Build grid body (only stored in YAML for submaps) - var gb strings.Builder - for _, row := range m.Grid { - for _, cell := range row { - if cell.Terrain < 0 || cell.Terrain >= len(m.Palette) { - gb.WriteByte(' ') - } else { - gb.WriteString(m.Palette[cell.Terrain].ASCII) - } - } - gb.WriteByte('\n') - } - if m.Parent != nil { - sd.GridBody = gb.String() - } - - for y := range m.Grid { - for x := range m.Grid[y] { - c := m.Grid[y][x] - if c.Color != "" { - sd.GridColors = append(sd.GridColors, fmt.Sprintf("%d,%d,%s", x, y, c.Color)) - } - } - } - for _, tl := range m.TextLabels { - sd.TextLabels = append(sd.TextLabels, tl) - } - for pt, sub := range m.Submaps { - sd.Submaps = append(sd.Submaps, SubmapRef{ - X: pt.X, Y: pt.Y, - Data: buildSaveData(sub), - }) - } - return sd -} - -// DeserializeMap reads a saved map file. -func DeserializeMap(path string) (*Map, error) { - data, err := os.ReadFile(path) - if err != nil { - return nil, err - } - content := string(data) - - if !strings.HasPrefix(content, "---\n") { - return nil, fmt.Errorf("invalid save file: missing YAML header") - } - - endIdx := strings.Index(content, "\n...\n") - if endIdx < 0 { - return nil, fmt.Errorf("invalid save file: missing ... terminator") - } - - yamlPart := content[4:endIdx] - gridPart := content[endIdx+5:] - - var sd SaveData - if err := yaml.Unmarshal([]byte(yamlPart), &sd); err != nil { - return nil, fmt.Errorf("invalid YAML header: %w", err) - } - - m := NewMap(sd.Name, sd.Width, sd.Height, sd.Palette) - m.Filename = path - - // Restore colors - for _, entry := range sd.GridColors { - var x, y int - var c string - if n, _ := fmt.Sscanf(entry, "%d,%d,%s", &x, &y, &c); n == 3 { - if y >= 0 && y < m.Height && x >= 0 && x < m.Width { - m.Grid[y][x].Color = c - } - } - } - - lines := strings.Split(strings.TrimRight(gridPart, "\n"), "\n") - for y, line := range lines { - if y >= m.Height { - break - } - for x, ch := range line { - if x >= m.Width { - break - } - for i, t := range m.Palette { - if string(ch) == t.ASCII { - m.Grid[y][x].Terrain = i - break - } - } - } - } - - for _, tl := range sd.TextLabels { - PlaceTextLabel(m, tl.Start, tl.Text, tl.Color) - } - - for _, sr := range sd.Submaps { - sub := restoreMap(&sr.Data, m) - m.Submaps[Point{sr.X, sr.Y}] = sub - } - - return m, nil -} - -func restoreMap(sd *SaveData, parent *Map) *Map { - m := NewMap(sd.Name, sd.Width, sd.Height, sd.Palette) - m.Parent = parent - // Restore colors - for _, entry := range sd.GridColors { - var x, y int - var c string - if n, _ := fmt.Sscanf(entry, "%d,%d,%s", &x, &y, &c); n == 3 { - if y >= 0 && y < m.Height && x >= 0 && x < m.Width { - m.Grid[y][x].Color = c - } - } - } - // Restore grid from GridBody - if sd.GridBody != "" { - lines := strings.Split(strings.TrimRight(sd.GridBody, "\n"), "\n") - for y, line := range lines { - if y >= m.Height { - break - } - for x, ch := range line { - if x >= m.Width { - break - } - for i, t := range m.Palette { - if string(ch) == t.ASCII { - m.Grid[y][x].Terrain = i - break - } - } - } - } - } - for _, tl := range sd.TextLabels { - PlaceTextLabel(m, tl.Start, tl.Text, tl.Color) - } - for _, sr := range sd.Submaps { - sub := restoreMap(&sr.Data, m) - m.Submaps[Point{sr.X, sr.Y}] = sub - } - return m -} -- cgit v1.2.3