Sprites2Go - C64 Sprite


Tweet blitz3d blitzbasic graphics retro code-archives
(Posted 5 months ago) RonTek

With this addon, you can have the Sprites drawn in your code, or have the Sprites, like they were used on the Commodore 64 machines,in the Data code.

Collision detection is not implemented, youll have to write one for your game, see below.

Image

Author: Dan

Usage:

First youll need to add collors to the Palette.

Call AddPal (Red,Green,Blue) with the desired values, in the range of 0 to 255 ($0-$ff), multiple times.
The first addpal entry will always be transparent, and is drawn with the space key. (" ")
You can add up to 64 colors.

Then you can use either c64ds() or c64datspr() functions to draw your sprites.

The standard commodore 64 sprite settings are used here, which is 24x21.

C64ds (dat$,newspr):

to draw 1 sprite you need to use this function 21 times.

Colors used are defined as chars from left to right: " "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

To draw an transparent pixel, you should use " ", Color number 1 would then be 0, Color #2 would be 1, color #11 = a and so on.

here is a small example:

C64ds (" 1");1
c64ds (" 11");2..
c64ds (" 222");20
c64ds ("fFfF");21 <- f and F are different colors ! (if defined by the AddPal() function)

Dat$ shall contain, (if not changed) up to 24 chars. To save bytes, transparent pixels to the right side, can be left out:

E.g.: c64ds (" 111122223333 ") can be written as c64ds (" 111122223333")
edit c64ds (" 111122223333 ") above has 8x" " after the 3333 !

and if the whole line contains only transparent pixels, then it can be written as c64ds (" ")

The newspr flag can be used to start a new Sprite drawing, (the old sprite will, then, be saved to a larger bitmap).
You do not need to use the newspr flag, if your sprites have 21 lines each.
At the 22th line, the sprite will be automaticaly stored to a larger bitmap!

C64datspr(dat,newsprite,color1,multicolor=2,color3) :

dat can be a number between 0 and 255, which represents, in the binary format, the pixels which will be drawn. (see C64 sprite data format : here )

If not changed, youll need to provide 3 Bytes of data for each Sprite line, 21 lines (which are standard setting)

newsprite can be used to start a new sprite, but can be left to 0, if you provide the 21 lines of data (which will automaticaly start the new sprite)

C64 sprites, in hires mode have only 2 colors. so for hires sprites there is only transparent and the color1 (1-63) - from your palete.

If your sprite data is in Multicolor format, which is Lowres, you have to set the multicolor and color3 flag to the number from your palette.
This will draw in the lowres format.

There is no error checking at all, so basicaly you can switch between lowres and hires colors (which is not possibile on the Real c64.

The only limitation is, if you draw a sprite, you can have only C64datspr or c64ds lines for one sprite, using them after eachother will start a new sprite.

c64_finalize()

Needs to be called,without parameter , after the last sprite is drawn ((after the last c64datspr or c64ds) to complete the copying process to the larger bitmap)

c64drawsprite (nr,x,y)

This will draw an image of the sprite to the Current Buffer.

If you need to do Collision check, then youll need to do something like this for each sprite on the screen:

;pseudo code, this is not tested 
spr1=CreateImage (c64i\spr_width,c64i\spr_height)
spr2=CreateImage (c64i\spr_width,c64i\spr_height)
...
setbuffer imageBuffer(spr1)
c64drawsprite(nr)

setbuffer imageBuffer(spr2)
c64drawsprite(nr)

if ImagesCollide (spr1,x,y,0,spr2,x,y,0) 
   ;collision 
EndIf

The last function, which can be used in your program, to access the colors of the palette is:

c64color(nr) (which is same as Color $xx,$xx,$xx)

And a Demo, which says more than 1000 words:

;Screen (320,350,1)
Graphics 320,250,32,6
Graphics 320,250,32,7   ;Make the Resizeable window 

Include "c64sprite_inc.bb"
SeedRnd MilliSecs()

temp=Rand(0,1) ; Each start use a randomly choosen Palette : 

;here are 2 WinVice modified palettes:

If temp=1
    AddPal ($00,$00,$00) ; transparent  " "
    AddPal ($01,$00,$00) ; Black        0
    AddPal ($FF,$FF,$FF) ; White        1
    AddPal ($88,$20,$00) ; Red          2
    AddPal ($68,$d0,$a8) ; Cyan         3
    AddPal ($a8,$38,$a0) ; Purple       4
    AddPal ($50,$b8,$18) ; Green        5
    AddPal ($18,$10,$90) ; Blue         6
    AddPal ($f0,$e8,$58) ; Yellow       7
    AddPal ($a0,$48,$00) ; Orange       8
    AddPal ($47,$2b,$1b) ; Brown        9
    AddPal ($c8,$78,$70) ; Light Red    a
    AddPal ($48,$48,$48) ; Dark Gray    b
    AddPal ($80,$80,$80) ; Medium Gray  c
    AddPal ($98,$ff,$98) ; Light Green  d
    AddPal ($50,$90,$d0) ; Light Blue   e
    AddPal ($b8,$b8,$b8) ; Light Gray   f
Else
    Restore paldat
    For x=1 To 17
        Read r,g,b
        addpal(r,g,b)
    Next
EndIf

.paldat
Data $0,$0,$0, $00,$00,$01 ,$FF,$FF,$FF ,$68,$37,$2b ,$70,$a4,$b2 ,$6f,$3d,$86 ,$58,$8d,$43 ,$35,$28,$79 ,$b8,$c7,$6f ,$6f,$4f,$25 ,$43,$39,$00 ,$9a,$67,$59 ,$44,$44,$44 ,$6c,$6c,$6c ,$9a,$d2,$84 ,$6c,$5e,$b5 ,$95,$95,$95 


;To display the Template correctly, use Fixed width font, like "Courier New","Lucida Console" or "Terminal"
; this is 24x21 template
;X=     123456789012345678901234      v-- y
;c64ds("                        ",1);01         ;Template ! use overwrite mode to draw inside ""
;C64DS("                        ")  ;02         ;,1 Starts a new sprite drawing
;c64ds("                        ")  ;03         ;if the whole line is transparent, you can use " " instead
;c64ds("                        ")  ;04
;c64ds("                        ")  ;05
;c64ds("                        ")  ;06
;c64ds("                        ")  ;07
;c64ds("                        ")  ;08
;c64ds("                        ")  ;09
;c64ds("                        ")  ;10
;c64ds("                        ")  ;11
;c64ds("                        ")  ;12
;c64ds("                        ")  ;13
;c64ds("                        ")  ;14
;c64ds("                        ")  ;15
;c64ds("                        ")  ;16
;c64ds("                        ")  ;17
;c64ds("                        ")  ;18
;c64ds("                        ")  ;19
;c64ds("                        ")  ;20
;c64ds("                        ")  ;21

.again
For z=1 To 1                    ;Increase this to 250 or 500 to test multiple sprite pages (will be 250*10 sprites in this case!)
    temp=(temp+1) Mod 10            ;make the program responsive, while reading data (for large for z= loop !)
    If temp=1 Then Delay 2

    ;Theese are test sprites, with added pixels, to see if they were drawn correctly
    c64ds ("  ffffffffffffffffffff  ");1
    c64ds ("                        ");2
    c64ds ("   111111111111111111   ");3
    c64ds ("  1                  1  ");4
    c64ds (" 1                    1 ");5
    c64ds (" 1   2222      2222   1 ");6
    c64ds (" 1  2    2    222222  1 ");7
    c64ds (" 1  2 77 2    222222  1 ");8
    c64ds (" 1  2    2    222222  1 ");9
    c64ds (" 1   2222      2222   1 ");10
    c64ds (" 1                    1 ");11
    c64ds (" 1                    1 ");12
    c64ds (" 1                    1 ");13
    c64ds (" 1                    1 ");14
    c64ds (" 1  34            43  1 ");15
    c64ds (" 1   34444444444443   1 ");16
    c64ds (" 1    333333333333    1 ");17
    c64ds (" 1                    1 ");18
    c64ds ("  1                  1  ");19
    c64ds ("   111111111111111111   ");20
    c64ds ("                        ");21

    c64ds ("3                      3")  ;1
    c64ds (" ")                         ;2
    c64ds ("   111111111111111111   ")  ;3
    c64ds ("  1                  1  ")  ;4
    c64ds (" 1                    1 ")  ;5
    c64ds (" 1   2222      2222   1 ")  ;6
    c64ds (" 1  2    2    2    2  1 ")  ;7
    c64ds (" 1  2 77 2    2 77 2  1 ")  ;8
    c64ds (" 1  2    2    2    2  1 ")  ;9
    c64ds (" 1   2222      2222   1 ")  ;10
    c64ds (" 1                    1 ")  ;11
    c64ds (" 1                    1 ")  ;12
    c64ds (" 1                    1 ")  ;13
    c64ds (" 1                    1 ")  ;14
    c64ds (" 1  34            43  1 ")  ;15
    c64ds (" 1   34444444444443   1 ")  ;16
    c64ds (" 1    333333333333    1 ")  ;17
    c64ds (" 1                    1 ")  ;18
    c64ds ("  1                  1  ")  ;19
    c64ds ("   111111111111111111   ")  ;20
    c64ds ("3                      3")  ;21

    c64ds ("         3333333        ");1
    c64ds ("       33333333333      ");2
    c64ds ("      3333333333333     ");3
    c64ds ("      33333   33333     ");4
    c64ds ("     33333 333   333    ");5
    c64ds ("     33333 333 33333    ");6
    c64ds ("4    33333 333   333   5");7
    c64ds ("4     33333   33333    6");8
    c64ds ("      3333333333333    7");9
    c64ds ("      3333333333333     ");10
    c64ds ("      3 333333333 3     ");11
    c64ds ("       3 3333333 3      ");12
    c64ds ("       3  33333  3      ");13
    c64ds ("        3  333  3       ");14
    c64ds ("        3  333  3       ");15
    c64ds ("         3  3  3        ");16
    c64ds ("         3  3  3        ");17
    c64ds ("          33333         ");18
    c64ds ("          33333         ");19
    c64ds ("          33333         ");20
    c64ds ("           333          ");21

    Restore spr

    For x=1 To 63                       ;Multicolor sprite data
        Read dat
        c64datspr(dat,0,2,5,8)
    Next 

    For y=1 To 3                        ;There are 3 sprite animations to read 
        ;testc=Rand(2,c64i\palcount)    ;Random color
        testc=2                         ;Fixed color (here 2 - white)

        For x=1 To 63                   ;Read 1 sprite data
            Read dat
            c64datspr(dat,x<2,testc)    ;x<2 here makes 1, if x is less than 2, or 0, if x is greater number
        Next 
    Next ;y

    c64ds ("111111111111111111111111");1
    c64ds ("222221222222222222222222");2
    c64ds ("333333233333333333333333");3
    c64ds ("444444434444444444444444");4
    c64ds ("555555554555555555555555");5
    c64ds ("666666666566666666666666");6
    c64ds ("777777777767777777777777");7
    c64ds ("888888888887888888888888");8
    c64ds ("999999999999899999999999");9
    c64ds ("aaaaaaaaaaaaa9aaaaaaaaaa");10
    c64ds ("abbbbbbbbbbbbbabbbbbbbba");11
    c64ds ("accccccccccccccbccccccca");12
    c64ds ("ddddddddddddddddcddddddd");13
    c64ds ("eeeeeeeeeeeeeeeeedeeeeee");14
    c64ds ("ffffffffffffffffffefffff");15
    c64ds ("gggggggggggggggggggfgggg");16 - Unused palette entries are drawn as transparent pixels !
    c64ds ("hhhhhhhhhhhhhhhhhhhhghhh");17
    c64ds ("iiiiiiiiiiiiiiiiiiiiihii");18
    c64ds ("jjjjjjjjjjjjjjjjjjjjjjij");19
    c64ds ("kkkkkkkkkkkkkkkkkkkkkkkj");20
    c64ds ("llllllllllllllllllllllll");21

    c64ds ("cc       bbbbbbb      cd");1
    c64ds ("cc     bbbbbbbbbbb    cd");2
    c64ds ("cc    bbbbbbbbbbbbb   cd");3
    c64ds ("cc    bbbbb   bbbbb   cd");4
    c64ds ("cc   bbbbb bbb  bbbb  cd");5
    c64ds ("cc   bbbbb bbb bbbbb  cd");6
    c64ds ("cc   bbbbb bbb  bbbb  cd");7
    c64ds ("cc    bbbbb   bbbbb   cd");8
    c64ds ("cc    bbbbbbbbbbbbb   cd");9
    c64ds ("cc    bbbbbbbbbbbbb   cd");10
    c64ds ("cc    b bbbbbbbbb b   cd");11
    c64ds ("cc     b bbbbbbb b    cd");12
    c64ds ("cc     b  bbbbb  b    cd");13
    c64ds ("cc      b  bbb  b     cd");14
    c64ds ("cc      b  bbb  b     cd");15
    c64ds ("cc       b  b  b      cd");16
    c64ds ("cc       b  b  b      cd");17
    c64ds ("cc        bbbbb       cd");18
    c64ds ("cc        bbbbb       cd");19
    c64ds ("cc        bbbbb       cd");20
    c64ds ("cc         bbb        cd");21

    c64ds ("         ccccccc        ");1
    c64ds ("       ccccccccccc      ");2
    c64ds ("      ccccccccccccc     ");3
    c64ds ("      cccc   cccccc     ");4
    c64ds ("     cccc cccc  cccc    ");5
    c64ds ("     cccc cccccccccc    ");6
    c64ds ("4    cccc cccc  cccc   5");7
    c64ds ("4     cccc   cccccc    6");8
    c64ds ("      ccccccccccccc    7");9
    c64ds ("      ccccccccccccc     ");10
    c64ds ("      c ccccccccc c     ");11
    c64ds ("       c ccccccc c      ");12
    c64ds ("       c  ccccc  c      ");13
    c64ds ("        c  ccc  c       ");14
    c64ds ("        c  ccc  c       ");15
    c64ds ("         c  c  c        ");16
    c64ds ("         c  c  c        ");17
    c64ds ("          ccccc         ");18
    c64ds ("          ccccc         ");19
    c64ds ("          ccccc         ");20
    c64ds ("           ccc          ");21
Next

c64_finalize()

SetBuffer BackBuffer()
Cls
x=0
For tmp.c64sprmap = Each c64sprmap
    x=x+1
    If tmp\image >0 
        DrawBlock tmp\image,0,0
    EndIf
    Delay 10
    Color $0,$ff,$ff
    Text 0,30,"Bitmap number "+x
    Text 0,45,"Press any key to show next"
    Flip
    WaitKey()
    Cls
Next

FlushKeys()
x=0
Print "Bitmap Listing:"
For tmp.c64sprmap = Each c64sprmap
    x=x+1
    Print "Image number ="+x+" IMG Handle="+tmp\image
Next
y=0
Flip
WaitKey()

SetBuffer BackBuffer()
animtimer=MilliSecs()

Repeat

    If dir=0
        cfl#=(cfl#+0.1) : If cfl#=>50 Then dir=1 
    Else
        cfl#=(cfl#-0.1) : If cfl#<=0 Then dir=0 
    EndIf
    Cls
    c=0
    For py=0 To GraphicsHeight() Step 10
        c=(c+1) Mod 2
        For px=0 To (GraphicsWidth()*0.80) Step 10
            c=(c+1) Mod 2
            If c=1 Then Color $50-cfl#,$0,$0
            If c=0 Then Color $0,$50+cfl#,$50+cfl#
            Rect px,py,10,10,1
        Next
    Next
    Color $ff,$ff,$0
    Text 40,10,"Mice Party - ESCape it"

    If MilliSecs()-animtimer>250
        animtimer=MilliSecs()
        y=(y+1) Mod 3
        s=(s+1) Mod 2
        t#=(t#+1.5) Mod 60
    EndIf

    x=(x+1) : If x>350 Then x=-120
    c64drawsprite(4+y,x,80)
    c64drawsprite(4+y,x+c64i\spr_width    ,120+(t#))
    c64drawsprite(4+y,x+(c64i\spr_width*2),110-(t#))
    c64drawsprite(4+y,x+(c64i\spr_width*3),120+(t#))
    c64drawsprite(4+y,x+(c64i\spr_width*4),110-(t#))

    c64drawsprite(0+s,10,10)

    six#=(six#+0.5) Mod 360
    siy#=(siy#-0.9) Mod 360
    c64drawsprite(2,100+Cos(six#)*106,100+Sin(six#)*60)
    c64drawsprite(8,50+Cos(siy#)*66,50+Sin(six#)*60)
    c64drawsprite(9,150+Cos(six#)*66,50+Sin(siy#)*60)
    c64drawsprite(7,150+Tan(six#)*66,50+Tan(siy#)*10)
    Flip
    Delay 1

Until KeyHit(1)

End

.spr
;this is the format which is used To draw one sprite: 21 * 3 bytes - here hexadecimal numbers
;1 multicolored sprite
;c64i\maxdrawx=3 in each row of the Sprite. 3*8=  c64i\spr_width=24 
Data $AA,$55,$FF
Data $AA,$55,$FF
Data $AA,$55,$FF
Data $82,$41,$C3
Data $82,$41,$C3
Data $82,$41,$C3
Data $82,$41,$C3
Data $82,$41,$C3
Data $82,$41,$C3
Data $82,$41,$C3
Data $82,$41,$C3
Data $82,$41,$C3
Data $82,$41,$C3
Data $82,$41,$C3
Data $82,$41,$C3
Data $82,$41,$C3
Data $82,$41,$C3
Data $82,$41,$C3
Data $AA,$55,$FF
Data $AA,$55,$FF
Data $AA,$55,$FF

;3 images of
;dancing mouse from <a href="http://www.zimmers.net/cbmpics/cbm/c64/c64prg.txt" target="_blank">http://www.zimmers.net/cbmpics/cbm/c64/c64prg.txt</a>  (here with correct data statemens !)
Data 30,0,120,63,0,252,127,129,254,127,129,254,127,189,254,127,255,254,63,255,252,31,187,248,3,187,192,1,255,128,3,189,192,1,231,128,1
Data 255,0,31,255,0,0,124,0,0,254,0,1,199,32,3,131,224,7,1,192,1,192,0,3,192,0
Data 30,0,120,63,0,252,127,129,254,127,129,254,127,189,254,127,255,254,63,255,252,31,221,248,3,221,192,1,255,128,3,255,192,1,195
Data 128,1,231,3,31,255,255,0,124,0,0,254,0,1,199,0,7,1,128,7,0,204,1,128,124,7,128,56,30,0,120,63,0,252,127,129,254,127,129,254,127,189
Data 254,127,255,254,63,255,252,31,221,248,3,221,192,1,255,134,3,189,204,1,199,152,1,255,48,1,255,224,1,252,0,3,254,0
Data 7,14,0,204,14,0,248,56,0,112,112,0,0,60,0

and the Include file, which shall be saved as c64sprite_inc.bb :

;======================================================================================
; Project: Sprites 2 Go - C64 sprite drawing method, expandable
;               Save this as c64sprite_inc.bb
; Version: 1.0
; Author: Dan
; Email: -.-
; Copyright: PD
; Description:    Draw Sprites in your Code, or use the C64 sprite data format 
;                   This makes your program Independant on external bitmap 
;                   Usage:
;                   AddPal(r,g,b) ;Adds color to the Palette, Call this multiple times to add More colors
;                             1st palette entry will always be transparent (make sure that if you set this to 0,0,0 your black collor shall be 0,0,1
;                   C64DS (" 1 1 2 3") Draws to the sprite (1 line here). Youll need to draw them manualy, (see at the bottom for the template)
;
;                   C64datspr(dat,newsprite,color1,multicolor=2,color3).  Adds C64 sprite data, 1 byte = 8 pixel to the sprite)
;                             (c64ds and c64datspr functions cannot be mixed/used together to draw to a same spite !, each other saves the current sprite and starts a new one
;
;                   c64_finalize() - needs to be called after your drawing is done or you may miss the last image or the whole sprite bitmap 
;
;                   c64drawsprite (nr,x,y) same as DrawImage, but this one uses your sprite drawings, starting with nr 0, at x,y coordinates
;                             This function is drawing the Sprites to the current buffer, so if you want to have collison detection with ImagesCollide or ImagesOverlap commands,
;                             youll need to make image holders for the sprites, set the buffer to their image buffer
;                             and call this function, with only image number to be copied to the holder (x=0,y=0 are set to default).Then Draw your sprites to the screen and do the collision check.
;
;                   aditionaly, you can use c64color(nr) function to set the foreground collor, from the defined palette
;======================================================================================
;how this works:
;You draw a small picture:
; ####
; #  #     save it into a bigger one:
; #### ---> ##################                                                ##################
;           #  #             #                                                #  #  #  #  #  # #
;           ####             #      --------------copy------------->          ##################
;           #                #                                                #  #  #  #  #  # #
;           ##################                                                ##################
;                              when the big picture is filled,make a copy,save it into a bitmap, 
;                              and reset the big picture.Repeat the process.


;Dont change the lines below, unless you know what you are doing
Const AddPaletteorder$=" 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ;64 colors (63+transparent)

Dim c64pal(Len(AddPaletteorder$)+1,2)

;Used to hold the Sprite frames in one or more bitmaps 
Type c64sprmap
    Field image
End Type

Type c64data
    Field palcount,imgdrawcount 
    Field dx,dy,maxdrawx
    Field spr_width,spr_height
    Field c64image,maxsprites
    Field imgcount,NrX,NrY,MaxNrX,MaxNrY
    Field DrawTo,picture[1]
    Field collection,recursion
    Field drawn
End Type

Global c64i.c64data = New c64data
Global c64_image.c64sprmap = New c64sprmap
;Dont change the lines above, unless you know what you are doing


;If you have a need to adapt the code to a bigger/smaller size, the next 5 variables should be changed and set up
c64i\maxdrawx=3                 ;c64datspr() - 3 bytes * 8bits = 24 pixel, make sure your data statement provide this many bytes * c64i\spr_height

;used for C64datSpr() and C64ds()   - needed for both and need to be adjusted manualy
c64i\spr_width=24                   ;width of the drawn image, for c64 is 3*8=24 !!!        - Correct this manually, if you use your own width/height format
c64i\spr_height=21                  ;height of the drawn image,c64 image standard is 21 !!! - Correct this manually, if you use your own width/height format

;How many Sprite images shall one bitmap contain:
c64i\MaxNrX=50                  ;50 images * 24 pixels = 1200 pixels width    ! depends on spr_width   - for C64storeimg()
c64i\MaxNrY=50                  ;50 images * 21 pixels = 1050 pixels height   ! depends on spr_height   - for C64storeimg()

;#####################################
;Dont change the values below :
c64i\palcount=0                 ;count added palette colors
c64i\imgdrawcount=-1                ;c64ds() to count lines drawn, depends on spr_Height setting !
c64i\dx=1                       ;c64datspr() - holds the current x drawing position - DONT CHANGE THIS
c64i\dy=0                       ;c64datspr() - holds the current y drawing position - DONT CHANGE THIS
c64i\imgcount=0                 ;c64storeImg() - how many images have been stored   - DONT CHANGE THIS
c64i\drawn=0                    ;Check if something was drawn                 DONT CHANGE This
c64i\NrX=0                      ;Holder of the current image on the X axis  - DONT CHANGE THIS
c64i\NrY=1                      ;Holder of the current image on the y axis  - DONT CHANGE THIS
c64i\DrawTo=0                   ;Draw to image buffer holder                - DONT CHANGE THIS
c64i\collection=0               ;How many image pages are created, (when maxnrx + maxnry) are reached 
c64i\c64image=CreateImage(c64i\spr_width,c64i\spr_height)               ;imagage to draw sprite !

;Dont Change the values above this line.
;#######################################

Function c64drawsprite (nr,x=0,y=0)
;sprite Nr begins with 0 !

    page=(nr)/(c64i\MaxNrX*c64i\MaxNrY)
    xp=((nr) Mod c64i\MaxNrX)*c64i\spr_width
    yp=(((nr-(page*(c64i\MaxNrX*c64i\MaxNrY)))/c64i\MaxNrY))*c64i\spr_height
    z=0
    For tmp.c64sprmap = Each c64sprmap
        If z=page
            DrawImageRect tmp\image,x,y,xp,yp,c64i\spr_width,c64i\spr_height
        EndIf
        z=z+1 
    Next

End Function

Function c64datspr(dat,newspr=0,col1=2,col2=-1,col3=-1)
;Usage: if col2 is set to a collor (=>0), then it will be a multi collored sprite !
;Use newspr to force drawing of the next sprite, (this can be left out, if your data has enough bytes to draw 1 whole sprite)
;
;draws 8 pixels of a sprite in a line, using commodore 64 sprite data format
;1 byte equals 8 pixel, where each bit represents 1 pixel
; 
;Spr width = c64i\maxdrawx * 8
;spr height= c64i\spr_height
;bytes needed for drawing = c64i\maxdrawx * c64i\spr_height

    SetBuffer ImageBuffer(c64i\c64image)

    If newspr=1
        If c64i\drawn>0 Then C64storeimg() : SetBuffer ImageBuffer(c64i\c64image)
        ClsColor c64pal(0,0),c64pal(0,1),c64pal(0,2)
        Cls
    Else
        If c64i\imgdrawcount>0 Or c64i\dy>c64i\spr_height-1             ;Used to save the sprite from the c64ds function !
            C64storeimg() 
            SetBuffer ImageBuffer(c64i\c64image)
            ClsColor c64pal(0,0),c64pal(0,1),c64pal(0,2)
            Cls
        EndIf
    EndIf   

    If col2<0               ;Draw Mono (hires) sprites 
        For x=1 To 8
            Select BitState(dat,x)
                Case 0
                    C64color(0)
                Case 1
                    C64color(col1)
            End Select
            Plot (c64i\dx*8)-x,c64i\dy
        Next

    Else                    ;Draw Multicolored (lowres) sprite
        For x=1 To 8 Step 2
            temp=(BitState(dat,x+1)*2)+BitState(dat,x)
            Select temp
                Case 0
                    C64color (0)
                Case 1
                    C64color (col1)
                Case 2
                    C64color (col2)
                Case 3
                    C64color (col3)
            End Select 

            Plot (c64i\dx*8)-x,c64i\dy 
            Plot ((c64i\dx*8)-x)-1,c64i\dy
        Next

    EndIf
    c64i\drawn=1
    c64i\dx=c64i\dx+1
    If c64i\dx>c64i\maxdrawx
        c64i\dx=1
        c64i\dy=c64i\dy+1
    EndIf

    SetBuffer BackBuffer()
End Function

;################################################################

Function c64ds (dat$,newspr=0)

    SetBuffer ImageBuffer(c64i\c64image)
    If newspr=1     ;Check if new
        If c64i\drawn>0 Then C64storeimg() : SetBuffer ImageBuffer(c64i\c64image) ;save to bigger pic if something was drawn
        ClsColor c64pal(0,0),c64pal(0,1),c64pal(0,2)  ;set the background collor (just in case)
        Cls
    Else
        If (c64i\imgdrawcount<(c64i\spr_height-1)) And c64i\dy=0    ;is the end of the spite reached ? and is c64datspr used 
            c64i\imgdrawcount=c64i\imgdrawcount+1                   ;if no, add a new line
        Else
        ;Save the image to a background image and start a new sprite
            C64storeimg() : SetBuffer ImageBuffer(c64i\c64image)     ;else save it first before drawing new sprite
            ClsColor c64pal(0,0),c64pal(0,1),c64pal(0,2)
            Cls
        EndIf
    EndIf

    If Len(dat$)>c64i\spr_width         ;is the dat$ longer than the Sprite width ?
        tmpx=c64i\spr_width             ;then set the tmpx to the length of the sprite
    Else
        tmpx=Len(dat$)                  ;set it to the width of the sprite (or length of the line (dat$))
    EndIf

    For x=0 To tmpx             ;Drawing is done here
        C64color (Instr(AddPaletteorder$,Mid$(dat$,x+1,1))-1)       ;Choose the color from the char
        Plot x,c64i\imgdrawcount                                    ;Plot the pixel
    Next
    c64i\drawn=1
    SetBuffer BackBuffer()
End Function

Function AddPal(r,g,b)
;r red value, g= green value, b= blue value
    If (r=>0 And r<=$ff) And (g=>0 And g<=$ff) And (b=>0 And b<=$ff)
    ;D'OH  ;)
    Else            ;invalid collors, set the default to $0
        r=0
        g=0
        b=0
    EndIf
    If c64i\palcount=<Len(AddPaletteorder$)-1
        c64pal(c64i\palcount,0)=r
        c64pal(c64i\palcount,1)=g
        c64pal(c64i\palcount,2)=b
        c64i\palcount=c64i\palcount+1
    EndIf
End Function

Function C64color(number)
    Color c64pal(number,0),c64pal(number,1),c64pal(number,2)
End Function

Function C64storeimg(final=0)
;   DebugLog c64i\DrawTo +" "+ c64i\NrX+"/" +c64i\NrY+" -- " + " "+c64i\imgcount 

    c64i\NrX=c64i\NrX+1
    c64i\maxsprites=c64i\maxsprites+1

    If c64i\NrX>c64i\MaxNrX 
;       DebugLog "reached 50 img"
        c64i\NrX=1
        c64i\NrY=c64i\NrY+1
    EndIf

    If c64i\imgcount>c64i\MaxNrX-1
        iw=50*c64i\spr_width
    Else
        iw=c64i\NrX*c64i\spr_width
    EndIf
    c64i\picture[c64i\DrawTo] = CreateImage(iw,c64i\NrY*c64i\spr_height)

    If c64i\imgcount >0 
        CopyRect 0,0,ImageWidth(c64i\picture[(c64i\DrawTo+1) Mod 2]),ImageHeight(c64i\picture[(c64i\DrawTo+1) Mod 2]),0,0,ImageBuffer(c64i\picture[(c64i\DrawTo+1) Mod 2]),ImageBuffer(c64i\picture[c64i\DrawTo])
        FreeImage c64i\picture[(c64i\DrawTo+1) Mod 2]
    EndIf

    SetBuffer ImageBuffer(c64i\picture[c64i\DrawTo]) 
    DrawBlock c64i\c64image,(c64i\NrX-1)*c64i\spr_width,(c64i\NrY-1)*c64i\spr_height

    If (c64i\NrY=c64i\MaxNrY) And c64i\NrX=c64i\MaxNrX
        c64_finalize(1)
;       DebugLog "finalize 1"
    ;set up to a new image
    Else
        If final=0
            c64i\DrawTo=(c64i\DrawTo + 1) Mod 2
            c64i\imgcount=c64i\imgcount+1
        Else
            c64i\recursion=0
        EndIf
    EndIf

    SetBuffer BackBuffer()
    c64i\drawn=0
    c64i\imgdrawcount=0                     ;Reset C64ds + C64datspr function drawings
    c64i\dy=0
    c64i\dx=1
    ClsColor $0,$0,$0
End Function

Function c64_finalize(nr=0)

    If nr=0
        If (c64i\dy>0 Or c64i\imgdrawcount>0) 
            C64storeimg(1)
            If c64i\recursion>0
                c64i\recursion=0
                Goto getout
            Else
                c64_image\image=CopyImage(c64i\picture[c64i\DrawTo])
                MaskImage c64_image\image,c64pal(0,0),c64pal(0,1),c64pal(0,2)
                c64i\collection=c64i\collection+1
                FreeImage c64i\picture[c64i\DrawTo]
                c64i\DrawTo=0
                c64i\NrX=0
                c64i\NrY=1
                c64i\imgdrawcount=0                     ;Reset C64ds + C64datspr function drawings
                c64i\dy=0
                c64i\dx=1
                c64i\imgcount=0
            EndIf
        EndIf
    Else 
        c64_image\image=CopyImage(c64i\picture[c64i\DrawTo])
        MaskImage c64_image\image,c64pal(0,0),c64pal(0,1),c64pal(0,2)
        c64i\collection=c64i\collection+1
        c64_image.c64sprmap = New c64sprmap
        FreeImage c64i\picture[c64i\DrawTo]
        c64i\DrawTo=0
        c64i\NrX=0
        c64i\NrY=1
        c64i\imgdrawcount=0                     ;Reset C64ds + C64datspr function drawings
        c64i\dy=0
        c64i\dx=1
        c64i\imgcount=0
        c64i\recursion=c64i\recursion+1
        Return
    EndIf

    .getout
    For tmp.c64sprmap = Each c64sprmap   ; clear unused !
        If tmp\image=0 
            Delete tmp
        EndIf
    Next

End Function

Function BitState(a,b)
;a = variable
;b = bit number to Check
    a=Mid(Bin$(a),Len(Bin$(a))-(b-1),1)
    Select a
        Case "0"
            Return False
        Case "1"
            Return True
    End Select
End Function

;To display the Template correctly, use Fixed width font, like "Courier New","Lucida Console" or "Terminal"
; this is 24x21 template
;X=     123456789012345678901234      v-- y
;c64ds("                        ",1);01         ;Template ! use overwrite mode to draw inside ""
;C64DS("                        ")  ;02         ;,1 Starts a new sprite drawing
;c64ds("                        ")  ;03         ;if the whole line is transparent, you can use " " instead
;c64ds("                        ")  ;04
;c64ds("                        ")  ;05
;c64ds("                        ")  ;06
;c64ds("                        ")  ;07
;c64ds("                        ")  ;08
;c64ds("                        ")  ;09
;c64ds("                        ")  ;10
;c64ds("                        ")  ;11
;c64ds("                        ")  ;12
;c64ds("                        ")  ;13
;c64ds("                        ")  ;14
;c64ds("                        ")  ;15
;c64ds("                        ")  ;16
;c64ds("                        ")  ;17
;c64ds("                        ")  ;18
;c64ds("                        ")  ;19
;c64ds("                        ")  ;20
;c64ds("                        ")  ;21

;Following are standard c64 Palette colors, you can change your own
;AddPal ($00,$00,$00) ; transparent " "
;AddPal ($01,$00,$00) ; Black       0
;AddPal ($FF,$FF,$FF) ; White       1
;AddPal ($88,$20,$00) ; Red         2
;AddPal ($68,$d0,$a8) ; Cyan        3
;AddPal ($a8,$38,$a0) ; Purple      4
;AddPal ($50,$b8,$18) ; Green       5
;AddPal ($18,$10,$90) ; Blue        6
;AddPal ($f0,$e8,$58) ; Yellow      7
;AddPal ($a0,$48,$00) ; Orange      8
;AddPal ($47,$2b,$1b) ; Brown       9
;AddPal ($c8,$78,$70) ; Light Red   a
;AddPal ($48,$48,$48) ; Dark Gray   b
;AddPal ($80,$80,$80) ; Medium Gray c
;AddPal ($98,$ff,$98) ; Light Green d
;AddPal ($50,$90,$d0) ; Light Blue  e
;AddPal ($b8,$b8,$b8) ; Light Gray  f

Reply To Topic (minimum 10 characters)

Please log in to reply