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 }