mirror of
https://github.com/irmen/prog8.git
synced 2024-06-30 18:29:48 +00:00
added cx16 sprite demo
This commit is contained in:
parent
66b3dce794
commit
2d528c26ae
|
@ -5,7 +5,7 @@
|
|||
|
||||
; "unlimited sprites / bobs" demo effect.
|
||||
; Note that everything is prog8, no inline assembly used/required.
|
||||
|
||||
; Note2: these aren't actual sprites, it's a bitmap backbuffer display trick.
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
|
@ -104,7 +104,7 @@ main {
|
|||
|
||||
bitshift(lsb(blit_x) & 7)
|
||||
|
||||
; left column of the (shifted)sprite
|
||||
; left column of the (shifted) "sprite" (bob)
|
||||
cx16.VERA_CTRL = 0
|
||||
cx16.VERA_ADDR_L = lsb(vmem)
|
||||
cx16.VERA_ADDR_M = msb(vmem)
|
||||
|
@ -117,7 +117,7 @@ main {
|
|||
for ix in 0 to len(shifted_sprite)-1 step 3
|
||||
cx16.VERA_DATA1 = cx16.VERA_DATA0 & shifted_mask[ix] | shifted_sprite[ix]
|
||||
|
||||
; middle column of the (shifted)sprite
|
||||
; middle column of the (shifted) "sprite" (bob)
|
||||
vmem++
|
||||
cx16.VERA_CTRL = 0
|
||||
cx16.VERA_ADDR_L = lsb(vmem)
|
||||
|
@ -128,7 +128,7 @@ main {
|
|||
for ix in 1 to len(shifted_sprite)-1 step 3
|
||||
cx16.VERA_DATA1 = cx16.VERA_DATA0 & shifted_mask[ix] | shifted_sprite[ix]
|
||||
|
||||
; right column of the (shifted)sprite
|
||||
; right column of the (shifted) "sprite" (bob)
|
||||
vmem++
|
||||
cx16.VERA_CTRL = 0
|
||||
cx16.VERA_ADDR_L = lsb(vmem)
|
||||
|
|
BIN
examples/cx16/sprites/DRAGONSPRITE.BIN
Normal file
BIN
examples/cx16/sprites/DRAGONSPRITE.BIN
Normal file
Binary file not shown.
BIN
examples/cx16/sprites/DRAGONSPRITE.PAL
Normal file
BIN
examples/cx16/sprites/DRAGONSPRITE.PAL
Normal file
Binary file not shown.
29
examples/cx16/sprites/convertsprite.py
Normal file
29
examples/cx16/sprites/convertsprite.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from PIL import Image
|
||||
|
||||
def make_cx16_palette(palette: list[int]) -> bytes:
|
||||
cx16palette = bytearray()
|
||||
for pi in range(0, len(palette), 3):
|
||||
r, g, b = palette[pi] >> 4, palette[pi + 1] >> 4, palette[pi + 2] >> 4
|
||||
cx16palette.append(g << 4 | b)
|
||||
cx16palette.append(r)
|
||||
return cx16palette
|
||||
|
||||
|
||||
img = Image.open("dragonsprite.png")
|
||||
assert img.size == (64, 128) and img.mode == 'P'
|
||||
|
||||
data = bytearray()
|
||||
for y in range(0, 128):
|
||||
for x in range(0, 64, 2):
|
||||
pix1 = img.getpixel((x, y))
|
||||
pix2 = img.getpixel((x + 1, y))
|
||||
data.append(pix1 << 4 | pix2)
|
||||
|
||||
palette = make_cx16_palette(img.getpalette())
|
||||
|
||||
assert len(data) == 64 * 128 / 2
|
||||
assert len(palette) <= 16*2
|
||||
open("DRAGONSPRITE.PAL", "wb").write(palette)
|
||||
open("DRAGONSPRITE.BIN", "wb").write(data)
|
76
examples/cx16/sprites/dragon.p8
Normal file
76
examples/cx16/sprites/dragon.p8
Normal file
|
@ -0,0 +1,76 @@
|
|||
%import diskio
|
||||
%zeropage basicsafe
|
||||
%option no_sysinit
|
||||
|
||||
main {
|
||||
const ubyte SPRITE_BANK = 0
|
||||
const uword SPRITE_ADDR = $2000
|
||||
|
||||
|
||||
sub start() {
|
||||
void diskio.vload_raw("dragonsprite.bin", SPRITE_BANK, SPRITE_ADDR)
|
||||
void diskio.vload_raw("dragonsprite.pal", 1, $fa00 + sprites.PALETTE_OFFSET) ; load directly into vera color palette
|
||||
sprites.init(1, SPRITE_ADDR) ; top half of dragon
|
||||
sprites.init(2, SPRITE_ADDR + 64*64/2) ; bottom half of dragon
|
||||
|
||||
word xpos = -64
|
||||
word ypos = 100
|
||||
ubyte tt = 0
|
||||
bool flipped
|
||||
|
||||
repeat {
|
||||
if flipped
|
||||
xpos -= 2
|
||||
else
|
||||
xpos += 2
|
||||
|
||||
if xpos >= 640 or xpos <= -64
|
||||
flipped = not flipped
|
||||
|
||||
ypos = (240-64 as word) + math.sin8(tt)
|
||||
tt++
|
||||
sys.waitvsync()
|
||||
sprites.pos(1, xpos, ypos)
|
||||
sprites.pos(2, xpos, ypos+64)
|
||||
sprites.flipx(1, flipped)
|
||||
sprites.flipx(2, flipped)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sprites {
|
||||
; sprite registers base in VRAM: $1fc00
|
||||
; Sprite 0: $1FC00 - $1FC07 ; used by the kernal for mouse pointer
|
||||
; Sprite 1: $1FC08 - $1FC0F
|
||||
; Sprite 2: $1FC10 - $1FC17
|
||||
; …
|
||||
; Sprite 127: $1FFF8 - $1FFFF
|
||||
const uword VERA_SPRITEREGS = $fc00 ; $1fc00
|
||||
const ubyte PALETTE_OFFSET = 32 ; in bytes, so 16 color entries
|
||||
|
||||
uword sprite_regs
|
||||
|
||||
sub init(ubyte sprite_num, uword data_addr) {
|
||||
cx16.VERA_DC_VIDEO |= %01000000 ; enable sprites globally
|
||||
uword address = data_addr >> 5
|
||||
sprite_regs = VERA_SPRITEREGS + sprite_num*$0008
|
||||
cx16.vpoke(1, sprite_regs, lsb(address)) ; address 12:5
|
||||
cx16.vpoke(1, sprite_regs+1, %00000000 | msb(address)) ; 4 bpp + address 16:13
|
||||
cx16.vpoke(1, sprite_regs+6, %00001100) ; sprite flags: enable sprite, z depth %11 = before both layers
|
||||
cx16.vpoke(1, sprite_regs+7, %11110000 | PALETTE_OFFSET>>5) ; 64x64 pixels, palette offset
|
||||
pos(sprite_num, 100, 100)
|
||||
}
|
||||
|
||||
sub flipx(ubyte sprite_num, bool flipped) {
|
||||
uword sprite_reg = VERA_SPRITEREGS + sprite_num*$0008 + 6
|
||||
cx16.vpoke(1, sprite_reg, cx16.vpeek(1, sprite_reg) & %11111110 | flipped)
|
||||
}
|
||||
|
||||
sub pos(ubyte sprite_num, word x, word y) {
|
||||
sprite_regs = VERA_SPRITEREGS + sprite_num*$0008
|
||||
cx16.vpoke(1, sprite_regs+2, lsb(x))
|
||||
cx16.vpoke(1, sprite_regs+3, msb(x))
|
||||
cx16.vpoke(1, sprite_regs+4, lsb(y))
|
||||
cx16.vpoke(1, sprite_regs+5, msb(y))
|
||||
}
|
||||
}
|
BIN
examples/cx16/sprites/dragonsprite.png
Normal file
BIN
examples/cx16/sprites/dragonsprite.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
Loading…
Reference in New Issue
Block a user