SECTION "rst 00", ROM0 di jp Entry SECTION "rst 10", ROM0 jp DelayFrame SECTION "rst 18", ROM0 jp JumpToFuncInTable SECTION "rst 20", ROM0 jp _ReadHalfword SECTION "VBlankInt", ROM0 jp VBlank SECTION "HBlankInt", ROM0 jp LCD SECTION "TimerInt", ROM0 jp Timer SECTION "SerialInt", ROM0 jp Serial SECTION "JoypadInt", ROM0 jp Joypad SECTION "Entry", ROM0 Entry: ; 0x100 nop jp Start SECTION "Header", ROM0 ; The header is generated by rgbfix. ; The space here is allocated to prevent code from being overwritten. rept $150 - $104 db 0 ;using ds fills the area with the fill value (which may not be $00); if this is changed from $00 the ROM won't build endr SECTION "Main", ROM0 Start: ; 0x150 ld [hGameBoyColorFlag], a ld sp, hGameBoyColorFlag di xor a ld [rIF], a ld a, [rLCDC] ; LCD Control bit 7, a ; Check if LCD Display is enabled jr nz, .LCDDisplayEnabled set 7, a ld [rLCDC], a .LCDDisplayEnabled ld bc, $0002 call SGBWait1750 .waitForVBlank ld a, [rLY] ; LY register (LCDC Y-Coordinate) cp 145 ; > 144 means V-Blank jr c, .waitForVBlank ld a, $81 ld [rLCDC], a ; Enable LCD Display xor a ld [rBGP], a ; Clear Palette Data ld [rOBP0], a ld [rOBP1], a ld bc, $0002 call SGBWait1750 .waitForVBlank2 ld a, [rLY] ; LY register (LCDC Y-Coordinate) cp 145 ; > 144 means V-Blank jr c, .waitForVBlank2 xor a ld [rLCDC], a ; Disable LCD Display ld hl, wc000 ld bc, $2000 call ClearData ; Clear WRAM Bank 0 ld hl, vTilesOB ld bc, $1000 call ClearData ; Clear First half of VRAM ld a, SRAM_ENABLE ld [MBC5SRamEnable], a ; Enable RAM ld a, $1 ld [MBC5RomBank], a ; Load ROM Bank $1 ld a, $0 ld [MBC5RomBankOn], a ; Enable ROM Banking Mode ld a, $0 ld [MBC5SRamBank], a ; Set bits 5 and 6 of ROM Bank Number ld a, $1 ld [hLoadedROMBank], a ld a, $1 ld [MBC5RomBankOn], a ; Enable RAM Banking Mode ld a, $0 ld [MBC5SRamBank], a ; Load RAM Bank $0 ld sp, wStack ; Initialize stack pointer to the end of WRAM Bank $1 ld hl, hPushOAM ld bc, $007e call ClearData ; Clear High RAM (HRAM) call WriteDMACodeToHRAM call ClearOAMBuffer xor a ld [wd7fb], a ld [wd7fc], a ld [wd7fd], a ld [hHBlankRoutine], a ld [$ffb1], a ld [wd8e1], a ld [wd7fe], a ld [hSGBInit], a ld hl, hLCDC xor a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld a, $8f ld [hli], a ld a, $a6 ld [hli], a ld a, $0 ld [wd849], a ld [wd84a], a ld a, Bank(PlaySong_BankF) call SetSongBank call Func_23b ld a, [hGameBoyColorFlag] and a jr nz, .asm_222 call InitSGB rl a and $1 ld [hSGBFlag], a call SendSGBBorder ld a, [hSGBFlag] and a jr z, .asm_222 ld a, $1 ld [wd917], a .asm_222 ld a, $1 ld [rIE], a ; Only enable LCD Status interrupt ei ld a, $ff ld [wd810], a call Func_97a xor a ld [wBootCheck], a ld a, BANK(Func_1ffc) ld hl, Func_1ffc call BankSwitchSimple Func_23b: ; 0x23b ld a, [hGameBoyColorFlag] cp $11 jr nz, .asm_248 ld a, $1 ld [hGameBoyColorFlag], a ld [$fffd], a ret .asm_248 xor a ld [hGameBoyColorFlag], a ld [$fffd], a ret SoftReset: di ld sp, hGameBoyColorFlag xor a ld [rIF], a ld bc, $2 call SGBWait1750 ld hl, wc000 ld bc, $2000 call ClearData ld hl, $8000 ld bc, $1000 call ClearData ld a, SRAM_ENABLE ld [MBC5SRamEnable], a ld a, $1 ld [MBC5RomBank], a ld a, $0 ld [MBC5RomBankOn], a ld a, $0 ld [MBC5SRamBank], a ld a, $1 ld [hLoadedROMBank], a ld a, $1 ld [MBC5RomBankOn], a ld a, $0 ld [MBC5SRamBank], a ld sp, wStack call WriteDMACodeToHRAM call ClearOAMBuffer xor a ld [wd7fb], a ld [wd7fc], a ld [wd7fd], a ld [hHBlankRoutine], a ld [$ffb1], a ld [wd8e1], a ld [wd7fe], a ld hl, hLCDC xor a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ld a, $8f ld [hli], a ld a, $a6 ld [hli], a ld a, $0 ld [wd849], a ld [wd84a], a ld a, BANK(Func_3c000) call SetSongBank ld a, [hSGBFlag] and a jr z, .asm_02d5 ld a, $1 ld [wd917], a .asm_02d5 ld a, $1 ld [rIE], a ei ld a, $ff ld [wd810], a call Func_97a ld a, [hGameBoyColorFlag] ld [$fffd], a xor a ld [wBootCheck], a ld a, $0 ld hl, Func_1ffc call BankSwitchSimple ; fallthrough VBlank: ; 0x2f2 push af push bc push de push hl call hPushOAM ; OAM DMA transfer ld a, [hLCDC] ld [rLCDC], a call Func_113a ei ld a, [rLY] cp $90 jr c, .asm_328 ld hl, hSTAT ld c, rSTAT - $ff00 ld a, [hli] ld [$ff00+c], a inc c ld a, [hli] ld [$ff00+c], a inc c ld a, [hli] ld [$ff00+c], a inc c inc c ld a, [hli] ld [$ff00+c], a inc c inc c ld a, [hli] ld [$ff00+c], a inc c ld a, [hli] ld [$ff00+c], a inc c ld a, [hli] ld [$ff00+c], a inc c ld a, [hli] ;hWY ld [$ff00+c], a ;into FF4A inc c ld a, [hli] ld [$ff00+c], a .asm_328 ld a, [hLYC] ld [hLastLYC], a ld a, [hNextLYCSub] ld [hLYCSub], a ld a, [hNextFrameHBlankSCX] ld [hHBlankSCX], a ld a, [hNextFrameHBlankSCY] ld [hHBlankSCY], a call ReadJoypad ld a, [wBootCheck] and a jr nz, .skipBootCheck ld a, [hJoypadState] cp $f jr nz, .skipBootCheck ld a, [hNewlyPressedButtons] and $f jr z, .skipBootCheck ld hl, sp + 8 ld [hl], Func_3c3 & $ff inc hl ld [hl], Func_3c3 >> 8 ld a, $1 ld [wBootCheck], a .skipBootCheck ld hl, hNumFramesSinceLastVBlank ld a, [hl] inc [hl] and a jr nz, .asm_365 ld hl, hNumFramesDropped inc [hl] .asm_365 ld hl, hVBlankCount inc [hl] ld a, [wd8e1] and a call nz, Func_167b ld a, [wd849] and a jr nz, .asm_37d ld a, [wd85d] and a call nz, UpdateSFX .asm_37d ld a, [wd84a] and a jr z, .asm_39d xor a ld [wd84a], a ld a, $1 ld [wd849], a ld a, $bc ld [rTMA], a ld a, $0 ld [rTAC], a ld hl, rIE set 2, [hl] ld a, $4 ld [rTAC], a .asm_39d ld hl, MBC5SRamBank ld a, [wd917] and a jr nz, .asm_3b5 ld a, [wRumblePattern] rrca ld [wRumblePattern], a and $1 jr z, .asm_3b5 set 3, [hl] jr .asm_3b7 .asm_3b5 res 3, [hl] .asm_3b7 ld a, [wDrawBottomMessageBox] and a call nz, DrawBottomMessageBox pop hl pop de pop bc pop af reti Func_3c3: ld a, [rLCDC] bit 7, a jr z, .asm_03cf call FadeOut ; Fades palettes in from white screen. call DisableLCD .asm_03cf ld hl, hSTAT res 6, [hl] ld hl, rIE res 1, [hl] xor a ld [MBC5SRamEnable], a ld [rSB], a ld [rSC], a ld [rIE], a ld [rNR52], a ld a, [$fffd] ld [hGameBoyColorFlag], a jp SoftReset LCD: ; 0x3ec push af push bc push de push hl ld a, [hHBlankRoutine] sla a ld c, a ld b, $0 ld hl, PointerTable_408 add hl, bc ld a, [hli] ld h, [hl] ld l, a jp hl Func_3ff: ; 0x3ff ld a, $1 ld [$ffb5], a pop hl pop de pop bc pop af reti PointerTable_408: ; 0x408 dw Func_fbc dw Func_fbf dw Func_fea dw Func_105d dw Func_109e dw Func_10a1 dw Func_10a4 dw Func_10a7 Timer: ; 0x418 ei push af push bc push de push hl ld a, [wd849] and a jr z, .asm_42a ld a, [wd85d] and a call nz, UpdateSFX .asm_42a ld a, [wd84a] and a jr z, .asm_440 xor a ld [wd84a], a ld [wd849], a ld a, $0 ld [rTAC], a ld hl, rIE res 2, [hl] .asm_440 pop hl pop de pop bc pop af reti Serial: ; 0x445 push af push bc push de push hl ld hl, Data_45d push hl ld a, [$ffb1] sla a ld c, a ld b, $0 ld hl, Data_462 add hl, bc ld c, [hl] inc hl ld b, [hl] push bc ret Data_45d: db $e1, $d1, $c1, $f1, $d9 Data_462: db $64, $16, $66, $04, $c9 Joypad: ; 0x467 reti DelayFrame: ; 0x468 ld a, [rLCDC] bit 7, a ret z ld hl, hNumFramesSinceLastVBlank xor a ld [hl], a .asm_472 ld a, [hl] and a jr z, .asm_472 ret JumpToFuncInTable: ; 0x477 ; Jumps to a function in the pointer table immediately following ; a "rst JumpTable" call. Function must be in the same Bank as the pointer table. ; input: a = index of function in table sla a pop hl push de ld e, a ld d, $0 add hl, de ld e, [hl] inc hl ld d, [hl] ld l, e ld h, d pop de jp hl _ReadHalfword: ; 0x486 rlca add l ld l, a jr nc, .noCarry inc h .noCarry ld a, [hli] ld h, [hl] ld l, a ret INCLUDE "home/audio.asm" CallInFollowingTable: ; 0x532 ; Calls a function in a table located immediately after a call to this function. ; Inputs: a = entry in the table ld e, a ld d, $0 sla e rl d sla e rl d ; multiplied a by 4 because entries in the table are 4 bytes each pop hl add hl, de ld e, [hl] inc hl ld d, [hl] inc hl ld a, [hl] ld h, d ld l, e jp BankSwitch BankSwitchSimple: ; 0x549 ; Switches to Bank in register a and jumps to hl. ld [hLoadedROMBank], a ld [MBC5RomBank], a ; Load Bank jp hl BankSwitch: ; 0x54f ld e, a ld a, [hLoadedROMBank] ; currently-loaded Bank cp e jr z, .doJump push af ld a, e call .loadNewBank call .doJump pop de ld a, d .loadNewBank push hl push de ld hl, rIE ld d, [hl] ld [hl], $0 ld [MBC5RomBank], a ld [hLoadedROMBank], a ld [hl], d pop de pop hl ret .doJump ld a, [hFarCallTempE] ld e, a ld a, [hFarCallTempA] jp hl DisableLCD: ; 0x576 ld a, [rLCDC] bit 7, a ret z ld a, [hLCDC] res 7, a ld [hLCDC], a .asm_581 ld a, [rLCDC] bit 7, a jr nz, .asm_581 ret EnableLCD: ; 0x588 ld a, [hFFC4] and a call nz, .UpdatePals ld a, [hLCDC] set 7, a ld [rLCDC], a ld [hLCDC], a ret .UpdatePals ld de, rBGPI ld a, $80 ld [de], a inc de ld b, $8 .asm_5a0 ld a, [wBGP] call .UpdateDMGPals dec b jr nz, .asm_5a0 ld de, rOBPI ld a, $80 ld [de], a inc de ld b, $4 .asm_5b2 ld a, [wOBP0] call .UpdateDMGPals ld a, [wOBP1] call .UpdateDMGPals dec b jr nz, .asm_5b2 ret .UpdateDMGPals push bc ld b, $4 .asm_5c5 push af push bc and $3 sla a ld c, a ld b, $0 ld hl, GreyscalePalette add hl, bc ld a, [hli] ld [de], a ld a, [hli] ld [de], a pop bc pop af srl a srl a dec b jr nz, .asm_5c5 pop bc ret GreyscalePalette: RGB 31, 31, 31 RGB 21, 21, 21 RGB 11, 11, 11 RGB 0, 0, 0 VBlankIntDisable: ld a, [rIE] res 0, a ld [rIE], a ret VBlankIntEnable: ld a, [rIE] set 0, a ld [rIE], a ret WriteDMACodeToHRAM: ; 0x5f7 ; Initializes registers hPushOAM - hFarCallTempA ld c, $80 ld b, $a ; number of bytes to load ld hl, DMARoutine .loop ld a, [hli] ld [$ff00+c], a ; add register c to $ff00, and store register a into the resulting address inc c dec b jr nz, .loop ret DMARoutine: ; This routine is initially loaded into hPushOAM - hFarCallTempA by WriteDMACodeToHRAM. ld a, (wOAMBuffer >> 8) ld [rDMA], a ; start DMA ld a, $28 .waitLoop ; wait for DMA to finish dec a jr nz, .waitLoop ret WaitForLCD: ; 0x60f ; Wait for LCD controller to stop reading from both OAM and VRAM because ; CPU can't access OAM, VRAM, or palette data ($ff69, $ff6b) during this time. ld a, [rSTAT] ; LCDC Status register and $3 jr nz, WaitForLCD ld a, $a .delay40Cycles dec a jr nz, .delay40Cycles ret Func_61b: ; 0x61b ld a, [rLY] ; LY register (LCDC Y-Coordinate) cp $40 jr c, .asm_625 cp $80 jr c, .asm_63d .asm_625 ld a, [rLY] ; LY register (LCDC Y-Coordinate) cp $40 jr c, .asm_625 cp $80 jr nc, .asm_625 .asm_62f ld a, [rSTAT] and $3 jr nz, .asm_62f ; wait for lcd controller to finish transferring data ld a, $15 .wait dec a jr nz, .wait nop nop nop .asm_63d ret INCLUDE "home/copy.asm" ClearOAMBuffer: ; 0x916 ; Clears the OAM buffer by loading $f0 into all of the entries. ld hl, wOAMBuffer ; 0xd000 ld b, 4 * 40 ; wOAMBuffer is 4 * 40 bytes long (40 OAM entries, 4 bytes each) ld a, $f0 ; byte to write .loop ld [hli], a dec b jr nz, .loop xor a ld [wOAMBufferSize], a ret CleanOAMBuffer: ; 0x926 ; Cleans up any trailing unused oam slots in the oam buffer. ld a, [wOAMBufferSize] cp wOAMBufferEnd % $100 jr nc, .done ld l, a ld h, wOAMBufferEnd / $100 cpl add (wOAMBufferEnd + 1) % $100 ld b, a ld a, $f0 .loop ld [hli], a dec b jr nz, .loop .done xor a ld [wOAMBufferSize], a ret AdvanceFrames: ; 0x93f push bc rst AdvanceFrame pop bc dec bc ld a, c or b jr nz, AdvanceFrames ret SGBWait1750: ; 0x948 ld de, 1750 .asm_94b nop nop nop dec de ld a, d or e jr nz, .asm_94b dec bc ld a, b or c jr nz, SGBWait1750 ret INCLUDE "home/random.asm" INCLUDE "home/joypad.asm" Func_b66: ; 0xb66 ld a, [hGameBoyColorFlag] and a jr nz, .asm_b73 xor a ld [hBGP], a ld [hOBP0], a ld [hOBP1], a ret .asm_b73 ld de, rBGPI ld hl, wPaletteData ld b, $0 ld c, $20 .asm_b7d ld a, b ld [rBGPI], a inc b ld a, [rBGPD] ld [hli], a ld a, b ld [rBGPI], a inc b ld a, [rBGPD] ld [hli], a dec c jr nz, .asm_b7d ld b, $0 ld c, $20 .asm_b92 ld a, b ld [rOBPI], a inc b ld a, [rOBPD] ld [hli], a ld a, b ld [rOBPI], a inc b ld a, [rOBPD] ld [hli], a dec c jr nz, .asm_b92 ld de, rBGPI ld b, $2 .asm_ba8 ld a, $80 ld [de], a inc de ld c, $20 .asm_bae ld a, $ff ld [de], a ld [hli], a ld a, $7f ld [de], a ld [hli], a dec c jr nz, .asm_bae inc de dec b jr nz, .asm_ba8 ret FadeIn: ; 0xbbe ; Fades palettes in from white screen. ld a, [hGameBoyColorFlag] and a jp nz, FadeIn_GameboyColor ; Regular Gameboy ld hl, hBGP ld de, wBGP ld b, $3 .loop ld a, [de] and $55 ld c, a ld a, [de] and $aa srl a and c ld [hli], a inc de dec b jr nz, .loop ld bc, $0002 call AdvanceFrames ld hl, hBGP ld de, wBGP ld b, $3 .loop2 ld a, [de] and $aa srl a add [hl] ld [hli], a inc de dec b jr nz, .loop2 ld bc, $0002 call AdvanceFrames ld hl, hBGP ld de, wBGP ld b, $3 .loop3 ld a, [de] and $55 ld c, a ld a, [de] and $aa srl a or c add [hl] ld [hli], a inc de dec b jr nz, .loop3 ld bc, $0002 call AdvanceFrames ret FadeIn_GameboyColor: ; 0xc19 ; Fades in to the target palette data in wPaletteData from wFadeBGPaletteData and wFadeOBJPaletteData ; Fade is completed after 16 frames of incrementally updating the palettes. ld b, 16 ; fade takes 16 frames to complete .loop push bc ld de, wPaletteData ld hl, wFadeBGPaletteData call FadeInStep call SetFadedPalettes pop bc dec b jr nz, .loop ret FadeInStep: ; 0xc2d ; de = base palette data ; hl = faded palette data ld a, b cp $1 jr z, .lastStep ld c, $40 ; total number of colors in BG and OBJ palettes .loop push bc ld a, [hli] sub $42 ld c, a ld a, [hld] sbc $8 ld b, a ; subtracted 2 from each RGB value of the color call GetNextFadedPalette ld a, c ld [hli], a ld a, b ld [hli], a pop bc dec c jr nz, .loop ret .lastStep ld c, $40 ; total number of colors in BG and OBJ palettes .loop2 push bc ld a, [hli] sub $21 ld c, a ld a, [hld] sbc $4 ld b, a call GetNextFadedPalette ld a, c ld [hli], a ld a, b ld [hli], a pop bc dec c jr nz, .loop2 ret GetNextFadedPalette: ; 0xc60 ; de = source palette data ; bc = target palette RGB - 2 ; Places the resulting palette RGB into bc push hl ld a, [de] and %00011111 ; Target RGB Blue value ld l, a ld a, c and %00011111 ; Current faded RBG Blue value - 2 cp l jr nc, .brighter ; set the current faded Blue value to the target blue value. ld a, c and %11100000 or l ld c, a .brighter ld a, [de] and %11100000 ld l, a inc de ld a, [de] srl a rr l srl a rr l ld a, c and %11100000 ld h, a ld a, b srl a rr h srl a rr h ld a, h cp l jr nc, .asm_ca3 ld h, $0 sla l rl h sla l rl h ld a, c and $1f or l ld c, a ld a, b and $7c or h ld b, a .asm_ca3 ld a, [de] and $7c ld l, a ld a, b and $7c cp l jr nc, .asm_cb2 ld a, b and $3 or l ld b, a .asm_cb2 inc de pop hl ret FadeOut: ; 0xcb5 ; Fades palettes out to a white screen. ld a, [hGameBoyColorFlag] and a jp nz, FadeOut_GameboyColor ; Regular Gameboy ld hl, hBGP ld b, $3 .loop push bc push hl ld b, $3 .loop2 ld a, [hl] and $55 ld c, a ld a, [hl] and $aa srl a or c cpl inc a add [hl] ld [hli], a dec b jr nz, .loop2 ld bc, $0002 call AdvanceFrames pop hl pop bc dec b jr nz, .loop xor a ld hl, hBGP ld [hli], a ld [hli], a ld [hl], a ld bc, $0002 call AdvanceFrames ret FadeOut_GameboyColor: ; 0xcee ; Fades out to white RGB colors from the currently-loaded palettes. ; Fade is completed after 16 frames of incrementally updating the palettes. ld hl, wFadeBGPaletteData ld de, rBGPI call LoadCurrentPalettesIntoFadePalettes ld hl, wFadeOBJPaletteData ld de, rOBPI call LoadCurrentPalettesIntoFadePalettes ld b, 16 ; fade takes 16 frames to complete .loop push bc ld hl, wFadeBGPaletteData call FadeOutStep call SetFadedPalettes pop bc dec b jr nz, .loop ret FadeOutStep: ; 0xd11 ; hl = faded palette data ld b, $40 .asm_d13 ld a, [hl] and $1f add $2 ld e, a cp $1f jr c, .asm_d1f ld e, $1f .asm_d1f ld a, [hl] and $e0 or e ld [hl], a ld a, [hli] and $e0 ld e, [hl] dec hl srl e rr a srl e rr a add $10 ld e, a jr nc, .asm_d38 ld e, $f8 .asm_d38 ld d, $0 sla e rl d sla e rl d ld a, [hl] and $1f or e ld [hli], a ld a, [hl] and $7c or d ld [hl], a ld a, [hl] and $7c add $8 ld e, a cp $7c jr c, .asm_d58 ld e, $7c .asm_d58 ld a, [hl] and $3 or e ld [hli], a dec b jr nz, .asm_d13 ret SetFadedPalettes: ; 0d61 ; Sets the current palette data to the faded palettes. ld a, [rIE] res 0, a ld [rIE], a ld hl, wFadeBGPaletteData ld de, rBGPI ld a, $80 ld [de], a inc de .waitForVBlank ld a, [rLY] cp $90 jr c, .waitForVBlank ld b, $10 .loadBGColorsLoop ld a, [hli] ld [de], a ld a, [hli] ld [de], a ld a, [hli] ld [de], a ld a, [hli] ld [de], a dec b jr nz, .loadBGColorsLoop inc de ld a, $80 ld [de], a inc de ld b, $10 .loadOBJColorsLoop ld a, [hli] ld [de], a ld a, [hli] ld [de], a ld a, [hli] ld [de], a ld a, [hli] ld [de], a dec b jr nz, .loadOBJColorsLoop ld a, [rIE] set 0, a ld [rIE], a ret LoadCurrentPalettesIntoFadePalettes: ; 0xd9d ; hl = destination for palette data ; de = source of palettes (rBGPI or rOBPI) ld b, $0 ld c, e inc c call WaitForLCD .asm_da4 call Func_61b .asm_da7 ld a, [rSTAT] and $3 jr nz, .asm_da7 ; wait for lcd controller to finish transferring data ld a, b ld [de], a ld a, [$ff00+c] ld [hli], a inc b ld a, b ld [de], a ld a, [$ff00+c] ld [hli], a inc b ld a, b ld [de], a ld a, [$ff00+c] ld [hli], a inc b ld a, b ld [de], a ld a, [$ff00+c] ld [hli], a inc b nop nop nop nop nop nop nop nop nop nop nop nop nop ld a, b cp $40 jr nz, .asm_da4 ret Func_dd4: ; 0xdd4 ; Return a * l to hl ; Stupid waste of space push bc ld c, l ld b, $0 ld hl, $0000 bit 0, a jr z, .asm_de0 add hl, bc .asm_de0 sla c rl b bit 1, a jr z, .asm_de9 add hl, bc .asm_de9 sla c rl b bit 2, a jr z, .asm_df2 add hl, bc .asm_df2 sla c rl b bit 3, a jr z, .asm_dfb add hl, bc .asm_dfb sla c rl b bit 4, a jr z, .asm_e04 add hl, bc .asm_e04 sla c rl b bit 5, a jr z, .asm_e0d add hl, bc .asm_e0d sla c rl b bit 6, a jr z, .asm_e16 add hl, bc .asm_e16 sla c rl b bit 7, a jr z, .asm_e1f add hl, bc .asm_e1f pop bc ret ConvertHexByteToDecWord: ; 0xe21 ; Convert the base-16 value in register a into a Binary Coded Decimal (base-10) word. ; Example: If a = $97, de = $0151. ld b, a ld hl, PowersOfTwo ld de, $0000 .asm_e28 srl b ld a, [hli] jr nc, .asm_e34 add e daa ld e, a ld a, [hl] adc d daa ld d, a .asm_e34 inc hl ld a, b and a jr nz, .asm_e28 ret PowersOfTwo: ; 0xe3a dw $0001 dw $0002 dw $0004 dw $0008 dw $0016 dw $0032 dw $0064 dw $0128 Increment_Max100: ; 0xe4a ; Increments the value at [hl], but caps it at 100. ; Sets carry flag if the increment happens. ld a, [hl] cp $64 jr z, .maxValue inc a ld [hl], a scf ret .maxValue and a ret Modulo_C: ; 0xe55 ; Calculates A modulo C ; Sets zero flag if result is zero cp c jr c, .done sub c jr Modulo_C .done and a ret Func_e5d: ; 0xe5d ld a, $1 ld [wd84a], a .asm_e62 ld a, [wd84a] and a jr nz, .asm_e62 ret DrawBottomMessageBox: ; 0xe69 ; Draws the current scrolling bottom message box to VRAM during V-Blank. ; Note, this only applies to the 1-tile high message bar. When it displays, things like Ball Bonus summary, and ; the Save/Cancel menu, this is not used to draw the message buffer. ld a, [rLY] cp $90 jr nc, DrawBottomMessageBox ; ensure we're in V-Blank .asm_e6f ld a, [rSTAT] and $3 jr nz, .asm_e6f ld a, $a .asm_e77 dec a jr nz, .asm_e77 ld hl, wBottomMessageBuffer + $40 call Load4BottomMessageBytes push hl ld hl, $9c00 call Write4BottomMessageBytes pop hl call Load4BottomMessageBytes push hl ld hl, $9c04 call Write4BottomMessageBytes pop hl call Load4BottomMessageBytes push hl ld hl, $9c08 call Write4BottomMessageBytes pop hl call Load4BottomMessageBytes push hl ld hl, $9c0c call Write4BottomMessageBytes pop hl call Load4BottomMessageBytes push hl ld hl, $9c10 call Write4BottomMessageBytes pop hl ld hl, wBottomMessageBuffer + $c0 call Load4BottomMessageBytes push hl ld hl, $9c20 call Write4BottomMessageBytes pop hl call Load4BottomMessageBytes push hl ld hl, $9c24 call Write4BottomMessageBytes pop hl call Load4BottomMessageBytes push hl ld hl, $9c28 call Write4BottomMessageBytes pop hl call Load4BottomMessageBytes push hl ld hl, $9c2c call Write4BottomMessageBytes pop hl call Load4BottomMessageBytes push hl ld hl, $9c30 call Write4BottomMessageBytes pop hl ret Load4BottomMessageBytes: ; 0xeef ld a, [hli] ld b, a ld a, [hli] ld c, a ld a, [hli] ld d, a ld a, [hli] ld e, a ret Write4BottomMessageBytes: ; 0xef8 ld a, [rSTAT] and $3 jr nz, Write4BottomMessageBytes ld a, b ld [hli], a ld a, c ld [hli], a ld a, d ld [hli], a ld a, e ld [hli], a ld a, $a .asm_f08 dec a jr nz, .asm_f08 ret INCLUDE "home/save.asm" Func_fbc: ; 0xfbc jp Func_3ff Func_fbf: ; 0xfbf ld hl, hLastLYC ld c, [hl] ld a, [rLY] cp c jp c, Func_3ff inc c inc c cp c jp nc, Func_3ff ld a, [hLCDCMask] ld c, a ld a, [hLCDC] xor $10 and c ld c, a ld hl, rSTAT .asm_fdb ld a, [hl] and $3 jr nz, .asm_fdb ld a, [rLCDC] and $80 or c ld [rLCDC], a jp Func_3ff Func_fea: ; 0xfea ld hl, hLastLYC ld a, [hLYCSub] cp [hl] jr nz, .asm_1015 ld a, [rLY] cp [hl] jp nz, Func_3ff ld a, [hLCDC] xor $18 ld c, a ld a, [hHBlankSCX] ld b, a ld hl, rSTAT .asm_1003 ld a, [hl] and $3 jr nz, .asm_1003 ld a, [rLCDC] and $80 or c ld [rLCDC], a ld a, b ld [rSCY], a jp Func_3ff .asm_1015 ld a, [rLY] cp [hl] jr nz, .asm_1037 ld a, [hLastLYC] ld hl, hLYCSub sub [hl] add $40 ld c, a ld a, [hLYCSub] ld b, a ld hl, rSTAT .asm_1029 ld a, [hl] and $3 jr nz, .asm_1029 ld a, c ld [rSCY], a ld a, b ld [rLYC], a jp Func_3ff .asm_1037 ld hl, hLYCSub ld a, [rLY] cp [hl] jp nz, Func_3ff ld a, [hLCDC] xor $18 ld c, a ld a, [hHBlankSCX] ld b, a ld hl, rSTAT .asm_104b ld a, [hl] and $3 jr nz, .asm_104b ld a, [rLCDC] and $80 or c ld [rLCDC], a ld a, b ld [rSCY], a jp Func_3ff Func_105d: ; 0x105d ld hl, hLastLYC ld a, [rLY] cp [hl] jr z, .asm_1069 dec a cp [hl] jr nz, .asm_1080 .asm_1069 ld a, [hLYCSub] ld c, a ld a, [hHBlankSCX] ld b, a ld hl, rSTAT .asm_1072 ld a, [hl] and $3 jr nz, .asm_1072 ld a, b ld [rSCY], a ld a, c ld [rLYC], a jp Func_3ff .asm_1080 ld hl, hLYCSub ld a, [rLY] cp [hl] jr z, .asm_108d dec a cp [hl] jp nz, Func_3ff .asm_108d ld a, [hHBlankSCY] ld b, a ld hl, rSTAT .asm_1093 ld a, [hl] and $3 jr nz, .asm_1093 ld a, b ld [rSCY], a jp Func_3ff Func_109e: ; 0x109e jp Func_3ff Func_10a1: ; 0x10a1 jp Func_3ff Func_10a4: ; 0x10a4 jp Func_3ff Func_10a7: ; 0x10a7 jp Func_3ff Func_10aa: ; 0x10aa ld c, a ld a, [hli] ld b, a .loop push bc ld a, c ld c, [hl] inc hl ld b, [hl] inc hl push af ld a, [bc] ld e, a inc bc ld a, [bc] ld d, a inc bc pop af push hl call Func_10c5 pop hl pop bc dec b jr nz, .loop ret Func_10c5: ; 0x10c5 push af ld a, [rLCDC] bit 7, a jr z, .skip_wait_ly .wait_ly ld a, [rLY] cp $88 jr nc, .wait_ly .skip_wait_ly pop af ld hl, wd7fb ld l, [hl] ld h, wcb00 / $100 inc bc ld [hl], c inc h ld [hl], b inc h ld [hl], a inc h ld [hl], e inc h ld [hl], d ld e, $ff ld [hROMBankBuffer], a ld a, [hLoadedROMBank] push af ld a, [hROMBankBuffer] ld [hLoadedROMBank], a ld [MBC5RomBank], a dec bc ld a, [bc] ld hl, wd7fa add [hl] cp $30 jr c, .size_okay ld a, [bc] ld e, $0 .size_okay add $4 ld [hl], a pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, wd7fb ld l, [hl] ld h, wca00 / $100 inc l ld [hl], $0 dec l ld [hl], e ld hl, wd7fb inc [hl] ld a, [rLCDC] bit 7, a ret nz ld a, [rIE] push af res 0, a ld [rIE], a call Func_113a pop af ld [rIE], a ret Func_1129: ; 0x1129 ld a, [wd7fb] ld [wd7fc], a ret Func_1130: ; 0x1130 push hl ld a, [wd7fb] ld hl, wd7fc cp [hl] pop hl ret Func_113a: ; 0x113a ld hl, wd7fc ld a, [wd7fb] cp [hl] ret z ld l, [hl] ld h, $ca ld [hl], $ff .loop ld a, [hl] and a jr z, .done push hl inc h ld e, [hl] inc h ld d, [hl] inc h ld a, [hLoadedROMBank] push af ld a, [hl] ld [hLoadedROMBank], a ld [MBC5RomBank], a inc h ld a, [hl] inc h ld h, [hl] ld l, a call JumpToHL pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a pop hl inc l jr .loop .done ld a, l ld [wd7fc], a ld hl, wd7fb cp [hl] ret nz xor a ld [wd7fa], a ret JumpToHL: ; 0x117a jp hl LoadTileLists: ; 0x117b ; Loads a series of defined tile ids into VRAM ; input: de = pointer to data structure ; data structure: list of VRAM tile data with the following format ; [num tiles][destination pointer][list of tile ids] ld h, d ld l, e .loadTileSequence ld a, [hli] and a ret z ld b, a ld a, [hli] ld e, a ld a, [hli] ld d, a ; de = destination for tile data .loadTileData ld a, [hli] ld [de], a inc de dec b jr nz, .loadTileData jr .loadTileSequence LoadTileListsBank1: ; 0x118d ld a, $1 ld [rVBK], a call LoadTileLists xor a ld [rVBK], a ret Func_1198: ld h, d ld l, e .asm_119a ld a, [hli] and a ret z ld b, a ld a, [hli] ld e, a ld a, [hli] ld d, a srl b jr nc, .asm_11a8 ld a, [hli] ld c, a .asm_11a8 push hl ld h, d ld l, e ld a, c .asm_11ac ld [hli], a inc a dec b jr nz, .asm_11ac ld c, a pop hl jr .asm_119a Func_11b5: ; 11b5 (0:11b5) ld h, d ld l, e .asm_11b7 ld a, [hli] and a ret z ld b, a ld a, [hli] ld e, a ld a, [hli] ld d, a ld a, [hli] .asm_11c0 ld [de], a inc de dec b jr nz, .asm_11c0 jr .asm_11b7 Func_11c7: ld a, $1 ld [rVBK], a call Func_11b5 xor a ld [rVBK], a ret Func_11d2: ld h, d ld l, e ld a, [hLoadedROMBank] ld [$ff94], a .asm_11d8 ld a, [hli] and a ret z ld [$ff95], a ld a, [hli] ld e, a ld a, [hli] ld d, a ld a, [hli] ld c, a ld a, [hli] ld b, a ld a, [hli] ld [hLoadedROMBank], a ld [MBC5RomBank], a push hl ld h, b ld l, c ld a, [$ff95] ld b, a .asm_11f1 ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc e ld a, [hli] ld [de], a inc de dec b jr nz, .asm_11f1 pop hl ld a, [$ff94] ld [hLoadedROMBank], a ld [MBC5RomBank], a jr .asm_11d8 Func_122e: ld a, $1 ld [rVBK], a ld h, d ld l, e ld a, [hLoadedROMBank] ld [$ff94], a .asm_1238 ld a, [hli] and a jr nz, .asm_1240 xor a ld [rVBK], a ret .asm_1240 ld [$ff95], a ld a, [hli] ld e, a ld a, [hli] ld d, a ld a, [hli] ld c, a ld a, [hli] ld b, a ld a, [hli] ld [hLoadedROMBank], a ld [MBC5RomBank], a push hl ld h, b ld l, c ld a, [$ff95] ld b, a .asm_1256 ld a, [hli] ld [de], a inc de dec b jr nz, .asm_1256 pop hl ld a, [$ff94] ld [hLoadedROMBank], a ld [MBC5RomBank], a jr .asm_1238 LoadPalettes: ; Loads either BG or OAM palette data ; de = pointer to palette data ; first byte is number of colors to load ; second byte determines BG or OAM palette data ; third and fourth byte are a pointer to actual color data ; fifth byte is Bank of actual color data ; $00 marks the end of the list ld h, d ld l, e .loop ld a, [hli] and a ret z ld [$ff94], a ld a, [hli] bit 6, a ld de, rBGPI jr z, .asm_127a res 6, a ld de, rOBPI .asm_127a set 7, a ld [de], a inc de ld a, [hli] ld c, a ld a, [hli] ld b, a ld a, [hLoadedROMBank] push af ld a, [hli] ld [hLoadedROMBank], a ld [MBC5RomBank], a push hl ld h, b ld l, c ld a, [$ff94] ld b, a .loadColor ld a, [hli] ld [de], a ld a, [hli] ld [de], a dec b jr nz, .loadColor pop hl pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a jr .loop INCLUDE "home/sgb.asm" INCLUDE "home/serial.asm" Func_1a21: ; 0x1a21 call Func_1a59 call Func_1a89 jr c, .asm_1a3f .asm_1a29 call Func_1aa9 call Func_1b3d jr c, .asm_1a3f ld a, [wd86c] and a jr z, .asm_1a29 call Func_1b60 jr c, .asm_1a3f call Func_1b88 .asm_1a3f call Func_1ba7 ret Func_1a43: ; 0x1a43 xor a ld [wd86e], a call Func_1a59 call Func_1a89 jr c, .asm_1a54 ld a, $1 ld [wd86e], a .asm_1a54 call Func_1ba7 ret ret ; unused instruction? Func_1a59: ; 0x1a59 ld [wd86a], a ld a, h ld [wd869], a ld a, l ld [wd868], a ld a, $80 ld [wd866], a ld a, $c2 ld [wd867], a xor a ld [wd86b], a ld [wd86c], a ld [wd86d], a call Func_16a2 ld hl, rIE set 3, [hl] xor a ld [$ffb1], a ld a, $1 ld [wd8e1], a ret Func_1a89: ; 0x1a89 call Func_16e2 cp $f0 jr z, .asm_1a9f cp $ff jp z, Func_1bb2 ld a, [wd8c8] cp $81 jp nz, Func_1bb2 and a ret .asm_1a9f ld a, [hNewlyPressedButtons] bit 1, a jp nz, Func_1bd3 rst AdvanceFrame jr Func_1a89 Func_1aa9: ; 0x1aa9 ld a, [wd866] ld l, a ld a, [wd867] ld h, a ld de, wc000 ld b, $2 .asm_1ab6 ld c, $14 .asm_1ab8 ld a, [hli] call Func_1ae2 dec c jr nz, .asm_1ab8 ld a, l add $c ld l, a jr nc, .asm_1ac6 inc h .asm_1ac6 dec b jr nz, .asm_1ab6 ld a, l ld [wd866], a ld a, h ld [wd867], a ld a, [wd86b] inc a ld [wd86b], a cp $9 jr nz, .asm_1ae1 ld a, $1 ld [wd86c], a .asm_1ae1 ret Func_1ae2: ; 0x1ae2 push bc push hl xor $80 swap a ld c, a and $f ld b, a ld a, c and $f0 ld c, a ld a, [wd868] ld l, a ld a, [wd869] ld h, a add hl, bc ld a, [hLoadedROMBank] push af ld a, [wd86a] ld [hLoadedROMBank], a ld [MBC5RomBank], a REPT 15 ld a, [hli] ld [de], a inc e ENDR ld a, [hli] ld [de], a inc de pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a pop hl pop bc ret Func_1b3d: ; 0x1b3d ld a, [wd86c] ld [wd8dd], a ld hl, wc000 ld a, $1 call Func_1779 cp $ff jp z, Func_1bb2 cp $f0 jr z, .asm_1b56 and a ret .asm_1b56 ld a, [hNewlyPressedButtons] bit BIT_B_BUTTON, a jp nz, Func_1bd3 rst AdvanceFrame jr Func_1b3d Func_1b60: ; 0x1b60 ld a, $1 ld [wd8a8], a ld a, $13 ld [wd8a9], a call Func_1740 cp $ff jp z, Func_1bb2 cp $f0 jr z, .asm_1b7e ld bc, $001e call AdvanceFrames and a ret .asm_1b7e ld a, [hNewlyPressedButtons] bit BIT_B_BUTTON, a jp nz, Func_1bd3 rst AdvanceFrame jr Func_1b60 Func_1b88: ; 0x1b88 ld a, [wd8c7] ld b, a cp $ff jr z, Func_1bb2 and $f0 jr nz, Func_1bb2 bit 1, b jr nz, .asm_1b9d call Func_16a2 and a ret .asm_1b9d ld a, [hNewlyPressedButtons] bit BIT_B_BUTTON, a jp nz, Func_1bd3 rst AdvanceFrame jr Func_1b88 Func_1ba7: ; 0x1ba7 ld hl, rIE res 3, [hl] xor a ld [wd8e1], a and a ret Func_1bb2: ; 0x1bb2 ld hl, Data_1bcf ld a, [wd8c7] cp $ff jr z, .asm_1bc6 ld b, $3 .asm_1bbe inc hl sla a jr c, .asm_1bc6 dec b jr nz, .asm_1bbe .asm_1bc6 ld a, [hl] ld [wd86d], a call Func_16a2 scf ret Data_1bcf: ; $ff, >$7f, >$3f, else db $02, $01, $04, $03 Func_1bd3: ; 0x1bd3 lb de, $00, $01 call PlaySoundEffect ld a, $5 ld [wd86d], a call Func_16a2 scf ret INCLUDE "home/ir.asm" Func_1ed9: push bc push de push hl ld e, a ld d, $0 sla e rl d ld a, [hLoadedROMBank] push af ld a, BANK(Data_8f06) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, Data_8f06 jr asm_1f3b Func_1ef2: push bc push de push hl ld e, a ld d, $0 sla e rl d ld a, [hLoadedROMBank] push af ld a, BANK(Data_8f06) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, Data_8f06 jr asm_1f3b LoadOAMData2: ; 0x1f0b ; This function loads OAM data, but it adds b and c to the x and y values ; input: a = OAM data id (see OAMDataPointers2) push bc push de push hl ld e, a ld d, $0 sla e rl d ld a, [hLoadedROMBank] push af ld a, Bank(OAMDataPointers2) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, OAMDataPointers2 jr asm_1f3b LoadOAMData: ; 0x1f24 ; This function loads OAM data, but it adds b and c to the x and y values ; input: a = OAM data id (see OAMDataPointers) push bc push de push hl ld e, a ld d, $0 sla e rl d ; multiply de by 2 ld a, [hLoadedROMBank] push af ld a, Bank(OAMDataPointers) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, OAMDataPointers asm_1f3b: ; 0x1f3b add hl, de ; hl points to oam pointer in OAMDataPointers ld a, [hli] ld e, a ld a, [hl] ld d, a ; de points to OAM data ld a, [wOAMBufferSize] ld l, a ld h, (wOAMBuffer >> 8) .loadOAMDataLoop ld a, [de] cp $80 ; OAM data list terminator jr z, .doneReadingOAMData add c ld [hli], a inc de ld a, [de] add b ld [hli], a inc de ld a, [de] ld [hli], a inc de ld a, [de] ld [hli], a inc de jr .loadOAMDataLoop .doneReadingOAMData ld a, l ld [wOAMBufferSize], a pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a pop hl pop de pop bc ret Func_1f68: push bc push de push hl ld e, a ld d, $0 sla e rl d ld a, [hLoadedROMBank] push af ld a, BANK(Data_8f06) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, Data_8f06 ; all 0s jr asm_1fca Func_1f81: push bc push de push hl ld e, a ld d, $0 sla e rl d ld a, [hLoadedROMBank] push af ld a, BANK(Data_8f06) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, Data_8f06 ; all 0s jr asm_1fca Func_1f9a: push bc push de push hl ld e, a ld d, $0 sla e rl d ld a, [hLoadedROMBank] push af ld a, BANK(OAMDataPointers2) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, OAMDataPointers2 jr asm_1fca Func_1fb3: push bc push de push hl ld e, a ld d, $0 sla e rl d ld a, [hLoadedROMBank] push af ld a, BANK(OAMDataPointers) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, OAMDataPointers asm_1fca add hl, de ld a, [hli] ld e, a ld a, [hl] ld d, a ld a, [wOAMBufferSize] ld l, a ld h, $d0 .asm_1fd5 ld a, [de] cp $80 jr z, .asm_1fee add c ld [hli], a inc de ld a, [de] add b ld [hli], a inc de ld a, [de] push hl ld hl, sp+$7 add [hl] pop hl ld [hli], a inc de ld a, [de] ld [hli], a inc de jr .asm_1fd5 .asm_1fee ld a, l ld [wOAMBufferSize], a pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a pop hl pop de pop bc ret Func_1ffc: ; 0x1ffc ld a, $b ld [wd806], a ld a, $4 ld [wd807], a callba Func_3c000 ld a, $1 ld [wd85d], a ld a, $37 ; space character for player high scores name ld [wPlayerName], a ld [wPlayerName + 1], a ld [wPlayerName + 2], a ld a, SCREEN_ERASE_ALL_DATA ld [wCurrentScreen], a .master_loop call TickRumbleDuration call DoScreenLogic call CleanOAMBuffer call ClearPersistentJoypadStates rst AdvanceFrame jr .master_loop TickRumbleDuration: ; 0x2034 ; Decrements the Gameboy rumble duration. ; Turns off rumble when it gets to 0. ld a, [wRumbleDuration] and a jr z, .rumbleOff dec a ld [wRumbleDuration], a ret .rumbleOff ld [wRumblePattern], a ret DoScreenLogic: ; 0x2043 ld a, [wCurrentScreen] call CallInFollowingTable CallTable_2049: ; 0x2049 ; First two bytes is function pointer. ; Third byte is bank of function. ; Fourth byte seems to be unused. ; SCREEN_SELECT_GAMEBOY_TARGET padded_dab HandleSelectGameboyTargetMenu ; SCREEN_ERASE_ALL_DATA padded_dab HandleEraseAllDataMenu ; SCREEN_COPYRIGHT padded_dab HandleCopyrightScreen ; SCREEN_TITLESCREEN padded_dab HandleTitlescreen ; SCREEN_PINBALL_GAME padded_dab HandlePinballGame ; SCREEN_POKEDEX padded_dab HandlePokedexScreen ; SCREEN_OPTIONS padded_dab HandleOptionsScreen ; SCREEN_HIGH_SCORES padded_dab HandleHighScoresScreen ; SCREEN_FIELD_SELECT padded_dab HandleFieldSelectScreen ; end of call table LoadDexVWFCharacter: ; 0x206d ; Loads a single variable-width-font character used in various parts of the Pokedex screen. ld a, [hLoadedROMBank] push af ld a, Bank(LoadDexVWFCharacter_) ld [hLoadedROMBank], a ld [MBC5RomBank], a call LoadDexVWFCharacter_ jr c, .asm_2084 pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a and a ret .asm_2084 pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a scf ret Func_208c: ; 0x208c ld a, [hLoadedROMBank] push af ld a, Bank(Func_8ee0) ld [hLoadedROMBank], a ld [MBC5RomBank], a call Func_8ee0 jr c, .asm_20a3 pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a and a ret .asm_20a3 pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a scf ret MultiplyBbyCUnsigned: ; 0x20ab ; u16 bc = (u8)b * (u8)c push af xor a ld [hSignedMathSignBuffer], a jr asm_20c6 MultiplyBbyCSigned: ; s16 bc = (s8)b * (s8)c push af ld a, b xor c ld [hSignedMathSignBuffer], a bit 7, b jr z, .asm_20be ld a, b cpl inc a ld b, a .asm_20be bit 7, c jr z, asm_20c6 ld a, c cpl inc a ld c, a asm_20c6 ; b*c == (b**2 + c**2 - (b - c)**2) / 2 push de push hl ld a, b cp c jr nc, .c_le_b ld b, c ld c, a .c_le_b ; hl = b**2 + c**2 ld h, SquaresLow / $100 ld l, c ld e, [hl] inc h ; SquaresHigh / $100 ld d, [hl] ld l, b ld a, [hl] dec h ld l, [hl] ld h, a add hl, de push af ; hl -= (b - c) ** 2 ld d, SquaresLow / $100 ld a, b sub c ld e, a ld a, [de] ld c, a inc d ; SquaresHigh / $100 ld a, [de] ld b, a ld a, l sub c ld l, a ld a, h sbc b ld h, a jr nc, .no_carry pop af ccf jr .check_sign .no_carry pop af .check_sign ; hl /= 2 rr h rr l ld b, h ld c, l ld a, [hSignedMathSignBuffer] rlca jr nc, .done ld a, c cpl add $1 ld c, a ld a, b cpl adc $0 ld b, a .done pop hl pop de pop af ret MultiplyBCByEAndRoundToMostSignificantShort: ; 0x210b ; bc = round(bc * e / 256) ; b^d = sign of output push af push hl ld a, b xor d ld [hSignedMathSignBuffer2], a bit 7, b jr z, .positive1 ld a, c cpl add $1 ld c, a ld a, b cpl adc $0 ld b, a .positive1 push bc ld b, e call MultiplyBbyCUnsigned ld l, c ld h, b ld bc, $0080 add hl, bc ld l, h ld h, $0 pop bc ld c, e call MultiplyBbyCUnsigned add hl, bc ld a, [hSignedMathSignBuffer2] rlca jr nc, .positive2 ld a, l cpl add $1 ld l, a ld a, h cpl adc $0 ld h, a .positive2 ld c, l ld b, h pop hl pop af ret Cosine: ; 0x2147 ; cos(a) add $40 ; fall through Sine: ; 0x2149 ; sin(a) push hl ld [hSignedMathSignBuffer], a and $7f ; subtract 180 degrees cp $40 jr c, .firstQuadrant ; convert angle so it's between 0 and 90 degrees cpl add $80+1 .firstQuadrant ld hl, SineTable ld e, a ld d, $0 add hl, de ld e, [hl] pop hl ld d, $0 ld a, [hSignedMathSignBuffer] sla a ret nc ld d, $ff ret ApplyGravityToBall: ; 0x2168 ; Adds a constant to the pinball's y velocity. ld a, [wEnableBallGravityAndTilt] and a ret z ld de, $000b ; gravity added to y velocity every frame ld hl, wBallYVelocity ld a, [hli] ld h, [hl] ld l, a add hl, de ld a, l ld [wBallYVelocity], a ld a, h ld [wBallYVelocity + 1], a ret LimitBallVelocity: ; 0x2180 ; Ensures that the ball's x and y velocity are kept under a threshold. ; The ball can travel at a higher max speed when moving diagonally, since it ; limits the x and y components independently. ld hl, wBallXVelocity + 1 call _LimitBallVelocity ld hl, wBallYVelocity + 1 ; fall through _LimitBallVelocity: ; 0x2189 ld a, [hl] bit 7, a ; is it negative velocity? (left or up) jr nz, .negativeVelocity cp $8 ret c ld a, $7 ; max positive velocity ld [hl], a ret .negativeVelocity cp $f9 ret nc ld a, $f9 ; max negative velocity ld [hl], a ret MoveBallPosition: ; 0x219c ; Updates the ball's position according to its velocity ld a, [wBallXPos] ld [wPreviousBallXPos], a ld a, [wBallXPos + 1] ld [wPreviousBallXPos + 1], a ld a, [wBallYPos] ld [wPreviousBallYPos], a ld a, [wBallYPos + 1] ld [wPreviousBallYPos + 1], a ld de, wBallXVelocity + 1 ld hl, wBallXPos call AddVelocityToPosition ld de, wBallYVelocity + 1 ld hl, wBallYPos ; fall through AddVelocityToPosition: ; 0x21c3 ld a, [de] bit 7, a jr nz, .asm_21d1 cp 1+4 jr c, .asm_21da ld bc, $04ff jr .asm_21de .asm_21d1 cp -4 jr nc, .asm_21da ld bc, -$04ff jr .asm_21de .asm_21da ld b, a dec de ld a, [de] ld c, a .asm_21de ld a, [hl] add c ld [hli], a ld a, [hl] adc b ld [hl], a ret NegateAngleAndApplyCollisionForce: ; 0x21e5 cpl inc a ; fall through ApplyCollisionForce: ; 0x21e7 push hl ; bc_ret = bc * cos(a) + de * sin(x) ; de_ret = bc * cos(a) - de * sin(x) push bc push de ld [hSineOrCosineArgumentBuffer], a call Cosine ld a, e ld [hCosineResultBuffer], a ld a, d ld [hCosineResultBuffer + 1], a call MultiplyBCByEAndRoundToMostSignificantShort ld l, c ld h, b pop bc push bc ld a, [hSineOrCosineArgumentBuffer] call Sine ld a, e ld [hSineResultBuffer], a ld a, d ld [hSineResultBuffer + 1], a call MultiplyBCByEAndRoundToMostSignificantShort add hl, bc pop de pop bc push hl push de ld a, [hSineResultBuffer] ld e, a ld a, [hSineResultBuffer + 1] cpl ld d, a call MultiplyBCByEAndRoundToMostSignificantShort ld l, c ld h, b pop bc ld a, [hCosineResultBuffer] ld e, a ld a, [hCosineResultBuffer + 1] ld d, a call MultiplyBCByEAndRoundToMostSignificantShort add hl, bc ld d, h ld e, l pop bc pop hl ret ApplyTorque: ; 0x222b push hl ld hl, wd7f8 ld [hl], $ff bit 7, d jr nz, .asm_2297 ld [hl], $0 ld a, d cp $3 jr c, .asm_2254 ld a, $ff ld [wRumblePattern], a ld a, $1 ld [wRumbleDuration], a ld a, [wFlipperCollision] and a jr nz, .asm_2254 push de ld de, $0008 call PlaySFXIfNoneActive pop de .asm_2254 srl d rr e srl d rr e ld h, d ld l, e srl d rr e ld a, [wd7eb] and a jr z, .asm_226c .asm_2268 add hl, de dec a jr nz, .asm_2268 .asm_226c ld d, h ld e, l ld a, e cpl add $1 ld e, a ld a, d cpl adc $0 ld d, a ld a, [wBallSpin] sra a ld l, a ld h, $0 bit 7, l jr z, .asm_2286 ld h, $ff .asm_2286 add hl, bc ld b, h ld c, l push bc sla c rl b sla c rl b ld a, b ld [wBallSpin], a pop bc .asm_2297 pop hl ret LoadBallVelocity: ; 0x2299 ; Loads velocity of the ball into bc and de ; bc = x velocity ; de = y velocity push hl ld hl, wBallXVelocity ld a, [hli] ld c, a ld a, [hli] ld b, a ld a, [hli] ld e, a ld a, [hl] ld d, a pop hl ret SetBallVelocity: ; 0x22a7 ; Sets the x and y velocities of the ball. ; bc = x velocity ; de = y velocity push hl ld hl, wBallXVelocity ld a, c ld [hli], a ld a, b ld [hli], a ld a, e ld [hli], a ld a, d ld [hl], a pop hl ret CheckObjectCollision: ; 0x22b5 ld a, [wBallXPos + 1] sub $4 push af and $7 ld [wSubTileBallXPos], a ; sub-tile position pop af and $f8 ld c, a ld a, [wBallYPos + 1] sub $4 push af and $7 ld [wSubTileBallYPos], a pop af and $f8 ld b, a ld l, b ; bc contains tile coords of ball position ld h, $0 sla l rl h sla l rl h ; b was multiplied by 4 (y tile position) srl c srl c srl c ; c was divided by 8 (x tile position) ld b, $0 add hl, bc ld a, l ld [wBallPositionPointerOffsetFromStageTopLeft], a ld a, h ld [wBallPositionPointerOffsetFromStageTopLeft + 1], a ld a, [wStageCollisionMapPointer] ld c, a ld a, [wStageCollisionMapPointer + 1] ld b, a add hl, bc ; hl = address of upper-left collision byte ld a, [hLoadedROMBank] push af ld a, [wStageCollisionMapBank] ld [hLoadedROMBank], a ld [MBC5RomBank], a ld bc, $001f ; number of tiles wide - 1 ld a, [hli] ld [wUpperLeftCollisionAttribute], a ld a, [hl] ld [wUpperRightCollisionAttribute], a add hl, bc ld a, [hli] ld [wLowerLeftCollisionAttribute], a ld a, [hl] ld [wLowerRightCollisionAttribute], a pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ld a, [hLoadedROMBank] push af ld a, [wStageCollisionMasksBank] ld [hLoadedROMBank], a ld [MBC5RomBank], a ld a, [wSubTileBallXPos] sla a ld c, a ld b, $0 ld hl, SubTileXPos_CollisionDataPointers add hl, bc ld e, [hl] inc hl ld d, [hl] ld a, [wSubTileBallYPos] ld c, a ld b, $10 ; number of times to loop over .asm_233d .asm_233d push bc ld a, [de] inc de add c ; add the sub tile y pos push af srl a srl a srl a ld c, a ld b, $0 ld hl, wUpperLeftCollisionAttribute add hl, bc ld a, [hl] call Func_248a jr nc, .asm_235e pop af and $7 ld c, a ld b, $0 add hl, bc jr .asm_237b .asm_235e ld c, a ld b, $0 sla c rl b sla c rl b sla c rl b ld hl, wStageCollisionMasksPointer ld a, [hli] ld h, [hl] ld l, a add hl, bc pop af and $7 ld c, a ld b, $0 add hl, bc .asm_237b ld a, [de] inc de and [hl] push af ld a, [de] inc de ld c, a ld hl, wd7c9 add hl, bc pop af ld [hl], a pop bc dec b jr nz, .asm_233d pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ld hl, wd7c9 ld de, wd7d9 ld b, $4 .asm_239a ld a, [hli] ld [de], a inc de ld a, [hli] ld [de], a inc de ld a, [hli] ld [de], a inc de ld a, [hli] ld [de], a inc de dec b jr nz, .asm_239a ld hl, wd7c9 ld de, $0000 ld b, $0 ld a, [hl] and a jr z, .asm_23c1 .asm_23b5 ld a, [hli] inc b and a jr z, .asm_23c1 ld a, b cp $11 jr nc, .asm_23ee jr .asm_23b5 .asm_23c1 ld a, [hli] inc b and a jr nz, .asm_23cd ld a, b cp $11 jr nc, .asm_23ee jr .asm_23c1 .asm_23cd push de ld d, $1 ld c, b dec c .asm_23d2 ld a, [hli] inc b inc d and a jr nz, .asm_23d2 dec d ld a, b dec a dec a and $f swap c or c ld c, a ld a, d cp e pop de jr c, .asm_23e9 ld e, a ld d, c .asm_23e9 ld a, b cp $10 jr c, .asm_23c1 .asm_23ee ld a, e ld [wd7e9], a and a ret z ld a, [hLoadedROMBank] push af ld a, Bank(CollisionForceAngles) ld [hLoadedROMBank], a ld [MBC5RomBank], a push de ld e, d ld d, $0 ld hl, CollisionForceAngles add hl, de ld a, [hl] ld [wCollisionForceAngle], a sla e rl d ld hl, CollisionYDeltas add hl, de ld a, [wBallYPos] add [hl] ld [wBallYPos], a inc hl ld a, [wBallYPos + 1] adc [hl] ld [wBallYPos + 1], a ld hl, CollisionXDeltas add hl, de ld a, [wBallXPos] add [hl] ld [wBallXPos], a inc hl ld a, [wBallXPos + 1] adc [hl] ld [wBallXPos + 1], a pop de pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ld a, d swap a and $f ld e, a ld a, d and $f sub e jr nc, .asm_2449 add $10 .asm_2449 add e add e inc a and $1e ld c, a ld b, $0 ld hl, SubTileBallPosDeltas add hl, bc ld a, [wSubTileBallXPos] add $4 add [hl] bit 3, a ld c, b jr z, .asm_2462 ld c, $2 .asm_2462 ld a, [wSubTileBallYPos] add $4 inc hl add [hl] bit 3, a jr z, .asm_246e inc c .asm_246e ld hl, wUpperLeftCollisionAttribute add hl, bc ld a, [hl] ld [wCurCollisionAttribute], a ld hl, BallPositionPointerOffsetDeltas add hl, bc ld a, [wBallPositionPointerOffsetFromStageTopLeft] add [hl] ld [wd7f6], a ld a, [wBallPositionPointerOffsetFromStageTopLeft + 1] adc $0 ld [wd7f7], a ret Func_248a: ; 0x248a push af ld a, [wCurrentStage] bit 0, a jr nz, .asm_2495 pop af and a ret .asm_2495 pop af cp $d0 ccf ret nc cp $e0 jr nc, .asm_24ab sub $d0 sla a sla a sla a ld l, a ld h, $c4 scf ret .asm_24ab push de sub $e0 ld b, a ld a, [wCurrentStage] cp $6 ; gengar stage buggy? jr nc, .bonusStage bit 4, b ld hl, BottomLeftCollisionMasks ld a, [wd7af] jr z, .asm_24c8 res 4, b ld hl, BottomRightCollisionMasks ld a, [wd7b3] .asm_24c8 ld de, $0080 cp $7 jr c, .asm_24d5 add hl, de cp $e jr c, .asm_24d5 add hl, de .asm_24d5 ld e, b sla e sla e sla e add hl, de pop de scf ret .bonusStage bit 4, b ld hl, BottomLeftBonusStageCollisionMasks ld a, [wd7af] jr z, .asm_24f2 res 4, b ld hl, BottomRightBonusStageCollisionMasks ld a, [wd7b3] .asm_24f2 ld de, $0080 cp $7 jr c, .asm_24ff add hl, de cp $e jr c, .asm_24ff add hl, de .asm_24ff ld e, b sla e sla e sla e add hl, de pop de scf ret BallPositionPointerOffsetDeltas: db $00, $20 db $01, $21 SubTileBallPosDeltas: db 4, 0 db 4, 1 db 3, 3 db 1, 4 db 0, 4 db -1, 4 db -3, 3 db -4, 1 db -4, 0 db -4, -1 db -3, -3 db -1, -4 db 0, -4 db 1, -4 db 3, -3 db 4, -1 SubTileXPos_CollisionDataPointers: ; 0x252e dw SubTileXPos_CollisionData0 dw SubTileXPos_CollisionData1 dw SubTileXPos_CollisionData2 dw SubTileXPos_CollisionData3 dw SubTileXPos_CollisionData4 dw SubTileXPos_CollisionData5 dw SubTileXPos_CollisionData6 dw SubTileXPos_CollisionData7 SubTileXPos_CollisionData0: ; 0x253e db $00, $10, $0B db $00, $08, $0C db $00, $04, $0D db $01, $40, $0A db $01, $01, $0E db $03, $80, $09 db $13, $80, $0F db $04, $80, $08 db $14, $80, $00 db $05, $80, $07 db $15, $80, $01 db $07, $40, $06 db $07, $01, $02 db $08, $10, $05 db $08, $08, $04 db $08, $04, $03 SubTileXPos_CollisionData1: ; 0x256e db $00, $08, $0B db $00, $04, $0C db $00, $02, $0D db $01, $20, $0A db $11, $80, $0E db $03, $40, $09 db $13, $40, $0F db $04, $40, $08 db $14, $40, $00 db $05, $40, $07 db $15, $40, $01 db $07, $20, $06 db $17, $80, $02 db $08, $08, $05 db $08, $04, $04 db $08, $02, $03 SubTileXPos_CollisionData2: ; 0x259e db $00, $04, $0B db $00, $02, $0C db $00, $01, $0D db $01, $10, $0A db $11, $40, $0E db $03, $20, $09 db $13, $20, $0F db $04, $20, $08 db $14, $20, $00 db $05, $20, $07 db $15, $20, $01 db $07, $10, $06 db $17, $40, $02 db $08, $04, $05 db $08, $02, $04 db $08, $01, $03 SubTileXPos_CollisionData3: ; 0x25ce db $00, $02, $0B db $00, $01, $0C db $10, $80, $0D db $01, $08, $0A db $11, $20, $0E db $03, $10, $09 db $13, $10, $0F db $04, $10, $08 db $14, $10, $00 db $05, $10, $07 db $15, $10, $01 db $07, $08, $06 db $17, $20, $02 db $08, $02, $05 db $08, $01, $04 db $18, $80, $03 SubTileXPos_CollisionData4: ; 0x25fe db $00, $01, $0B db $10, $80, $0C db $10, $40, $0D db $01, $04, $0A db $11, $10, $0E db $03, $08, $09 db $13, $08, $0F db $04, $08, $08 db $14, $08, $00 db $05, $08, $07 db $15, $08, $01 db $07, $04, $06 db $17, $10, $02 db $08, $01, $05 db $18, $80, $04 db $18, $40, $03 SubTileXPos_CollisionData5: ; 0x262e db $10, $80, $0B db $10, $40, $0C db $10, $20, $0D db $01, $02, $0A db $11, $08, $0E db $03, $04, $09 db $13, $04, $0F db $04, $04, $08 db $14, $04, $00 db $05, $04, $07 db $15, $04, $01 db $07, $02, $06 db $17, $08, $02 db $18, $80, $05 db $18, $40, $04 db $18, $20, $03 SubTileXPos_CollisionData6: ; 0x265e db $10, $40, $0B db $10, $20, $0C db $10, $10, $0D db $01, $01, $0A db $11, $04, $0E db $03, $02, $09 db $13, $02, $0F db $04, $02, $08 db $14, $02, $00 db $05, $02, $07 db $15, $02, $01 db $07, $01, $06 db $17, $04, $02 db $18, $40, $05 db $18, $20, $04 db $18, $10, $03 SubTileXPos_CollisionData7: ; 0x268e db $10, $20, $0B db $10, $10, $0C db $10, $08, $0D db $11, $80, $0A db $11, $02, $0E db $03, $01, $09 db $13, $01, $0F db $04, $01, $08 db $14, $01, $00 db $05, $01, $07 db $15, $01, $01 db $17, $80, $06 db $17, $02, $02 db $18, $20, $05 db $18, $10, $04 db $18, $08, $03 INCLUDE "data/sine_table.asm" INCLUDE "engine/pinball_game/object_collision/object_collision.asm" Func_2862: ; 0x2862 ld a, [wd7be] and a jr nz, .asm_287c ld a, [hGameBoyColorFlag] and a jr z, .asm_287b ld a, $0 ld hl, Data_2890 ld de, $0052 ld bc, $0004 call FarCopyPalettes .asm_287b ret .asm_287c ld a, [hGameBoyColorFlag] and a jr z, .asm_288f ld a, $0 ld hl, Data_2894 ld de, $0052 ld bc, $0004 call FarCopyPalettes .asm_288f ret Data_2890: RGB 31, 31, 31 RGB 21, 21, 27 Data_2894: RGB 27, 10, 10 RGB 20, 04, 04 CatchBarTiles: ; The tile ids for the blue CATCH! bar under the wild pokemon db $80, $AE, $AF, $B0, $B1, $B2, $B3, $80 CatchBarTilesEnd: InitAnimation: ; 0x28a0 ; Initializes an OAM animation. ; hl = pointer to first frame of animation ; de = pointer to destination animation struct ld a, [hli] ld [de], a inc de ld a, [hli] ld [de], a inc de xor a ld [de], a ret UpdateAnimation: ; 0x28a9 ; Updates an animation struct. (See wDugtrioAnimationFrameCounter) ; Input: de = pointer to 3-byte animation struct ; hl = pointer to animation frames data ; Sets carry flag if the animation is over. ld a, [de] and a ret z ; return, if counter is zero dec a ld [de], a ret nz ; return if counter is not zero after the decrement push de inc de inc de ld a, [de] ; a = current frame index inc a ld [de], a ld c, a ld b, $0 sla c rl b add hl, bc ; hl = pointer to two-byte entry in the frames data table ld a, [hli] pop de and a scf ret z ; return if the next entry is $00 push de ld [de], a ; save the animation duration inc de ld a, [hli] ld [de], a ; save the next animation frame id pop de ret INCLUDE "home/text.asm" Func_3500: ld hl, wScoreToAdd ld a, e ld [hli], a ld a, d ld [hli], a ld a, c ld [hli], a ld a, b ld [hli], a xor a ld [hli], a ld [hl], a ld bc, wScoreToAdd callba AddBigBCD6FromQueueWithBallMultiplier ret AddBCDEToCurBufferValue: ; 0x351c ld hl, wScoreToAdd ld a, e ld [hli], a ld a, d ld [hli], a ld a, c ld [hli], a ld a, b ld [hli], a xor a ld [hli], a ld [hl], a ld bc, wScoreToAdd callba AddBigBCD6FromQueue ret Func_3538: ; 0x3538 ; Add BCD value bcde to [wd47a]. Cap at $99999999. ld hl, wd47a ld a, [hl] add e daa ld [hli], a ld a, [hl] adc d daa ld [hli], a ld a, [hl] adc c daa ld [hli], a ld a, [hl] adc b daa ld [hli], a ret nc ld hl, wd47a ld a, $99 ld [hli], a ld [hli], a ld [hli], a ld [hli], a ret Retrieve8DigitBCDValueAtwd47a: ; 0x3556 ; Retrieves a 4-byte BCD value at wd47a ld a, [wd47a] ld e, a ld a, [wd47a + 1] ld d, a ld a, [wd47a + 2] ld c, a ld a, [wd47a + 3] ld b, a ret Func_3567: ; BCD add bc to hl ld a, l add c daa ld l, a ld a, h adc b daa ld h, a ret Func_3570: ; BCD add de to hl ld a, l add e daa ld l, a ld a, h adc d daa ld h, a ret Func_3579: ; 0x3579 ; Delete 4-byte BCD value at wd47a ld hl, wd47a xor a ld [hli], a ld [hli], a ld [hli], a ld [hli], a ret HandleTilts: ; 0x3582 call HandleLeftTilt call HandleRightTilt call HandleUpperTilt ret HandleLeftTilt: ; 0x358c ld a, [wLeftTiltReset] and a jr nz, .tiltCoolDown ld hl, wKeyConfigLeftTilt call IsKeyPressed2 jr z, .tiltCoolDown ld a, [wLeftTiltCounter] cp $3 jr z, .startCoolDown inc a ld [wLeftTiltCounter], a cp $1 jr nz, .skipSoundEffect lb de, $00, $3f call PlaySoundEffect .skipSoundEffect ld a, [wPinballIsVisible] ld hl, wEnableBallGravityAndTilt and [hl] jr z, .skipBallMovement ld a, [wBallXPos + 1] dec a ; move ball's position to the left by 1 pixel ld [wBallXPos + 1], a .skipBallMovement ld a, [wd79f] inc a ld [wd79f], a ld a, $1 ld [wLeftTiltPushing], a ret .startCoolDown ld a, $1 ld [wLeftTiltReset], a .tiltCoolDown xor a ld [wLeftTiltPushing], a ld a, [wLeftTiltCounter] and a jr z, .done dec a ld [wLeftTiltCounter], a ld a, [wd79f] dec a ld [wd79f], a ret .done ld hl, wKeyConfigLeftTilt call IsKeyPressed2 ret nz xor a ld [wLeftTiltReset], a ret HandleRightTilt: ; 0x35f3 ld a, [wRightTiltReset] and a jr nz, .tiltCoolDown ld hl, wKeyConfigRightTilt call IsKeyPressed2 jr z, .tiltCoolDown ld a, [wRightTiltCounter] cp $3 jr z, .startCoolDown inc a ld [wRightTiltCounter], a cp $1 jr nz, .skipSoundEffect lb de, $00, $3f call PlaySoundEffect .skipSoundEffect ld a, [wPinballIsVisible] ld hl, wEnableBallGravityAndTilt and [hl] jr z, .skipBallMovement ld a, [wBallXPos + 1] inc a ; move ball's position to the right by 1 pixel ld [wBallXPos + 1], a .skipBallMovement ld a, [wd79f] dec a ld [wd79f], a ld a, $1 ld [wRightTiltPushing], a ret .startCoolDown ld a, $1 ld [wRightTiltReset], a .tiltCoolDown xor a ld [wRightTiltPushing], a ld a, [wRightTiltCounter] and a jr z, .done dec a ld [wRightTiltCounter], a ld a, [wd79f] inc a ld [wd79f], a ret .done ld hl, wKeyConfigRightTilt call IsKeyPressed2 ret nz xor a ld [wRightTiltReset], a ret HandleUpperTilt: ; 0x365a ld a, [wUpperTiltReset] and a jr nz, .tiltCoolDown ld hl, wKeyConfigUpperTilt call IsKeyPressed2 jr z, .tiltCoolDown ld a, [wUpperTiltCounter] cp $4 jr z, .startCoolDown inc a ld [wUpperTiltCounter], a cp $1 jr nz, .skipSoundEffect lb de, $00, $3f call PlaySoundEffect .skipSoundEffect ld a, [wPinballIsVisible] ld hl, wEnableBallGravityAndTilt and [hl] jr z, .skipBallMovement ld a, [wBallYPos + 1] inc a ; move ball's position down by 1 pixel ld [wBallYPos + 1], a .skipBallMovement ld a, [wd7a0] dec a ld [wd7a0], a ld a, $1 ld [wUpperTiltPushing], a ret .startCoolDown ld a, $1 ld [wUpperTiltReset], a .tiltCoolDown xor a ld [wUpperTiltPushing], a ld a, [wUpperTiltCounter] and a jr z, .done dec a ld [wUpperTiltCounter], a ld a, [wd7a0] inc a ld [wd7a0], a ret .done ld hl, wKeyConfigUpperTilt call IsKeyPressed2 ret nz xor a ld [wUpperTiltReset], a ret ApplyTiltForces: ; 0x36c1 ld a, [wPinballIsVisible] ld hl, wEnableBallGravityAndTilt and [hl] ret z ld c, $0 ld a, [wUpperTiltPushing] srl a rl c ld a, [wRightTiltPushing] srl a rl c ld a, [wLeftTiltPushing] srl a rl c ld b, $0 sla c ld hl, Data_372d add hl, bc ld a, [hli] ld h, [hl] ld l, a bit 7, h ret nz ld a, [wCollisionForceAngle] ld c, a ld b, $0 sla c rl b sla c rl b add hl, bc ld a, [hLoadedROMBank] push af ld a, BANK(TiltLeftOnlyForce) ld [hLoadedROMBank], a ld [MBC5RomBank], a ld a, [wBallXVelocity] add [hl] ld [wBallXVelocity], a inc hl ld a, [wBallXVelocity + 1] adc [hl] ld [wBallXVelocity + 1], a inc hl ld a, [wBallYVelocity] add [hl] ld [wBallYVelocity], a inc hl ld a, [wBallYVelocity + 1] adc [hl] ld [wBallYVelocity + 1], a pop af ld [hLoadedROMBank], a ld [MBC5RomBank], a ret Data_372d: dw -1 ; no tilt dw TiltLeftOnlyForce dw TiltRightOnlyForce dw -1 ; left + right (cancel) dw TiltUpOnlyForce dw TiltUpLeftForce dw TiltUpRightForce dw TiltUpOnlyForce SECTION "bank0.2", ROM0 BottomLeftCollisionMasks: INCBIN "data/collision/masks/bottom_left_masks.masks" BottomRightCollisionMasks: INCBIN "data/collision/masks/bottom_right_masks.masks" BottomLeftBonusStageCollisionMasks: INCBIN "data/collision/masks/bottom_left_bonus_stage_masks.masks" BottomRightBonusStageCollisionMasks: INCBIN "data/collision/masks/bottom_right_bonus_stage_masks.masks" SquaresLow: x = 0 rept 256 db (x * x) % $100 x = x + 1 endr SquaresHigh: x = 0 rept 256 db (x * x) / $100 x = x + 1 endr