Created
October 25, 2022 02:54
-
-
Save reltham/cb607cb91eae8bc8a7a1609e791fe6ea to your computer and use it in GitHub Desktop.
sprite test code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%import textio | |
%import syslib | |
%import cx16diskio | |
%zeropage basicsafe | |
main { | |
sub start() { | |
txt.chrout(19) ; HOME | |
txt.print("\nsprite test\n\n") | |
; load our sprites into VERA | |
void cx16diskio.vload("birdsprites.bin", 8, 0, $a000) | |
; enable sprites | |
cx16.VERA_DC_VIDEO = cx16.VERA_DC_VIDEO | %01000000 | |
; setup sprite 1 | |
sprite.setup(1, %00000101, %00011000, 0) | |
set_sprite_frame(1, 0) | |
uword birdX = 50 | |
uword birdY = 50 | |
sprite.position(1, birdX, birdY) | |
bool xDir = true | |
bool yDir = true | |
sprite.flips(1, xDir) | |
ubyte i = 0 | |
repeat { | |
set_sprite_frame(1, i) | |
i++ | |
if (i > 7) i = 0 | |
sprite.position(1, birdX, birdY) | |
if (xDir) birdX++ else birdX-- | |
if (yDir) birdY++ else birdY-- | |
if (birdX > 300 or birdX < 10) | |
{ | |
xDir = not xDir | |
sprite.flips(1, xDir) | |
} | |
if (birdY > 100 or birdY < 30) yDir = not yDir | |
sys.wait(mkword(0,1)) | |
} | |
} | |
; select which sprite image to display using sprite 1 (second sprite) | |
sub set_sprite_frame(ubyte spriteNum, ubyte index) { | |
; sprites are in VERA memory at $a000 | |
uword sprite_data_addr = $a000 | |
; each sprite is 256 bytes so incrementing the upper byte of the uword advances to the next sprite image | |
sprite_data_addr += mkword(index, 0) | |
sprite.set_address(spriteNum, 0, sprite_data_addr) | |
} | |
} | |
sprite { | |
; widthHeight = (width << 2) | (height) | |
; width and height are o to 3 for 0 = 8, 1 = 16, 2 = 32, 3 = 64. | |
; modeZDepthVHFlips = (mode << 4) | (zDepth << 2) | (vFlip << 1) | hFlip | |
; mode is 0 = 4bpp and 1 = 8bpp | |
; zDepth is 0 to 3, 0 = disabled, 1 = behind layer0, 2 = between layer0 and layer1, 3 = in front of layer1 | |
; vFlip and hFlip are 0 = not flipped, 1 = flipped | |
; collisionMaskPaletteOffset | |
; paletteOffset lower 4 bits | |
; collisionMask upper 4 bits | |
sub setup(ubyte spriteNum, ubyte widthHeight, ubyte modeZDepthVHFlip, ubyte collisionMaskPaletteOffset) { | |
uword offset = spriteNum << 3 | |
ubyte temp1 = (widthHeight << 4) | (collisionMaskPaletteOffset & $0F) | |
ubyte temp2 = (collisionMaskPaletteOffset & $F0) | (modeZDepthVHFlip & $0F) | |
ubyte temp3 = ((modeZDepthVHFlip & $F0) << 3) | (cx16.vpeek(1, $fc01 + offset) & $7F) | |
cx16.vpoke(1, $fc01 + offset, temp3) | |
cx16.vpoke(1, $fc06 + offset, temp2) | |
cx16.vpoke(1, $fc07 + offset, temp1) | |
} | |
sub flips(ubyte spriteNum, ubyte VHFlips) { | |
uword offset = spriteNum << 3 | |
cx16.vpoke_and(1, $fc06 + offset, %11111100) | |
cx16.vpoke_or(1, $fc06 + offset, (VHFlips & $03)) | |
} | |
; xPos and yPox only use the lower 10 bits, the upper bits are ignored | |
sub position(ubyte spriteNum, uword xPos, uword yPos) { | |
uword offset = spriteNum << 3 | |
cx16.vpoke(1, $fc02 + offset, lsb(xPos)) | |
cx16.vpoke(1, $fc03 + offset, msb(xPos)) | |
cx16.vpoke(1, $fc04 + offset, lsb(yPos)) | |
cx16.vpoke(1, $fc05 + offset, msb(yPos)) | |
} | |
; sprites have to be 32 byte aligned, so the lower 5 bits of spriteAddress are ignored | |
sub set_address(ubyte spriteNum, ubyte spriteBank, uword spriteAddress) { | |
uword offset = spriteNum << 3 | |
uword addr = (spriteAddress >> 5) | ((spriteBank as uword & 1) << 11) | |
cx16.vpoke(1, $fc00 + offset, lsb(addr)) | |
ubyte currentModeValue = cx16.vpeek(1, $fc01 + offset) & %10000000 | |
cx16.vpoke(1, $fc01 + offset, currentModeValue | msb(addr)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment