diff --git a/Makefile b/Makefile index d493419..8aeba6c 100644 --- a/Makefile +++ b/Makefile @@ -41,9 +41,9 @@ ROM = $(BINDIR)/$(ROMNAME).$(ROMEXT) # Argument constants INCDIRS = src/ src/include/ WARNINGS = all extra -ASFLAGS = -p $(PADVALUE) $(addprefix -i,$(INCDIRS)) $(addprefix -W,$(WARNINGS)) -LDFLAGS = -p $(PADVALUE) -FIXFLAGS = -p $(PADVALUE) -v -i "$(GAMEID)" -k "$(LICENSEE)" -l $(OLDLIC) -m $(MBC) -n $(VERSION) -r $(SRAMSIZE) -t $(TITLE) +ASFLAGS = -p 0xFF $(addprefix -i,$(INCDIRS)) $(addprefix -W,$(WARNINGS)) +LDFLAGS = -p 0xFF +FIXFLAGS = -p 0xFF -l 0x33 -m 0x03 -r 0x02 -v -i $(GAMEID) -k $(LICENSEE) -t $(TITLE) -n $(VERSION) # The list of "root" ASM files that RGBASM will be invoked on SRCS = $(wildcard src/*.asm) diff --git a/project.mk b/project.mk index 7947a4b..d1afdee 100644 --- a/project.mk +++ b/project.mk @@ -1,13 +1,29 @@ -PADVALUE := 0xFF -VERSION := 0 +# ROM Version +VERSION := 0x01 + +# 4 Character Game ID GAMEID := DTGM + +# ROM Title (14 chars max) TITLE := DMGTRIS + +# "Licensee" code (2 chars) LICENSEE := NR -OLDLIC := 0x33 -MBC := 0x03 -SRAMSIZE := 0x02 -ROMNAME := out -ROMEXT := gb + +# Output options +ROMNAME := DMGTRIS +ROMEXT := GBC + +# Extra assembler flags +# Do not insert nop after halt ASFLAGS += -h -LDFLAGS += -d +# Do optimize ld to ldh +ASFLAGS += -l + +# Extra linker flags +# Tiny Rom LDFLAGS += -t + +# Extra fix flags +# SEt as gbc compatible +FIXFLAGS += -c diff --git a/src/field.asm b/src/field.asm index 443cd85..402cdda 100644 --- a/src/field.asm +++ b/src/field.asm @@ -143,6 +143,11 @@ FromShadowField: ; This routine will copy wField onto the screen. BlitField:: + ; Hold on, are we on a gbc? + ld a, [wInitialA] + cp a, $11 + jp z, GBCBlitField + ; What to copy ld de, wField + 40 ; Where to put it diff --git a/src/gbc.asm b/src/gbc.asm new file mode 100644 index 0000000..ab606d1 --- /dev/null +++ b/src/gbc.asm @@ -0,0 +1,558 @@ +; DMGTRIS +; Copyright (C) 2023 - Randy Thiemann + +; This program is free software: you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation, either version 3 of the License, or +; (at your option) any later version. + +; This program is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; GNU General Public License for more details. + +; You should have received a copy of the GNU General Public License +; along with this program. If not, see . + + +IF !DEF(GBC_ASM) +DEF GBC_ASM EQU 1 + + +INCLUDE "globals.asm" + +DEF B0 EQU %0010000000000000 +DEF B1 EQU %0100000000000000 +DEF B2 EQU %0101000000000000 +DEF B3 EQU %0111110000000000 +DEF G0 EQU %0000000100000000 +DEF G1 EQU %0000001000000000 +DEF G2 EQU %0000001010000000 +DEF G3 EQU %0000001111100000 +DEF R0 EQU %0000000000001000 +DEF R1 EQU %0000000000010000 +DEF R2 EQU %0000000000010100 +DEF R3 EQU %0000000000011111 + + +SECTION "GBC Shadow Tilemap", WRAM0, ALIGN[8] +wShadowTilemap:: ds 32*32 + +SECTION "GBC Shadow Tile Attributes", WRAM0, ALIGN[8] +wShadowTileAttrs:: ds 32*32 + +SECTION "GBC Variables", WRAM0 +wOuterReps:: ds 1 +wInnerReps:: ds 1 + + + + +SECTION "GBC Functions", ROM0 +ToVRAM:: + ; Bank 1 + ld a, 1 + ldh [rVBK], a + ld a, HIGH(wShadowTileAttrs) + ldh [rHDMA1], a + ld a, LOW(wShadowTileAttrs) + ldh [rHDMA2], a + ld a, HIGH($9800) + ldh [rHDMA3], a + ld a, LOW($9800) + ldh [rHDMA4], a + ld a, 39 + ldh [rHDMA5], a + + + ; Bank 1 + ld a, 0 + ldh [rVBK], a + ld a, HIGH(wShadowTilemap) + ldh [rHDMA1], a + ld a, LOW(wShadowTilemap) + ldh [rHDMA2], a + ld a, HIGH($9800) + ldh [rHDMA3], a + ld a, LOW($9800) + ldh [rHDMA4], a + ld a, 39 | $80 + ldh [rHDMA5], a + +GBCPalettes:: + ld a, [wInitialA] + cp a, $11 + ret nz + ld a, BCPSF_AUTOINC + ldh [rBCPS], a + ldh [rOCPS], a + + ; Pal 0 (red, I) + ld bc, R3 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, R2 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, R1 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, R0 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ; Pal 1 (green, Z) + ld bc, G3 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, G2 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, G1 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, G0 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ; Pal 2 (purple, S) + ld bc, R3 | B3 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, R2 | B2 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, R1 | B1 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, R0 | B0 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ; Pal 3 (blue, J) + ld bc, B3 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, B2 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, B1 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, B0 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ; Pal 4 (orange, L) + ld bc, R3 | G2 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, R2 | G1 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, R1 | G0 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, R0 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ; Pal 5 (yellow, O) + ld bc, R3 | G3 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, R2 | G2 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, R1 | G1 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, R0 | G0 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ; Pal 6 (cyan, T) + ld bc, B3 | G3 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, B2 | G2 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, B1 | G1 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ld bc, B0 | G0 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + ret + + +GBCTitleInit:: + ld a, [wInitialA] + cp a, $11 + ret nz + ld a, BCPSF_AUTOINC | (7*8) + ldh [rBCPS], a + ldh [rOCPS], a + + ; Pal 7 (grayscale, inverted) + ld bc, %0000000000000000 + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld bc, %0010000100001000 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + ld bc, %0100001000010000 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + ld bc, %0111111111111111 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + + ; Copy the tilemap to shadow. + ld de, $9800 + ld hl, wShadowTilemap + ld bc, 32*32 + call UnsafeMemCopy + + ; Copy set attrs to pal 7 and copy to shadow. + ld a, 1 + ldh [rVBK], a + ld d, $07 + ld hl, $9800 + ld bc, (32*32) + call UnsafeMemSet + ld de, $9800 + ld hl, wShadowTileAttrs + ld bc, 32*32 + call UnsafeMemCopy + + ; Reset back to bank 0. + xor a, a + ldh [rVBK], a + ret + + +GBCGameplayInit:: + ld a, [wInitialA] + cp a, $11 + ret nz + ld a, BCPSF_AUTOINC | (7*8) + ldh [rBCPS], a + ldh [rOCPS], a + + ; Pal 7 (grayscale) + ld bc, %0111111111111111 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + ld bc, %0100001000010000 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + ld bc, %0010000100001000 + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + ld bc, %0000000000000000 + ld a, b + ldh [rBCPD], a + ldh [rOCPD], a + ld a, c + ldh [rBCPD], a + ldh [rOCPD], a + + ; Copy the tilemap to shadow. + ld de, $9800 + ld hl, wShadowTilemap + ld bc, 32*32 + call UnsafeMemCopy + + ; Copy set attrs to pal 7 and copy to shadow. + ld a, 1 + ldh [rVBK], a + ld d, $07 + ld hl, $9800 + ld bc, (32*32) + call UnsafeMemSet + ld de, $9800 + ld hl, wShadowTileAttrs + ld bc, 32*32 + call UnsafeMemCopy + + ; Reset back to bank 0. + xor a, a + ldh [rVBK], a + ret + + +GBCGameplayProcess:: + ld a, [wInitialA] + cp a, $11 + ret nz + + + ; What to copy + ld de, wField + 40 + ; Where to put it + ld hl, wShadowTilemap + 1 + ; How much to increment hl after each row + ld bc, 32-10 + + ; Blit me up daddy. + ld a, 20 + ld [wOuterReps], a +.outer1 + ld a, 10 + ld [wInnerReps], a +.inner1 + ld a, [de] + ld [hl+], a + inc de + ld a, [wInnerReps] + dec a + ld [wInnerReps], a + jr nz, .inner1 + + add hl, bc + ld a, [wOuterReps] + dec a + ld [wOuterReps], a + jr nz, .outer1 + + + ; What to copy + ld de, wField + 40 + ; Where to put it + ld hl, wShadowTileAttrs + 1 + ; How much to increment hl after each row + ld bc, 32-10 + + ; Blit me up daddy. + ld a, 20 + ld [wOuterReps], a +.outer2 + ld a, 10 + ld [wInnerReps], a +.inner2 + ld a, [de] + cp a, 10 + jr c, .empty + cp a, 10 + (1*7) + jr c, .sub10 + cp a, 10 + (2*7) + jr c, .sub17 + cp a, 10 + (3*7) + jr c, .sub24 + cp a, 10 + (4*7) + jr c, .sub31 + cp a, 10 + (5*7) + jr c, .sub38 + cp a, 10 + (6*7) + jr c, .sub45 + cp a, 10 + (7*7) + jr c, .sub52 + cp a, 10 + (8*7) + jr c, .sub59 +.empty + ld a, $07 + jr .done +.sub59 + sub a, 7 +.sub52 + sub a, 7 +.sub45 + sub a, 7 +.sub38 + sub a, 7 +.sub31 + sub a, 7 +.sub24 + sub a, 7 +.sub17 + sub a, 7 +.sub10 + sub a, 10 +.done + ld [hl+], a + inc de + ld a, [wInnerReps] + dec a + ld [wInnerReps], a + jr nz, .inner2 + + add hl, bc + ld a, [wOuterReps] + dec a + ld [wOuterReps], a + jr nz, .outer2 + + + ret + + + +GBCBlitField:: + call ToVRAM + jp EventLoop + + +ENDC diff --git a/src/main.asm b/src/main.asm index 2b2cd2b..4e60602 100644 --- a/src/main.asm +++ b/src/main.asm @@ -86,6 +86,16 @@ Main:: ; Set up stack ld sp, wStackEnd-1 + ; GBC? Double speed mode and set up palettes. + ld a, [wInitialA] + cp a, $11 + jr nz, .notgbc + ld a, KEY1F_PREPARE + ldh [rKEY1], a + stop + call GBCPalettes +.notgbc + ; We use a single set of tiles for the entire game, so we copy it at the start. ld de, Tiles ld hl, _VRAM diff --git a/src/sprites.asm b/src/sprites.asm index db49fa6..52e048d 100644 --- a/src/sprites.asm +++ b/src/sprites.asm @@ -101,6 +101,12 @@ ClearOAM:: SECTION "Domain Specific Functions", ROM0 ; Index of next piece in A. ApplyNext:: + ; Correct color + ld [wSPRNext1+3], a + ld [wSPRNext2+3], a + ld [wSPRNext3+3], a + ld [wSPRNext4+3], a + ; Correct tile add a, TILE_PIECE_0 ld [wSPRNext1+2], a @@ -167,6 +173,12 @@ ApplyHold:: ret .doApplyHold + ; Correct color + ld [wSPRHold1+3], a + ld [wSPRHold2+3], a + ld [wSPRHold3+3], a + ld [wSPRHold4+3], a + ; Correct tile add a, TILE_PIECE_0 ld [wSPRHold1+2], a @@ -277,7 +289,7 @@ SetNumberSpritePositions:: inc hl inc hl ld b, a - ld a, OAMF_PAL1 + ld a, OAMF_PAL1 | $07 ld [hl], a ld a, b add a, 8 @@ -289,7 +301,7 @@ SetNumberSpritePositions:: inc hl inc hl ld b, a - ld a, OAMF_PAL1 + ld a, OAMF_PAL1 | $07 ld [hl], a ld a, b add a, 8 @@ -301,7 +313,7 @@ SetNumberSpritePositions:: inc hl inc hl ld b, a - ld a, OAMF_PAL1 + ld a, OAMF_PAL1 | $07 ld [hl], a ld a, b add a, 8 @@ -313,7 +325,7 @@ SetNumberSpritePositions:: inc hl inc hl ld b, a - ld a, OAMF_PAL1 + ld a, OAMF_PAL1 | $07 ld [hl], a ld a, b add a, 8 @@ -325,7 +337,7 @@ SetNumberSpritePositions:: inc hl inc hl ld b, a - ld a, OAMF_PAL1 + ld a, OAMF_PAL1 | $07 ld [hl], a ld a, b add a, 8 @@ -336,7 +348,7 @@ SetNumberSpritePositions:: ld [hl], a inc hl inc hl - ld a, OAMF_PAL1 + ld a, OAMF_PAL1 | $07 ld [hl], a ld a, LEVEL_BASE_X @@ -347,7 +359,7 @@ SetNumberSpritePositions:: inc hl inc hl ld b, a - ld a, OAMF_PAL1 + ld a, OAMF_PAL1 | $07 ld [hl], a ld a, b add a, 8 @@ -359,7 +371,7 @@ SetNumberSpritePositions:: inc hl inc hl ld b, a - ld a, OAMF_PAL1 + ld a, OAMF_PAL1 | $07 ld [hl], a ld a, b add a, 8 @@ -371,7 +383,7 @@ SetNumberSpritePositions:: inc hl inc hl ld b, a - ld a, OAMF_PAL1 + ld a, OAMF_PAL1 | $07 ld [hl], a ld a, b add a, 8 @@ -382,7 +394,7 @@ SetNumberSpritePositions:: ld [hl], a inc hl inc hl - ld a, OAMF_PAL1 + ld a, OAMF_PAL1 | $07 ld [hl], a ld a, LEVEL_BASE_X @@ -393,7 +405,7 @@ SetNumberSpritePositions:: inc hl inc hl ld b, a - ld a, OAMF_PAL1 + ld a, OAMF_PAL1 | $07 ld [hl], a ld a, b add a, 8 @@ -405,7 +417,7 @@ SetNumberSpritePositions:: inc hl inc hl ld b, a - ld a, OAMF_PAL1 + ld a, OAMF_PAL1 | $07 ld [hl], a ld a, b add a, 8 @@ -417,7 +429,7 @@ SetNumberSpritePositions:: inc hl inc hl ld b, a - ld a, OAMF_PAL1 + ld a, OAMF_PAL1 | $07 ld [hl], a ld a, b add a, 8 @@ -428,7 +440,7 @@ SetNumberSpritePositions:: ld [hl], a inc hl inc hl - ld a, OAMF_PAL1 + ld a, OAMF_PAL1 | $07 ld [hl], a ret diff --git a/src/state_gameplay.asm b/src/state_gameplay.asm index a8a82fd..c7b527d 100644 --- a/src/state_gameplay.asm +++ b/src/state_gameplay.asm @@ -110,6 +110,9 @@ SwitchToGameplay:: ld a, LEADY_TIME ldh [hModeCounter], a + ; GBC init + call GBCGameplayInit + ; Install the event loop handlers. ld a, 1 ldh [hGameState], a @@ -526,6 +529,8 @@ drawStaticInfo: ld de, hNLevel call ApplyNumbers + call GBCGameplayProcess + jp EventLoopPostHandler diff --git a/src/state_title.asm b/src/state_title.asm index a713d86..980a81a 100644 --- a/src/state_title.asm +++ b/src/state_title.asm @@ -78,6 +78,9 @@ SwitchToTitle:: set_obj0_palette set_obj1_palette + ; GBC init + call GBCTitleInit + ; Install the event loop handlers. ld a, 0 ldh [hGameState], a