-
Notifications
You must be signed in to change notification settings - Fork 6
/
spritehard.go
110 lines (101 loc) · 2.77 KB
/
spritehard.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
package spritehard
import (
"encoding/binary"
"errors"
"image"
"image/color"
"io"
"os"
"github.com/jeromelesaux/m4client/cpc"
"github.com/jeromelesaux/martine/config"
"github.com/jeromelesaux/martine/export/amsdos"
"github.com/jeromelesaux/martine/export/compression"
"github.com/jeromelesaux/martine/log"
)
type SpriteHard struct {
Data [256]byte
}
type SprImpdraw struct {
Data []SpriteHard
}
func (s *SprImpdraw) Images(pal color.Palette) []*image.NRGBA {
imgs := make([]*image.NRGBA, 0)
for _, v := range s.Data {
imgs = append(imgs, v.Image(pal))
}
return imgs
}
func (s *SpriteHard) Image(pal color.Palette) *image.NRGBA {
img := image.NewNRGBA(image.Rectangle{Min: image.Point{0, 0}, Max: image.Point{16, 16}})
var index int
for y := 0; y < 16; y++ {
for x := 0; x < 16; x++ {
var c color.Color = color.Black
if index < len(s.Data) && int(s.Data[index]) < len(pal) {
c = pal[int(s.Data[index])]
}
img.Set(x, y, c)
index++
}
}
return img
}
func OpenSpr(filePath string) (*SprImpdraw, error) {
spr := SprImpdraw{Data: make([]SpriteHard, 0)}
fr, err := os.Open(filePath)
if err != nil {
log.GetLogger().Error("Error while opening file (%s) error %v\n", filePath, err)
return &spr, err
}
header := &cpc.CpcHead{}
if err := binary.Read(fr, binary.LittleEndian, header); err != nil {
log.GetLogger().Error("Cannot read the Sprite Hard Amsdos header (%s) with error :%v, trying to skip it\n", filePath, err)
_, err := fr.Seek(0, io.SeekStart)
if err != nil {
return &spr, err
}
}
if header.Checksum != header.ComputedChecksum16() {
log.GetLogger().Error("Cannot read the Sprite Hard Amsdos header (%s) with error :%v, trying to skip it\n", filePath, err)
_, err := fr.Seek(0, io.SeekStart)
if err != nil {
return &spr, err
}
}
for {
spriteHard := SpriteHard{}
if err = binary.Read(fr, binary.LittleEndian, &spriteHard); err != nil {
if errors.Is(err, io.EOF) {
break
} else {
log.GetLogger().Error("Error while opening file (%s) error %v\n", filePath, err)
return &spr, err
}
}
spr.Data = append(spr.Data, spriteHard)
}
return &spr, nil
}
func Spr(filePath string, spr SprImpdraw, cfg *config.MartineConfig) error {
osFilename := cfg.AmsdosFullPath(filePath, ".SPR")
log.GetLogger().Info("Saving SPR file (%s)\n", osFilename)
content := make([]byte, 0)
for _, v := range spr.Data {
content = append(content, v.Data[:]...)
}
content, _ = compression.Compress(content, cfg.Compression)
ext := ".SPR"
if cfg.Compression != compression.NONE {
ext = ".SPR.zxo"
}
if !cfg.NoAmsdosHeader {
if err := amsdos.SaveAmsdosFile(osFilename, ext, content, 2, 0, 0x0, 0x4000); err != nil {
return err
}
} else {
if err := amsdos.SaveOSFile(osFilename, content); err != nil {
return err
}
}
return nil
}