mirror of
https://github.com/irmen/prog8.git
synced 2024-12-27 05:29:38 +00:00
331 lines
8.9 KiB
Lua
331 lines
8.9 KiB
Lua
%import palette
|
|
%import conv
|
|
%import textio
|
|
%import math
|
|
|
|
; "unlimited sprites / bobs" demo effect.
|
|
; Note that everything is prog8, no inline assembly used/required.
|
|
|
|
|
|
main {
|
|
sub start() {
|
|
void cx16.screen_mode(3, false)
|
|
txt.print("\n\n how many sprites does\n the commander x16 have?\n")
|
|
sys.wait(120)
|
|
txt.print("\n\n the manual says: '128'.\n")
|
|
sys.wait(80)
|
|
txt.print("\n\n but that's just a manual...\n")
|
|
sys.wait(80)
|
|
txt.print("\n\n let's find out for ourselves,\n shall we?")
|
|
sys.wait(180)
|
|
|
|
; enable bitmap mode 320x240, 1 bpp, only layer 1
|
|
cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000
|
|
cx16.VERA_DC_HSCALE = 64
|
|
cx16.VERA_DC_VSCALE = 64
|
|
cx16.VERA_L1_CONFIG = %00000100
|
|
cx16.VERA_L1_MAPBASE = 0
|
|
cx16.VERA_L1_TILEBASE = 0
|
|
|
|
; limit display heigth to 200 pixels to have enough vram for 14 backbuffers
|
|
const ubyte vstart = 20
|
|
const ubyte vheight = 200
|
|
cx16.VERA_CTRL = %00000010
|
|
cx16.VERA_DC_VSTART = vstart
|
|
cx16.VERA_DC_VSTOP = vstart + vheight - 1
|
|
|
|
init_buffers()
|
|
palette.set_color(0, $000)
|
|
palette.set_color(1, $af8)
|
|
|
|
cx16.set_rasterirq(&irq, 340) ; time it so that the page flip at the end occurs near the bottom of the screen to avoid tearing
|
|
|
|
repeat {
|
|
; don't exit
|
|
}
|
|
}
|
|
|
|
const ubyte num_backbuffers = 12 ; there is vram space for 14 backbuffers. reduce to make tighter "loops"
|
|
uword num_bobs = 0
|
|
ubyte backbuffer = num_backbuffers-1
|
|
ubyte blitbuffer = 0
|
|
uword anim1 = $0432
|
|
uword anim2 = $f123
|
|
uword anim3 = $e321
|
|
uword anim4 = $7500
|
|
|
|
sub irq() {
|
|
|
|
; palette.set_color(0, $f00) ; debug rastertime
|
|
|
|
; draw 2 bobs per frame to speed up bob count
|
|
ubyte vmembase = blitbuffer*4 ; 2048 * 4 per backbuffer
|
|
blit(vmembase)
|
|
blitbuffer++
|
|
if blitbuffer==num_backbuffers
|
|
blitbuffer=0
|
|
vmembase = blitbuffer*4 ; 2048 * 4 per backbuffer
|
|
blit(vmembase)
|
|
blitbuffer++
|
|
if blitbuffer==num_backbuffers
|
|
blitbuffer=0
|
|
|
|
backbuffer++
|
|
if backbuffer==num_backbuffers {
|
|
backbuffer=0
|
|
num_bobs+=2
|
|
}
|
|
|
|
vmembase = backbuffer*4 ; 2048 * 4 per backbuffer
|
|
draw_number(vmembase, num_bobs)
|
|
cx16.VERA_L1_TILEBASE = vmembase << 2 ; flip to next backbuffer
|
|
|
|
; palette.set_color(0, $000)
|
|
}
|
|
|
|
sub init_buffers() {
|
|
; erase all vram
|
|
cx16.VERA_CTRL = 0
|
|
cx16.VERA_ADDR_L = 0
|
|
cx16.VERA_ADDR_M = 0
|
|
cx16.VERA_ADDR_H = %00010000 ; auto incr 1
|
|
repeat $ffff
|
|
cx16.VERA_DATA0 = 0
|
|
repeat $f960
|
|
cx16.VERA_DATA0 = 0
|
|
}
|
|
|
|
sub blit(ubyte vmembase) {
|
|
ubyte bank = vmembase>=32
|
|
uword vmem = vmembase * 2048 ; mkword(vmembase,0) * 8
|
|
uword blit_x = (math.cos8u(msb(anim1)) as uword) + math.sin8u(msb(anim2))/6
|
|
ubyte blit_y = math.sin8u(msb(anim3))/2 + math.cos8u(msb(anim4))/5
|
|
vmem += blit_x/8 + (blit_y as uword) * 40
|
|
|
|
bitshift(lsb(blit_x) & 7)
|
|
|
|
; left column of the (shifted)sprite
|
|
cx16.VERA_CTRL = 0
|
|
cx16.VERA_ADDR_L = lsb(vmem)
|
|
cx16.VERA_ADDR_M = msb(vmem)
|
|
cx16.VERA_ADDR_H = bank | %10110000 ; increment 40 for read (next line)
|
|
cx16.VERA_CTRL = 1
|
|
cx16.VERA_ADDR_L = lsb(vmem)
|
|
cx16.VERA_ADDR_M = msb(vmem)
|
|
cx16.VERA_ADDR_H = bank | %10110000 ; increment 40 for read (next line)
|
|
ubyte ix
|
|
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
|
|
vmem++
|
|
cx16.VERA_CTRL = 0
|
|
cx16.VERA_ADDR_L = lsb(vmem)
|
|
cx16.VERA_ADDR_M = msb(vmem)
|
|
cx16.VERA_CTRL = 1
|
|
cx16.VERA_ADDR_L = lsb(vmem)
|
|
cx16.VERA_ADDR_M = msb(vmem)
|
|
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
|
|
vmem++
|
|
cx16.VERA_CTRL = 0
|
|
cx16.VERA_ADDR_L = lsb(vmem)
|
|
cx16.VERA_ADDR_M = msb(vmem)
|
|
cx16.VERA_CTRL = 1
|
|
cx16.VERA_ADDR_L = lsb(vmem)
|
|
cx16.VERA_ADDR_M = msb(vmem)
|
|
for ix in 2 to len(shifted_sprite)-1 step 3
|
|
cx16.VERA_DATA1 = cx16.VERA_DATA0 & shifted_mask[ix] | shifted_sprite[ix]
|
|
|
|
anim1 += 117
|
|
anim2 += 90
|
|
anim3 += 122
|
|
anim4 += 145
|
|
}
|
|
|
|
sub bitshift(ubyte shift) {
|
|
ubyte yix
|
|
ubyte yy
|
|
for yy in 0 to 15 {
|
|
uword @zp sprw = sprite[yy]
|
|
uword @zp maskw = mask[yy]
|
|
ubyte @zp sprite_3 = 0
|
|
ubyte @zp mask_3 = 255
|
|
repeat shift {
|
|
sprw >>= 1
|
|
ror(sprite_3)
|
|
sys.set_carry()
|
|
ror(maskw)
|
|
ror(mask_3)
|
|
}
|
|
shifted_sprite[yix] = msb(sprw)
|
|
shifted_mask[yix] = msb(maskw)
|
|
yix++
|
|
shifted_sprite[yix] = lsb(sprw)
|
|
shifted_mask[yix] = lsb(maskw)
|
|
yix++
|
|
shifted_sprite[yix] = sprite_3
|
|
shifted_mask[yix] = mask_3
|
|
yix++
|
|
}
|
|
}
|
|
|
|
sub draw_number(ubyte vmembase, uword number) {
|
|
uword vmem = vmembase * 2048 ; mkword(vmembase,0) * 8
|
|
ubyte bank = vmembase>=32
|
|
vmem += 35
|
|
conv.str_uw0(number)
|
|
uword pixelsptr = &numberpixels + (conv.string_out[1] & 15)*7
|
|
ubyte pix
|
|
cx16.VERA_CTRL = 0
|
|
cx16.VERA_ADDR_L = lsb(vmem)
|
|
cx16.VERA_ADDR_M = msb(vmem)
|
|
cx16.VERA_ADDR_H = bank | %10110000 ; increment 40 for read (next line)
|
|
for pix in 0 to 6
|
|
cx16.VERA_DATA0 = pixelsptr[pix]
|
|
vmem++
|
|
cx16.VERA_ADDR_L = lsb(vmem)
|
|
cx16.VERA_ADDR_M = msb(vmem)
|
|
pixelsptr = &numberpixels + (conv.string_out[2] & 15)*7
|
|
for pix in 0 to 6
|
|
cx16.VERA_DATA0 = pixelsptr[pix]
|
|
vmem++
|
|
cx16.VERA_ADDR_L = lsb(vmem)
|
|
cx16.VERA_ADDR_M = msb(vmem)
|
|
pixelsptr = &numberpixels + (conv.string_out[3] & 15)*7
|
|
for pix in 0 to 6
|
|
cx16.VERA_DATA0 = pixelsptr[pix]
|
|
vmem++
|
|
cx16.VERA_ADDR_L = lsb(vmem)
|
|
cx16.VERA_ADDR_M = msb(vmem)
|
|
pixelsptr = &numberpixels + (conv.string_out[4] & 15)*7
|
|
for pix in 0 to 6
|
|
cx16.VERA_DATA0 = pixelsptr[pix]
|
|
}
|
|
|
|
ubyte[10*7] numberpixels = [
|
|
%00111000,
|
|
%01000100,
|
|
%10000100,
|
|
%10000100,
|
|
%10000100,
|
|
%01111000,
|
|
%00000000,
|
|
|
|
%00010000,
|
|
%00110000,
|
|
%01010000,
|
|
%00010000,
|
|
%00010000,
|
|
%01111100,
|
|
%00000000,
|
|
|
|
%01111000,
|
|
%10000100,
|
|
%00011000,
|
|
%00110000,
|
|
%01100000,
|
|
%11111100,
|
|
%00000000,
|
|
|
|
%01111000,
|
|
%00000100,
|
|
%00111000,
|
|
%00000100,
|
|
%00000100,
|
|
%11111000,
|
|
%00000000,
|
|
|
|
%00010100,
|
|
%00100100,
|
|
%01000100,
|
|
%11111100,
|
|
%00000100,
|
|
%00000100,
|
|
%00000000,
|
|
|
|
%11111000,
|
|
%10000000,
|
|
%11111000,
|
|
%00000100,
|
|
%00000100,
|
|
%11111000,
|
|
%00000000,
|
|
|
|
%01111000,
|
|
%10000000,
|
|
%11111000,
|
|
%10000100,
|
|
%10000100,
|
|
%01111000,
|
|
%00000000,
|
|
|
|
%11111100,
|
|
%00001000,
|
|
%00010000,
|
|
%00010000,
|
|
%00010000,
|
|
%00010000,
|
|
%00000000,
|
|
|
|
%01111000,
|
|
%10000100,
|
|
%01111000,
|
|
%10000100,
|
|
%10000100,
|
|
%01111000,
|
|
%00000000,
|
|
|
|
%01111000,
|
|
%10000100,
|
|
%01111100,
|
|
%00000100,
|
|
%10000100,
|
|
%01111000,
|
|
%00000000
|
|
]
|
|
|
|
uword[16] sprite = [
|
|
%0000001111000000,
|
|
%0001111111111000,
|
|
%0011111110101100,
|
|
%0111111011010010,
|
|
%0111111010100010,
|
|
%0111110100001010,
|
|
%1111101000100001,
|
|
%1111010000000001,
|
|
%1111000100100001,
|
|
%1110100000000001,
|
|
%0110001000000010,
|
|
%0101000000000010,
|
|
%0100000000000010,
|
|
%0010100000000100,
|
|
%0001110000111000,
|
|
%0000001111000000
|
|
]
|
|
|
|
uword[16] mask = [
|
|
%1111110000111111,
|
|
%1110000000000111,
|
|
%1100000000000011,
|
|
%1000000000000001,
|
|
%1000000000000001,
|
|
%1000000000000001,
|
|
%0000000000000000,
|
|
%0000000000000000,
|
|
%0000000000000000,
|
|
%0000000000000000,
|
|
%1000000000000001,
|
|
%1000000000000001,
|
|
%1000000000000001,
|
|
%1100000000000011,
|
|
%1110000000000111,
|
|
%1111110000111111
|
|
]
|
|
|
|
ubyte[16*3] shifted_sprite
|
|
ubyte[16*3] shifted_mask
|
|
}
|