diff --git a/src/include/constants.asm b/src/include/constants.asm index cb6588a..7014261 100644 --- a/src/include/constants.asm +++ b/src/include/constants.asm @@ -313,30 +313,10 @@ DEF PALETTE_LIGHTER_0 EQU %11100100 DEF PALETTE_LIGHTER_1 EQU %10010000 DEF PALETTE_LIGHTER_2 EQU %01000000 DEF PALETTE_LIGHTER_3 EQU %00000000 -DEF FIELD_TOP_LEFT EQU $9800+(0*32)+1 -DEF FIELD_ROW_1 EQU $9800+(0*32)+1 -DEF FIELD_ROW_2 EQU $9800+(1*32)+1 -DEF FIELD_ROW_3 EQU $9800+(2*32)+1 -DEF FIELD_ROW_4 EQU $9800+(3*32)+1 -DEF FIELD_ROW_5 EQU $9800+(4*32)+1 -DEF FIELD_ROW_6 EQU $9800+(5*32)+1 -DEF FIELD_ROW_7 EQU $9800+(6*32)+1 -DEF FIELD_ROW_8 EQU $9800+(7*32)+1 -DEF FIELD_ROW_9 EQU $9800+(8*32)+1 -DEF FIELD_ROW_10 EQU $9800+(9*32)+1 -DEF FIELD_ROW_11 EQU $9800+(10*32)+1 -DEF FIELD_ROW_12 EQU $9800+(11*32)+1 -DEF FIELD_ROW_13 EQU $9800+(12*32)+1 -DEF FIELD_ROW_14 EQU $9800+(13*32)+1 -DEF FIELD_ROW_15 EQU $9800+(14*32)+1 -DEF FIELD_ROW_16 EQU $9800+(15*32)+1 -DEF FIELD_ROW_17 EQU $9800+(16*32)+1 -DEF FIELD_ROW_18 EQU $9800+(17*32)+1 -DEF FIELD_ROW_19 EQU $9800+(18*32)+1 -DEF FIELD_ROW_20 EQU $9800+(19*32)+1 +DEF FIELD_TOP_LEFT EQU $9800+(1*32)+1 DEF TILE_FIELD_EMPTY EQU 7 DEF TILE_PIECE_0 EQU 10 -DEF TILE_0 EQU 110 +DEF TILE_0 EQU 100 DEF NEXT_BASE_X EQU 120 DEF NEXT_BASE_Y EQU 40 DEF HOLD_BASE_X EQU 120 diff --git a/src/include/field.asm b/src/include/field.asm new file mode 100644 index 0000000..c0b1765 --- /dev/null +++ b/src/include/field.asm @@ -0,0 +1,55 @@ +IF !DEF(FIELD_ASM) +DEF FIELD_ASM EQU 1 + + +SECTION "Field Variables", WRAM0 +wField:: ds (10*21) + + +SECTION "Field Functions", ROM0 +FieldInit:: + ld hl, wField + ld bc, 10*21 + ld d, TILE_FIELD_EMPTY + call UnsafeMemSet + ret + + +BlitField:: + ; The first 14 rows can be blitted without checking for vram access. + ld de, wField + (1*10) + DEF row = 0 + REPT 14 + ld hl, FIELD_TOP_LEFT+(32*row) + REPT 10 + ld a, [de] + ld [hl+], a + inc de + ENDR + DEF row += 1 + ENDR + + ; The last 6 rows need some care. + REPT 6 + ld hl, FIELD_TOP_LEFT+(32*row) + REPT 2 +: ldh a, [rSTAT] + and STATF_LCD + cp STATF_HBL + jr z, :- +: ldh a, [rSTAT] + and STATF_LCD + cp STATF_HBL + jr nz, :- + REPT 5 + ld a, [de] + ld [hl+], a + inc de + ENDR + ENDR + DEF row += 1 + ENDR + ret + + +ENDC diff --git a/src/include/globals.asm b/src/include/globals.asm index dd43d78..d81899d 100644 --- a/src/include/globals.asm +++ b/src/include/globals.asm @@ -7,17 +7,8 @@ INCLUDE "vendor/structs.asm" INCLUDE "constants.asm" -SECTION "General Game Variables", WRAM0 -wLCDCCtr:: db -wEvenFrame:: db -wField:: ds (10*22) - - SECTION "Important Game Variables", HRAM -hCtr:: ds 1 -hScore:: ds 6 -hCLevel:: ds 6 -hNLevel:: ds 6 +hCtr:: ds 1 ; Waits for VRAM to be safe to access. (Includes hblank.) @@ -69,9 +60,9 @@ ENDM ; Sets all palettes to A. MACRO set_all_palettes - set_bg_palette a - set_obj0_palette a - set_obj1_palette a + set_bg_palette + set_obj0_palette + set_obj1_palette ENDM diff --git a/src/include/input.asm b/src/include/input.asm new file mode 100644 index 0000000..ea2cbe3 --- /dev/null +++ b/src/include/input.asm @@ -0,0 +1,149 @@ +IF !DEF(INPUT_ASM) +DEF INPUT_ASM EQU 1 + + +SECTION "Input Variables", HRAM +hUpState:: ds 1 +hDownState:: ds 1 +hLeftState:: ds 1 +hRightState:: ds 1 +hAState:: ds 1 +hBState:: ds 1 +hStartState:: ds 1 +hSelectState:: ds 1 + + + +SECTION "Input Functions", ROM0 +InputInit:: + xor a, a + ldh [hUpState], a + ldh [hDownState], a + ldh [hLeftState], a + ldh [hRightState], a + ldh [hAState], a + ldh [hBState], a + ldh [hStartState], a + ldh [hSelectState], a + ret + + +GetInput:: + ; Get the button state. +.btns + ld a, P1F_GET_BTN + ldh [rP1], a + ldh a, [rP1] + ldh a, [rP1] + ldh a, [rP1] + ldh a, [rP1] + ld b, a + +.readA + bit 0, b ; A + jr nz, .clearA +.setA + ld a, 1 + ldh [hAState], a + jr .readB +.clearA + xor a, a + ldh [hAState], a + +.readB + bit 1, b ; B + jr nz, .clearB +.setB + ld a, 1 + ldh [hBState], a + jr .readSelect +.clearB + xor a, a + ldh [hBState], a + +.readSelect + bit 2, b ; Select + jr nz, .clearSelect +.setSelect + ld a, 1 + ldh [hSelectState], a + jr .readStart +.clearSelect + xor a, a + ldh [hSelectState], a + +.readStart + bit 3, b ; Start + jr nz, .clearStart +.setStart + ld a, 1 + ldh [hStartState], a + jr .dpad +.clearStart + xor a, a + ldh [hStartState], a + + + ; Get the dpad state. +.dpad + ld a, P1F_GET_DPAD + ldh [rP1], a + ldh a, [rP1] + ldh a, [rP1] + ldh a, [rP1] + ldh a, [rP1] + ld b, a + +.readUp + bit 2, b ; Up + jr nz, .clearUp +.setUp + ld a, 1 + ldh [hUpState], a + jr .readDown +.clearUp + xor a, a + ldh [hUpState], a + +.readDown + bit 3, b ; Down + jr nz, .clearDown +.setDown + ld a, 1 + ldh [hDownState], a + jr .readLeft +.clearDown + xor a, a + ldh [hDownState], a + +.readLeft + bit 1, b ; Left + jr nz, .clearLeft +.setLeft + ldh a, [hLeftState] + cp $FF + jr z, .readRight + inc a + ldh [hLeftState], a + jr .readRight +.clearLeft + xor a, a + ldh [hLeftState], a + +.readRight + bit 0, b ; Right + jr nz, .clearRight +.setRight + ldh a, [hRightState] + cp $FF + ret z + inc a + ldh [hRightState], a + ret +.clearRight + xor a, a + ldh [hRightState], a + ret + + +ENDC diff --git a/src/include/interrupts.asm b/src/include/interrupts.asm index fba6778..fff903c 100644 --- a/src/include/interrupts.asm +++ b/src/include/interrupts.asm @@ -2,7 +2,17 @@ IF !DEF(INTERRUPTS_ASM) DEF INTERRUPTS_ASM EQU 1 +SECTION "Interrupt Variables", HRAM +hLCDCCtr:: ds 1 + + SECTION "Interrupt Initialization Functions", ROM0 +IntrInit:: + xor a, a + ldh [hLCDCCtr], a + ret + + InitializeLCDCInterrupt:: ld a, STATF_LYC ldh [rSTAT], a @@ -18,7 +28,7 @@ InitializeLCDCInterrupt:: ret -SECTION "LCDC Interrupt", ROM0[$0048] +SECTION "LCDC Interrupt", ROM0[INT_HANDLER_STAT] LCDCInterrupt: push af push hl @@ -39,11 +49,11 @@ LCDCInterrupt_WaitUntilNotBusy: ldh [rLYC], a ; Check our interrupt counter - ld a, [wLCDCCtr] + ldh a, [hLCDCCtr] cp 21 jp nz, LCDCInterrupt_End ld a, 255 - ld [wLCDCCtr], a + ldh [hLCDCCtr], a ld a, 6 ldh [rLYC], a ld a, 0 @@ -51,7 +61,7 @@ LCDCInterrupt_WaitUntilNotBusy: LCDCInterrupt_End: inc a - ld [wLCDCCtr], a + ldh [hLCDCCtr], a pop hl pop af reti diff --git a/src/include/level.asm b/src/include/level.asm new file mode 100644 index 0000000..1749ee0 --- /dev/null +++ b/src/include/level.asm @@ -0,0 +1,30 @@ +IF !DEF(LEVEL_ASM) +DEF LEVEL_ASM EQU 1 + + +SECTION "Level Variables", WRAM0 +wCLevel:: ds 6 +wNLevel:: ds 6 + + +SECTION "Level Functions", ROM0 +LevelInit:: + xor a, a + ld hl, wCLevel + ld [hl+], a + ld [hl+], a + ld [hl+], a + ld [hl+], a + ld [hl+], a + ld [hl], a + ld hl, wNLevel + ld [hl+], a + ld [hl+], a + ld [hl+], a + ld [hl+], a + ld [hl+], a + ld [hl], a + ret + + +ENDC diff --git a/src/include/score.asm b/src/include/score.asm new file mode 100644 index 0000000..5d0eb76 --- /dev/null +++ b/src/include/score.asm @@ -0,0 +1,22 @@ +IF !DEF(SCORE_ASM) +DEF SCORE_ASM EQU 1 + + +SECTION "Score Variables", WRAM0 +wScore:: ds 6 + + +SECTION "Score Functions", ROM0 +ScoreInit:: + xor a, a + ld hl, wScore + ld [hl+], a + ld [hl+], a + ld [hl+], a + ld [hl+], a + ld [hl+], a + ld [hl], a + ret + + +ENDC diff --git a/src/include/sprites.asm b/src/include/sprites.asm index 41dc5e4..e2f3614 100644 --- a/src/include/sprites.asm +++ b/src/include/sprites.asm @@ -249,92 +249,210 @@ SetNumberSpritePositions:: ld [hl], SCORE_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRScore2 ld [hl], SCORE_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRScore3 ld [hl], SCORE_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRScore4 ld [hl], SCORE_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRScore5 ld [hl], SCORE_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRScore6 ld [hl], SCORE_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld a, OAMF_PAL1 + ld [hl], a + ld a, DIGIT_BASE_X ld hl, wSPRCLevel1 ld [hl], CLEVEL_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRCLevel2 ld [hl], CLEVEL_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRCLevel3 ld [hl], CLEVEL_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRCLevel4 ld [hl], CLEVEL_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRCLevel5 ld [hl], CLEVEL_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRCLevel6 ld [hl], CLEVEL_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld a, OAMF_PAL1 + ld [hl], a + ld a, DIGIT_BASE_X ld hl, wSPRNLevel1 ld [hl], NLEVEL_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRNLevel2 ld [hl], NLEVEL_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRNLevel3 ld [hl], NLEVEL_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRNLevel4 ld [hl], NLEVEL_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRNLevel5 ld [hl], NLEVEL_BASE_Y inc hl ld [hl], a + inc hl + inc hl + ld b, a + ld a, OAMF_PAL1 + ld [hl], a + ld a, b add a, 8 + ld hl, wSPRNLevel6 ld [hl], NLEVEL_BASE_Y inc hl ld [hl], a - add a, 8 + inc hl + inc hl + ld a, OAMF_PAL1 + ld [hl], a ret diff --git a/src/include/time.asm b/src/include/time.asm new file mode 100644 index 0000000..1fcc759 --- /dev/null +++ b/src/include/time.asm @@ -0,0 +1,23 @@ +IF !DEF(TIME_ASM) +DEF TIME_ASM EQU 1 + + +SECTION "Time Variables", HRAM +hEvenFrame:: ds 1 + + +SECTION "Time Functions", ROM0 +TimeInit:: + xor a, a + ldh [hEvenFrame], a + ret + +HandleTimers:: + ldh a, [hEvenFrame] + inc a + and 1 + ldh [hEvenFrame], a + ret + + +ENDC diff --git a/src/main.asm b/src/main.asm index b2afc58..ac2ee22 100644 --- a/src/main.asm +++ b/src/main.asm @@ -3,6 +3,11 @@ INCLUDE "memory.asm" INCLUDE "interrupts.asm" INCLUDE "sprites.asm" INCLUDE "rng.asm" +INCLUDE "input.asm" +INCLUDE "time.asm" +INCLUDE "score.asm" +INCLUDE "level.asm" +INCLUDE "field.asm" INCLUDE "res/tiles.inc" INCLUDE "res/gameplay_map.inc" @@ -47,7 +52,10 @@ Main:: ; Set up the palettes. ld a, PALETTE_REGULAR - set_all_palettes + set_bg_palette + set_obj0_palette + ld a, PALETTE_LIGHTER_1 + set_obj1_palette ; Get the timer going. It's used for RNG. xor a, a @@ -95,15 +103,15 @@ GameLoop:: call ApplyHold ld hl, wSPRScore1 - ld de, hScore + ld de, wScore call ApplyNumbers ld hl, wSPRCLevel1 - ld de, hCLevel + ld de, wCLevel call ApplyNumbers ld hl, wSPRNLevel1 - ld de, hNLevel + ld de, wNLevel call ApplyNumbers GameLoopEnd: @@ -121,61 +129,10 @@ GameLoopEnd: ; ***************************************************************************** SECTION "Functions", ROM0 InitializeVariables: - xor a, a - ld [wLCDCCtr], a - ld hl, wField - ld bc, 10*22 - ld d, TILE_FIELD_EMPTY - call UnsafeMemSet - ld hl, hScore - ld bc, (6*3) - ld d, 0 - call UnsafeMemSet - ret - - -BlitField: - ; The first 14 rows can be blitted without checking for vram access. - ld de, wField + (2*10) - DEF row = 0 - REPT 14 - ld hl, FIELD_TOP_LEFT+(32*row) - REPT 10 - ld a, [de] - ld [hl+], a - inc de - ENDR - DEF row += 1 - ENDR - - ; The last 6 rows need some care. - REPT 6 - ld hl, FIELD_TOP_LEFT+(32*row) - REPT 2 -: ldh a, [rSTAT] - and STATF_LCD - cp STATF_HBL - jr z, :- -: ldh a, [rSTAT] - and STATF_LCD - cp STATF_HBL - jr nz, :- - REPT 5 - ld a, [de] - ld [hl+], a - inc de - ENDR - ENDR - DEF row += 1 - ENDR - ret - -GetInput: - ret - -HandleTimers: - ld a, [wEvenFrame] - inc a - and 1 - ld [wEvenFrame], a + call TimeInit + call IntrInit + call InputInit + call ScoreInit + call LevelInit + call FieldInit ret diff --git a/tools/Emulicious.ini b/tools/Emulicious.ini index 8c0ab8d..76dacd0 100644 --- a/tools/Emulicious.ini +++ b/tools/Emulicious.ini @@ -1,5 +1,5 @@ #Emulicious settings file -#Fri Oct 13 08:36:54 CEST 2023 +#Fri Oct 13 11:18:40 CEST 2023 SouthPanelHeight=635 GameBoyErrorBreakpointMessage6= GameBoyErrorBreakpointMessage5= @@ -184,7 +184,7 @@ GameBoyErrorBreakpointSuspend2=true GameBoyErrorBreakpointSuspend1=true GameBoyErrorBreakpointSuspend0=true Scale=5.0 -DebuggerMemorySelectedAddress=390 +DebuggerMemorySelectedAddress=4 WindowEmuliciousWidth=816 GameBoyErrorBreakpointSuspend20=true DataExecutionBreakpointCondition= @@ -217,8 +217,8 @@ WindowTilemapViewerHeight=744 GameBoyErrorBreakpointMessage20= WindowTileViewerWidth=467 MemoryTracerDisplayFileOffsetsForROM=true -WindowDebuggerY=189 -WindowDebuggerX=1113 +WindowDebuggerY=170 +WindowDebuggerX=1172 Key37=-1 Key36=-1 WindowTileViewerOpen=false @@ -275,7 +275,7 @@ BankSwapAtPCBreakpointSuspend=true Key20=-1 WindowEmuliciousY=489 WindowEmuliciousX=666 -DebuggerMemorySelectedTab=RAM +DebuggerMemorySelectedTab=HRAM WindowDebuggerWidth=1481 GameBoyErrorBreakpointMessage9= GameBoyErrorBreakpointMessage8=