aboutsummaryrefslogtreecommitdiff
path: root/io.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-29 04:03:38 -0400
committerhistoria <[not public]>2026-06-29 04:03:38 -0400
commitba34490aaed5f7c242c2b0453130fefc07d0d5d0 (patch)
treedb5818757d5080221494cead1c7e61a576d1cb65 /io.go
parentb1e252c996a6332d391f96624a7d6f149eb097c4 (diff)
downloadtui-ascii-mapper-ba34490aaed5f7c242c2b0453130fefc07d0d5d0.tar.gz
restructured projectHEADmain
Diffstat (limited to 'io.go')
-rw-r--r--io.go222
1 files changed, 0 insertions, 222 deletions
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:
-// ---
-// <yaml metadata>
-// ...
-// <grid lines>
-
-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
-}