5,112 bytes added,
01:52, 2 February 2010 The Plus hardware sprite format is different to the standard CPC sprite format, so sprites have to be converted if you want to use them as hardware sprites on the Plus.
== The formats ==
Plus hardware sprites are 16x16 pixels in size and have 16 colours, with colour 0 always being transparent. Therefore, when converting standard CPC sprites it is easiest to convert them from MODE 0 because this mode supports a colour depth of 16 and two pixels are stored in one byte.
The pixel data on the standard CPC is stored in an awkward manner and a byte is organised as follows:
[[File:Pixels.png]]
The top row shows the two pixels and the bottom row shows how they are arranged in one byte on the standard CPC.
The pixel data on the Plus is organised in a straight forward manner being that each byte is a pixel and its value is the PEN colour. For example, the first two lines of a Plus sprite could be:
<geshi lang=Z80>
00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15
01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,00
</geshi>
== Conversion ==
To convert a sprite, you can use the converter utility on the DSK image (to load type RUN”DISC”) which can be downloaded below.
To use the converter utility, you must have first capture your standard CPC sprite (you can use the SPRITER utility on the disc) which must be 16 x 16 in size (8 bytes wide by 16 lines high). The converter utility will then display the sprites and convert them before saving the converted sprite to the disk.
== Download ==
[[Media:Convspr.dsk]] - DSK image containing the converter utility
== Source code ==
The source code for the converter (which will assemble in WinAPE and Maxam) is as follows:
<geshi lang=Z80>
;Convert CPC sprite to Plus sprite
;by Redbox, February 2010
;Public Domain
org &8200
ld b,16 ;loop counter, sprite is 16 lines high
mainloop: push bc ;preserve loop counter
call doline
ld hl,(scraddr) ;load HL with screen address
call nextline ;work out next screen line down
ld (scraddr),hl ;and store the screen address
pop bc ;restore loop counter
djnz mainloop ;decrease B and jump back to loop if not 0
ret ;exit
doline: ld b,8 ;loop counter, sprite is 8 bytes wide = 16 pixels
lineloop: push bc ;store counter
ld hl,(scraddr) ;get screen location
ld a,(hl) ;and load data from it into A
bit 7,a ;does bit 0 equal 1? if so, reset Z
ld b,&1 ;pixel 0, bit 0 = &1
call nz,addbit ;and write it out to sprite memory
bit 3,a ;does bit 0 equal 1? if so, reset Z
ld b,&2 ;pixel 0, bit 1 (%0010) = &2
call nz,addbit ;and write it out to sprite memory
bit 5,a ;does bit 0 equal 1? if so, reset Z
ld b,&4 ;pixel 0, bit 2 (%0100) = &4
call nz,addbit ;and write it out to sprite memory
bit 1,a ;does bit 0 equal 1? if so, reset Z
ld b,&8 ;pixel 0, bit 3 (%1000) = &8
call nz,addbit ;and write it out to sprite memory
call storeit ;store pixel at sprite address
ld a,&0 ;reset pixel
ld (pixel),a ;and store reset
ld hl,(scraddr) ;get data from current screen location
ld a,(hl) ;and load it into A
bit 6,a ;does bit 0 equal 1? if so, reset Z
ld b,&1 ;pixel 1, bit 0 (%0001) = &1
call nz,addbit ;and write it out to sprite memory
bit 2,a ;does bit 0 equal 1? if so, reset Z
ld b,&2 ;pixel 1, bit 1 (%0010) = &2
call nz,addbit ;and write it out to sprite memory
bit 4,a ;does bit 0 equal 1? if so, reset Z
ld b,&4 ;pixel 1, bit 2 (%0100) = &4
call nz,addbit ;and write it out to sprite memory
bit 0,a ;does bit 0 equal 1? if so, reset Z
ld b,&8 ;pixel 1, bit 3 (%1000) = &8
call nz,addbit ;and write it out to sprite memory
call storeit ;store pixel at sprite address
ld a,&0 ;reset pixel
ld (pixel),a ;and store reset
ld hl,(scraddr) ;get screen address
inc hl ;increase it
ld (scraddr),hl ;store it for next time
pop bc ;restore loop counter
djnz lineloop ;decrease B and jump back to loop if not 0
ret ;else return
addbit: push af ;preserve screen data
ld a,(pixel) ;load A with pixel
add b ;add what we've found to it
ld (pixel),a ;store it again
pop af ;restore screen data
ret
storeit: ld hl,(spraddr) ;load HL with sprite address
ld a,(pixel) ;load pixel into A
ld (hl),a ;load sprite address with pixel value
inc hl ;increase sprite address
ld (spraddr),hl ;and store it for next time
ret
nextline: ld a,l ;load A with L (low byte of screen address)
sub 8 ;subtract the 8 bytes we've already done
ld l,a ;and load it back into L
ld a,8 ;load A with 8
add a,h ;which means we add &800 for the next pixel line down
ld h,a ;write new address back to H
ret nc ;and return if no overflow
ld de,&C050 ;else loop back round to top of screen plus one pixel line
add hl,de ;by adding &C000+&50 to HL
ret
scraddr: dw &C000
pixel: db &0
spraddr: dw &9000
</geshi>
== See also ==
*[[Programming:CPC Plus Hardware Sprites]]
[[Category:CPC Plus]][[Category: Programming]]