huh
This commit is contained in:
parent
47850d7b13
commit
4057b3c3c6
|
@ -13,7 +13,7 @@ type Frame struct {
|
|||
CoordinateCount uint32
|
||||
Coordinates [][2]uint32
|
||||
Unknown1 string
|
||||
Sound_effect string
|
||||
SoundEffect string
|
||||
Unknown2 string
|
||||
Camp CampSection
|
||||
}
|
||||
|
@ -23,8 +23,17 @@ type CampSection struct {
|
|||
Extra string
|
||||
}
|
||||
|
||||
type Plane struct {
|
||||
BitmapId uint32
|
||||
PlaneX int32
|
||||
PlaneY int32
|
||||
Opacity uint32
|
||||
Blend BlendMode
|
||||
FlagParam uint32
|
||||
RenderFlag uint32
|
||||
}
|
||||
type Animation struct {
|
||||
Title string
|
||||
Title [32]byte
|
||||
|
||||
// std::vector<uint32> frame_offsets
|
||||
FrameCount uint32
|
||||
|
@ -32,9 +41,15 @@ type Animation struct {
|
|||
}
|
||||
|
||||
func (a *Animation) Decode(rd *bufio.Reader, version int) error {
|
||||
if err := binary.Read(rd, end, a.Title[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := binary.Read(rd, end, &a.FrameCount); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := rd.Discard(4 * int(a.FrameCount)); err != nil {
|
||||
return err
|
||||
}
|
||||
a.Frames = make([]*Frame, int(a.FrameCount))
|
||||
for i := range a.Frames {
|
||||
cf := &Frame{}
|
||||
|
@ -42,29 +57,31 @@ func (a *Animation) Decode(rd *bufio.Reader, version int) error {
|
|||
if err := binary.Read(rd, end, &cf.Duration); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := binary.Read(rd, end, &cf.PlaneCount); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cf.Planes = make([]*Plane, int(cf.PlaneCount))
|
||||
for i := range cf.Planes {
|
||||
cp := &Plane{}
|
||||
cf.Planes[i] = cp
|
||||
if err := binary.Read(rd, end, &cp.BitmapId); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := binary.Read(rd, end, &cp.PlaneX); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := binary.Read(rd, end, &cp.PlaneY); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := binary.Read(rd, end, &cp.Opacity); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := binary.Read(rd, end, &cp.RenderFlag); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := binary.Read(rd, end, &cp.Blend); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := binary.Read(rd, end, &cp.FlagParam); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -75,7 +92,10 @@ func (a *Animation) Decode(rd *bufio.Reader, version int) error {
|
|||
}
|
||||
cf.Coordinates = make([][2]uint32, cf.CoordinateCount)
|
||||
for i := range cf.Coordinates {
|
||||
if err := binary.Read(rd, end, cf.Coordinates[i]); err != nil {
|
||||
if err := binary.Read(rd, end, &cf.Coordinates[i][0]); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := binary.Read(rd, end, &cf.Coordinates[i][1]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -112,9 +132,9 @@ func (a *Animation) Decode(rd *bufio.Reader, version int) error {
|
|||
if err := binary.Read(rd, end, &cast); err != nil {
|
||||
return err
|
||||
}
|
||||
if version > 303 && (cast > 1) {
|
||||
if version >= 303 && (cast > 0) {
|
||||
cf.Camp = CampSection{}
|
||||
if err := binary.Read(rd, end, &cf.Camp.Params); err != nil {
|
||||
if err := binary.Read(rd, end, cf.Camp.Params[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
sz := int(cf.Camp.Params[1]) * int(cf.Camp.Params[2])
|
||||
|
@ -122,17 +142,10 @@ func (a *Animation) Decode(rd *bufio.Reader, version int) error {
|
|||
if _, err := io.ReadFull(rd, cf.Camp.Array); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := rd.Discard(20); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Plane struct {
|
||||
Bitmap_id uint32
|
||||
PlaneX int32
|
||||
PlaneY int32
|
||||
Opacity uint32
|
||||
Blend BlendMode
|
||||
FlagParam uint32
|
||||
RenderFlag uint32
|
||||
}
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
package nori
|
||||
|
||||
import "gitlab.com/gfxlabs/gfximg/apng"
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/draw"
|
||||
|
||||
func (n *Nori) ExportAnimation() *apng.APNG {
|
||||
"git.tuxpa.in/a/zlog/log"
|
||||
"gitlab.com/gfxlabs/gfximg/apng"
|
||||
)
|
||||
|
||||
func (n *Nori) ShowAnimation() *apng.APNG {
|
||||
g := n.Gawi
|
||||
a := &apng.APNG{
|
||||
Frames: make([]apng.Frame, 0, len(g.Images)),
|
||||
}
|
||||
for i := 0; i < len(g.Images); i++ {
|
||||
fr := apng.Frame{
|
||||
Image: g.Images[i].Frame,
|
||||
Image: g.Images[i].Img,
|
||||
DelayNumerator: uint16(g.Images[i].Delay),
|
||||
DelayDenominator: 1000,
|
||||
}
|
||||
|
@ -17,3 +24,60 @@ func (n *Nori) ExportAnimation() *apng.APNG {
|
|||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func (n *Nori) ExportAnimation() (*apng.APNG, error) {
|
||||
g := n.Gawi
|
||||
a := &apng.APNG{
|
||||
Frames: make([]apng.Frame, 0, len(g.Images)),
|
||||
}
|
||||
for i := 0; i < len(n.Animations); i++ {
|
||||
for _, v := range n.Animations[i].Frames {
|
||||
canvasRect := image.Rect(0, 0, 0, 0)
|
||||
for _, plane := range v.Planes {
|
||||
if int(plane.BitmapId) >= len(n.Gawi.Images) {
|
||||
log.Printf("could not find bitmap %d, only have %d", plane.BitmapId, len(n.Gawi.Images))
|
||||
}
|
||||
bitmap := n.Gawi.Images[plane.BitmapId]
|
||||
canvasRect = canvasRect.Union(bitmap.Img.Bounds())
|
||||
}
|
||||
img := image.NewRGBA64(canvasRect)
|
||||
for _, plane := range v.Planes {
|
||||
bitmap := n.Gawi.Images[plane.BitmapId]
|
||||
transparent := false
|
||||
//flipx
|
||||
if plane.RenderFlag&1 != 0 {
|
||||
}
|
||||
//flipy
|
||||
if plane.RenderFlag&2 != 0 {
|
||||
}
|
||||
// is transparent
|
||||
if plane.RenderFlag&0x20 != 0 {
|
||||
transparent = true
|
||||
}
|
||||
_ = transparent
|
||||
switch plane.Blend {
|
||||
case BlendMode_Alpha:
|
||||
case BlendMode_Mul, BlendMode_Mul7:
|
||||
case BlendMode_Add, BlendMode_Add8:
|
||||
case BlendMode_InvertMul, BlendMode_InvertMul5:
|
||||
case BlendMode_None:
|
||||
break
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown blend mode: %d", plane.Blend)
|
||||
}
|
||||
draw.Draw(img,
|
||||
img.Rect,
|
||||
bitmap.Img,
|
||||
image.Point{X: int(plane.PlaneX),
|
||||
Y: int(plane.PlaneY)}, draw.Over)
|
||||
}
|
||||
fr := apng.Frame{
|
||||
Image: g.Images[i].Img,
|
||||
DelayNumerator: uint16(g.Images[i].Delay),
|
||||
DelayDenominator: 1000,
|
||||
}
|
||||
a.Frames = append(a.Frames, fr)
|
||||
}
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
|
|
@ -22,13 +22,12 @@ type Image struct {
|
|||
Size uint32
|
||||
Data []byte
|
||||
|
||||
Frame image.Image
|
||||
Img image.Image
|
||||
}
|
||||
|
||||
|
||||
func (i *Image) Decode(rd *bufio.Reader, palette *PaletteSection) error {
|
||||
cf := image.NewRGBA64(image.Rect(0, 0, int(i.Width), int(i.Height)))
|
||||
i.Frame = cf
|
||||
i.Img = cf
|
||||
switch i.Bpp {
|
||||
case 8:
|
||||
if palette == nil {
|
||||
|
@ -80,4 +79,3 @@ func (i *Image) Decode(rd *bufio.Reader, palette *PaletteSection) error {
|
|||
return fmt.Errorf("unsupported bpp, %d", i.Bpp)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,43 +12,53 @@ import (
|
|||
func TestParseFile1(t *testing.T) {
|
||||
rd, err := os.OpenFile("./nori_test/test1.nri", os.O_RDONLY, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("open file: %s", err)
|
||||
t.Errorf("open file: %s", err)
|
||||
}
|
||||
nori, err := NewReader(rd).Decode()
|
||||
if err != nil {
|
||||
t.Fatalf("decode: %s", err)
|
||||
t.Errorf("decode: %s", err)
|
||||
}
|
||||
t.Logf("\n nori: %+v", nori)
|
||||
t.Logf("\n gawi: %+v", nori.Gawi)
|
||||
a, err := nori.ExportAnimation()
|
||||
if err != nil {
|
||||
t.Errorf("export: %s", err)
|
||||
}
|
||||
t.Logf("\n nori: %+v\n gawi: %+v", nori, nori.Gawi)
|
||||
a := nori.ExportAnimation()
|
||||
writeApng(a, "./nori_test/test1.apng")
|
||||
}
|
||||
|
||||
func TestParseFile2(t *testing.T) {
|
||||
rd, err := os.OpenFile("./nori_test/test2.nri", os.O_RDONLY, 0666)
|
||||
if err != nil {
|
||||
t.Fatalf("open file: %s", err)
|
||||
t.Errorf("open file: %s", err)
|
||||
}
|
||||
nori, err := NewReader(rd).Decode()
|
||||
if err != nil {
|
||||
t.Fatalf("decode: %s", err)
|
||||
t.Errorf("decode: %s", err)
|
||||
}
|
||||
t.Logf("\n nori: %+v\n gawi: %+v", nori, nori.Gawi)
|
||||
a := nori.ExportAnimation()
|
||||
a, err := nori.ExportAnimation()
|
||||
if err != nil {
|
||||
t.Errorf("export: %s", err)
|
||||
}
|
||||
|
||||
writeApng(a, "./nori_test/test2.apng")
|
||||
}
|
||||
|
||||
func TestParsePalette(t *testing.T) {
|
||||
rd, err := os.OpenFile("./nori_test/palette.nri", os.O_RDONLY, 0666)
|
||||
if err != nil {
|
||||
t.Logf("open file: %s", err)
|
||||
t.Fail()
|
||||
t.Errorf("open file: %s", err)
|
||||
}
|
||||
nori, err := NewReader(rd).Decode()
|
||||
if err != nil {
|
||||
t.Errorf("decode: %s", err)
|
||||
}
|
||||
t.Logf("\n nori: %+v\n gawi: %+v\n palette: %+v\n", nori, nori.Gawi, nori.Gawi.Palette)
|
||||
a := nori.ExportAnimation()
|
||||
a, err := nori.ExportAnimation()
|
||||
if err != nil {
|
||||
t.Errorf("export: %s", err)
|
||||
}
|
||||
writeApng(a, "./nori_test/palette.apng")
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 969 KiB After Width: | Height: | Size: 1.9 MiB |
|
@ -26,28 +26,28 @@ func NewReader(rd io.Reader) *Reader {
|
|||
|
||||
func (n *Reader) Decode() (*Nori, error) {
|
||||
if _, err := io.ReadFull(n, n.nori.lastSignature[:]); err != nil {
|
||||
return nil, err
|
||||
return n.nori, err
|
||||
}
|
||||
if sig, target := string(n.nori.lastSignature[:]), "NORI"; sig != target {
|
||||
return nil, fmt.Errorf("expected header %s, got %s", target, sig)
|
||||
return n.nori, fmt.Errorf("expected header %s, got %s", target, sig)
|
||||
}
|
||||
if err := binary.Read(n, end, &n.nori.Version); err != nil {
|
||||
return nil, err
|
||||
return n.nori, err
|
||||
}
|
||||
if err := binary.Read(n, end, n.nori.Params[:]); err != nil {
|
||||
return nil, err
|
||||
return n.nori, err
|
||||
}
|
||||
if err := binary.Read(n, end, &n.nori.AnimationCount); err != nil {
|
||||
return nil, err
|
||||
return n.nori, err
|
||||
}
|
||||
if err := binary.Read(n, end, &n.nori.SizeNoGawi); err != nil {
|
||||
return nil, err
|
||||
return n.nori, err
|
||||
}
|
||||
if err := binary.Read(n, end, &n.nori.TotalSize); err != nil {
|
||||
return nil, err
|
||||
return n.nori, err
|
||||
}
|
||||
if err := n.decodeGawi(); err != nil {
|
||||
return nil, err
|
||||
return n.nori, err
|
||||
}
|
||||
return n.nori, nil
|
||||
}
|
||||
|
@ -117,6 +117,12 @@ func (n *Reader) decodeGawi() error {
|
|||
return err
|
||||
}
|
||||
n.nori.Animations = make([]*Animation, n.nori.AnimationCount)
|
||||
for i := range n.nori.Animations {
|
||||
n.nori.Animations[i] = &Animation{}
|
||||
if err := n.nori.Animations[i].Decode(n.r, int(n.nori.Version)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue