gigatron/rom/Contrib/at67/gbas/demos/Xmas2020_ROMv5a.gbas
2025-01-28 19:17:01 +03:00

147 lines
3.9 KiB
Plaintext

_runtimePath_ "../runtime"
_runtimeStart_ &h7FFF
_codeRomType_ ROMv5a
'defines the amount of contiguous RAM needed for sprite stripes, (in this case 15*6 + 1), also min address and search direction
_spriteStripeChunks_ 15, &h3EA0, descending
'not using strings
free STRINGWORKAREA
const numPixels = 32 'yxDelay, yxPixel and yxPos addresses need to be adjusted accordingly
const yxDelay = &h0660 'need space for at least numPixels * sizeof(byte)
const yxPixel = &h0680 'need space for at least numPixels * sizeof(word)
const yxPos = &h06C0 'need space for at least numPixels * sizeof(word)
const yTop = 23
const yEnd = 120
const vTop = 8
def byte(yxDelay, 0, 1, numPixels) = 0
def word(yxPixel, 0, 1, numPixels) = 0
def word(yxPos, 0, 1, numPixels) = (rnd(75)+yTop+vTop)*256 + urnd(2, 157, numPixels, 2)
module "../../res/audio/Xmas2020/Merry.m"
'santa-sleigh, loaded into 0,0 to 255, 23 : i.e. offscreen as well as onscreen memory
'compiler allocates memory automatically for offscreen areas
'santa-sleigh could also be a sprite, but as he is not animated and his movement is achieved by scrolling
'we cheat and directly load him into offscreen memory, (256x24), thus saving memory and vCPU drawing cycles
load image, ../../res/image/Xmas2020/SantaSleigh.tga, &h0800
'background, loaded into 0, 24 to 159, 119 : i.e. the remaining onscreen area
load image, ../../res/image/Xmas2020/XmasTree.tga, &h2000
load sprite, ../../res/image/Xmas2020/Rudolph0.tga, 0
load sprite, ../../res/image/Xmas2020/Rudolph1.tga, 1
load sprite, ../../res/image/Xmas2020/Rudolph2.tga, 2
load sprite, ../../res/image/Xmas2020/Rudolph3.tga, 3
load sprite, ../../res/image/Xmas2020/Rudolph4.tga, 4
load sprite, ../../res/image/Xmas2020/Rudolph5.tga, 5
'scrolling has to happen immediately after vertical blank or glitches ensue, so attach scroll sub before midi player
init scrollSanta, MIDI
def frame, cont, yxd, anim0, anim1, scrollTmp
gosub initialise
loop:
flip = frame AND 1
for i=0 &to (numPixels-1)*2 step 2
gosub delayPixel
if &(cont) then continue
yx = deek(yxPos + i)
update = yx.hi AND &h80
yx = yx AND &h7FFF
yx.lo = (yx.lo AND &hFE) + ((yx.hi AND 4) LSR 2) 'jitter position
poke yxPixel + i + flip, peek(yx)
if &(update)
f = flip XOR 1
gosub jitterPixel
endif
poke yx, &h3F
inc yx.hi
update = &h8000
if yx.hi &&= yEnd + 8
f = flip
gosub jitterPixel
gosub resetPixel
endif
doke yxPos + i, yx OR update
continue:
next i
inc frame
'animate the dodgey rudolph's
inc anim0
inc anim1
if anim0 &&= 12 then anim0 = 0
if anim1 &&= 12 then anim1 = 0
a0 = anim0 LSR 1
a1 = anim1 LSR 1
sprite noFlip, a0, 193, 0
sprite noFlip, a1, 223, 0
goto loop
'cannot use any gtBASIC operators/code/reserved words/runtime/etc in a vBLANK handler, code in assembler for safety
'you still have access to gtBASIC variables within the assembler by prepending an underscore
scrollSanta:
asm
LDWI 0x0101
STW _scrollTmp
LDI 0
SUBW _frame
POKE _scrollTmp
LDWI 0x012F
STW _scrollTmp
LDW _frame
POKE _scrollTmp
endasm
ret
resetPixel:
yx.hi = yTop + vTop
update = &h0000
poke yxd, rnd(0) AND &h1F
return
jitterPixel:
jyx = yx - &h0100
jyx.lo = (jyx.lo AND &hFE) + ((jyx.hi AND 4) LSR 2)
poke jyx, peek(yxPixel + i + f)
return
delayPixel:
cont = 0
i2 = i LSR 1
yxd = yxDelay + i2
d = peek(yxd)
if &(d)
cont = 1
dec d
poke yxd, d
endif
return
initialise:
mode 2
frame = 0 : cont = frame : yxd = cont : anim0 = yxd
anim1 = 6
'audio fix for ROMv5a
poke &h21, peek(&h21) OR 3
play MIDI, &h20A0, 3
return