From 54035e555224e94453196bac8c0ab1b5482b16df Mon Sep 17 00:00:00 2001 From: artemus Date: Wed, 4 Feb 2026 18:04:03 +1030 Subject: [PATCH] Add jukebox functionality --- code/bank3Cutscenes.s | 147 ++++++++++++++++-- constants/common/music.s | 3 + .../common/spr_titlescreen_sprites.png | Bin 669 -> 568 bytes .../common/spr_titlescreen_sprites.properties | 2 +- .../common/spr_titlescreen_sprites.cmp | Bin 590 -> 535 bytes 5 files changed, 142 insertions(+), 10 deletions(-) diff --git a/code/bank3Cutscenes.s b/code/bank3Cutscenes.s index 51d408e2b..d85b5b107 100644 --- a/code/bank3Cutscenes.s +++ b/code/bank3Cutscenes.s @@ -532,9 +532,8 @@ intro_titlescreen: ld a,(wTmpcbb3) and $20 ret nz - ld hl,bank3f.titlescreenPressStartSprites - ld e,:bank3f.titlescreenPressStartSprites - jp addSpritesFromBankToOam + ; Display track number instead of "Press Start" + jp titlescreen_drawTrackNumber .else; ROM_SEASONS @@ -544,8 +543,8 @@ intro_titlescreen: ld a,(wTmpcbb3) and $20 ret nz - ld hl,titlescreenPressStartSprites - jp addSpritesToOam + ; Display track number instead of "Press Start" + jp titlescreen_drawTrackNumber .endif ;; @@ -579,6 +578,13 @@ intro_titlescreen_state0: ld a,$09 ldi (hl),a ; [wTmpcbb4] = $09 + ; Initialize sound test: wTmpcbb5 = current track number + ; wTmpcbb6 = delay counter before playing (0 = no delay pending) + ld a,MUS_TITLESCREEN + ld (wTmpcbb5),a + xor a + ld (wTmpcbb6),a + call intro_incState ld a,MUS_TITLESCREEN @@ -590,16 +596,64 @@ intro_titlescreen_state0: ;; ; State 1: waiting for player to press start intro_titlescreen_state1: + ; Check if we have a pending track to play after delay + ld a,(wTmpcbb6) + or a + jr z,@noDelayPending + dec a + ld (wTmpcbb6),a + jr nz,@checkInputs + ; Delay finished, play the track now + ld a,(wTmpcbb5) + call playSound + jr @checkInputs + +@noDelayPending: +@checkInputs: ld a,(wKeysJustPressed) and BTN_START jr nz,@pressedStart - ; Check to automatically exit the titlescreen + ; Sound test: Check for left/right key presses + ld a,(wKeysJustPressed) + and BTN_RIGHT + jr nz,@nextTrack + ld a,(wKeysJustPressed) + and BTN_LEFT + jr nz,@prevTrack + + ; Decrement blink timer (for sprite blinking effect) but don't auto-exit ld hl,wTmpcbb3 call decHlRef16WithCap - ret nz - ld a,$02 - jr @gotoState + ; Ignore the zero result - don't exit to cutscene + ret + +@nextTrack: + ; Increment track, wrap at MUS_MAX_TRACK+1 back to 0 + ld a,(wTmpcbb5) + inc a + cp MUS_MAX_TRACK+1 + jr c,@setTrack + xor a + jr @setTrack + +@prevTrack: + ; Decrement track, wrap at 0 to MUS_MAX_TRACK + ld a,(wTmpcbb5) + or a + jr nz,@decTrack + ld a,MUS_MAX_TRACK+1 +@decTrack: + dec a + +@setTrack: + ld (wTmpcbb5),a + ; Stop current music and set delay before playing new track + ld a,SNDCTRL_STOPMUSIC + call playSound + ld a,30 ; ~500ms delay at 60fps + ld (wTmpcbb6),a + ret @pressedStart: ld a,SND_SELECTITEM @@ -633,6 +687,81 @@ intro_titlescreen_state3: call threadRestart jp stubThreadStart +;; +; Draw track number on the title screen using dynamically generated sprites +; Displays "0xYY" where YY is the current track number in hex +titlescreen_drawTrackNumber: + ; Get OAM tail position + ldh a,(wOam + + ; Sprite format: Y, X, Tile, Attr + ; Hex digit tiles: after interleaving, digit N is at tile $38 + N*2 + ; (Hex digits are in row 0 of PNG, which maps to VRAM tiles $38-$56) + ; Display "0YY" centered (3 sprites × 8 pixels = 24 pixels) + ; Screen is 160 pixels, center at X = (160-24)/2 + 8 = 76 = $4C + + ; Get the track number from wTmpcbb5 + ld a,(wTmpcbb5) + ld b,a + + ; Draw "0" prefix at X=$4C (leftmost digit) + ld a,$80 ; Y position + ld (de),a + inc e + ld a,$4C ; X position + ld (de),a + inc e + ld a,$38 ; Tile $38 = digit "0" + ld (de),a + inc e + xor a ; Attr = 0 + ld (de),a + inc e + + ; Draw high nibble at X=$54 + ld a,$80 ; Y position + ld (de),a + inc e + ld a,$54 ; X position + ld (de),a + inc e + ld a,b + swap a ; Get high nibble + and $0F + add a ; Double it (tiles are at $38 + digit*2 due to interleaving) + add $38 ; Convert to tile index + ld (de),a + inc e + xor a ; Attr = 0 + ld (de),a + inc e + + ; Draw low nibble at X=$5C + ld a,$80 ; Y position + ld (de),a + inc e + ld a,$5C ; X position + ld (de),a + inc e + ld a,b + and $0F ; Get low nibble + add a ; Double it (tiles are at $38 + digit*2 due to interleaving) + add $38 ; Convert to tile index + ld (de),a + inc e + xor a ; Attr = 0 + ld (de),a + inc e + + ; Update OAM tail + ld a,e + ldh (U zjfvRg0|O$Nb@6@XEF1Ub*^&%oh1&gGznqDdhNPjRML99BBpMQ$9z=`oj zjfx^pQL8qHL~wjMMZ|aulGMcbc+G`V4E3Q1NjCxXmq_iwYV>Mr@_Hg4$?GYE|Mjo6 zSS$i`X)1hxbM@&mW>yqFZoSzUz!xq8*Wp3xH*P^y6b}^$?nVz?O`R(+jQv()H^&vl zz3s#>f62R5I)8xaWQn!KZjPx2gKr6NST5dPCO;biOP#3SV&uVvV1dcxNBQP($lfI| z`C2yu8aMkAsZ!R)6ovtR^v{88UcsD$6Ofp zjp%Nv>hGOqs6#2K7FTJ$pXO2Huix#GW1;T;prrr+002ov KPDHLkU;%>cq5j_h delta 621 zcmV-z0+Ri>1f2ztJAVR9Nkl-p>1U8td!~XIiS7~!uGZ&sEuh)t8_L7oet3Xv(%T5gz)q>OkRe$cmKFLPAX^& z1bPqywNZ7j`oT0gxxZ;@T$Jb*h^c_w#l<2OOQn6|l1gN3oOk$wt&$?G(U0@(nVt@Zxv^<{4NRM;><$vtCs9zz# z+B{%Dx!Yjx*i~bN@bu}9i<}Rn`mKFH&niZv&p=P+K8w~JH?`Ixp!J><^e=c|$HCr` zfPOZ8wv}Fo?yc$^VOm_Yb}-C}7*3x3aRfcGUxH+W>)K zOjwoyr7)zTLO@kblXK5&(Op$tj5Wj!^Nt&2oG(cEM=IK|tzt4~%*}2zvCn9Dz}s++kE8 zDWj;@ivVZZ?I@B`_ftq0nydF;%5Ql4m;5}A=PK8sS#7?NuhMHIEf3e3rX3jr`DcG~ z|HjO8CjEK%G(3OzvZIJ@!Z^aN<0J_0Tv?jBXrj}gAJfMRlt9_^dEy8FRb)R_n^V)k znL#j&Zoqh>)qgE4u)Ofg!K3sU9BlskDsP7|BsG`$1~GsT1Dh(HArmfJCQbqgj3!sf zXbLDAHVpotl(~2K_MH$_P87XVxH)??N&sTV>BL3O4UZ3D0C?c^lRk7AB$ZQC q)AM-?A+HoaLF9uB-LSCn0)M}ip1A~aZ|_HOx8rAOoD%{7=l%oeD65VD literal 590 zcmXAlPe>GD9EN|hv(An-I%8UnusSolth<%E6OwK@Hs2-{dk73EA__i*7AeRPg7zRY zvk>VasAJ-xy>zJ4LLDlQzWzWVRC^6Nj0lN`r2#Dz*7=(3{JcCoyo|>pAOY;zwD?I& z1=!dAK=T3(=J#%&SK5zHQWK8_I8|6w+HF`lG5uz~jdHYjWB?@kRWoH{EnHoV87rY6 zf1|6JrLW!KT3F|7cEU{CjD*x`4CMzq154kG3BvFuP2G>Hd(ZSFp~4znYsVa!~q zLDjE%m5Nsbf5OV-Bq{9upR{D{Ck4T{19P)a>G!vr6s=wuH7_~^2VT(U!MUKnA(cvi z1fi`3=x%+vJ~@0F~erjz)wiLOs*6VS zQ6p}~Kw%URxfqjYUo$WVRvvX<7FdfWY3Blk@%LxrMnqLBx>wR>V5h&4X>>N=-^0i! wKJZ@XMzSJsVl2imx8M-HH}!$qcJJXZ;m5TgF-F(dVNI)5tqEP%B}ozf0ym!5E&u=k