News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

SPR File Decoder / Loader

Started by kevin, March 12, 2013, 08:46:07 AM

Previous topic - Next topic

kevin

 SPR File Decoder / Loader

   This example decodes null byte compressed palette mapped sprites from constructor into a series of regular RGB images.  The convertor doesn't include a palette decoder, since that data isn't stored within the sprite file,  it's housed else where.  But the format is just IFF so loading them is trivial, I just don't have the required file, so haven't bothered.

  Info on the sprite format can be found here
  https://github.com/shlainn/game-file-formats/wiki/Constructor-.SPR-files



PlayBASIC Code: [Select]
   ; File to decode
file$="Location_Of_File_Here.spr"

// ---------------------------------------------------------
// Here we're building a shaded palette in whatever colour we want
// since sprite files don't actually contain the palette data in them
// the palette is stored in a different file.

// Link to a SPR format dizzy
// https://github.com/shlainn/game-file-formats/wiki/Constructor-.SPR-files
// ---------------------------------------------------------

Dim Palette(255)
For lp =0 to 255
Palette(lp)=rgbalphamult(rgb(lp,lp,lp),$ffffff)
next

// Load the Sprite file into a bank
Bank=LoadFileToBank(file$)


// DIm the array that will hold the converted frames
Dim Sprites(0)

// Decode the raw frames
Sprites()=Decode_Sprites(Bank,Palette())

// The bank is no longer needed so delete it
deleteBank Bank





; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; -[ MAIN LOOP ]-------------------------------------------------------
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------

SetFps 60

Frame=1

Maxframes=GetArrayElements(Sprites())

Do

;clear screen to black
Cls

; check for up arrow
if upkey() and Frame>1
Frame--
endif

; check for down arrow
if downkey() and Frame<MaxFrames
Frame++
endif

; get the image of this frame
ThisImage=Sprites(Frame)

if ThisIMage
Width#=GetImageWidth(ThisImage)
Height#=GetImageWidth(ThisImage)
drawRotatedimage ThisIMage,400,300,0,2,2,Width#/-2,Height#/-2,false
endif

print "Sprite frame#"+str$(frame)+" of #"+str$(MaxFrames)

sync
loop


; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; -[ Decode Sprites ]-------------------------------------------------------
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------

Function Decode_Sprites(SpriteBank,Palette())

Dim Frames(0)

if GetBankStatus(SpriteBank)

SpriteBankSize=GetBankSize(SpriteBank)

if SpriteBankSize>4

NumberOfFrames = PeekBankInt(SpriteBank, 0 ) ; read integer from mem block at offset 0

DIm Frames(NumberOfFrames)

print NumberOfFrames


// -------------------------------------
// decode frames
// -------------------------------------
For framelp=0 to NumberOfFrames-1

// Get the offset with the mem block of where this frame starts
FrameDataOffset = PeekBankInt(SpriteBank, 4+(FrameLp*4) )

// does this frame have any data ?
if FrameDataOffset<>0
#print FrameDataOffset


// --------------------------------------------------------------------------------
// decompress frame, here i'm assuming the frame offset is relative to the start
// of the file, it might be relative to it's position it the sprite table
// --------------------------------------------------------------------------------

// Grab the info about the sprite from it's header.

FrameWidth=PeekBankWORD(SpriteBank, FrameDataOffset + 4 )
FrameHeight=PeekBankWORD(SpriteBank, FrameDataOffset + 6 )

// calc current /start offset of the compressed pixel data for this frame
PixelDataAddress =FrameDataOffset + 8

// Alloc a bank to store the temp pixel data.
// it's probably a good idea to pad this, just in case :)

DecompressedBank = NewBank( (FrameWidth+1) * FrameHeight)

#print FrameWidth
#print FrameHeight
#print DecompressedBank
#print ""


// --------------------------------------------------------------------------------
// decode the pixel data that makes up to this frame into the temp bank
// --------------------------------------------------------------------------------

MaxPixelCount = FrameWidth * FrameHeight
PixelCount =0


repeat
// read the pixel
ThisPixel = PeekBankByte(SpriteBank, PixelDataAddress)

Login required to view complete source code



Related Articles:

    * C64 Styled Sprite Rendering Example
    * Palette Mapped / Raster Bar Examples
    * LowRES PlayBASIC - 8bit Retro Graphics Library
     * Challenge #27 -  Learn binary operations through Retro Computer Graphics