-
Notifications
You must be signed in to change notification settings - Fork 0
/
gani.go
137 lines (109 loc) · 2.57 KB
/
gani.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package gani
import (
"bufio"
"bytes"
"strings"
)
// Need some examples before I can really do anything w. these.
// TODO: SCRIPT block(s)? [Anything else we are missing?]
// TODO: COLOREFFECT?
// Gani defines the Gani file format
type Gani struct {
Sprites []*Sprite
Settings *Settings
Frames []*Frame
header string
}
func (g *Gani) String() string {
builder := strings.Builder{}
builder.WriteString(g.header)
builder.WriteString("\n")
for _, sprite := range g.Sprites {
builder.WriteString(sprite.String())
builder.WriteString("\n")
}
builder.WriteString("\n")
builder.WriteString(g.Settings.String())
builder.WriteString("\n")
builder.WriteString("ANI\n")
for i, frame := range g.Frames {
builder.WriteString(frame.String())
if i != len(g.Frames)-1 {
builder.WriteString("\n")
}
}
builder.WriteString("ANIEND\n")
return builder.String()
}
// Parse extracts the Gani data from the incoming buffer
func (g *Gani) Parse(b []byte) error {
scanner := bufio.NewScanner(bytes.NewReader(b))
scanner.Scan()
// SPRITE lines
for scanner.Scan() {
if strings.EqualFold(scanner.Text(), "") {
break
}
sprite, err := NewSprite(scanner.Text())
if err != nil {
return err
}
g.Sprites = append(g.Sprites, sprite)
}
// Settings lines
for scanner.Scan() {
if strings.EqualFold(scanner.Text(), "") {
break
}
if err := g.Settings.Parse(scanner.Text()); err != nil {
return err
}
}
// ANI - ANIEND
for scanner.Scan() {
if strings.EqualFold(scanner.Text(), "ANI") {
continue
}
// Populate the Frame data
frame := NewFrame(g.Settings.SingleDirection)
for i := 0; i < 4; i++ {
err := frame.AppendPlacedSprites(scanner.Text(), FrameDirection(i))
if err != nil {
return err
}
if !scanner.Scan() {
break
}
// Break if we new-line or hit a wait/playsound
if strings.EqualFold(scanner.Text(), "") ||
strings.HasPrefix(scanner.Text(), "WAIT") ||
strings.HasPrefix(scanner.Text(), "PLAYSOUND") {
break
}
}
// Populate the WAIT & PLAYSOUND(s)
for !strings.EqualFold(scanner.Text(), "") && !strings.EqualFold(scanner.Text(), "ANIEND") {
if err := frame.ParseWaitOrSound(scanner.Text()); err != nil {
return err
}
if !scanner.Scan() {
break
}
}
g.Frames = append(g.Frames, frame)
// Reached the end
if strings.EqualFold(scanner.Text(), "ANIEND") {
break
}
}
return nil
}
// NewGani creates a new empty Gani
func NewGani() *Gani {
return &Gani{
Sprites: make([]*Sprite, 0),
Settings: NewSettings(),
Frames: make([]*Frame, 0),
header: "GANI0001",
}
}