Another night of .obj failure
This commit is contained in:
@@ -67,85 +67,71 @@ var (
|
||||
"j_tree2.obj", // ObjectHeader is completely empty
|
||||
"inven.obj", // Main header padding contains unknown values: [134744072 134744072 134744072]
|
||||
}
|
||||
objFrameMagic = uint32(0x014200D1)
|
||||
)
|
||||
|
||||
func init() {
|
||||
sort.Strings(objBlacklist)
|
||||
}
|
||||
|
||||
type FrameHeader struct {
|
||||
Magic uint32
|
||||
Width uint16 // FIXME: I'm not certain this is what these are. If they are, they may be the wrong way around
|
||||
Height uint16
|
||||
type SpriteHeader struct {
|
||||
Unknown0 uint32
|
||||
Width uint16 // FIXME: I'm not certain this is what these are.
|
||||
Height uint16 // FIXME: If they are, they may be the wrong way around
|
||||
Padding1 uint32 // I don't think this is used. Could be wrong.
|
||||
PixelSize uint32 // Size of PixelData, excluding this frame header
|
||||
PixelSize uint32 // Size of PixelData, excluding this sprite header
|
||||
Padding2 uint64 // I don't think this is used either. Could be wrong.
|
||||
}
|
||||
|
||||
func (f FrameHeader) Check(expectedSize uint32) error {
|
||||
// There seem to be different frame types, keyed by the magic value?
|
||||
// if f.Magic != objFrameMagic {
|
||||
// return fmt.Errorf("Unexpected magic value: %d (expected %d)", f.Magic, objFrameMagic)
|
||||
// }
|
||||
|
||||
if f.Padding1 != 0 || f.Padding2 != 0 {
|
||||
return fmt.Errorf("Frame header padding contains unknown values: %d %d", f.Padding1, f.Padding2)
|
||||
func (s SpriteHeader) Check(expectedSize uint32) error {
|
||||
if s.Padding1 != 0 || s.Padding2 != 0 {
|
||||
return fmt.Errorf("Sprite header padding contains unknown values: %d %d", s.Padding1, s.Padding2)
|
||||
}
|
||||
|
||||
// Remove 24 bytes from passed-in size to account for the header
|
||||
if f.PixelSize != expectedSize-24 {
|
||||
return fmt.Errorf("Advertised pixel size: %d differs from expected: %v", f.PixelSize, expectedSize-24)
|
||||
if s.PixelSize != expectedSize-24 {
|
||||
return fmt.Errorf("Advertised pixel size: %d differs from expected: %v", s.PixelSize, expectedSize-24)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type Frame struct {
|
||||
FrameHeader
|
||||
type Sprite struct {
|
||||
SpriteHeader
|
||||
|
||||
PixelData []byte
|
||||
}
|
||||
|
||||
type frameInfoHeader struct {
|
||||
Offset uint32 // Offset of the frame relative to the frame data segment
|
||||
Size uint32 // Size of the frame in bytes, including the header
|
||||
type dirEntry struct {
|
||||
Offset uint32 // Offset of the sprite relative to the data block
|
||||
Size uint32 // Size of the sprite in bytes, including any header
|
||||
}
|
||||
|
||||
func (f frameInfoHeader) Check() error {
|
||||
if f.Size < 24 {
|
||||
return fmt.Errorf("Unexpected frame size: %d (expected >= 24)", f.Size)
|
||||
func (d dirEntry) Check() error {
|
||||
if d.Size < 24 {
|
||||
return fmt.Errorf("Unexpected sprite size: %d (expected >= 24)", d.Size)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ObjectHeader totals 32 bytes on disk
|
||||
// ObjectHeader totals 24 bytes on disk
|
||||
type ObjectHeader struct {
|
||||
NumFrames uint32 // How many frames does this object have?
|
||||
MainHeaderSize uint32 // Number of bytes taken by this header. Should always be `32`
|
||||
FrameInfoSize uint32 // Number of bytes taken up by the next block. 8 * NumFrames
|
||||
FrameDataOffset uint32 // The starting point of the frame data
|
||||
FrameDataSize uint32 // frame data should take up this many bytes
|
||||
|
||||
Padding [3]uint32 // Unused, as far as I can see
|
||||
NumSprites uint32 // How many sprites does this object have?
|
||||
DirOffset uint32 // Offset of the directory block
|
||||
DirSize uint32 // Size of the directory block. 8 * NumSprites
|
||||
DataOffset uint32 // Offset of the sprite data block
|
||||
DataSize uint32 // Size of the sprite data block
|
||||
}
|
||||
|
||||
func (h ObjectHeader) ExpectedFrameInfoSize() uint32 {
|
||||
return h.NumFrames * 8
|
||||
func (h ObjectHeader) ExpectedDirSize() uint32 {
|
||||
return h.NumSprites * 8
|
||||
}
|
||||
|
||||
func (h ObjectHeader) Check() error {
|
||||
if h.MainHeaderSize != 32 {
|
||||
return fmt.Errorf("Unexpected main header size: %d (expected 32)", h.MainHeaderSize)
|
||||
}
|
||||
// TODO: check for overlaps
|
||||
|
||||
if h.ExpectedFrameInfoSize() != h.FrameInfoSize {
|
||||
return fmt.Errorf("Unexpected frame info size: %d (expected %d)", h.FrameInfoSize, h.ExpectedFrameInfoSize())
|
||||
}
|
||||
|
||||
if h.Padding[0] != 0 || h.Padding[1] != 0 || h.Padding[2] != 0 {
|
||||
return fmt.Errorf("Main header padding contains unknown values: %+v", h.Padding)
|
||||
if h.ExpectedDirSize() != h.DirSize {
|
||||
return fmt.Errorf("Unexpected sprite directory size: %d (expected %d)", h.DirSize, h.ExpectedDirSize())
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -155,7 +141,7 @@ type Object struct {
|
||||
ObjectHeader
|
||||
|
||||
Filename string
|
||||
Frames []*Frame
|
||||
Sprites []*Sprite
|
||||
}
|
||||
|
||||
func LoadObject(filename string) (*Object, error) {
|
||||
@@ -175,14 +161,17 @@ func LoadObject(filename string) (*Object, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Now load all frames into memory
|
||||
|
||||
framesInfo := make([]frameInfoHeader, out.NumFrames)
|
||||
if err := binary.Read(f, binary.LittleEndian, &framesInfo); err != nil {
|
||||
// Now load all sprites into memory
|
||||
dir := make([]dirEntry, out.NumSprites)
|
||||
if _, err := f.Seek(int64(out.DirOffset), io.SeekStart); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := f.Seek(int64(out.FrameDataOffset), io.SeekStart); err != nil {
|
||||
if err := binary.Read(f, binary.LittleEndian, &dir); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := f.Seek(int64(out.DataOffset), io.SeekStart); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -195,42 +184,38 @@ func LoadObject(filename string) (*Object, error) {
|
||||
|
||||
buf := bytes.NewReader(data)
|
||||
|
||||
for _, frameInfo := range framesInfo {
|
||||
if err := frameInfo.Check(); err != nil {
|
||||
for _, dirEntry := range dir {
|
||||
if err := dirEntry.Check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := buf.Seek(int64(frameInfo.Offset), io.SeekStart); err != nil {
|
||||
if _, err := buf.Seek(int64(dirEntry.Offset), io.SeekStart); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
frame := &Frame{}
|
||||
sprite := &Sprite{}
|
||||
|
||||
if err := binary.Read(buf, binary.LittleEndian, &frame.FrameHeader); err != nil {
|
||||
if err := binary.Read(buf, binary.LittleEndian, &sprite.SpriteHeader); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := frame.Check(frameInfo.Size); err != nil {
|
||||
if err := sprite.Check(dirEntry.Size); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// It's safe to assume that a `bytes.Reader` will always satisfy the
|
||||
// requested read size.
|
||||
frame.PixelData = make([]byte, frame.PixelSize)
|
||||
if _, err := buf.Read(frame.PixelData); err != nil {
|
||||
sprite.PixelData = make([]byte, sprite.PixelSize)
|
||||
if _, err := buf.Read(sprite.PixelData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out.Frames = append(out.Frames, frame)
|
||||
out.Sprites = append(out.Sprites, sprite)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func readObjFrame(f io.Reader, obj *Object) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func LoadObjects(dir string) (map[string]*Object, error) {
|
||||
fis, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user