From 2ab9a1f3a04cc7f9fa1dea9d4c85d619a6804144 Mon Sep 17 00:00:00 2001 From: Louis Pearson Date: Thu, 18 Apr 2024 01:48:36 -0600 Subject: [PATCH] feat: 3d movement Needs gravity, shadow --- build.zig | 1 + main.asm | 199 +++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 184 insertions(+), 16 deletions(-) diff --git a/build.zig b/build.zig index ebf0782..0214274 100644 --- a/build.zig +++ b/build.zig @@ -10,6 +10,7 @@ pub fn build(b: *std.Build) !void { }); const assemble = b.addRunArtifact(rgbds.artifact("rgbasm")); + assemble.addArg("-H"); assemble.addArg("-L"); assemble.addArg("-o"); const main_obj = assemble.addOutputFileArg("main.o"); diff --git a/main.asm b/main.asm index 6c937a2..268eff3 100644 --- a/main.asm +++ b/main.asm @@ -7,7 +7,7 @@ SECTION "Header", ROM0[$100] ds $150 - @, 0 ; Make room for the header -SECTION "Init", ROM0 +SECTION "Main", ROM0 Init: ; Shut down audio circuitry ld a, 0 @@ -46,11 +46,23 @@ WaitVBlank: ld a, 8 ld [hl], a - ld hl, wMetaspritePosition + ld hl, wMetaspritePosition.x ld a, 0 - ld [wMetaspritePosition], a + ld [wMetaspritePosition.x], a ld a, $80 - ld [wMetaspritePosition + 1], a + ld [wMetaspritePosition.x + 1], a + + ld hl, wMetaspritePosition.y + ld a, 0 + ld [wMetaspritePosition.y], a + ld a, $80 + ld [wMetaspritePosition.y + 1], a + + ld hl, wMetaspritePosition.z + ld a, 0 + ld [wMetaspritePosition.z], a + ld a, 0 + ld [wMetaspritePosition.z + 1], a ; Copy the tile data ld de, Tiles @@ -85,6 +97,103 @@ WaitVBlank: Main: call ResetShadowOAM + call UpdateJoypadState + + ld a, [wJoypadState] + bit PADB_LEFT, a + jr nz, .leftend + + ld a, [wMetaspritePosition.x] + add a, 16 + ld b, a + ld [wMetaspritePosition.x], a + ld a, [wMetaspritePosition.x+1] + adc 0 + ld c, a + ld [wMetaspritePosition.x+1], a +.leftend: + + ld a, [wJoypadState] + bit PADB_RIGHT, a + jr nz, .rightend + + ld a, [wMetaspritePosition.x] + sub a, 16 + ld b, a + ld [wMetaspritePosition.x], a + ld a, [wMetaspritePosition.x+1] + sbc 0 + ld c, a + ld [wMetaspritePosition.x+1], a +.rightend: + + ld a, [wJoypadState] + bit PADB_UP, a + jr nz, .upend + + ld a, [wMetaspritePosition.y] + add a, 16 + ld b, a + ld [wMetaspritePosition.y], a + ld a, [wMetaspritePosition.y+1] + adc 0 + ld c, a + ld [wMetaspritePosition.y+1], a +.upend: + + ld a, [wJoypadState] + bit PADB_DOWN, a + jr nz, .downend + + ld a, [wMetaspritePosition.y] + sub a, 16 + ld b, a + ld [wMetaspritePosition.y], a + ld a, [wMetaspritePosition.y+1] + sbc 0 + ld c, a + ld [wMetaspritePosition.y+1], a +.downend: + + ld a, [wJoypadState] + bit PADB_A, a + jr nz, .jumpend + + ld a, [wMetaspritePosition.z] + add a, 16 + ld b, a + ld [wMetaspritePosition.z], a + ld a, [wMetaspritePosition.z+1] + adc 0 + ld c, a + ld [wMetaspritePosition.z+1], a + +.jumpend + + ld a, [wJoypadState] + bit PADB_B, a + jr nz, .fallend + + ld a, [wMetaspritePosition.z + 1] + cp 0 + jr nz, .fall + ld a, [wMetaspritePosition.z] + cp 16 + jr nc, .fall + ld a, 0 + ld [wMetaspritePosition.z], a + jr .fallend + +.fall + ld a, [wMetaspritePosition.z] + sub a, 16 + ld b, a + ld [wMetaspritePosition.z], a + ld a, [wMetaspritePosition.z+1] + sbc 0 + ld c, a + ld [wMetaspritePosition.z+1], a +.fallend ld de, $0100 ld c, 8 @@ -94,11 +203,24 @@ Main: ld hl, wSimplePosition inc [hl] - ld bc, (96.0 >> 12) & $FFFF - ld a, [wMetaspritePosition] + ; load de + ld a, [wMetaspritePosition.x] ld e, a - ld a, [wMetaspritePosition + 1] + ld a, [wMetaspritePosition.x + 1] ld d, a + + ; load bc + ld a, [wMetaspritePosition.z] + ld c, a + ld a, [wMetaspritePosition.y] + sub a, c + ld c, a + ld a, [wMetaspritePosition.z + 1] + ld b, a + ld a, [wMetaspritePosition.y + 1] + sbc a, b + ld b, a + ld hl, CatMetasprite call RenderMetasprite @@ -125,6 +247,40 @@ Memcopy:: jr nz, .loop ret +UpdateJoypadState:: + ld hl, rP1 + ld [hl], P1F_GET_BTN + ; Read button state twice to ensure we get the proper state + ld a, [hl] + ld a, [hl] + ld [hl], P1F_GET_DPAD + cpl ; Inputs are active low - invert so it makes more sense + and PADF_A | PADF_B | PADF_SELECT | PADF_START + ld c, a ; Store lower 4 button bits in c + + ; On real hardware, rP1 needs to be read 8 times to ensure proper state is read + ld b, 8 +.dpadDebounceLoop: + ld a, [hl] + dec b + jr nz, .dpadDebounceLoop + ld [hl], P1F_GET_NONE ; Disable joypad inputs + + swap a ; Swap the nibbles to store dpad in upper 4 bits + cpl ; invert the bits + and PADF_RIGHT | PADF_LEFT | PADF_UP | PADF_DOWN + or c + ld c, a + + ; Compare with previously stored state + ld hl, wJoypadState + xor [hl] + and c + ld [wJoypadPressed], a + ld a, c + ld [wJoypadState], a + ret + SECTION "VBlank Interrupt", ROM0[$0040] VBlankInterrupt: @@ -265,25 +421,36 @@ TilemapEnd: SECTION "Graphics", ROM0 GfxCat: - INCBIN "cat.2bpp" + INCBIN "cat.2bpp" .end:: CatMetasprite: - db 16, 8, 0, 0 - db 12, 16, 0, 0 - db 20, 20, 0, 0 - db 24, 12, 0, 0 - db 128 + db 16, 8, 0, 0 + db 12, 16, 0, 0 + db 20, 20, 0, 0 + db 24, 12, 0, 0 + db 128 SECTION "Position Vars", WRAM0 ; 8-bit X position wSimplePosition: - ds 1 + ds 1 ; Q12.4 fixed-point X posiition wMetaspritePosition: - dw +.x: + dw +.y: + dw +.z: + dw ; Q4.4 fixed-point velocity wMetaspriteVelocity:: - db + db + +SECTION "Joypad Vars", WRAM0 +wJoypadState: + ds 1 +wJoypadPressed: + ds 1