From 2dc24297353e4de484fc3d458008b40ed7be9f07 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 31 Aug 2023 23:24:46 +0200 Subject: [PATCH] tweaks to the cx16 sprite example --- compiler/res/prog8lib/cx16/syslib.p8 | 3 +- examples/cx16/sprites/dragon.p8 | 77 +++++++++++++++++++++------- gradle.properties | 2 +- 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/compiler/res/prog8lib/cx16/syslib.p8 b/compiler/res/prog8lib/cx16/syslib.p8 index fe61526af..8530972d1 100644 --- a/compiler/res/prog8lib/cx16/syslib.p8 +++ b/compiler/res/prog8lib/cx16/syslib.p8 @@ -515,7 +515,8 @@ asmsub vpeek(ubyte bank @A, uword address @XY) -> ubyte @A { ; note: inefficient when reading multiple sequential bytes! %asm {{ pha - lda #1 + lda cx16.VERA_CTRL + ora #1 sta cx16.VERA_CTRL pla and #1 diff --git a/examples/cx16/sprites/dragon.p8 b/examples/cx16/sprites/dragon.p8 index 06938e083..63e3c8e3a 100644 --- a/examples/cx16/sprites/dragon.p8 +++ b/examples/cx16/sprites/dragon.p8 @@ -1,23 +1,25 @@ %import diskio +%import textio %zeropage basicsafe %option no_sysinit main { - ; we choose arbitrary unused vram location for sprite data: $12000 - const ubyte SPRITE_DATA_BANK = 1 - const uword SPRITE_DATA_ADDR = $2000 - - sub start() { - void diskio.vload_raw("dragonsprite.bin", SPRITE_DATA_BANK, SPRITE_DATA_ADDR) - void diskio.vload_raw("dragonsprite.pal", 1, $fa00 + sprites.PALETTE_OFFSET*2) ; load directly into vera color palette - sprites.init(1, SPRITE_DATA_BANK, SPRITE_DATA_ADDR) ; top half of dragon - sprites.init(2, SPRITE_DATA_BANK, SPRITE_DATA_ADDR + 64*64/2) ; bottom half of dragon + txt.plot(32,30) + txt.print("there be dragons!") + + ; load the sprite data and color palette directly into Vera ram + void diskio.vload_raw("dragonsprite.bin", sprites.DATA_BANK, sprites.DATA_ADDR) + void diskio.vload_raw("dragonsprite.pal", 1, $fa00 + sprites.PALETTE_OFFSET*2) + + ; initialize the dragon sprites + sprites.init(1, sprites.DATA_BANK, sprites.DATA_ADDR, sprites.SIZE_64, sprites.SIZE_64) ; top half of dragon + sprites.init(2, sprites.DATA_BANK, sprites.DATA_ADDR + 64*64/2, sprites.SIZE_64, sprites.SIZE_64) ; bottom half of dragon - word xpos = -64 - word ypos = 100 ubyte tt = 0 - bool flippedx + word xpos = -64 + word ypos + bool flippedx = false repeat { if flippedx @@ -31,6 +33,13 @@ main { ypos = (240-64 as word) + math.sin8(tt) tt++ + txt.plot(32, 32) + txt.print("at: ") + txt.print_w(sprites.getx(1)) + txt.chrout(',') + txt.print_w(sprites.gety(1)) + txt.print(" ") + sys.waitvsync() sprites.pos(1, xpos, ypos) sprites.pos(2, xpos, ypos+64) @@ -40,6 +49,7 @@ main { } } + sprites { ; sprite registers base in VRAM: $1fc00 ; Sprite 0: $1FC00 - $1FC07 ; used by the kernal for mouse pointer @@ -49,10 +59,17 @@ sprites { ; Sprite 127: $1FFF8 - $1FFFF const uword VERA_SPRITEREGS = $fc00 ; $1fc00 const ubyte PALETTE_OFFSET = 16 ; color palette indices 16-31 + const ubyte SIZE_8 = 0 + const ubyte SIZE_16 = 1 + const ubyte SIZE_32 = 2 + const ubyte SIZE_64 = 3 + ; we choose arbitrary unused vram location for sprite data: $12000 + const ubyte DATA_BANK = 1 + const uword DATA_ADDR = $2000 uword @zp sprite_reg - sub init(ubyte sprite_num, ubyte data_bank, uword data_addr) { + sub init(ubyte sprite_num, ubyte data_bank, uword data_addr, ubyte width_flag, ubyte height_flag) { hide(sprite_num) cx16.VERA_DC_VIDEO |= %01000000 ; enable sprites globally data_addr >>= 5 @@ -61,7 +78,7 @@ sprites { cx16.vpoke(1, sprite_reg, lsb(data_addr)) ; address 12:5 cx16.vpoke(1, sprite_reg+1, %00000000 | msb(data_addr)) ; 4 bpp + address 16:13 cx16.vpoke(1, sprite_reg+6, %00001100) ; z depth %11 = in front of both layers, no flips - cx16.vpoke(1, sprite_reg+7, %11110000 | PALETTE_OFFSET>>4) ; 64x64 pixels, palette offset + cx16.vpoke(1, sprite_reg+7, height_flag<<6 | width_flag<<4 | PALETTE_OFFSET>>4) ; 64x64 pixels, palette offset } sub hide(ubyte sprite_num) { @@ -76,11 +93,33 @@ sprites { cx16.vpoke_mask(1, VERA_SPRITEREGS + 6 + sprite_num*$0008, %11111101, flipped<<1) } - sub pos(ubyte sprite_num, word x, word y) { + sub pos(ubyte sprite_num, word xpos, word ypos) { sprite_reg = VERA_SPRITEREGS + 2 + sprite_num*$0008 - cx16.vpoke(1, sprite_reg, lsb(x)) - cx16.vpoke(1, sprite_reg+1, msb(x)) - cx16.vpoke(1, sprite_reg+2, lsb(y)) - cx16.vpoke(1, sprite_reg+3, msb(y)) + cx16.vpoke(1, sprite_reg, lsb(xpos)) + cx16.vpoke(1, sprite_reg+1, msb(xpos)) + cx16.vpoke(1, sprite_reg+2, lsb(ypos)) + cx16.vpoke(1, sprite_reg+3, msb(ypos)) + } + + sub setx(ubyte sprite_num, word xpos) { + sprite_reg = VERA_SPRITEREGS + 2 + sprite_num*$0008 + cx16.vpoke(1, sprite_reg, lsb(xpos)) + cx16.vpoke(1, sprite_reg+1, msb(xpos)) + } + + sub sety(ubyte sprite_num, word ypos) { + sprite_reg = VERA_SPRITEREGS + 4 + sprite_num*$0008 + cx16.vpoke(1, sprite_reg, lsb(ypos)) + cx16.vpoke(1, sprite_reg+1, msb(ypos)) + } + + sub getx(ubyte sprite_num) -> word { + sprite_reg = VERA_SPRITEREGS + 2 + sprite_num*$0008 + return mkword(cx16.vpeek(1, sprite_reg+1), cx16.vpeek(1, sprite_reg)) as word + } + + sub gety(ubyte sprite_num) -> word { + sprite_reg = VERA_SPRITEREGS + 4 + sprite_num*$0008 + return mkword(cx16.vpeek(1, sprite_reg+1), cx16.vpeek(1, sprite_reg)) as word } } diff --git a/gradle.properties b/gradle.properties index 2de63d48b..9d0a920cf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,4 +5,4 @@ org.gradle.daemon=true kotlin.code.style=official javaVersion=11 kotlinVersion=1.9.10 -version=9.4 +version=9.5-SNAPSHOT