C64 Styled Sprite Rendering Example
This snippet of code is recreating how C64 sprites are set out in memory. C64 Sprites have two basic modes, High resolution and MultiColour resolution.
High Resolution sprites are only one 1 colour. So each bit in the sprite represents a pixel on screen. The pixels are coloured either as the background colour (0 = transparent/ mask colour for us), or 1 for the Sprites unique colour. So a bit pattern of %0011 draws a pair of transparent pixels followed by a pair of 'sprite colour' pixels.
Multi colour sprites are 4 colour and half the horizontal resolution of high resolution sprites. They're the same on screen width (24 pixels), but in order to index the 4 possible colours, each pixel is made up from a pair of bits. Since it's using two bits per pixel, our numeric range increases from 2 possible states to 4 possible states
ie.
%00 = palette(0)
%01 = palette(1)
%10 = palette(2)
%11 = palette(3)
In this demo palette(0) is output images transparent colour, which will be black by default. Anyway the following bit pattern of %0011 draws two pixels (each is two pixels wide). The first pixel is %00 is palette(0) and thus the transparent colour and should be ignored, the second is %11 (Palette(3), which will be whatever colour passed to the function.
[pbcode]
; PROJECT : C64-Sprite-Render
; AUTHOR : Kevin Picone
; CREATED : 3/26/2013
; EDITED : 3/26/2013
; ---------------------------------------------------------------------
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; --[ C64 Styled Sprite Render (to IMage) ]-------------------------------------
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
Cls 255
; render to set of data out as an image
TestIMage =C64_Styled_Sprite_Render("TestSprite",$ffffff,$ff0000,$0000ff)
; draw the image
DrawImage TestImage,100,100,0
; render to set of data out as an image
RectIMage =C64_Styled_Sprite_Render("RectSprite",$ffffff,$ff0000,$0000ff)
; draw the image
DrawImage RectImage,200,100,0
sync
waitkey
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
; --[ C64 Styled Sprite Render (to IMage) ]-------------------------------------
; ------------------------------------------------------------------------------
; ------------------------------------------------------------------------------
;
; This Function draws a set of data statements that form an emulation of C64
; sprite memory is set out. C64 Sprites are 24 pixels by 21 rows high. Which
; isn't much to work with today given the resolution of the screens we use, but
; back then when lowres (320*200) was common, that resolution was reaonable.
;
; ------------------------------------------------------------------------------
; Since the c64 sprites are so small, this constant allows us to control
; the amount of linear scaling applied to the post processed image.
; Setting to 2 for example, will double the size of each pixel..
Constant C64_Sprite_Scalar =2
; Sprites can either be Hires (1 colour) or Mulicolour (4 colour)
; Multicolour sprites use bit pairs to get the colour index, this halves
; the resolution on the horizontal resolution
; Multicolour bit pairs
; %00 = Palete(0)
; %01 = Palete(1)
; %10 = Palete(2)
; %11 = Palete(3)
Constant HiRes_Sprite =1
Constant MultiColour_Sprite =2
Function C64_Styled_Sprite_Render(DataID$,Colour1,Colour2,COlour3)
oldsurface=getsurface()
oldpos=GetDataPOinter()
Restore DATAID$
SkipMe$=ReadData$()
ColourFormat = ReadData()
Thisimage=NewIMage(24,21,2)
Dim Palette(3)
Palette(0)=0
Palette(1)=Colour1
Palette(2)=Colour2
Palette(3)=Colour3
rendertoimage ThisImage
Lockbuffer
ThisRGB=POint(0,0)
For ylp =0 to 20
RowBits=ReadData()
Xpos=23
Select ColourFormat
case HiRes_Sprite
for Xpos=23 to 0 step -1
FastDot Xpos,ylp,Palette(RowBits and 1)
RowBits/=2
next
case MultiColour_Sprite
for Xpos=22 to 0 step -2
ThisRgb=Palette(RowBits and 3)
FastDot Xpos,ylp,ThisRGB
FastDot Xpos+1,ylp,ThisRGB
RowBits/=4
next
endselect
next
unLockbuffer
rendertoimage oldsurface
ScaleImage ThisImage,C64_Sprite_Scalar,C64_Sprite_Scalar,0
restore OldPos
EndFunction ThisIMage
; ---------------------------------------
; Sprite are 24*21 pixels so 3 bytes wide and 21 rows high
; ---------------------------------------
/*
Black Template sprite data
Data "SPRITE_1"
Data Colour format (Hires =1 , Multicolour=2)
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
*/
; -------------------------------------------------------------------
; -------------------------------------------------------------------
Data "TestSprite"
; -------------------------------------------------------------------
Data MultiColour_Sprite
Data %001101100000000000000000
Data %100001100000000000001100
Data %010001100000000000001100
Data %110001100000000000011000
Data %000001100000000000110000
Data %000001100000000001100000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
Data %000000000000000000000000
; -------------------------------------------------------------------
; -------------------------------------------------------------------
Data "RectSprite"
; -------------------------------------------------------------------
Data Hires_Sprite
Data %111111111111111111111111 ;0
Data %100000000000000000000001 ;1
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %100000000000000000000001
Data %111111111111111111111111
[/pbcode]
Related Articles:
* SPR File Decoder / Loader (http://www.underwaredesign.com/forums/index.php?topic=4019.0)
* Convert Bitplanes to Chunky pixels (http://www.underwaredesign.com/forums/index.php?topic=4040.0)