108 lines
2.1 KiB
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
|
|
}
|