nori/frame.go

108 lines
2.1 KiB
Go

package nori
import (
"encoding/binary"
"io"
)
type Frame struct {
Duration uint32
PlaneCount uint32
Planes []*Plane
CoordinateCount uint32
Coordinates [][2]uint32
Unknown1 string
SoundEffect string
Unknown2 string
HasCamp bool
Camp struct {
Params [7]uint32
Array []byte
Extra string
}
Version int
}
func NewFrame(version int) *Frame {
return &Frame{Version: version}
}
func (f *Frame) Decode(rd io.Reader) error {
if err := binary.Read(rd, end, &f.Duration); err != nil {
return err
}
if err := binary.Read(rd, end, &f.PlaneCount); err != nil {
return err
}
f.Planes = make([]*Plane, int(f.PlaneCount))
for i := range f.Planes {
f.Planes[i] = &Plane{}
if err := f.Planes[i].Decode(rd); err != nil {
return err
}
}
if f.Version != 300 {
if err := binary.Read(rd, end, &f.CoordinateCount); err != nil {
return err
}
f.Coordinates = make([][2]uint32, f.CoordinateCount)
for i := range f.Coordinates {
if err := binary.Read(rd, end, f.Coordinates[i][:]); err != nil {
return err
}
}
}
switch f.Version {
case 300, 301:
if err := discardN(rd, 144); err != nil {
return err
}
case 302, 303:
if err := discardN(rd, 96); err != nil {
return err
}
}
if f.Version >= 302 {
// entry blocks
if err := discardN(rd, 28*6); err != nil {
return err
}
}
// unknown1
if err := discardN(rd, 44); err != nil {
return err
}
//sound_effect
if err := discardN(rd, 18); err != nil {
return err
}
// unknown2
if err := discardN(rd, 18); err != nil {
return err
}
if f.Version >= 303 {
var cast uint32
if err := binary.Read(rd, end, &cast); err != nil {
return err
}
// camp
f.HasCamp = cast > 0
if f.HasCamp {
if err := binary.Read(rd, end, f.Camp.Params[:]); err != nil {
return err
}
sz := int(f.Camp.Params[1]) * int(f.Camp.Params[2])
f.Camp.Array = make([]byte, sz)
if _, err := io.ReadFull(rd, f.Camp.Array); err != nil {
return err
}
if err := discardN(rd, 20); err != nil {
return err
}
}
}
return nil
}