diff --git a/galactic-armada/Makefile b/galactic-armada/Makefile deleted file mode 100644 index 4bcb26a7..00000000 --- a/galactic-armada/Makefile +++ /dev/null @@ -1,120 +0,0 @@ -# You can set the name of the .gb ROM file here -PROJECTNAME = GalacticArmada -SRCDIR = src -LIBDIR = libs -OBJDIR = obj -DSTDIR = dist -RESDIR = $(SRCDIR)/resources -ASMDIR = $(SRCDIR)/main -RESSPRITES = $(RESDIR)/sprites -RESBACKGROUNDS = $(RESDIR)/backgrounds -GENDIR = $(SRCDIR)/generated -GENSPRITES = $(GENDIR)/sprites -GENBACKGROUNDS = $(GENDIR)/backgrounds -BINS = $(DSTDIR)/$(PROJECTNAME).gb - -# Tools -RGBDS ?= -ASM := $(RGBDS)rgbasm -GFX := $(RGBDS)rgbgfx -LINK := $(RGBDS)rgblink -FIX := $(RGBDS)rgbfix - -# Tool flags -ASMFLAGS := -L -FIXFLAGS := -v -p 0xFF - -# https://stackoverflow.com/a/18258352 -# Make does not offer a recursive wild card function, so here's one: -rwildcard = $(foreach d,\ - $(wildcard $(1:=/*)), \ - $(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d) \ - ) - -# https://stackoverflow.com/a/16151140 -# This makes it so every entry in a space-delimited list appears only once -unique = $(if $1,\ - $(firstword $1) $(call unique,$(filter-out $(firstword $1),$1)) \ - ) - -# Collect ASM sources from ASMDIR and LIBDIR. -ASMSOURCES_COLLECTED = \ - $(call rwildcard,$(ASMDIR),*.asm) $(call rwildcard,$(LIBDIR),*.asm) - -OBJS = $(patsubst %.asm,$(OBJDIR)/%.o,$(notdir $(ASMSOURCES_COLLECTED))) - -all: $(BINS) - -# ANCHOR: generate-graphics -NEEDED_GRAPHICS = \ - $(GENSPRITES)/player-ship.2bpp \ - $(GENSPRITES)/enemy-ship.2bpp \ - $(GENSPRITES)/bullet.2bpp \ - $(GENBACKGROUNDS)/text-font.2bpp \ - $(GENBACKGROUNDS)/star-field.tilemap \ - $(GENBACKGROUNDS)/title-screen.tilemap - -# Generate sprites, ensuring the containing directories have been created. -$(GENSPRITES)/%.2bpp: $(RESSPRITES)/%.png | $(GENSPRITES) - $(GFX) -c "#FFFFFF,#cfcfcf,#686868,#000000;" --columns -o $@ $< - -# Generate background tile set, ensuring the containing directories have been created. -$(GENBACKGROUNDS)/%.2bpp: $(RESBACKGROUNDS)/%.png | $(GENBACKGROUNDS) - $(GFX) -c "#FFFFFF,#cbcbcb,#414141,#000000;" -o $@ $< - -# Generate background tile map *and* tile set, ensuring the containing directories -# have been created. -$(GENBACKGROUNDS)/%.tilemap: $(RESBACKGROUNDS)/%.png | $(GENBACKGROUNDS) - $(GFX) -c "#FFFFFF,#cbcbcb,#414141,#000000;" \ - --tilemap $@ \ - --unique-tiles \ - -o $(GENBACKGROUNDS)/$*.2bpp \ - $< -# ANCHOR_END: generate-graphics - -compile.bat: Makefile - @echo "REM Automatically generated from Makefile" > compile.bat - @make -sn | sed y/\\/\\\\/\\\\\\\^/ | grep -v make >> compile.bat - - -# ANCHOR: generate-objects -# Extract directories from collected ASM sources and append "%.asm" to each one, -# creating a wildcard-rule. -ASMSOURCES_DIRS = $(patsubst %,%%.asm,\ - $(call unique,$(dir $(ASMSOURCES_COLLECTED))) \ - ) - -# This is a Makefile "macro". -# It defines a %.o target from a corresponding %.asm, ensuring the -# "prepare" step has ran and the graphics are already generated. -define object-from-asm -$(OBJDIR)/%.o: $1 | $(OBJDIR) $(NEEDED_GRAPHICS) - $$(ASM) $$(ASMFLAGS) -o $$@ $$< -endef - -# Run the macro for each directory listed in ASMSOURCES_DIRS, thereby -# creating the appropriate targets. -$(foreach i, $(ASMSOURCES_DIRS), $(eval $(call object-from-asm,$i))) -# ANCHOR_END: generate-objects - -# Link and build the final ROM. -$(BINS): $(OBJS) | $(DSTDIR) - $(LINK) -o $@ $^ - $(FIX) $(FIXFLAGS) $@ -# Ensure directories for generated files exist. -define ensure-directory -$1: - mkdir -p $$@ -endef - -PREPARE_DIRECTORIES = \ - $(OBJDIR) $(GENSPRITES) $(GENBACKGROUNDS) $(DSTDIR) - -$(foreach i, $(PREPARE_DIRECTORIES), $(eval $(call ensure-directory,$i))) - -# Clean up generated directories. -clean: - rm -rfv $(PREPARE_DIRECTORIES) -# Declare these targets as "not actually files". -.PHONY: clean all - diff --git a/galactic-armada/libs/input.asm b/galactic-armada/libs/input.asm deleted file mode 100644 index 1ccc8608..00000000 --- a/galactic-armada/libs/input.asm +++ /dev/null @@ -1,45 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; It's straight from: https://gbdev.io/gb-asm-tutorial/part2/input.html -; In their words (paraphrased): reading player input for gameboy is NOT a trivial task -; So it's best to use some tested code -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -include "src/main/utils/hardware.inc" - - SECTION "Input", ROM0 - -Input:: - ; Poll half the controller - ld a, P1F_GET_BTN - call .onenibble - ld b, a ; B7-4 = 1; B3-0 = unpressed buttons - - ; Poll the other half - ld a, P1F_GET_DPAD - call .onenibble - swap a ; A3-0 = unpressed directions; A7-4 = 1 - xor a, b ; A = pressed buttons + directions - ld b, a ; B = pressed buttons + directions - - ; And release the controller - ld a, P1F_GET_NONE - ldh [rP1], a - - ; Combine with previous wCurKeys to make wNewKeys - ld a, [wCurKeys] - xor a, b ; A = keys that changed state - and a, b ; A = keys that changed to pressed - ld [wNewKeys], a - ld a, b - ld [wCurKeys], a - ret - -.onenibble - ldh [rP1], a ; switch the key matrix - call .knownret ; burn 10 cycles calling a known ret - ldh a, [rP1] ; ignore value while waiting for the key matrix to settle - ldh a, [rP1] - ldh a, [rP1] ; this read counts - or a, $F0 ; A7-4 = 1; A3-0 = unpressed keys -.knownret - ret \ No newline at end of file diff --git a/galactic-armada/libs/sporbs_lib.asm b/galactic-armada/libs/sporbs_lib.asm deleted file mode 100644 index 3f36a6ec..00000000 --- a/galactic-armada/libs/sporbs_lib.asm +++ /dev/null @@ -1,222 +0,0 @@ -; Sprite Objects Library - by Eievui -; -; This is a small, lightweight library meant to facilitate the rendering of -; sprite objects, including Shadow OAM and OAM DMA, single-entry "simple" sprite -; objects, and Q12.4 fixed-point position metasprite rendering. -; -; The library is only 127 bytes of ROM0, 160 bytes of WRAM0 for Shadow OAM, and a -; single HRAM byte for tracking the current position in OAM. -; -; The library is relatively simple to use, with 4 steps to rendering: -; 1. Call InitSprObjLib during initilizations - This copies the OAMDMA function to -; HRAM. -; 2. Call ResetShadowOAM at the beginning of each frame - This hides all sprites -; and resets hOAMIndex, allowing you to render a new frame of sprites. -; 3. Call rendering functions - Push simple sprites or metasprites to Shadow OAM. -; 4. Wait for VBlank and call hOAMDMA - Copies wShadowOAM to the Game Boy's OAM in -; just 160 M-cycles. Make sure to pass HIGH(wShadowOAM) in the a register. -; -; Copyright 2021, Eievui -; -; This software is provided 'as-is', without any express or implied -; warranty. In no event will the authors be held liable for any damages -; arising from the use of this software. -; -; Permission is granted to anyone to use this software for any purpose, -; including commercial applications, and to alter it and redistribute it -; freely, subject to the following restrictions: -; -; 1. The origin of this software must not be misrepresented; you must not -; claim that you wrote the original software. If you use this software -; in a product, an acknowledgment in the product documentation would be -; appreciated but is not required. -; 2. Altered source versions must be plainly marked as such, and must not be -; misrepresented as being the original software. -; 3. This notice may not be removed or altered from any source distribution. -; - -INCLUDE "src/main/utils/hardware.inc" - -SECTION "OAM DMA Code", ROM0 -OAMDMACode:: -LOAD "OAM DMA", HRAM -; Begin an OAM DMA, waiting 160 cycles for the DMA to finish. -; This quickly copies Shadow OAM to the Game Boy's OAM, allowing the PPU to draw -; the objects. hOAMDMA should be called once per frame near the end of your -; VBlank interrupt. While an OAM DMA is running no sprites objects can be drawn -; by the PPU, which makes it preferrable to run within the VBlank interrupt, but -; it can be run at any point if more than 40 sprite objects are needed. -; @param a: High byte of active Shadow OAM. Shadow OAM must be aligned to start -; at the beginning of a page (low byte == $00). -hOAMDMA:: - ldh [rDMA], a - ld a, 40 -.wait - dec a - jr nz, .wait - ret -ENDL -OAMDMACodeEnd:: - -SECTION "Initialize Sprite Object Library", ROM0 - -; A wrapper or the InitSprObjLib code -; from: https://github.com/eievui5/gb-sprobj-lib -; The library is relatively simple to get set up. First, put the following in your initialization code: -; Initilize Sprite Object Library. -InitSprObjLibWrapper:: - - call InitSprObjLib - ; Reset hardware OAM - xor a, a - ld b, 160 - ld hl, _OAMRAM - -.resetOAM - ld [hli], a - dec b - jr nz, .resetOAM - - ret - -; Initializes the sprite object library, copying things such as the hOAMDMA -; function and reseting hOAMIndex -; @clobbers: a, bc, hl -InitSprObjLib:: - ; Copy OAM DMA. - ld b, OAMDMACodeEnd - OAMDMACode - ld c, LOW(hOAMDMA) - ld hl, OAMDMACode -.memcpy - ld a, [hli] - ldh [c], a - inc c - dec b - jr nz, .memcpy - xor a, a - ldh [hOAMIndex], a ; hOAMIndex must be reset before running ResetShadowOAM. - ret - -SECTION "Reset Shadow OAM", ROM0 -; Reset the Y positions of every sprite object that was used in the last frame, -; effectily hiding them, and reset hOAMIndex. Run this function each frame -; before rendering sprite objects. -; @clobbers: a, c, hl -ResetShadowOAM:: - xor a, a ; clear carry - ldh a, [hOAMIndex] - rra - rra ; a / 4 - and a, a - jr z, .skip - ld c, a - ld hl, wShadowOAM - xor a, a -.clearOAM - ld [hli], a - inc l - inc l - inc l - dec c - jr nz, .clearOAM - ldh [hOAMIndex], a -.skip - ret - -SECTION "Render Simple Sprite", ROM0 -; Render a single object, or sprite, to OAM. -; @param b: Y position -; @param c: X position -; @param d: Tile ID -; @param e: Tile Attribute -; @clobbers: hl -RenderSimpleSprite:: - ld h, HIGH(wShadowOAM) - ldh a, [hOAMIndex] - ld l, a - ld a, b - add a, 16 - ld [hli], a - ld a, c - add a, 8 - ld [hli], a - ld a, d - ld [hli], a - ld a, e - ld [hli], a - ld a, l - ldh [hOAMIndex], a - ret - -SECTION "Render Metasprite", ROM0 -; Render a metasprite to OAM. -; @param bc: Q12.4 fixed-point Y position. -; @param de: Q12.4 fixed-point X position. -; @param hl: Pointer to current metasprite. -RenderMetasprite:: - ; Adjust Y and store in b. - ld a, c - rrc b - rra - rrc b - rra - rrc b - rra - rrc b - rra - ld b, a - ; Adjust X and store in c. - ld a, e - rrc d - rra - rrc d - rra - rrc d - rra - rrc d - rra - ld c, a - ; Load Shadow OAM pointer. - ld d, HIGH(wShadowOAM) - ldh a, [hOAMIndex] - ld e, a - ; Now: - ; bc - Y, X - ; de - Shadow OAM - ; hl - Metasprite - ; Time to render! -.loop - ; Load Y. - ld a, [hli] - add a, b - ld [de], a - inc e - ; Load X. - ld a, [hli] - add a, c - ld [de], a - inc e - ; Load Tile. - ld a, [hli] - ld [de], a - inc e - ; Load Attribute. - ld a, [hli] - ld [de], a - inc e - ; Check for null end byte. - ld a, [hl] - cp a, 128 - jr nz, .loop - ld a, e - ldh [hOAMIndex], a - ret - -SECTION "Shadow OAM", WRAM0, ALIGN[8] -wShadowOAM:: - ds 160 - -SECTION "Shadow OAM Index", HRAM -; The current low byte of shadow OAM. -hOAMIndex:: - db \ No newline at end of file diff --git a/galactic-armada/main.asm b/galactic-armada/main.asm deleted file mode 100644 index 71fe3a47..00000000 --- a/galactic-armada/main.asm +++ /dev/null @@ -1,788 +0,0 @@ - -; ANCHOR: sprite-tile-data - -playerShipTileData: INCBIN "src/generated/sprites/player-ship.2bpp" -playerShipTileDataEnd: - -enemyShipTileData:: INCBIN "src/generated/sprites/enemy-ship.2bpp" -enemyShipTileDataEnd:: - -bulletTileData:: INCBIN "src/generated/sprites/bullet.2bpp" -bulletTileDataEnd:: - -; ANCHOR_END: sprite-tile-data - -; ANCHOR: game-entry-point - -SECTION "Header", ROM0[$100] - - jp EntryPoint - - ds $150 - @, 0 ; Make room for the header - -EntryPoint: - -; ANCHOR_END: game-entry-point - - -; ANCHOR: game-states-switch - -; Initiate the next state - ld a, [wGameState] - cp a, 2 ; 2 = Gameplay - call z, InitGameplayState - ld a, [wGameState] - cp a, 1 ; 1 = Story - call z, InitStoryState - ld a, [wGameState] - cp a, 0 ; 0 = Menu - call z, InitTitleScreenState - - ; Update the next state - ld a, [wGameState] - cp a, 2 ; 2 = Gameplay - jp z, UpdateGameplayState - cp a, 1 ; 1 = Story - jp z, UpdateStoryState - jp UpdateTitleScreenState - -; ANCHOR_END: game-states-switch - - -; ANCHOR: load-text-font - -LoadTextFontIntoVRAM:: - ; Copy the tile data - ld de, textFontTileData ; de contains the address where data will be copied from; - ld hl, $9000 ; hl contains the address where data will be copied to; - ld bc, textFontTileDataEnd - textFontTileData ; bc contains how many bytes we have to copy. - -LoadTextFontIntoVRAM_Loop: - ld a, [de] - ld [hli], a - inc de - dec bc - ld a, b - or a, c - jp nz, LoadTextFontIntoVRAM_Loop ; Jump to COpyTiles, if the z flag is not set. (the last operation had a non zero result) - ret - - -; ANCHOR_END: load-text-font - - -; ANCHOR: wait-for-key - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Wait for A -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; Save the passed value into the variable: mWaitKey -; The WaitForKeyFunction always checks against this vriable -ld a,PADF_A -ld [mWaitKey], a - -call WaitForKeyFunction - -; ANCHOR_END: wait-for-key - -; ANCHOR: draw-title-screen - -DrawTitleScreen:: - - ; Copy the tile data - ld de, titleScreenTileData ; de contains the address where data will be copied from; - ld hl, $9340 ; hl contains the address where data will be copied to; - ld bc, titleScreenTileDataEnd - titleScreenTileData ; bc contains how many bytes we have to copy. - -DrawTitleScreen_Loop: - ld a, [de] - ld [hli], a - inc de - dec bc - ld a, b - or a, c - jp nz, DrawTitleScreen_Loop ; Jump to COpyTiles, if the z flag is not set. (the last operation had a non zero result) - - ; Copy the tilemap - ld de, titleScreenTileMap - ld hl, $9800 - ld bc, titleScreenTileMapEnd - titleScreenTileMap - -DrawTitleScreen_Tilemap: - ld a, [de] - add a, 52 ; add 52 to skip the text-font tiles - ld [hli], a - inc de - dec bc - ld a, b - or a, c - jp nz, DrawTitleScreen_Tilemap - - ret - -; ANCHOR_END: draw-title-screen - - -; ANCHOR: draw-text-tiles - - -DrawTextTilesLoop:: - - ; Check for the end of string character 255 - ld a, [hl] - cp 255 - ret z - - ; Write the current character (in hl) to the address - ; on the tilemap (in de) - ld a, [hl] - ld [de], a - - inc hl - inc de - - ; move to the next character and next background tile - jp DrawTextTilesLoop - - -; ANCHOR_END: draw-text-tiles - -; ANCHOR: draw-text - - ; Call Our function that draws text onto background/window tiles - ld de, $9c00 - ld hl, wScoreText - call DrawTextTilesLoop - - -; ANCHOR_END: draw-text - -; ANCHOR: draw-press-play - - -wPressPlayText:: db "press a to play", 255 - -InitTitleScreenState:: - - ... - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Draw the press play text - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ; Call Our function that draws text onto background/window tiles - ld de, $99C3 - ld hl, wPressPlayText - call DrawTextTilesLoop - - ... - - ret; - - - -; ANCHOR_END: draw-press-play - - -; ANCHOR: charmap - -CHARMAP " ", 0 -CHARMAP ".", 24 -CHARMAP "-", 25 -CHARMAP "a", 26 -CHARMAP "b", 27 -CHARMAP "c", 28 -.... d - w omitted to keeep the snippet short -CHARMAP "x", 49 -CHARMAP "y", 50 -CHARMAP "z", 51 - - - -; ANCHOR_END: charmap - - -; ANCHOR: draw-text-typewriter - -DrawText_WithTypewriterEffect:: - - ; Wait a small amount of time - ... wait for 3 vblank phases - - ; Check for the end of string character 255 - ld a, [hl] - cp 255 - ret z - - ; Write the current character (in hl) to the address - ; on the tilemap (in de) - ld a, [hl] - ld [de], a - - ; move to the next character and next background tile - inc hl - inc de - - jp DrawText_WithTypewriterEffect - - -; ANCHOR_END: draw-text-typewriter - -; ANCHOR: story-state -Story: - .Line1 db "the galatic feder-", 255 - .Line2 db "ation rules the g-", 255 - .Line3 db "alaxy with an iron", 255 - .Line4 db "fist.", 255 - .Line5 db "the rebel force r-", 255 - .Line6 db "emain hopeful of", 255 - .Line7 db "freedoms dying li-", 255 - .Line8 db "ght.", 255 - -UpdateStoryState:: - - ; Call Our function that typewrites text onto background/window tiles - ld de, $9821 - ld hl, Story.Line1 - call DrawText_WithTypewriterEffect - - - ; Call Our function that typewrites text onto background/window tiles - ld de, $9861 - ld hl, Story.Line2 - call DrawText_WithTypewriterEffect - - - ; Call Our function that typewrites text onto background/window tiles - ld de, $98A1 - ld hl, Story.Line3 - call DrawText_WithTypewriterEffect - - - ; Call Our function that typewrites text onto background/window tiles - ld de, $98E1 - ld hl, Story.Line4 - call DrawText_WithTypewriterEffect - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Wait for A - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ; Save the passed value into the variable: mWaitKey - ; The WaitForKeyFunction always checks against this vriable - ld a,PADF_A - ld [mWaitKey], a - - call WaitForKeyFunction - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - call ClearBackground - - - ; Call Our function that typewrites text onto background/window tiles - ld de, $9821 - ld hl, Story.Line5 - call DrawText_WithTypewriterEffect - - - ; Call Our function that typewrites text onto background/window tiles - ld de, $9861 - ld hl, Story.Line6 - call DrawText_WithTypewriterEffect - - - ; Call Our function that typewrites text onto background/window tiles - ld de, $98A1 - ld hl, Story.Line7 - call DrawText_WithTypewriterEffect - - - ; Save the passed value into the variable: mWaitKey - ; The WaitForKeyFunction always checks against this vriable - ld a,PADF_A - ld [mWaitKey], a - - call WaitForKeyFunction - - -; ANCHOR_END: story-state - - - -; ANCHOR: scrolling-background - -; This is called during gameplay state on every frame -ScrollBackground:: - - ; Increase our scaled integer for the background by 5 - ld a , [mBackgroundScroll+0] - add a , 5 - ld [mBackgroundScroll+0], a - ld a , [mBackgroundScroll+1] - adc a , 0 - ld [mBackgroundScroll+1], a - - ; we want to Get our true (non-scaled) value, and save it for later usage - ld a, [mBackgroundScroll+0] - ld b,a - - ld a, [mBackgroundScroll+1] - ld c,a - - ; Descale our 16 bit integer - srl c - rr b - srl c - rr b - srl c - rr b - srl c - rr b - - ; Save our descaled value in a RAM variable - ld a,b - ld [mBackgroundScrollReal], a - - ret - -; This is called during vblanks -UpdateBackgroundPosition:: - - ; Tell our background to use our previously saved true value - ld a, [mBackgroundScrollReal] - ld [rSCY], a - - ret - - -; ANCHOR_END: scrolling-background - - -; ANCHOR: turn-on-lcd - -; Turn the LCD on - ld a, LCDCF_ON | LCDCF_BGON|LCDCF_OBJON | LCDCF_OBJ16 | LCDCF_WINON | LCDCF_WIN9C00|LCDCF_BG9800 - ld [rLCDC], a - - -; ANCHOR_END: turn-on-lcd - -; ANCHOR: stat-interrupt - -; Define a new section and hard-code it to be at $0048. -SECTION "Stat Interrupt", ROM0[$0048] -StatInterrupt: - - push af - - ; Check if we are on the first scanline - ldh a, [rLYC] - cp 0 - jp z, LYCEqualsZero - -LYCEquals8: - - ; Don't call the next stat interrupt until scanline 8 - ld a, 0 - ldh [rLYC], a - - ; Turn the LCD on including sprites. But no window - ld a, LCDCF_ON | LCDCF_BGON | LCDCF_OBJON | LCDCF_OBJ16 | LCDCF_WINOFF | LCDCF_WIN9C00|LCDCF_BG9800 - ldh [rLCDC], a - - jp EndStatInterrupts - -LYCEqualsZero: - - ; Don't call the next stat interrupt until scanline 8 - ld a, 8 - ldh [rLYC], a - - ; Turn the LCD on including the window. But no sprites - ld a, LCDCF_ON | LCDCF_BGON | LCDCF_OBJOFF | LCDCF_OBJ16| LCDCF_WINON | LCDCF_WIN9C00|LCDCF_BG9800 - ldh [rLCDC], a - -EndStatInterrupts: - - pop af - - reti; - -; ANCHOR_END: stat-interrupt - - -; ANCHOR: init-stat-interrupt - -InitStatInterrupts:: - - ld a, IEF_STAT - ldh [rIE], a - xor a, a ; This is equivalent to `ld a, 0`! - ldh [rIF], a - ei - - ; This makes our stat interrupts occur when the current scanline is equal to the rLYC register - ld a, STATF_LYC - ldh [rSTAT], a - - ; We'll start with the first scanline - ; The first stat interrupt will call the next time rLY = 0 - ld a, 0 - ldh [rLYC], a - - ret - - -; ANCHOR_END: init-stat-interrupt - -; ANCHOR: draw-score-text - -wScoreText:: db "score", 255 - -InitGameplayState:: - - ... - - ; Call Our function that draws text onto background/window tiles - ld de, $9c00 - ld hl, wScoreText - call DrawTextTilesLoop - - ... - - -; ANCHOR_END: draw-score-text - -; ANCHOR: score-variables - -SECTION "GameplayVariables", WRAM0 - -wScore:: ds 6 - -; ANCHOR_END: score-variables - -; ANCHOR: increase-score - -IncreaseScore:: - - ; We have 6 digits, start with the right-most digit (the last byte) - ld c, 0 - ld hl, wScore+5 - -IncreaseScore_Loop: - - ; Increase the digit - ld a, [hl] - inc a - ld [hl], a - - ; Stop if it hasn't gone past 0 - cp a, 9 - ret c - -; If it HAS gone past 9 -IncreaseScore_Next: - - ; Increase a counter so we can not go out of our scores bounds - ld a, c - inc a - ld c, a - - ; Check if we've gone our o our scores bounds - cp a, 6 - ret z - - ; Reset the current digit to zero - ; Then go to the previous byte (visually: to the left) - ld a, 0 - ld [hl], a - ld [hld], a - - jp IncreaseScore_Loop -; ANCHOR_END: increase-score - -; ANCHOR: draw-score - -DrawScore:: - - ; Our score has max 6 digits - ; We'll start with the left-most digit (visually) which is also the first byte - ld c, 6 - ld hl, wScore - ld de, $9C06 ; The window tilemap starts at $9C00 - -DrawScore_Loop: - - ld a, [hli] - add a, 10 ; our numeric tiles start at tile 10, so add to 10 to each bytes value - ld [de], a - - ; Decrease how many numbers we have drawn - ld a, c - dec a - ld c, a - - ; Stop when we've drawn all the numbers - ret z - - ; Increase which tile we are drawing to - inc de - - jp DrawScore_Loop - - - -; ANCHOR_END: draw-score - -; ANCHOR: enemy-metasprites - -enemyShipMetasprite:: - .metasprite1 db 0,0,4,0 - .metasprite2 db 0,8,6,0 - .metaspriteEnd db 128 - -; ANCHOR_END: enemy-metasprites - - -; ANCHOR: draw-enemy-metasprites -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; call the 'DrawMetasprites function. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; Save the x position -ld a, b -ld [wMetaspriteX],a - -; Save the y position -ld a, c -ld [wMetaspriteY],a - -; Actually call the 'DrawMetasprites function -call DrawMetasprites; -; ANCHOR_END: draw-enemy-metasprites - -; ANCHOR: w-bullets - -; Bytes: active, x , y (low), y (high) -wBullets:: ds MAX_BULLET_COUNT*PER_BULLET_BYTES_COUNT - -; ANCHOR_END: w-bullets - -; ANCHOR: bullet-offset-constants - -; from https://rgbds.gbdev.io/docs/v0.6.1/rgbasm.5#EXPRESSIONS -; The RS group of commands is a handy way of defining structure offsets: -RSRESET -DEF bullet_activeByte RB 1 -DEF bullet_xByte RB 1 -DEF bullet_yLowByte RB 1 -DEF bullet_yHighByte RB 1 -DEF PER_BULLET_BYTES_COUNT RB 0 - - -; ANCHOR_END: bullet-offset-constants - -; ANCHOR: w-enemies - -; Bytes: active, x , y (low), y (high), speed, health -wEnemies:: ds MAX_ENEMY_COUNT*PER_ENEMY_BYTES_COUNT - -; ANCHOR_END: w-enemies - -; ANCHOR: w-bullets - -; Bytes: active, x , y (low), y (high) -wBullets:: ds MAX_BULLET_COUNT*PER_BULLET_BYTES_COUNT - -; ANCHOR_END: w-bullets - -; ANCHOR: update-bullets - -UpdateBullets:: - - ; Make sure we have SOME active enemies - ld a, [wActiveBulletCounter] - cp a, 0 - ret z - - ; Reset our counter for how many bullets we have tried to update - ld a, 0 - ld [wUpdateBulletsCounter], a - - ; copy wBullets, into wUpdateBulletsCurrentBulletAddress - ld a, LOW(wBullets) - ld [wUpdateBulletsCurrentBulletAddress+0], a - ld a, HIGH(wBullets) - ld [wUpdateBulletsCurrentBulletAddress+1], a - - ; Update the first bullet - jp UpdateBullets_PerBullet - -UpdateBullets_Loop: - - ; Check our coutner, if it's zero - ; Stop the function - ld a, [wUpdateBulletsCounter] - inc a - ld [wUpdateBulletsCounter], a - - ; Check if we've already - ld a, [wUpdateBulletsCounter] - cp a, MAX_BULLET_COUNT - ret nc - -UpdateBullets_PerBullet: - - ; The first byte is if the bullet is active - ; If it's zero, it's inactive, go to the loop section - ld a, [wUpdateBulletsCurrentBulletAddress+0] - ld l, a - ld a, [wUpdateBulletsCurrentBulletAddress+1] - ld h, a - ld a, [hli] - cp a, 0 - jp z, UpdateBullets_Loop - - ... Proceed to update the bullet pointed to by 'wUpdateBulletsCurrentBulletAddress' - -; ANCHOR_END: update-bullets - - -; ANCHOR: joypad-constants - -;*************************************************************************** -;* -;* Keypad related -;* -;*************************************************************************** - -DEF PADF_DOWN EQU $80 -DEF PADF_UP EQU $40 -DEF PADF_LEFT EQU $20 -DEF PADF_RIGHT EQU $10 -DEF PADF_START EQU $08 -DEF PADF_SELECT EQU $04 -DEF PADF_B EQU $02 -DEF PADF_A EQU $01 - -; ANCHOR_END: joypad-constants - -; ANCHOR: update-player - -UpdatePlayer:: - -UpdatePlayer_HandleInput: - - ld a, [wCurKeys] - and a, PADF_UP - call nz, MoveUp - - ld a, [wCurKeys] - and a, PADF_DOWN - call nz, MoveDown - - ld a, [wCurKeys] - and a, PADF_LEFT - call nz, MoveLeft - - ld a, [wCurKeys] - and a, PADF_RIGHT - call nz, MoveRight - - ld a, [wCurKeys] - and a, PADF_A - call nz, TryShoot - -UpdatePlayer_UpdateSprite: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Drawing the player metasprite - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - - ; Save the address of the metasprite into the 'wMetaspriteAddress' variable - ; Our DrawMetasprites functoin uses that variable - ld a, LOW(playerTestMetaSprite) - ld [wMetaspriteAddress+0], a - ld a, HIGH(playerTestMetaSprite) - ld [wMetaspriteAddress+1], a - - - ; Save the x position - ld a, b - ld [wMetaspriteX],a - - ; Save the y position - ld a, c - ld [wMetaspriteY],a - - ; Actually call the 'DrawMetasprites function - call DrawMetasprites; - - ret -; ANCHOR_END: update-player - -; ANCHOR: rand - -;; From: https://github.com/pinobatch/libbet/blob/master/src/rand.z80#L34-L54 -; Generates a pseudorandom 16-bit integer in BC -; using the LCG formula from cc65 rand(): -; x[i + 1] = x[i] * 0x01010101 + 0xB3B3B3B3 -; @return A=B=state bits 31-24 (which have the best entropy), -; C=state bits 23-16, HL trashed -rand:: - ; Add 0xB3 then multiply by 0x01010101 - ld hl, randstate+0 - ld a, [hl] - add a, $B3 - ld [hl+], a - adc a, [hl] - ld [hl+], a - adc a, [hl] - ld [hl+], a - ld c, a - adc a, [hl] - ld [hl], a - ld b, a - ret -; ANCHOR_END: rand - - - - -; ANCHOR: player-collision-label - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Check the absolute distances. Jump to 'NoAxisOverlap' on failure - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - - ld a, b - ld [wObject1Value], a - - ld a, d - ld [wObject2Value], a - - ; Save if the minimum distance - ld a, 16 - ld [wSize], a - - call CheckObjectPositionDifference - - ld a, [wResult] - cp a, 0 - jp z, NoAxisOverlap - -OverlapExists: - - ... There is an overlap - -NoAxisOverlap: - - ... no overlap - - -; ANCHOR_END: player-collision-label \ No newline at end of file diff --git a/galactic-armada/src/main/GalacticArmada.asm b/galactic-armada/src/main/GalacticArmada.asm deleted file mode 100644 index 7d18967b..00000000 --- a/galactic-armada/src/main/GalacticArmada.asm +++ /dev/null @@ -1,98 +0,0 @@ -; ANCHOR: entry-point -INCLUDE "src/main/utils/hardware.inc" - -SECTION "GameVariables", WRAM0 - -wLastKeys:: db -wCurKeys:: db -wNewKeys:: db -wGameState::db - -SECTION "Header", ROM0[$100] - - jp EntryPoint - - ds $150 - @, 0 ; Make room for the header - -EntryPoint: -; ANCHOR_END: entry-point - -; ANCHOR: entry-point-end - ; Shut down audio circuitry - ld a, 0 - ld [rNR52], a - - ld a, 0 - ld [wGameState], a - - ; Wait for the vertical blank phase before initiating the library - call WaitForOneVBlank - - ; from: https://github.com/eievui5/gb-sprobj-lib - ; The library is relatively simple to get set up. First, put the following in your initialization code: - ; Initilize Sprite Object Library. - call InitSprObjLibWrapper - - ; Turn the LCD off - ld a, 0 - ld [rLCDC], a - - ; Load our common text font into VRAM - call LoadTextFontIntoVRAM - - ; Turn the LCD on - ld a, LCDCF_ON | LCDCF_BGON|LCDCF_OBJON | LCDCF_OBJ16 | LCDCF_WINON | LCDCF_WIN9C00 - ld [rLCDC], a - - ; During the first (blank) frame, initialize display registers - ld a, %11100100 - ld [rBGP], a - ld a, %11100100 - ld [rOBP0], a - -; ANCHOR_END: entry-point-end -; ANCHOR: next-game-state - -NextGameState:: - - ; Do not turn the LCD off outside of VBlank - call WaitForOneVBlank - - call ClearBackground; - - - ; Turn the LCD off - ld a, 0 - ld [rLCDC], a - - ld a, 0 - ld [rSCX],a - ld [rSCY],a - ld [rWX],a - ld [rWY],a - ; disable interrupts - call DisableInterrupts - - ; Clear all sprites - call ClearAllSprites - - ; Initiate the next state - ld a, [wGameState] - cp a, 2 ; 2 = Gameplay - call z, InitGameplayState - ld a, [wGameState] - cp a, 1 ; 1 = Story - call z, InitStoryState - ld a, [wGameState] - cp a, 0 ; 0 = Menu - call z, InitTitleScreenState - - ; Update the next state - ld a, [wGameState] - cp a, 2 ; 2 = Gameplay - jp z, UpdateGameplayState - cp a, 1 ; 1 = Story - jp z, UpdateStoryState - jp UpdateTitleScreenState - -; ANCHOR_END: next-game-state \ No newline at end of file diff --git a/galactic-armada/src/main/states/gameplay/gameplay-background.asm b/galactic-armada/src/main/states/gameplay/gameplay-background.asm deleted file mode 100644 index 25d3e47d..00000000 --- a/galactic-armada/src/main/states/gameplay/gameplay-background.asm +++ /dev/null @@ -1,72 +0,0 @@ -; ANCHOR: gameplay-background-initialize -INCLUDE "src/main/utils/hardware.inc" -INCLUDE "src/main/utils/macros/text-macros.inc" - -SECTION "BackgroundVariables", WRAM0 - -mBackgroundScroll:: dw - -SECTION "GameplayBackgroundSection", ROM0 - -starFieldMap: INCBIN "src/generated/backgrounds/star-field.tilemap" -starFieldMapEnd: - -starFieldTileData: INCBIN "src/generated/backgrounds/star-field.2bpp" -starFieldTileDataEnd: - -InitializeBackground:: - - ; Copy the tile data - ld de, starFieldTileData ; de contains the address where data will be copied from; - ld hl, $9340 ; hl contains the address where data will be copied to; - ld bc, starFieldTileDataEnd - starFieldTileData ; bc contains how many bytes we have to copy. - call CopyDEintoMemoryAtHL - - ; Copy the tilemap - ld de, starFieldMap - ld hl, $9800 - ld bc, starFieldMapEnd - starFieldMap - call CopyDEintoMemoryAtHL_With52Offset - - ld a, 0 - ld [mBackgroundScroll+0],a - ld a, 0 - ld [mBackgroundScroll+1],a - - ret -; ANCHOR_END: gameplay-background-initialize - -; ANCHOR: gameplay-background-update-start -; This is called during gameplay state on every frame -UpdateBackground:: - - ; Increase our scaled integer by 5 - ; Get our true (non-scaled) value, and save it for later usage in bc - ld a , [mBackgroundScroll+0] - add a , 5 - ld b,a - ld [mBackgroundScroll+0], a - ld a , [mBackgroundScroll+1] - adc a , 0 - ld c,a - ld [mBackgroundScroll+1], a -; ANCHOR_END: gameplay-background-update-start - -; ANCHOR: gameplay-background-update-end - ; Descale our scaled integer - ; shift bits to the right 4 spaces - srl c - rr b - srl c - rr b - srl c - rr b - srl c - rr b - - ; Use the de-scaled low byte as the backgrounds position - ld a,b - ld [rSCY], a - - ret -; ANCHOR_END: gameplay-background-update-end \ No newline at end of file diff --git a/galactic-armada/src/main/states/gameplay/gameplay-state.asm b/galactic-armada/src/main/states/gameplay/gameplay-state.asm deleted file mode 100644 index 2e051ba0..00000000 --- a/galactic-armada/src/main/states/gameplay/gameplay-state.asm +++ /dev/null @@ -1,130 +0,0 @@ -; ANCHOR: gameplay-data-variables -INCLUDE "src/main/utils/hardware.inc" -INCLUDE "src/main/utils/macros/text-macros.inc" - -SECTION "GameplayVariables", WRAM0 - -wScore:: ds 6 -wLives:: db - -SECTION "GameplayState", ROM0 - -wScoreText:: db "score", 255 -wLivesText:: db "lives", 255 -; ANCHOR_END: gameplay-data-variables - -; ANCHOR: init-gameplay-state -InitGameplayState:: - - ld a, 3 - ld [wLives+0], a - - ld a, 0 - ld [wScore+0], a - ld [wScore+1], a - ld [wScore+2], a - ld [wScore+3], a - ld [wScore+4], a - ld [wScore+5], a - - call InitializeBackground - call InitializePlayer - call InitializeBullets - call InitializeEnemies - - ; Initiate STAT interrupts - call InitStatInterrupts - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ; Call Our function that draws text onto background/window tiles - ld de, $9c00 - ld hl, wScoreText - call DrawTextTilesLoop - - ; Call Our function that draws text onto background/window tiles - ld de, $9c0D - ld hl, wLivesText - call DrawTextTilesLoop - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - call DrawScore - call DrawLives - - ld a, 0 - ld [rWY], a - - ld a, 7 - ld [rWX], a - - ; Turn the LCD on - ld a, LCDCF_ON | LCDCF_BGON|LCDCF_OBJON | LCDCF_OBJ16 | LCDCF_WINON | LCDCF_WIN9C00|LCDCF_BG9800 - ld [rLCDC], a - - ret; -; ANCHOR_END: init-gameplay-state - -; ANCHOR: update-gameplay-state-start -UpdateGameplayState:: - - ; save the keys last frame - ld a, [wCurKeys] - ld [wLastKeys], a - - ; This is in input.asm - ; It's straight from: https://gbdev.io/gb-asm-tutorial/part2/input.html - ; In their words (paraphrased): reading player input for gameboy is NOT a trivial task - ; So it's best to use some tested code - call Input -; ANCHOR_END: update-gameplay-state-start - -; ANCHOR: update-gameplay-oam - ; from: https://github.com/eievui5/gb-sprobj-lib - ; hen put a call to ResetShadowOAM at the beginning of your main loop. - call ResetShadowOAM - call ResetOAMSpriteAddress -; ANCHOR_END: update-gameplay-oam - -; ANCHOR: update-gameplay-elements - call UpdatePlayer - call UpdateEnemies - call UpdateBullets - call UpdateBackground -; ANCHOR_END: update-gameplay-elements - -; ANCHOR: update-gameplay-clear-sprites - ; Clear remaining sprites to avoid lingering rogue sprites - call ClearRemainingSprites -; ANCHOR_END: update-gameplay-clear-sprites - -; ANCHOR: update-gameplay-end-update - ld a, [wLives] - cp a, 250 - jp nc, EndGameplay - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Call our function that performs the code - call WaitForOneVBlank - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ; from: https://github.com/eievui5/gb-sprobj-lib - ; Finally, run the following code during VBlank: - ld a, HIGH(wShadowOAM) - call hOAMDMA - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Call our function that performs the code - call WaitForOneVBlank - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - jp UpdateGameplayState - -EndGameplay: - - ld a, 0 - ld [wGameState],a - jp NextGameState -; ANCHOR_END: update-gameplay-end-update \ No newline at end of file diff --git a/galactic-armada/src/main/states/gameplay/hud.asm b/galactic-armada/src/main/states/gameplay/hud.asm deleted file mode 100644 index 8eb420cc..00000000 --- a/galactic-armada/src/main/states/gameplay/hud.asm +++ /dev/null @@ -1,86 +0,0 @@ -INCLUDE "src/main/utils/hardware.inc" - - -SECTION "GameplayHUD", ROM0 - -; ANCHOR: hud-increase-score -IncreaseScore:: - - ; We have 6 digits, start with the right-most digit (the last byte) - ld c, 0 - ld hl, wScore+5 - -IncreaseScore_Loop: - - ; Increase the digit - ld a, [hl] - inc a - ld [hl], a - - ; Stop if it hasn't gone past 0 - cp a, 9 - ret c - -; If it HAS gone past 9 -IncreaseScore_Next: - - ; Increase a counter so we can not go out of our scores bounds - ld a, c - inc a - ld c, a - - ; Check if we've gone our o our scores bounds - cp a, 6 - ret z - - ; Reset the current digit to zero - ; Then go to the previous byte (visually: to the left) - ld a, 0 - ld [hl], a - ld [hld], a - - jp IncreaseScore_Loop -; ANCHOR_END: hud-increase-score - - -; ANCHOR: hud-draw-lives -DrawLives:: - - ld hl, wLives - ld de, $9C13 ; The window tilemap starts at $9C00 - - ld a, [hl] - add a, 10 ; our numeric tiles start at tile 10, so add to 10 to each bytes value - ld [de], a - - ret -; ANCHOR_END: hud-draw-lives - -; ANCHOR: hud-draw-score -DrawScore:: - - ; Our score has max 6 digits - ; We'll start with the left-most digit (visually) which is also the first byte - ld c, 6 - ld hl, wScore - ld de, $9C06 ; The window tilemap starts at $9C00 - -DrawScore_Loop: - - ld a, [hli] - add a, 10 ; our numeric tiles start at tile 10, so add to 10 to each bytes value - ld [de], a - - ; Decrease how many numbers we have drawn - ld a, c - dec a - ld c, a - - ; Stop when we've drawn all the numbers - ret z - - ; Increase which tile we are drawing to - inc de - - jp DrawScore_Loop -; ANCHOR_END: hud-draw-score \ No newline at end of file diff --git a/galactic-armada/src/main/states/gameplay/interrupts.asm b/galactic-armada/src/main/states/gameplay/interrupts.asm deleted file mode 100644 index a6397742..00000000 --- a/galactic-armada/src/main/states/gameplay/interrupts.asm +++ /dev/null @@ -1,73 +0,0 @@ - -; ANCHOR: interrupts-start -INCLUDE "src/main/utils/hardware.inc" - - SECTION "Interrupts", ROM0 - - DisableInterrupts:: - ld a, 0 - ldh [rSTAT], a - di - ret - -InitStatInterrupts:: - - ld a, IEF_STAT - ldh [rIE], a - xor a, a ; This is equivalent to `ld a, 0`! - ldh [rIF], a - ei - - ; This makes our stat interrupts occur when the current scanline is equal to the rLYC register - ld a, STATF_LYC - ldh [rSTAT], a - - ; We'll start with the first scanline - ; The first stat interrupt will call the next time rLY = 0 - ld a, 0 - ldh [rLYC], a - - ret -; ANCHOR_END: interrupts-start - -; ANCHOR: interrupts-section -; Define a new section and hard-code it to be at $0048. -SECTION "Stat Interrupt", ROM0[$0048] -StatInterrupt: - - push af - - ; Check if we are on the first scanline - ldh a, [rLYC] - cp 0 - jp z, LYCEqualsZero - -LYCEquals8: - - ; Don't call the next stat interrupt until scanline 8 - ld a, 0 - ldh [rLYC], a - - ; Turn the LCD on including sprites. But no window - ld a, LCDCF_ON | LCDCF_BGON | LCDCF_OBJON | LCDCF_OBJ16 | LCDCF_WINOFF | LCDCF_WIN9C00 - ldh [rLCDC], a - - jp EndStatInterrupts - -LYCEqualsZero: - - ; Don't call the next stat interrupt until scanline 8 - ld a, 8 - ldh [rLYC], a - - ; Turn the LCD on including the window. But no sprites - ld a, LCDCF_ON | LCDCF_BGON | LCDCF_OBJOFF | LCDCF_OBJ16| LCDCF_WINON | LCDCF_WIN9C00 - ldh [rLCDC], a - - -EndStatInterrupts: - - pop af - - reti; -; ANCHOR_END: interrupts-section \ No newline at end of file diff --git a/galactic-armada/src/main/states/gameplay/objects/bullets.asm b/galactic-armada/src/main/states/gameplay/objects/bullets.asm deleted file mode 100644 index 52ae54d0..00000000 --- a/galactic-armada/src/main/states/gameplay/objects/bullets.asm +++ /dev/null @@ -1,287 +0,0 @@ - -; ANCHOR: bullets-top -include "src/main/utils/hardware.inc" -include "src/main/utils/constants.inc" - -SECTION "BulletVariables", WRAM0 - -wSpawnBullet:db - -; how many bullets are currently active -wActiveBulletCounter:: db - -; how many bullet's we've updated -wUpdateBulletsCounter:db - -; Bytes: active, x , y (low), y (high) -wBullets:: ds MAX_BULLET_COUNT*PER_BULLET_BYTES_COUNT - -SECTION "Bullets", ROM0 - -bulletMetasprite:: - .metasprite1 db 0,0,8,0 - .metaspriteEnd db 128 - -bulletTileData:: INCBIN "src/generated/sprites/bullet.2bpp" -bulletTileDataEnd:: - - -; ANCHOR_END: bullets-top - -; ANCHOR: bullets-initialize -InitializeBullets:: - - ld a, 0 - ld [wSpawnBullet], a - - ; Copy the bullet tile data intto vram - ld de, bulletTileData - ld hl, BULLET_TILES_START - ld bc, bulletTileDataEnd - bulletTileData - call CopyDEintoMemoryAtHL - - ; Reset how many bullets are active to 0 - ld a,0 - ld [wActiveBulletCounter],a - - ld b, 0 - ld hl, wBullets - -InitializeBullets_Loop: - - ld a, 0 - ld [hl], a - - ; Increase the address - ld a, l - add a, PER_BULLET_BYTES_COUNT - ld l, a - ld a, h - adc a, 0 - ld h, a - - ; Increase how many bullets we have initailized - ld a, b - inc a - ld b ,a - - cp a, MAX_BULLET_COUNT - ret z - - jp InitializeBullets_Loop -; ANCHOR_END: bullets-initialize - -; ANCHOR: bullets-update-start -UpdateBullets:: - - ; Make sure we have SOME active enemies - ld a, [wSpawnBullet] - ld b, a - ld a, [wActiveBulletCounter] - or a,b - cp a, 0 - ret z - - ; Reset our counter for how many bullets we have checked - ld a, 0 - ld [wUpdateBulletsCounter], a - - ; Get the address of the first bullet in hl - ld a, LOW(wBullets) - ld l, a - ld a, HIGH(wBullets) - ld h, a - - jp UpdateBullets_PerBullet -; ANCHOR_END: bullets-update-start - -; ANCHOR: bullets-update-loop -UpdateBullets_Loop: - - ; Check our counter, if it's zero - ; Stop the function - ld a, [wUpdateBulletsCounter] - inc a - ld [wUpdateBulletsCounter], a - - ; Check if we've already - ld a, [wUpdateBulletsCounter] - cp a, MAX_BULLET_COUNT - ret nc - - ; Increase the bullet data our address is pointingtwo - ld a, l - add a, PER_BULLET_BYTES_COUNT - ld l, a - ld a, h - adc a, 0 - ld h, a -; ANCHOR_END: bullets-update-loop - -; ANCHOR: bullets-update-per -UpdateBullets_PerBullet: - - ; The first byte is if the bullet is active - ; If it's NOT zero, it's active, go to the normal update section - ld a, [hl] - cp a, 0 - jp nz, UpdateBullets_PerBullet_Normal - - ; Do we need to spawn a bullet? - ; If we dont, loop to the next enemy - ld a, [wSpawnBullet] - cp a, 0 - jp z, UpdateBullets_Loop - -UpdateBullets_PerBullet_SpawnDeactivatedBullet: - - ; reset this variable so we don't spawn anymore - ld a, 0 - ld [wSpawnBullet], a - - ; Increase how many bullets are active - ld a,[wActiveBulletCounter] - inc a - ld [wActiveBulletCounter], a - - push hl - - ; Set the current bullet as active - ld a, 1 - ld [hli], a - - ; Get the unscaled player x position in b - ld a, [wPlayerPositionX+0] - ld b, a - ld a, [wPlayerPositionX+1] - ld d, a - - ; Descale the player's x position - ; the result will only be in the low byt - srl d - rr b - srl d - rr b - srl d - rr b - srl d - rr b - - ; Set the x position to equal the player's x position - ld a, b - ld [hli], a - - ; Set the y position (low) - ld a, [wPlayerPositionY+0] - ld [hli], a - - ;Set the y position (high) - ld a, [wPlayerPositionY+1] - ld [hli], a - - pop hl - -UpdateBullets_PerBullet_Normal: - - ; Save our active byte - push hl - - inc hl - - ; Get our x position - ld a, [hli] - ld b, a - - ; get our 16-bit y position - ld a, [hl] - sub a, BULLET_MOVE_SPEED - ld [hli], a - ld c, a - ld a, [hl] - sbc a, 0 - ld [hl], a - ld d, a - - pop hl; go to the active byte - - ; Descale our y position - srl d - rr c - srl d - rr c - srl d - rr c - srl d - rr c - - ; See if our non scaled low byte is above 160 - ld a, c - cp a, 178 - ; If it below 160, continue on to deactivate - jp nc, UpdateBullets_DeActivateIfOutOfBounds - -; ANCHOR_END: bullets-update-per -; ANCHOR: draw-bullets - - push hl - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Drawing a metasprite - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ; Save the address of the metasprite into the 'wMetaspriteAddress' variable - ; Our DrawMetasprites functoin uses that variable - ld a, LOW(bulletMetasprite) - ld [wMetaspriteAddress+0], a - ld a, HIGH(bulletMetasprite) - ld [wMetaspriteAddress+1], a - - ; Save the x position - ld a, b - ld [wMetaspriteX],a - - ; Save the y position - ld a, c - ld [wMetaspriteY],a - - ; Actually call the 'DrawMetasprites function - call DrawMetasprites; - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - pop hl - - jp UpdateBullets_Loop -; ANCHOR_END: draw-bullets - -; ANCHOR: deactivate-bullets -UpdateBullets_DeActivateIfOutOfBounds: - - ; if it's y value is grater than 160 - ; Set as inactive - ld a, 0 - ld [hl], a - - ; Decrease counter - ld a,[wActiveBulletCounter] - dec a - ld [wActiveBulletCounter], a - - jp UpdateBullets_Loop -; ANCHOR_END: deactivate-bullets - -; ANCHOR: fire-bullets -FireNextBullet:: - - ; Make sure we don't have the max amount of enmies - ld a, [wActiveBulletCounter] - cp a, MAX_BULLET_COUNT - ret nc - - ; Set our spawn bullet variable to true - ld a, 1 - ld [wSpawnBullet], a - - ret -; ANCHOR_END: fire-bullets \ No newline at end of file diff --git a/galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm b/galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm deleted file mode 100644 index 44c75ce7..00000000 --- a/galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm +++ /dev/null @@ -1,210 +0,0 @@ - -; ANCHOR: enemy-bullet-collision-start -include "src/main/utils/hardware.inc" -include "src/main/utils/constants.inc" -include "src/main/utils/hardware.inc" - -SECTION "EnemyBulletCollisionVariables", WRAM0 - -wEnemyBulletCollisionCounter: db -wBulletAddresses: dw - -SECTION "EnemyBulletCollision", ROM0 - -; called from enemies.asm -CheckCurrentEnemyAgainstBullets:: - - - ld a, l - ld [wUpdateEnemiesCurrentEnemyAddress+0], a - ld a, h - ld [wUpdateEnemiesCurrentEnemyAddress+1], a - - ld a, 0 - ld [wEnemyBulletCollisionCounter], a - - ; Copy our bullets address into wBulletAddress - ld a, LOW(wBullets) - ld l, a - ld a, HIGH(wBullets) - ld h, a - - jp CheckCurrentEnemyAgainstBullets_PerBullet -; ANCHOR_END: enemy-bullet-collision-start - -; ANCHOR: enemy-bullet-collision-loop -CheckCurrentEnemyAgainstBullets_Loop: - - ; increase our counter - ld a, [wEnemyBulletCollisionCounter] - inc a - ld [wEnemyBulletCollisionCounter], a - - ; Stop if we've checked all bullets - cp a, MAX_BULLET_COUNT - ret nc - - ; Increase the data our address is pointing to - ld a, l - add a, PER_BULLET_BYTES_COUNT - ld l, a - ld a, h - adc a, 0 - ld h, a -; ANCHOR_END: enemy-bullet-collision-loop - - -; ANCHOR: enemy-bullet-collision-per-bullet-start -CheckCurrentEnemyAgainstBullets_PerBullet: - - ld a, [hl] - cp a, 1 - jp nz, CheckCurrentEnemyAgainstBullets_Loop -; ANCHOR_END: enemy-bullet-collision-per-bullet-start - -; ANCHOR: enemy-bullet-collision-per-bullet-x-overlap -CheckCurrentEnemyAgainstBullets_Check_X_Overlap: - - ; Save our first byte address - push hl - - inc hl - - ; Get our x position - ld a, [hli] - add a, 4 - ld b, a - - push hl - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Start: Checking the absolute difference - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ; The first value - ld a, b - ld [wObject1Value], a - - ; The second value - ld a, [wCurrentEnemyX] - add a, 8 - ld [wObject2Value], a - - ; Save if the minimum distance - ld a, 12 - ld [wSize], a - - call CheckObjectPositionDifference - - - ld a, [wResult] - cp a, 0 - jp z, CheckCurrentEnemyAgainstBullets_Check_X_Overlap_Fail - - - pop hl - - jp CheckCurrentEnemyAgainstBullets_PerBullet_Y_Overlap - -CheckCurrentEnemyAgainstBullets_Check_X_Overlap_Fail: - - pop hl - pop hl - - jp CheckCurrentEnemyAgainstBullets_Loop -; ANCHOR_END: enemy-bullet-collision-per-bullet-x-overlap - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; End: Checking the absolute difference - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; ANCHOR: enemy-bullet-collision-per-bullet-y-overlap - -CheckCurrentEnemyAgainstBullets_PerBullet_Y_Overlap: - - ; get our bullet 16-bit y position - ld a, [hli] - ld b, a - - ld a, [hli] - ld c, a - - ; Descale our 16 bit y position - srl c - rr b - srl c - rr b - srl c - rr b - srl c - rr b - - ; preserve our first byte addresss - pop hl - push hl - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; Start: Checking the absolute difference - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ; The first value - ld a, b - ld [wObject1Value], a - - ; The second value - ld a, [wCurrentEnemyY] - ld [wObject2Value], a - - ; Save if the minimum distance - ld a, 16 - ld [wSize], a - - call CheckObjectPositionDifference - - pop hl - - ld a, [wResult] - cp a, 0 - jp z, CheckCurrentEnemyAgainstBullets_Loop - jp CheckCurrentEnemyAgainstBullets_PerBullet_Collision - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;; End: Checking the absolute difference - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; ANCHOR_END: enemy-bullet-collision-per-bullet-y-overlap - - -; ANCHOR: enemy-bullet-collision-per-bullet-collision -CheckCurrentEnemyAgainstBullets_PerBullet_Collision: - - ; set the active byte and x value to 0 for bullets - ld a, 0 - ld [hli], a - ld [hl], a - - ld a, [wUpdateEnemiesCurrentEnemyAddress+0] - ld l, a - ld a, [wUpdateEnemiesCurrentEnemyAddress+1] - ld h, a - - ; set the active byte and x value to 0 for enemies - ld a, 0 - ld [hli], a - ld [hl], a - - call IncreaseScore; - call DrawScore - - ; Decrease how many active enemies their are - ld a, [wActiveEnemyCounter] - dec a - ld [wActiveEnemyCounter], a - - ; Decrease how many active bullets their are - ld a, [wActiveBulletCounter] - dec a - ld [wActiveBulletCounter], a - - ret -; ANCHOR_END: enemy-bullet-collision-per-bullet-collision \ No newline at end of file diff --git a/galactic-armada/src/main/states/gameplay/objects/collision/enemy-player-collision.asm b/galactic-armada/src/main/states/gameplay/objects/collision/enemy-player-collision.asm deleted file mode 100644 index f85217fc..00000000 --- a/galactic-armada/src/main/states/gameplay/objects/collision/enemy-player-collision.asm +++ /dev/null @@ -1,114 +0,0 @@ -; ANCHOR: enemies-start -include "src/main/utils/hardware.inc" -include "src/main/utils/constants.inc" - -SECTION "EnemiesPlayerCollision", ROM0 - -; ANCHOR: get-player-x -CheckEnemyPlayerCollision:: - - ; Get our player's unscaled x position in d - ld a, [wPlayerPositionX+0] - ld d,a - - ld a, [wPlayerPositionX+1] - ld e,a - - srl e - rr d - srl e - rr d - srl e - rr d - srl e - rr d - -; ANCHOR_END: get-player-x - -; ANCHOR: check-x-overlap - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Check the x distances. Jump to 'NoCollisionWithPlayer' on failure - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ld a, [wCurrentEnemyX] - ld [wObject1Value], a - - ld a, d - ld [wObject2Value], a - - ; Save if the minimum distance - ld a, 16 - ld [wSize], a - - call CheckObjectPositionDifference - - ld a, [wResult] - cp a, 0 - jp z, NoCollisionWithPlayer - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - -; ANCHOR_END: check-x-overlap - -; ANCHOR: get-y - ; Get our player's unscaled y position in d - ld a, [wPlayerPositionY+0] - ld d,a - - ld a, [wPlayerPositionY+1] - ld e,a - - srl e - rr d - srl e - rr d - srl e - rr d - srl e - rr d - -; ANCHOR_END: get-y - - -; ANCHOR: check-y-overlap - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Check the y distances. Jump to 'NoCollisionWithPlayer' on failure - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - - ld a, [wCurrentEnemyY] - ld [wObject1Value], a - - ld a, d - ld [wObject2Value], a - - ; Save if the minimum distance - ld a, 16 - ld [wSize], a - - call CheckObjectPositionDifference - - ld a, [wResult] - cp a, 0 - jp z, NoCollisionWithPlayer - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; ANCHOR_END: check-y-overlap - -; ANCHOR: result - - ld a, 1 - ld [wResult], a - - ret - -NoCollisionWithPlayer:: - - ld a, 0 - ld [wResult], a - - ret - -; ANCHOR_END: result \ No newline at end of file diff --git a/galactic-armada/src/main/states/gameplay/objects/enemies.asm b/galactic-armada/src/main/states/gameplay/objects/enemies.asm deleted file mode 100644 index ea4a2d5c..00000000 --- a/galactic-armada/src/main/states/gameplay/objects/enemies.asm +++ /dev/null @@ -1,359 +0,0 @@ -; ANCHOR: enemies-start -include "src/main/utils/hardware.inc" -include "src/main/utils/constants.inc" - -SECTION "EnemyVariables", WRAM0 - -wCurrentEnemyX:: db -wCurrentEnemyY:: db - -wSpawnCounter: db -wNextEnemyXPosition: db -wActiveEnemyCounter::db -wUpdateEnemiesCounter:db -wUpdateEnemiesCurrentEnemyAddress::dw - -; Bytes: active, x , y (low), y (high), speed, health -wEnemies:: ds MAX_ENEMY_COUNT*PER_ENEMY_BYTES_COUNT - -; ANCHOR_END: enemies-start -; ANCHOR: enemies-tile-metasprite -SECTION "Enemies", ROM0 - -enemyShipTileData:: INCBIN "src/generated/sprites/enemy-ship.2bpp" -enemyShipTileDataEnd:: - -enemyShipMetasprite:: - .metasprite1 db 0,0,4,0 - .metasprite2 db 0,8,6,0 - .metaspriteEnd db 128 -; ANCHOR_END: enemies-tile-metasprite - -; ANCHOR: enemies-initialize -InitializeEnemies:: - - ld de, enemyShipTileData - ld hl, ENEMY_TILES_START - ld bc, enemyShipTileDataEnd - enemyShipTileData - call CopyDEintoMemoryAtHL - - ld a, 0 - ld [wSpawnCounter], a - ld [wActiveEnemyCounter], a - ld [wNextEnemyXPosition], a - - ld b, 0 - - ld hl, wEnemies - -InitializeEnemies_Loop: - - ; Set as inactive - ld a, 0 - ld [hl], a - - ; Increase the address - ld a, l - add a, PER_ENEMY_BYTES_COUNT - ld l, a - ld a, h - adc a, 0 - ld h, a - - ld a, b - inc a - ld b ,a - - cp a, MAX_ENEMY_COUNT - ret z - - jp InitializeEnemies_Loop -; ANCHOR_END: enemies-initialize - -; ANCHOR: enemies-update-start -UpdateEnemies:: - - call TryToSpawnEnemies - - ; Make sure we have active enemies - ; or we want to spawn a new enemy - ld a, [wNextEnemyXPosition] - ld b, a - ld a, [wActiveEnemyCounter] - or a, b - cp a, 0 - ret z - - ld a, 0 - ld [wUpdateEnemiesCounter], a - - ld a, LOW(wEnemies) - ld l, a - ld a, HIGH(wEnemies) - ld h, a - - jp UpdateEnemies_PerEnemy -; ANCHOR_END: enemies-update-start -; ANCHOR: enemies-update-loop -UpdateEnemies_Loop: - - ; Check our coutner, if it's zero - ; Stop the function - ld a, [wUpdateEnemiesCounter] - inc a - ld [wUpdateEnemiesCounter], a - - ; Compare against the active count - ld a, [wUpdateEnemiesCounter] - cp a, MAX_ENEMY_COUNT - ret nc - - ; Increase the enemy data our address is pointingtwo - ld a, l - add a, PER_ENEMY_BYTES_COUNT - ld l, a - ld a, h - adc a, 0 - ld h, a -; ANCHOR_END: enemies-update-loop - - -; ANCHOR: enemies-update-per-enemy -UpdateEnemies_PerEnemy: - - ; The first byte is if the current object is active - ; If it's not zero, it's active, go to the normal update section - ld a, [hl] - cp 0 - jp nz, UpdateEnemies_PerEnemy_Update - -UpdateEnemies_SpawnNewEnemy: - - ; If this enemy is NOT active - ; Check If we want to spawn a new enemy - ld a, [wNextEnemyXPosition] - cp 0 - - ; If we don't want to spawn a new enemy, we'll skip this (deactivated) enemy - jp z, UpdateEnemies_Loop - - push hl - - ; If they are deactivated, and we want to spawn an enemy - ; activate the enemy - ld a, 1 - ld [hli], a - - ; Put the value for our enemies x position - ld a, [wNextEnemyXPosition] - ld [hli], a - - ; Put the value for our enemies y position to equal 0 - ld a, 0 - ld [hli], a - ld [hld], a - - ld a, 0 - ld [wNextEnemyXPosition], a - - pop hl - - ; Increase counter - ld a,[wActiveEnemyCounter] - inc a - ld [wActiveEnemyCounter], a - -; ANCHOR_END: enemies-update-per-enemy - -; ANCHOR: enemies-update-per-enemy2 -UpdateEnemies_PerEnemy_Update: - - ; Save our first bytye - push hl - - ; Get our move speed in e - ld bc, enemy_speedByte - add hl, bc - ld a, [hl] - ld e, a - - ; Go back to the first byte - ; put the address toe the first byte back on the stack for later - pop hl - push hl - - inc hl - - ; Get our x position - ld a, [hli] - ld b, a - ld [wCurrentEnemyX],a - - ; get our 16-bit y position - ; increase it (by e), but also save it - ld a, [hl] - add a, 10 - ld [hli], a - ld c, a - ld a, [hl] - adc a, 0 - ld [hl], a - ld d, a - - pop hl - - ; Descale the y psoition - srl d - rr c - srl d - rr c - srl d - rr c - srl d - rr c - - ld a, c - ld [wCurrentEnemyY],a - -; ANCHOR_END: enemies-update-per-enemy2 - - -; ANCHOR: enemies-update-check-collision -UpdateEnemies_PerEnemy_CheckPlayerCollision: - - push hl - - call CheckCurrentEnemyAgainstBullets - - pop hl - push hl - - call CheckEnemyPlayerCollision - - pop hl - - ld a, [wResult] - cp a, 0 - jp z, UpdateEnemies_NoCollisionWithPlayer - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - push hl - - call DamagePlayer - call DrawLives - - pop hl - - jp UpdateEnemies_DeActivateEnemy -; ANCHOR_END: enemies-update-check-collision - - -; ANCHOR: enemies-update-deactivate -UpdateEnemies_DeActivateEnemy: - - ; Set as inactive - ld a, 0 - ld [hl], a - - ; Decrease counter - ld a,[wActiveEnemyCounter] - dec a - ld [wActiveEnemyCounter], a - - jp UpdateEnemies_Loop - -; ANCHOR_END: enemies-update-deactivate - -; ANCHOR: enemies-update-nocollision -UpdateEnemies_NoCollisionWithPlayer:: - - ; See if our non scaled low byte is above 160 - ld a, [wCurrentEnemyY] - cp a, 160 - jp nc, UpdateEnemies_DeActivateEnemy - - push hl - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; call the 'DrawMetasprites function. setup variables and call - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ; Save the address of the metasprite into the 'wMetaspriteAddress' variable - ; Our DrawMetasprites functoin uses that variable - ld a, LOW(enemyShipMetasprite) - ld [wMetaspriteAddress+0], a - ld a, HIGH(enemyShipMetasprite) - ld [wMetaspriteAddress+1], a - - ; Save the x position - ld a, [wCurrentEnemyX] - ld [wMetaspriteX],a - - ; Save the y position - ld a, [wCurrentEnemyY] - ld [wMetaspriteY],a - - ; Actually call the 'DrawMetasprites function - call DrawMetasprites; - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - pop hl - - jp UpdateEnemies_Loop -; ANCHOR_END: enemies-update-nocollision - - - -; ANCHOR: enemies-spawn -TryToSpawnEnemies:: - - ; Increase our spwncounter - ld a, [wSpawnCounter] - inc a - ld [wSpawnCounter], a - - ; Check our spawn acounter - ; Stop if it's below a given value - ld a, [wSpawnCounter] - cp a, ENEMY_SPAWN_DELAY_MAX - ret c - - ; Check our next enemy x position variable - ; Stop if it's non zero - ld a, [wNextEnemyXPosition] - cp a, 0 - ret nz - - ; Make sure we don't have the max amount of enmies - ld a, [wActiveEnemyCounter] - cp a, MAX_ENEMY_COUNT - ret nc - -GetSpawnPosition: - - ; Generate a semi random value - call rand - - ; make sure it's not above 150 - ld a,b - cp a, 150 - ret nc - - ; make sure it's not below 24 - ld a, b - cp a, 24 - ret c - - ; reset our spawn counter - ld a, 0 - ld [wSpawnCounter], a - - ld a, b - ld [wNextEnemyXPosition], a - - - ret -; ANCHOR_END: enemies-spawn \ No newline at end of file diff --git a/galactic-armada/src/main/states/gameplay/objects/player.asm b/galactic-armada/src/main/states/gameplay/objects/player.asm deleted file mode 100644 index 2b43c238..00000000 --- a/galactic-armada/src/main/states/gameplay/objects/player.asm +++ /dev/null @@ -1,282 +0,0 @@ -; ANCHOR: player-start -include "src/main/utils/hardware.inc" -include "src/main/utils/hardware.inc" -include "src/main/utils/constants.inc" - -SECTION "PlayerVariables", WRAM0 - -; first byte is low, second is high (little endian) -wPlayerPositionX:: dw -wPlayerPositionY:: dw - -mPlayerFlash: dw -; ANCHOR_END: player-start -; ANCHOR: player-data -SECTION "Player", ROM0 - -playerShipTileData: INCBIN "src/generated/sprites/player-ship.2bpp" -playerShipTileDataEnd: - -playerTestMetaSprite:: - .metasprite1 db 0,0,0,0 - .metasprite2 db 0,8,2,0 - .metaspriteEnd db 128 -; ANCHOR_END: player-data - -; ANCHOR: player-initialize -InitializePlayer:: - - ld a, 0 - ld [mPlayerFlash+0],a - ld [mPlayerFlash+1],a - - ; Place in the middle of the screen - ld a, 0 - ld [wPlayerPositionX+0], a - ld [wPlayerPositionY+0], a - - ld a, 5 - ld [wPlayerPositionX+1], a - ld [wPlayerPositionY+1], a - - -CopyPlayerTileDataIntoVRAM: - ; Copy the player's tile data into VRAM - ld de, playerShipTileData - ld hl, PLAYER_TILES_START - ld bc, playerShipTileDataEnd - playerShipTileData - call CopyDEintoMemoryAtHL - - ret; -; ANCHOR_END: player-initialize - -; ANCHOR: player-update-start -UpdatePlayer:: - -UpdatePlayer_HandleInput: - - ld a, [wCurKeys] - and a, PADF_UP - call nz, MoveUp - - ld a, [wCurKeys] - and a, PADF_DOWN - call nz, MoveDown - - ld a, [wCurKeys] - and a, PADF_LEFT - call nz, MoveLeft - - ld a, [wCurKeys] - and a, PADF_RIGHT - call nz, MoveRight - - ld a, [wCurKeys] - and a, PADF_A - call nz, TryShoot -; ANCHOR_END: player-update-start - - -; ANCHOR: player-update-flashing - ld a, [mPlayerFlash+0] - ld b, a - - ld a, [mPlayerFlash+1] - ld c, a - -UpdatePlayer_UpdateSprite_CheckFlashing: - - ld a, b - or a, c - jp z, UpdatePlayer_UpdateSprite - - ; decrease bc by 5 - ld a, b - sub a, 5 - ld b, a - ld a, c - sbc a, 0 - ld c, a - - -UpdatePlayer_UpdateSprite_DecreaseFlashing: - - ld a, b - ld [mPlayerFlash+0], a - ld a, c - ld [mPlayerFlash+1], a - - ; descale bc - srl c - rr b - srl c - rr b - srl c - rr b - srl c - rr b - - ld a, b - cp a, 5 - jp c, UpdatePlayer_UpdateSprite_StopFlashing - - - bit 0, b - jp z, UpdatePlayer_UpdateSprite - -UpdatePlayer_UpdateSprite_Flashing: - - ret; -UpdatePlayer_UpdateSprite_StopFlashing: - - ld a, 0 - ld [mPlayerFlash+0],a - ld [mPlayerFlash+1],a -; ANCHOR_END: player-update-flashing - -; ANCHOR: player-update-sprite -UpdatePlayer_UpdateSprite: - - ; Get the unscaled player x position in b - ld a, [wPlayerPositionX+0] - ld b, a - ld a, [wPlayerPositionX+1] - ld d, a - - srl d - rr b - srl d - rr b - srl d - rr b - srl d - rr b - - ; Get the unscaled player y position in c - ld a, [wPlayerPositionY+0] - ld c, a - ld a, [wPlayerPositionY+1] - ld e, a - - srl e - rr c - srl e - rr c - srl e - rr c - srl e - rr c - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Drawing the palyer metasprite - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - - ; Save the address of the metasprite into the 'wMetaspriteAddress' variable - ; Our DrawMetasprites functoin uses that variable - ld a, LOW(playerTestMetaSprite) - ld [wMetaspriteAddress+0], a - ld a, HIGH(playerTestMetaSprite) - ld [wMetaspriteAddress+1], a - - - ; Save the x position - ld a, b - ld [wMetaspriteX],a - - ; Save the y position - ld a, c - ld [wMetaspriteY],a - - ; Actually call the 'DrawMetasprites function - call DrawMetasprites; - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ret -; ANCHOR_END: player-update-sprite - -; ANCHOR: player-shoot -TryShoot: - ld a, [wLastKeys] - and a, PADF_A - ret nz - - call FireNextBullet; - - ret -; ANCHOR_END: player-shoot - -; ANCHOR: player-damage -DamagePlayer:: - - - - ld a, 0 - ld [mPlayerFlash+0], a - ld a, 1 - ld [mPlayerFlash+1], a - - ld a, [wLives] - dec a - ld [wLives], a - - ret -; ANCHOR_END: player-damage - -; ANCHOR: player-movement -MoveUp: - - ; decrease the player's y position - ld a, [wPlayerPositionY+0] - sub a, PLAYER_MOVE_SPEED - ld [wPlayerPositionY+0], a - - ld a, [wPlayerPositionY+1] - sbc a, 0 - ld [wPlayerPositionY+1], a - - ret - -MoveDown: - - ; increase the player's y position - ld a, [wPlayerPositionY+0] - add a, PLAYER_MOVE_SPEED - ld [wPlayerPositionY+0], a - - ld a, [wPlayerPositionY+1] - adc a, 0 - ld [wPlayerPositionY+1], a - - ret - -MoveLeft: - - ; decrease the player's x position - ld a, [wPlayerPositionX+0] - sub a, PLAYER_MOVE_SPEED - ld [wPlayerPositionX+0], a - - ld a, [wPlayerPositionX+1] - sbc a, 0 - ld [wPlayerPositionX+1], a - ret - -MoveRight: - - ; increase the player's x position - ld a, [wPlayerPositionX+0] - add a, PLAYER_MOVE_SPEED - ld [wPlayerPositionX+0], a - - ld a, [wPlayerPositionX+1] - adc a, 0 - ld [wPlayerPositionX+1], a - - ret -; ANCHOR_END: player-movement - - diff --git a/galactic-armada/src/main/states/story/story-state.asm b/galactic-armada/src/main/states/story/story-state.asm deleted file mode 100644 index 5353137c..00000000 --- a/galactic-armada/src/main/states/story/story-state.asm +++ /dev/null @@ -1,110 +0,0 @@ -; ANCHOR: init-story-state -INCLUDE "src/main/utils/hardware.inc" -INCLUDE "src/main/utils/macros/text-macros.inc" - -SECTION "StoryStateASM", ROM0 - -InitStoryState:: - - ; Turn the LCD on - ld a, LCDCF_ON | LCDCF_BGON|LCDCF_OBJON | LCDCF_OBJ16 - ld [rLCDC], a - - ret; -; ANCHOR_END: init-story-state - -; ANCHOR: story-screen-data -Story: - .Line1 db "the galatic empire", 255 - .Line2 db "rules the galaxy", 255 - .Line3 db "with an iron", 255 - .Line4 db "fist.", 255 - .Line5 db "the rebel force", 255 - .Line6 db "remain hopeful of", 255 - .Line7 db "freedoms light", 255 - -; ANCHOR_END: story-screen-data -; ANCHOR: story-screen-page1 -UpdateStoryState:: - - ; Call Our function that typewrites text onto background/window tiles - ld de, $9821 - ld hl, Story.Line1 - call DrawText_WithTypewriterEffect - - - ; Call Our function that typewrites text onto background/window tiles - ld de, $9861 - ld hl, Story.Line2 - call DrawText_WithTypewriterEffect - - - ; Call Our function that typewrites text onto background/window tiles - ld de, $98A1 - ld hl, Story.Line3 - call DrawText_WithTypewriterEffect - - - ; Call Our function that typewrites text onto background/window tiles - ld de, $98E1 - ld hl, Story.Line4 - call DrawText_WithTypewriterEffect - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Wait for A - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ; Save the passed value into the variable: mWaitKey - ; The WaitForKeyFunction always checks against this vriable - ld a,PADF_A - ld [mWaitKey], a - - call WaitForKeyFunction - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; ANCHOR_END: story-screen-page1 - - - call ClearBackground - - -; ANCHOR: story-screen-page2 - ; Call Our function that typewrites text onto background/window tiles - ld de, $9821 - ld hl, Story.Line5 - call DrawText_WithTypewriterEffect - - - ; Call Our function that typewrites text onto background/window tiles - ld de, $9861 - ld hl, Story.Line6 - call DrawText_WithTypewriterEffect - - - ; Call Our function that typewrites text onto background/window tiles - ld de, $98A1 - ld hl, Story.Line7 - call DrawText_WithTypewriterEffect - - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Wait for A - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ; Save the passed value into the variable: mWaitKey - ; The WaitForKeyFunction always checks against this vriable - ld a,PADF_A - ld [mWaitKey], a - - call WaitForKeyFunction - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - -; ANCHOR_END: story-screen-page2 - -; ANCHOR: story-screen-end - ld a, 2 - ld [wGameState],a - jp NextGameState -; ANCHOR_END: story-screen-end \ No newline at end of file diff --git a/galactic-armada/src/main/states/title-screen/title-screen-state.asm b/galactic-armada/src/main/states/title-screen/title-screen-state.asm deleted file mode 100644 index 6953d815..00000000 --- a/galactic-armada/src/main/states/title-screen/title-screen-state.asm +++ /dev/null @@ -1,78 +0,0 @@ -; ANCHOR: title-screen-start -INCLUDE "src/main/utils/hardware.inc" -INCLUDE "src/main/utils/macros/text-macros.inc" - -SECTION "TitleScreenState", ROM0 - -wPressPlayText:: db "press a to play", 255 - -titleScreenTileData: INCBIN "src/generated/backgrounds/title-screen.2bpp" -titleScreenTileDataEnd: - -titleScreenTileMap: INCBIN "src/generated/backgrounds/title-screen.tilemap" -titleScreenTileMapEnd: -; ANCHOR_END: title-screen-start -; ANCHOR: title-screen-init -InitTitleScreenState:: - - call DrawTitleScreen - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Draw the press play text - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ; Call Our function that draws text onto background/window tiles - ld de, $99C3 - ld hl, wPressPlayText - call DrawTextTilesLoop - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ; Turn the LCD on - ld a, LCDCF_ON | LCDCF_BGON|LCDCF_OBJON | LCDCF_OBJ16 - ld [rLCDC], a - - ret; -; ANCHOR_END: title-screen-init - -; ANCHOR: draw-title-screen -DrawTitleScreen:: - - ; Copy the tile data - ld de, titleScreenTileData ; de contains the address where data will be copied from; - ld hl, $9340 ; hl contains the address where data will be copied to; - ld bc, titleScreenTileDataEnd - titleScreenTileData ; bc contains how many bytes we have to copy. - call CopyDEintoMemoryAtHL; - - ; Copy the tilemap - ld de, titleScreenTileMap - ld hl, $9800 - ld bc, titleScreenTileMapEnd - titleScreenTileMap - call CopyDEintoMemoryAtHL_With52Offset - - ret -; ANCHOR_END: draw-title-screen - -; ANCHOR: update-title-screen -UpdateTitleScreenState:: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Wait for A - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ; Save the passed value into the variable: mWaitKey - ; The WaitForKeyFunction always checks against this vriable - ld a,PADF_A - ld [mWaitKey], a - - call WaitForKeyFunction - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ld a, 1 - ld [wGameState],a - jp NextGameState -; ANCHOR_END: update-title-screen diff --git a/galactic-armada/src/main/utils/background-utils.asm b/galactic-armada/src/main/utils/background-utils.asm deleted file mode 100644 index 6f5e220e..00000000 --- a/galactic-armada/src/main/utils/background-utils.asm +++ /dev/null @@ -1,34 +0,0 @@ -; ANCHOR: background-utils -include "src/main/utils/hardware.inc" - -SECTION "Background", ROM0 - -ClearBackground:: - - ; Turn the LCD off - ld a, 0 - ld [rLCDC], a - - ld bc,1024 - ld hl, $9800 - -ClearBackgroundLoop: - - ld a,0 - ld [hli], a - - - dec bc - ld a, b - or a, c - - jp nz, ClearBackgroundLoop - - - ; Turn the LCD on - ld a, LCDCF_ON | LCDCF_BGON|LCDCF_OBJON | LCDCF_OBJ16 - ld [rLCDC], a - - - ret -; ANCHOR_END: background-utils \ No newline at end of file diff --git a/galactic-armada/src/main/utils/collision-utils.asm b/galactic-armada/src/main/utils/collision-utils.asm deleted file mode 100644 index 6142a2f0..00000000 --- a/galactic-armada/src/main/utils/collision-utils.asm +++ /dev/null @@ -1,57 +0,0 @@ -; ANCHOR: collision-utils -include "src/main/utils/hardware.inc" -include "src/main/utils/constants.inc" -include "src/main/utils/hardware.inc" - -SECTION "CollisionUtilsVariables", WRAM0 - -wResult::db; -wSize::db; -wObject1Value:: db -wObject2Value:: db - -SECTION "CollisionUtils", ROM0 - -CheckObjectPositionDifference:: - - ; at this point in time; e = enemy.y, b =bullet.y - - ld a, [wObject1Value] - ld e, a - ld a, [wObject2Value] - ld b, a - - ld a, [wSize] - ld d, a - - ; subtract bullet.y, (aka b) - (enemy.y+8, aka e) - ; carry means eb, means enemy.top is visually below bullet.y (no collision) - ld a, e - sub a, d - cp a, b - - ; no carry means no collision - jp nc, CheckObjectPositionDifference_Failure - - ld a,1 - ld [wResult], a - ret; - - -CheckObjectPositionDifference_Failure: - - ld a,0 - ld [wResult], a - ret; - -; ANCHOR_END: collision-utils \ No newline at end of file diff --git a/galactic-armada/src/main/utils/constants.inc b/galactic-armada/src/main/utils/constants.inc deleted file mode 100644 index 239a8d7f..00000000 --- a/galactic-armada/src/main/utils/constants.inc +++ /dev/null @@ -1,50 +0,0 @@ -include "src/main/utils/hardware.inc" - -DEF MAX_ENEMY_COUNT EQU 10 -DEF MAX_BULLET_COUNT EQU 5 - -DEF ENEMY_SPAWN_DELAY_MAX EQU 70 - -; from https://rgbds.gbdev.io/docs/v0.6.1/rgbasm.5#EXPRESSIONS -; The RS group of commands is a handy way of defining structure offsets: -RSRESET -DEF metasprite_y RB 1 -DEF metasprite_x RB 1 -DEF metasprite_tile RB 1 -DEF metasprite_flag RB 1 -DEF METASPRITE_BYTES_COUNT RB 0 - -; from https://rgbds.gbdev.io/docs/v0.6.1/rgbasm.5#EXPRESSIONS -; The RS group of commands is a handy way of defining structure offsets: -RSRESET -DEF enemy_activeByte RB 1 -DEF enemy_xByte RB 1 -DEF enemy_yLowByte RB 1 -DEF enemy_yHighByte RB 1 -DEF enemy_speedByte RB 1 -DEF enemy_healthByte RB 1 -DEF PER_ENEMY_BYTES_COUNT RB 0 - -; from https://rgbds.gbdev.io/docs/v0.6.1/rgbasm.5#EXPRESSIONS -; The RS group of commands is a handy way of defining structure offsets: -RSRESET -DEF bullet_activeByte RB 1 -DEF bullet_xByte RB 1 -DEF bullet_yLowByte RB 1 -DEF bullet_yHighByte RB 1 -DEF PER_BULLET_BYTES_COUNT RB 0 - -; ANCHOR: sprite-vram-constants -RSRESET -DEF spriteTilesStart RB _VRAM -DEF PLAYER_TILES_START RB 4*16 -DEF ENEMY_TILES_START RB 4*16 -DEF BULLET_TILES_START RB 0 -; ANCHOR_END: sprite-vram-constants - - -DEF ENEMY_MOVE_SPEED EQU 11 -DEF BULLET_MOVE_SPEED EQU 20 - -DEF PLAYER_MOVE_SPEED EQU 15 -DEF PADDLE_Y_POSITION EQU 136 diff --git a/galactic-armada/src/main/utils/hardware.inc b/galactic-armada/src/main/utils/hardware.inc deleted file mode 100644 index 281c7724..00000000 --- a/galactic-armada/src/main/utils/hardware.inc +++ /dev/null @@ -1,922 +0,0 @@ -;* -;* Gameboy Hardware definitions -;* -;* Based on Jones' hardware.inc -;* And based on Carsten Sorensen's ideas. -;* -;* Rev 1.1 - 15-Jul-97 : Added define check -;* Rev 1.2 - 18-Jul-97 : Added revision check macro -;* Rev 1.3 - 19-Jul-97 : Modified for RGBASM V1.05 -;* Rev 1.4 - 27-Jul-97 : Modified for new subroutine prefixes -;* Rev 1.5 - 15-Aug-97 : Added _HRAM, PAD, CART defines -;* : and Nintendo Logo -;* Rev 1.6 - 30-Nov-97 : Added rDIV, rTIMA, rTMA, & rTAC -;* Rev 1.7 - 31-Jan-98 : Added _SCRN0, _SCRN1 -;* Rev 1.8 - 15-Feb-98 : Added rSB, rSC -;* Rev 1.9 - 16-Feb-98 : Converted I/O registers to $FFXX format -;* Rev 2.0 - : Added GBC registers -;* Rev 2.1 - : Added MBC5 & cart RAM enable/disable defines -;* Rev 2.2 - : Fixed NR42,NR43, & NR44 equates -;* Rev 2.3 - : Fixed incorrect _HRAM equate -;* Rev 2.4 - 27-Apr-13 : Added some cart defines (AntonioND) -;* Rev 2.5 - 03-May-15 : Fixed format (AntonioND) -;* Rev 2.6 - 09-Apr-16 : Added GBC OAM and cart defines (AntonioND) -;* Rev 2.7 - 19-Jan-19 : Added rPCMXX (ISSOtm) -;* Rev 2.8 - 03-Feb-19 : Added audio registers flags (Álvaro Cuesta) -;* Rev 2.9 - 28-Feb-20 : Added utility rP1 constants -;* Rev 3.0 - 27-Aug-20 : Register ordering, byte-based sizes, OAM additions, general cleanup (Blitter Object) -;* Rev 4.0 - 03-May-21 : Updated to use RGBDS 0.5.0 syntax, changed IEF_LCDC to IEF_STAT (Eievui) - -IF __RGBDS_MAJOR__ == 0 && __RGBDS_MINOR__ < 5 - FAIL "This version of 'hardware.inc' requires RGBDS version 0.5.0 or later." -ENDC - -; If all of these are already defined, don't do it again. - - IF !DEF(HARDWARE_INC) -DEF HARDWARE_INC EQU 1 - -MACRO rev_Check_hardware_inc -;NOTE: REVISION NUMBER CHANGES MUST BE ADDED -;TO SECOND PARAMETER IN FOLLOWING LINE. - IF \1 > 4.0 ;PUT REVISION NUMBER HERE - WARN "Version \1 or later of 'hardware.inc' is required." - ENDC -ENDM - -DEF _VRAM EQU $8000 ; $8000->$9FFF -DEF _VRAM8000 EQU _VRAM -DEF _VRAM8800 EQU _VRAM+$800 -DEF _VRAM9000 EQU _VRAM+$1000 -DEF _SCRN0 EQU $9800 ; $9800->$9BFF -DEF _SCRN1 EQU $9C00 ; $9C00->$9FFF -DEF _SRAM EQU $A000 ; $A000->$BFFF -DEF _RAM EQU $C000 ; $C000->$CFFF / $C000->$DFFF -DEF _RAMBANK EQU $D000 ; $D000->$DFFF -DEF _OAMRAM EQU $FE00 ; $FE00->$FE9F -DEF _IO EQU $FF00 ; $FF00->$FF7F,$FFFF -DEF _AUD3WAVERAM EQU $FF30 ; $FF30->$FF3F -DEF _HRAM EQU $FF80 ; $FF80->$FFFE - -; *** MBC5 Equates *** - -DEF rRAMG EQU $0000 ; $0000->$1fff -DEF rROMB0 EQU $2000 ; $2000->$2fff -DEF rROMB1 EQU $3000 ; $3000->$3fff - If more than 256 ROM banks are present. -DEF rRAMB EQU $4000 ; $4000->$5fff - Bit 3 enables rumble (if present) - - -;*************************************************************************** -;* -;* Custom registers -;* -;*************************************************************************** - -; -- -; -- P1 ($FF00) -; -- Register for reading joy pad info. (R/W) -; -- -DEF rP1 EQU $FF00 - -DEF P1F_5 EQU %00100000 ; P15 out port, set to 0 to get buttons -DEF P1F_4 EQU %00010000 ; P14 out port, set to 0 to get dpad -DEF P1F_3 EQU %00001000 ; P13 in port -DEF P1F_2 EQU %00000100 ; P12 in port -DEF P1F_1 EQU %00000010 ; P11 in port -DEF P1F_0 EQU %00000001 ; P10 in port - -DEF P1F_GET_DPAD EQU P1F_5 -DEF P1F_GET_BTN EQU P1F_4 -DEF P1F_GET_NONE EQU P1F_4 | P1F_5 - - -; -- -; -- SB ($FF01) -; -- Serial Transfer Data (R/W) -; -- -DEF rSB EQU $FF01 - - -; -- -; -- SC ($FF02) -; -- Serial I/O Control (R/W) -; -- -DEF rSC EQU $FF02 - - -; -- -; -- DIV ($FF04) -; -- Divider register (R/W) -; -- -DEF rDIV EQU $FF04 - - -; -- -; -- TIMA ($FF05) -; -- Timer counter (R/W) -; -- -DEF rTIMA EQU $FF05 - - -; -- -; -- TMA ($FF06) -; -- Timer modulo (R/W) -; -- -DEF rTMA EQU $FF06 - - -; -- -; -- TAC ($FF07) -; -- Timer control (R/W) -; -- -DEF rTAC EQU $FF07 - -DEF TACF_START EQU %00000100 -DEF TACF_STOP EQU %00000000 -DEF TACF_4KHZ EQU %00000000 -DEF TACF_16KHZ EQU %00000011 -DEF TACF_65KHZ EQU %00000010 -DEF TACF_262KHZ EQU %00000001 - - -; -- -; -- IF ($FF0F) -; -- Interrupt Flag (R/W) -; -- -DEF rIF EQU $FF0F - - -; -- -; -- AUD1SWEEP/NR10 ($FF10) -; -- Sweep register (R/W) -; -- -; -- Bit 6-4 - Sweep Time -; -- Bit 3 - Sweep Increase/Decrease -; -- 0: Addition (frequency increases???) -; -- 1: Subtraction (frequency increases???) -; -- Bit 2-0 - Number of sweep shift (# 0-7) -; -- Sweep Time: (n*7.8ms) -; -- -DEF rNR10 EQU $FF10 -DEF rAUD1SWEEP EQU rNR10 - -DEF AUD1SWEEP_UP EQU %00000000 -DEF AUD1SWEEP_DOWN EQU %00001000 - - -; -- -; -- AUD1LEN/NR11 ($FF11) -; -- Sound length/Wave pattern duty (R/W) -; -- -; -- Bit 7-6 - Wave Pattern Duty (00:12.5% 01:25% 10:50% 11:75%) -; -- Bit 5-0 - Sound length data (# 0-63) -; -- -DEF rNR11 EQU $FF11 -DEF rAUD1LEN EQU rNR11 - - -; -- -; -- AUD1ENV/NR12 ($FF12) -; -- Envelope (R/W) -; -- -; -- Bit 7-4 - Initial value of envelope -; -- Bit 3 - Envelope UP/DOWN -; -- 0: Decrease -; -- 1: Range of increase -; -- Bit 2-0 - Number of envelope sweep (# 0-7) -; -- -DEF rNR12 EQU $FF12 -DEF rAUD1ENV EQU rNR12 - - -; -- -; -- AUD1LOW/NR13 ($FF13) -; -- Frequency low byte (W) -; -- -DEF rNR13 EQU $FF13 -DEF rAUD1LOW EQU rNR13 - - -; -- -; -- AUD1HIGH/NR14 ($FF14) -; -- Frequency high byte (W) -; -- -; -- Bit 7 - Initial (when set, sound restarts) -; -- Bit 6 - Counter/consecutive selection -; -- Bit 2-0 - Frequency's higher 3 bits -; -- -DEF rNR14 EQU $FF14 -DEF rAUD1HIGH EQU rNR14 - - -; -- -; -- AUD2LEN/NR21 ($FF16) -; -- Sound Length; Wave Pattern Duty (R/W) -; -- -; -- see AUD1LEN for info -; -- -DEF rNR21 EQU $FF16 -DEF rAUD2LEN EQU rNR21 - - -; -- -; -- AUD2ENV/NR22 ($FF17) -; -- Envelope (R/W) -; -- -; -- see AUD1ENV for info -; -- -DEF rNR22 EQU $FF17 -DEF rAUD2ENV EQU rNR22 - - -; -- -; -- AUD2LOW/NR23 ($FF18) -; -- Frequency low byte (W) -; -- -DEF rNR23 EQU $FF18 -DEF rAUD2LOW EQU rNR23 - - -; -- -; -- AUD2HIGH/NR24 ($FF19) -; -- Frequency high byte (W) -; -- -; -- see AUD1HIGH for info -; -- -DEF rNR24 EQU $FF19 -DEF rAUD2HIGH EQU rNR24 - - -; -- -; -- AUD3ENA/NR30 ($FF1A) -; -- Sound on/off (R/W) -; -- -; -- Bit 7 - Sound ON/OFF (1=ON,0=OFF) -; -- -DEF rNR30 EQU $FF1A -DEF rAUD3ENA EQU rNR30 - - -; -- -; -- AUD3LEN/NR31 ($FF1B) -; -- Sound length (R/W) -; -- -; -- Bit 7-0 - Sound length -; -- -DEF rNR31 EQU $FF1B -DEF rAUD3LEN EQU rNR31 - - -; -- -; -- AUD3LEVEL/NR32 ($FF1C) -; -- Select output level -; -- -; -- Bit 6-5 - Select output level -; -- 00: 0/1 (mute) -; -- 01: 1/1 -; -- 10: 1/2 -; -- 11: 1/4 -; -- -DEF rNR32 EQU $FF1C -DEF rAUD3LEVEL EQU rNR32 - - -; -- -; -- AUD3LOW/NR33 ($FF1D) -; -- Frequency low byte (W) -; -- -; -- see AUD1LOW for info -; -- -DEF rNR33 EQU $FF1D -DEF rAUD3LOW EQU rNR33 - - -; -- -; -- AUD3HIGH/NR34 ($FF1E) -; -- Frequency high byte (W) -; -- -; -- see AUD1HIGH for info -; -- -DEF rNR34 EQU $FF1E -DEF rAUD3HIGH EQU rNR34 - - -; -- -; -- AUD4LEN/NR41 ($FF20) -; -- Sound length (R/W) -; -- -; -- Bit 5-0 - Sound length data (# 0-63) -; -- -DEF rNR41 EQU $FF20 -DEF rAUD4LEN EQU rNR41 - - -; -- -; -- AUD4ENV/NR42 ($FF21) -; -- Envelope (R/W) -; -- -; -- see AUD1ENV for info -; -- -DEF rNR42 EQU $FF21 -DEF rAUD4ENV EQU rNR42 - - -; -- -; -- AUD4POLY/NR43 ($FF22) -; -- Polynomial counter (R/W) -; -- -; -- Bit 7-4 - Selection of the shift clock frequency of the (scf) -; -- polynomial counter (0000-1101) -; -- freq=drf*1/2^scf (not sure) -; -- Bit 3 - Selection of the polynomial counter's step -; -- 0: 15 steps -; -- 1: 7 steps -; -- Bit 2-0 - Selection of the dividing ratio of frequencies (drf) -; -- 000: f/4 001: f/8 010: f/16 011: f/24 -; -- 100: f/32 101: f/40 110: f/48 111: f/56 (f=4.194304 Mhz) -; -- -DEF rNR43 EQU $FF22 -DEF rAUD4POLY EQU rNR43 - - -; -- -; -- AUD4GO/NR44 ($FF23) -; -- -; -- Bit 7 - Inital -; -- Bit 6 - Counter/consecutive selection -; -- -DEF rNR44 EQU $FF23 -DEF rAUD4GO EQU rNR44 - - -; -- -; -- AUDVOL/NR50 ($FF24) -; -- Channel control / ON-OFF / Volume (R/W) -; -- -; -- Bit 7 - Vin->SO2 ON/OFF (Vin??) -; -- Bit 6-4 - SO2 output level (volume) (# 0-7) -; -- Bit 3 - Vin->SO1 ON/OFF (Vin??) -; -- Bit 2-0 - SO1 output level (volume) (# 0-7) -; -- -DEF rNR50 EQU $FF24 -DEF rAUDVOL EQU rNR50 - -DEF AUDVOL_VIN_LEFT EQU %10000000 ; SO2 -DEF AUDVOL_VIN_RIGHT EQU %00001000 ; SO1 - - -; -- -; -- AUDTERM/NR51 ($FF25) -; -- Selection of Sound output terminal (R/W) -; -- -; -- Bit 7 - Output sound 4 to SO2 terminal -; -- Bit 6 - Output sound 3 to SO2 terminal -; -- Bit 5 - Output sound 2 to SO2 terminal -; -- Bit 4 - Output sound 1 to SO2 terminal -; -- Bit 3 - Output sound 4 to SO1 terminal -; -- Bit 2 - Output sound 3 to SO1 terminal -; -- Bit 1 - Output sound 2 to SO1 terminal -; -- Bit 0 - Output sound 0 to SO1 terminal -; -- -DEF rNR51 EQU $FF25 -DEF rAUDTERM EQU rNR51 - -; SO2 -DEF AUDTERM_4_LEFT EQU %10000000 -DEF AUDTERM_3_LEFT EQU %01000000 -DEF AUDTERM_2_LEFT EQU %00100000 -DEF AUDTERM_1_LEFT EQU %00010000 -; SO1 -DEF AUDTERM_4_RIGHT EQU %00001000 -DEF AUDTERM_3_RIGHT EQU %00000100 -DEF AUDTERM_2_RIGHT EQU %00000010 -DEF AUDTERM_1_RIGHT EQU %00000001 - - -; -- -; -- AUDENA/NR52 ($FF26) -; -- Sound on/off (R/W) -; -- -; -- Bit 7 - All sound on/off (sets all audio regs to 0!) -; -- Bit 3 - Sound 4 ON flag (read only) -; -- Bit 2 - Sound 3 ON flag (read only) -; -- Bit 1 - Sound 2 ON flag (read only) -; -- Bit 0 - Sound 1 ON flag (read only) -; -- -DEF rNR52 EQU $FF26 -DEF rAUDENA EQU rNR52 - -DEF AUDENA_ON EQU %10000000 -DEF AUDENA_OFF EQU %00000000 ; sets all audio regs to 0! - - -; -- -; -- LCDC ($FF40) -; -- LCD Control (R/W) -; -- -DEF rLCDC EQU $FF40 - -DEF LCDCF_OFF EQU %00000000 ; LCD Control Operation -DEF LCDCF_ON EQU %10000000 ; LCD Control Operation -DEF LCDCF_WIN9800 EQU %00000000 ; Window Tile Map Display Select -DEF LCDCF_WIN9C00 EQU %01000000 ; Window Tile Map Display Select -DEF LCDCF_WINOFF EQU %00000000 ; Window Display -DEF LCDCF_WINON EQU %00100000 ; Window Display -DEF LCDCF_BG8800 EQU %00000000 ; BG & Window Tile Data Select -DEF LCDCF_BG8000 EQU %00010000 ; BG & Window Tile Data Select -DEF LCDCF_BG9800 EQU %00000000 ; BG Tile Map Display Select -DEF LCDCF_BG9C00 EQU %00001000 ; BG Tile Map Display Select -DEF LCDCF_OBJ8 EQU %00000000 ; OBJ Construction -DEF LCDCF_OBJ16 EQU %00000100 ; OBJ Construction -DEF LCDCF_OBJOFF EQU %00000000 ; OBJ Display -DEF LCDCF_OBJON EQU %00000010 ; OBJ Display -DEF LCDCF_BGOFF EQU %00000000 ; BG Display -DEF LCDCF_BGON EQU %00000001 ; BG Display -; "Window Character Data Select" follows BG - - -; -- -; -- STAT ($FF41) -; -- LCDC Status (R/W) -; -- -DEF rSTAT EQU $FF41 - -DEF STATF_LYC EQU %01000000 ; LYC=LY Coincidence (Selectable) -DEF STATF_MODE10 EQU %00100000 ; Mode 10 -DEF STATF_MODE01 EQU %00010000 ; Mode 01 (V-Blank) -DEF STATF_MODE00 EQU %00001000 ; Mode 00 (H-Blank) -DEF STATF_LYCF EQU %00000100 ; Coincidence Flag -DEF STATF_HBL EQU %00000000 ; H-Blank -DEF STATF_VBL EQU %00000001 ; V-Blank -DEF STATF_OAM EQU %00000010 ; OAM-RAM is used by system -DEF STATF_LCD EQU %00000011 ; Both OAM and VRAM used by system -DEF STATF_BUSY EQU %00000010 ; When set, VRAM access is unsafe - - -; -- -; -- SCY ($FF42) -; -- Scroll Y (R/W) -; -- -DEF rSCY EQU $FF42 - - -; -- -; -- SCX ($FF43) -; -- Scroll X (R/W) -; -- -DEF rSCX EQU $FF43 - - -; -- -; -- LY ($FF44) -; -- LCDC Y-Coordinate (R) -; -- -; -- Values range from 0->153. 144->153 is the VBlank period. -; -- -DEF rLY EQU $FF44 - - -; -- -; -- LYC ($FF45) -; -- LY Compare (R/W) -; -- -; -- When LY==LYC, STATF_LYCF will be set in STAT -; -- -DEF rLYC EQU $FF45 - - -; -- -; -- DMA ($FF46) -; -- DMA Transfer and Start Address (W) -; -- -DEF rDMA EQU $FF46 - - -; -- -; -- BGP ($FF47) -; -- BG Palette Data (W) -; -- -; -- Bit 7-6 - Intensity for %11 -; -- Bit 5-4 - Intensity for %10 -; -- Bit 3-2 - Intensity for %01 -; -- Bit 1-0 - Intensity for %00 -; -- -DEF rBGP EQU $FF47 - - -; -- -; -- OBP0 ($FF48) -; -- Object Palette 0 Data (W) -; -- -; -- See BGP for info -; -- -DEF rOBP0 EQU $FF48 - - -; -- -; -- OBP1 ($FF49) -; -- Object Palette 1 Data (W) -; -- -; -- See BGP for info -; -- -DEF rOBP1 EQU $FF49 - - -; -- -; -- WY ($FF4A) -; -- Window Y Position (R/W) -; -- -; -- 0 <= WY <= 143 -; -- When WY = 0, the window is displayed from the top edge of the LCD screen. -; -- -DEF rWY EQU $FF4A - - -; -- -; -- WX ($FF4B) -; -- Window X Position (R/W) -; -- -; -- 7 <= WX <= 166 -; -- When WX = 7, the window is displayed from the left edge of the LCD screen. -; -- Values of 0-6 and 166 are unreliable due to hardware bugs. -; -- -DEF rWX EQU $FF4B - - -; -- -; -- SPEED ($FF4D) -; -- Select CPU Speed (R/W) -; -- -DEF rKEY1 EQU $FF4D -DEF rSPD EQU rKEY1 - -DEF KEY1F_DBLSPEED EQU %10000000 ; 0=Normal Speed, 1=Double Speed (R) -DEF KEY1F_PREPARE EQU %00000001 ; 0=No, 1=Prepare (R/W) - - -; -- -; -- VBK ($FF4F) -; -- Select Video RAM Bank (R/W) -; -- -; -- Bit 0 - Bank Specification (0: Specify Bank 0; 1: Specify Bank 1) -; -- -DEF rVBK EQU $FF4F - - -; -- -; -- HDMA1 ($FF51) -; -- High byte for Horizontal Blanking/General Purpose DMA source address (W) -; -- CGB Mode Only -; -- -DEF rHDMA1 EQU $FF51 - - -; -- -; -- HDMA2 ($FF52) -; -- Low byte for Horizontal Blanking/General Purpose DMA source address (W) -; -- CGB Mode Only -; -- -DEF rHDMA2 EQU $FF52 - - -; -- -; -- HDMA3 ($FF53) -; -- High byte for Horizontal Blanking/General Purpose DMA destination address (W) -; -- CGB Mode Only -; -- -DEF rHDMA3 EQU $FF53 - - -; -- -; -- HDMA4 ($FF54) -; -- Low byte for Horizontal Blanking/General Purpose DMA destination address (W) -; -- CGB Mode Only -; -- -DEF rHDMA4 EQU $FF54 - - -; -- -; -- HDMA5 ($FF55) -; -- Transfer length (in tiles minus 1)/mode/start for Horizontal Blanking, General Purpose DMA (R/W) -; -- CGB Mode Only -; -- -DEF rHDMA5 EQU $FF55 - -DEF HDMA5F_MODE_GP EQU %00000000 ; General Purpose DMA (W) -DEF HDMA5F_MODE_HBL EQU %10000000 ; HBlank DMA (W) - -; -- Once DMA has started, use HDMA5F_BUSY to check when the transfer is complete -DEF HDMA5F_BUSY EQU %10000000 ; 0=Busy (DMA still in progress), 1=Transfer complete (R) - - -; -- -; -- RP ($FF56) -; -- Infrared Communications Port (R/W) -; -- CGB Mode Only -; -- -DEF rRP EQU $FF56 - -DEF RPF_ENREAD EQU %11000000 -DEF RPF_DATAIN EQU %00000010 ; 0=Receiving IR Signal, 1=Normal -DEF RPF_WRITE_HI EQU %00000001 -DEF RPF_WRITE_LO EQU %00000000 - - -; -- -; -- BCPS ($FF68) -; -- Background Color Palette Specification (R/W) -; -- -DEF rBCPS EQU $FF68 - -DEF BCPSF_AUTOINC EQU %10000000 ; Auto Increment (0=Disabled, 1=Increment after Writing) - - -; -- -; -- BCPD ($FF69) -; -- Background Color Palette Data (R/W) -; -- -DEF rBCPD EQU $FF69 - - -; -- -; -- OCPS ($FF6A) -; -- Object Color Palette Specification (R/W) -; -- -DEF rOCPS EQU $FF6A - -DEF OCPSF_AUTOINC EQU %10000000 ; Auto Increment (0=Disabled, 1=Increment after Writing) - - -; -- -; -- OCPD ($FF6B) -; -- Object Color Palette Data (R/W) -; -- -DEF rOCPD EQU $FF6B - - -; -- -; -- SMBK/SVBK ($FF70) -; -- Select Main RAM Bank (R/W) -; -- -; -- Bit 2-0 - Bank Specification (0,1: Specify Bank 1; 2-7: Specify Banks 2-7) -; -- -DEF rSVBK EQU $FF70 -DEF rSMBK EQU rSVBK - - -; -- -; -- PCM12 ($FF76) -; -- Sound channel 1&2 PCM amplitude (R) -; -- -; -- Bit 7-4 - Copy of sound channel 2's PCM amplitude -; -- Bit 3-0 - Copy of sound channel 1's PCM amplitude -; -- -DEF rPCM12 EQU $FF76 - - -; -- -; -- PCM34 ($FF77) -; -- Sound channel 3&4 PCM amplitude (R) -; -- -; -- Bit 7-4 - Copy of sound channel 4's PCM amplitude -; -- Bit 3-0 - Copy of sound channel 3's PCM amplitude -; -- -DEF rPCM34 EQU $FF77 - - -; -- -; -- IE ($FFFF) -; -- Interrupt Enable (R/W) -; -- -DEF rIE EQU $FFFF - -DEF IEF_HILO EQU %00010000 ; Transition from High to Low of Pin number P10-P13 -DEF IEF_SERIAL EQU %00001000 ; Serial I/O transfer end -DEF IEF_TIMER EQU %00000100 ; Timer Overflow -DEF IEF_STAT EQU %00000010 ; STAT -DEF IEF_VBLANK EQU %00000001 ; V-Blank - - -;*************************************************************************** -;* -;* Flags common to multiple sound channels -;* -;*************************************************************************** - -; -- -; -- Square wave duty cycle -; -- -; -- Can be used with AUD1LEN and AUD2LEN -; -- See AUD1LEN for more info -; -- -DEF AUDLEN_DUTY_12_5 EQU %00000000 ; 12.5% -DEF AUDLEN_DUTY_25 EQU %01000000 ; 25% -DEF AUDLEN_DUTY_50 EQU %10000000 ; 50% -DEF AUDLEN_DUTY_75 EQU %11000000 ; 75% - - -; -- -; -- Audio envelope flags -; -- -; -- Can be used with AUD1ENV, AUD2ENV, AUD4ENV -; -- See AUD1ENV for more info -; -- -DEF AUDENV_UP EQU %00001000 -DEF AUDENV_DOWN EQU %00000000 - - -; -- -; -- Audio trigger flags -; -- -; -- Can be used with AUD1HIGH, AUD2HIGH, AUD3HIGH -; -- See AUD1HIGH for more info -; -- - -DEF AUDHIGH_RESTART EQU %10000000 -DEF AUDHIGH_LENGTH_ON EQU %01000000 -DEF AUDHIGH_LENGTH_OFF EQU %00000000 - - -;*************************************************************************** -;* -;* CPU values on bootup (a=type, b=qualifier) -;* -;*************************************************************************** - -DEF BOOTUP_A_DMG EQU $01 ; Dot Matrix Game -DEF BOOTUP_A_CGB EQU $11 ; Color GameBoy -DEF BOOTUP_A_MGB EQU $FF ; Mini GameBoy (Pocket GameBoy) - -; if a=BOOTUP_A_CGB, bit 0 in b can be checked to determine if real CGB or -; other system running in GBC mode -DEF BOOTUP_B_CGB EQU %00000000 -DEF BOOTUP_B_AGB EQU %00000001 ; GBA, GBA SP, Game Boy Player, or New GBA SP - - -;*************************************************************************** -;* -;* Cart related -;* -;*************************************************************************** - -; $0143 Color GameBoy compatibility code -DEF CART_COMPATIBLE_DMG EQU $00 -DEF CART_COMPATIBLE_DMG_GBC EQU $80 -DEF CART_COMPATIBLE_GBC EQU $C0 - -; $0146 GameBoy/Super GameBoy indicator -DEF CART_INDICATOR_GB EQU $00 -DEF CART_INDICATOR_SGB EQU $03 - -; $0147 Cartridge type -DEF CART_ROM EQU $00 -DEF CART_ROM_MBC1 EQU $01 -DEF CART_ROM_MBC1_RAM EQU $02 -DEF CART_ROM_MBC1_RAM_BAT EQU $03 -DEF CART_ROM_MBC2 EQU $05 -DEF CART_ROM_MBC2_BAT EQU $06 -DEF CART_ROM_RAM EQU $08 -DEF CART_ROM_RAM_BAT EQU $09 -DEF CART_ROM_MMM01 EQU $0B -DEF CART_ROM_MMM01_RAM EQU $0C -DEF CART_ROM_MMM01_RAM_BAT EQU $0D -DEF CART_ROM_MBC3_BAT_RTC EQU $0F -DEF CART_ROM_MBC3_RAM_BAT_RTC EQU $10 -DEF CART_ROM_MBC3 EQU $11 -DEF CART_ROM_MBC3_RAM EQU $12 -DEF CART_ROM_MBC3_RAM_BAT EQU $13 -DEF CART_ROM_MBC5 EQU $19 -DEF CART_ROM_MBC5_BAT EQU $1A -DEF CART_ROM_MBC5_RAM_BAT EQU $1B -DEF CART_ROM_MBC5_RUMBLE EQU $1C -DEF CART_ROM_MBC5_RAM_RUMBLE EQU $1D -DEF CART_ROM_MBC5_RAM_BAT_RUMBLE EQU $1E -DEF CART_ROM_MBC7_RAM_BAT_GYRO EQU $22 -DEF CART_ROM_POCKET_CAMERA EQU $FC -DEF CART_ROM_BANDAI_TAMA5 EQU $FD -DEF CART_ROM_HUDSON_HUC3 EQU $FE -DEF CART_ROM_HUDSON_HUC1 EQU $FF - -; $0148 ROM size -; these are kilobytes -DEF CART_ROM_32KB EQU $00 ; 2 banks -DEF CART_ROM_64KB EQU $01 ; 4 banks -DEF CART_ROM_128KB EQU $02 ; 8 banks -DEF CART_ROM_256KB EQU $03 ; 16 banks -DEF CART_ROM_512KB EQU $04 ; 32 banks -DEF CART_ROM_1024KB EQU $05 ; 64 banks -DEF CART_ROM_2048KB EQU $06 ; 128 banks -DEF CART_ROM_4096KB EQU $07 ; 256 banks -DEF CART_ROM_8192KB EQU $08 ; 512 banks -DEF CART_ROM_1152KB EQU $52 ; 72 banks -DEF CART_ROM_1280KB EQU $53 ; 80 banks -DEF CART_ROM_1536KB EQU $54 ; 96 banks - -; $0149 SRAM size -; these are kilobytes -DEF CART_SRAM_NONE EQU 0 -DEF CART_SRAM_2KB EQU 1 ; 1 incomplete bank -DEF CART_SRAM_8KB EQU 2 ; 1 bank -DEF CART_SRAM_32KB EQU 3 ; 4 banks -DEF CART_SRAM_128KB EQU 4 ; 16 banks - -DEF CART_SRAM_ENABLE EQU $0A -DEF CART_SRAM_DISABLE EQU $00 - -; $014A Destination code -DEF CART_DEST_JAPANESE EQU $00 -DEF CART_DEST_NON_JAPANESE EQU $01 - - -;*************************************************************************** -;* -;* Keypad related -;* -;*************************************************************************** - -DEF PADF_DOWN EQU $80 -DEF PADF_UP EQU $40 -DEF PADF_LEFT EQU $20 -DEF PADF_RIGHT EQU $10 -DEF PADF_START EQU $08 -DEF PADF_SELECT EQU $04 -DEF PADF_B EQU $02 -DEF PADF_A EQU $01 - -DEF PADB_DOWN EQU $7 -DEF PADB_UP EQU $6 -DEF PADB_LEFT EQU $5 -DEF PADB_RIGHT EQU $4 -DEF PADB_START EQU $3 -DEF PADB_SELECT EQU $2 -DEF PADB_B EQU $1 -DEF PADB_A EQU $0 - - -;*************************************************************************** -;* -;* Screen related -;* -;*************************************************************************** - -DEF SCRN_X EQU 160 ; Width of screen in pixels -DEF SCRN_Y EQU 144 ; Height of screen in pixels -DEF SCRN_X_B EQU 20 ; Width of screen in bytes -DEF SCRN_Y_B EQU 18 ; Height of screen in bytes - -DEF SCRN_VX EQU 256 ; Virtual width of screen in pixels -DEF SCRN_VY EQU 256 ; Virtual height of screen in pixels -DEF SCRN_VX_B EQU 32 ; Virtual width of screen in bytes -DEF SCRN_VY_B EQU 32 ; Virtual height of screen in bytes - - -;*************************************************************************** -;* -;* OAM related -;* -;*************************************************************************** - -; OAM attributes -; each entry in OAM RAM is 4 bytes (sizeof_OAM_ATTRS) -RSRESET -DEF OAMA_Y RB 1 ; y pos -DEF OAMA_X RB 1 ; x pos -DEF OAMA_TILEID RB 1 ; tile id -DEF OAMA_FLAGS RB 1 ; flags (see below) -DEF sizeof_OAM_ATTRS RB 0 - -DEF OAM_COUNT EQU 40 ; number of OAM entries in OAM RAM - -; flags -DEF OAMF_PRI EQU %10000000 ; Priority -DEF OAMF_YFLIP EQU %01000000 ; Y flip -DEF OAMF_XFLIP EQU %00100000 ; X flip -DEF OAMF_PAL0 EQU %00000000 ; Palette number; 0,1 (DMG) -DEF OAMF_PAL1 EQU %00010000 ; Palette number; 0,1 (DMG) -DEF OAMF_BANK0 EQU %00000000 ; Bank number; 0,1 (GBC) -DEF OAMF_BANK1 EQU %00001000 ; Bank number; 0,1 (GBC) - -DEF OAMF_PALMASK EQU %00000111 ; Palette (GBC) - -DEF OAMB_PRI EQU 7 ; Priority -DEF OAMB_YFLIP EQU 6 ; Y flip -DEF OAMB_XFLIP EQU 5 ; X flip -DEF OAMB_PAL1 EQU 4 ; Palette number; 0,1 (DMG) -DEF OAMB_BANK1 EQU 3 ; Bank number; 0,1 (GBC) - - -;* -;* Nintendo scrolling logo -;* (Code won't work on a real GameBoy) -;* (if next lines are altered.) -MACRO NINTENDO_LOGO - DB $CE,$ED,$66,$66,$CC,$0D,$00,$0B,$03,$73,$00,$83,$00,$0C,$00,$0D - DB $00,$08,$11,$1F,$88,$89,$00,$0E,$DC,$CC,$6E,$E6,$DD,$DD,$D9,$99 - DB $BB,$BB,$67,$63,$6E,$0E,$EC,$CC,$DD,$DC,$99,$9F,$BB,$B9,$33,$3E -ENDM - -; Deprecated constants. Please avoid using. - -DEF IEF_LCDC EQU %00000010 ; LCDC (see STAT) - - ENDC ;HARDWARE_INC \ No newline at end of file diff --git a/galactic-armada/src/main/utils/input-utils.asm b/galactic-armada/src/main/utils/input-utils.asm deleted file mode 100644 index 89878d04..00000000 --- a/galactic-armada/src/main/utils/input-utils.asm +++ /dev/null @@ -1,56 +0,0 @@ -; ANCHOR: input-utils -SECTION "InputUtilsVariables", WRAM0 - -mWaitKey:: db - -SECTION "InputUtils", ROM0 - -WaitForKeyFunction:: - - ; Save our original value - push bc - - -WaitForKeyFunction_Loop: - - ; save the keys last frame - ld a, [wCurKeys] - ld [wLastKeys], a - - ; This is in input.asm - ; It's straight from: https://gbdev.io/gb-asm-tutorial/part2/input.html - ; In their words (paraphrased): reading player input for gameboy is NOT a trivial task - ; So it's best to use some tested code - call Input - - - ld a, [mWaitKey] - ld b,a - ld a, [wCurKeys] - and a, b - jp z,WaitForKeyFunction_NotPressed - - ld a, [wLastKeys] - and a, b - jp nz,WaitForKeyFunction_NotPressed - - ; restore our original value - pop bc - - ret - - -WaitForKeyFunction_NotPressed: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Wait a small amount of time - ; Save our count in this variable - ld a, 1 - ld [wVBlankCount], a - - ; Call our function that performs the code - call WaitForVBlankFunction - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - jp WaitForKeyFunction_Loop -; ANCHOR_END: input-utils \ No newline at end of file diff --git a/galactic-armada/src/main/utils/macros/text-macros.inc b/galactic-armada/src/main/utils/macros/text-macros.inc deleted file mode 100644 index a894cb63..00000000 --- a/galactic-armada/src/main/utils/macros/text-macros.inc +++ /dev/null @@ -1,32 +0,0 @@ -; ANCHOR: charmap -; The character map for the text-font -CHARMAP " ", 0 -CHARMAP ".", 24 -CHARMAP "-", 25 -CHARMAP "a", 26 -CHARMAP "b", 27 -CHARMAP "c", 28 -CHARMAP "d", 29 -CHARMAP "e", 30 -CHARMAP "f", 31 -CHARMAP "g", 32 -CHARMAP "h", 33 -CHARMAP "i", 34 -CHARMAP "j", 35 -CHARMAP "k", 36 -CHARMAP "l", 37 -CHARMAP "m", 38 -CHARMAP "n", 39 -CHARMAP "o", 40 -CHARMAP "p", 41 -CHARMAP "q", 42 -CHARMAP "r", 43 -CHARMAP "s", 44 -CHARMAP "t", 45 -CHARMAP "u", 46 -CHARMAP "v", 47 -CHARMAP "w", 48 -CHARMAP "x", 49 -CHARMAP "y", 50 -CHARMAP "z", 51 -; ANCHOR_END: charmap diff --git a/galactic-armada/src/main/utils/math.asm b/galactic-armada/src/main/utils/math.asm deleted file mode 100644 index 69d434f8..00000000 --- a/galactic-armada/src/main/utils/math.asm +++ /dev/null @@ -1,28 +0,0 @@ - -SECTION "MathVariables", WRAM0 -randstate:: ds 4 - -SECTION "Math", ROM0 - - -;; From: https://github.com/pinobatch/libbet/blob/master/src/rand.z80#L34-L54 -; Generates a pseudorandom 16-bit integer in BC -; using the LCG formula from cc65 rand(): -; x[i + 1] = x[i] * 0x01010101 + 0xB3B3B3B3 -; @return A=B=state bits 31-24 (which have the best entropy), -; C=state bits 23-16, HL trashed -rand:: - ; Add 0xB3 then multiply by 0x01010101 - ld hl, randstate+0 - ld a, [hl] - add a, $B3 - ld [hl+], a - adc a, [hl] - ld [hl+], a - adc a, [hl] - ld [hl+], a - ld c, a - adc a, [hl] - ld [hl], a - ld b, a - ret \ No newline at end of file diff --git a/galactic-armada/src/main/utils/memory-utils.asm b/galactic-armada/src/main/utils/memory-utils.asm deleted file mode 100644 index 8ddeb8b9..00000000 --- a/galactic-armada/src/main/utils/memory-utils.asm +++ /dev/null @@ -1,24 +0,0 @@ -; ANCHOR: memory-utils -SECTION "MemoryUtilsSection", ROM0 - -CopyDEintoMemoryAtHL:: - ld a, [de] - ld [hli], a - inc de - dec bc - ld a, b - or a, c - jp nz, CopyDEintoMemoryAtHL ; Jump to COpyTiles, if the z flag is not set. (the last operation had a non zero result) - ret; - -CopyDEintoMemoryAtHL_With52Offset:: - ld a, [de] - add a, 52 - ld [hli], a - inc de - dec bc - ld a, b - or a, c - jp nz, CopyDEintoMemoryAtHL_With52Offset ; Jump to COpyTiles, if the z flag is not set. (the last operation had a non zero result) - ret; -; ANCHOR_END: memory-utils \ No newline at end of file diff --git a/galactic-armada/src/main/utils/metasprites.asm b/galactic-armada/src/main/utils/metasprites.asm deleted file mode 100644 index 0ae2d1c4..00000000 --- a/galactic-armada/src/main/utils/metasprites.asm +++ /dev/null @@ -1,79 +0,0 @@ - -include "src/main/utils/constants.inc" -SECTION "MetaSpriteVariables", WRAM0 - -wMetaspriteAddress:: dw -wMetaspriteX:: db -wMetaspriteY::db - -SECTION "MetaSprites", ROM0 - -DrawMetasprites:: - - - ; get the metasprite address - ld a, [wMetaspriteAddress+0] - ld l, a - ld a, [wMetaspriteAddress+1] - ld h, a - - ; Get the y position - ld a, [hli] - ld b, a - - ; stop if the y position is 128 - ld a, b - cp 128 - ret z - - ld a, [wMetaspriteY] - add a, b - ld [wMetaspriteY],a - - ; Get the x position - ld a, [hli] - ld c, a - - ld a, [wMetaspriteX] - add a,c - ld [wMetaspriteX],a - - ; Get the tile position - ld a, [hli] - ld d, a - - ; Get the flag position - ld a, [hli] - ld e, a - - - ;Get our offset address in hl - ld a,[wLastOAMAddress+0] - ld l, a - ld a, HIGH(wShadowOAM) - ld h, a - - ld a, [wMetaspriteY] - ld [hli], a - - ld a, [wMetaspriteX] - ld [hli], a - - ld a, d - ld [hli], a - - ld a, e - ld [hli], a - - call NextOAMSprite - - ; increase the wMetaspriteAddress - ld a, [wMetaspriteAddress+0] - add a, METASPRITE_BYTES_COUNT - ld [wMetaspriteAddress+0], a - ld a, [wMetaspriteAddress+1] - adc a, 0 - ld [wMetaspriteAddress+1], a - - - jp DrawMetasprites diff --git a/galactic-armada/src/main/utils/sprites-utils.asm b/galactic-armada/src/main/utils/sprites-utils.asm deleted file mode 100644 index 512b69b5..00000000 --- a/galactic-armada/src/main/utils/sprites-utils.asm +++ /dev/null @@ -1,95 +0,0 @@ - -include "src/main/utils/hardware.inc" - -SECTION "SpriteVariables", WRAM0 - -wLastOAMAddress:: dw -wSpritesUsed:: db -wHelperValue::db - -SECTION "Sprites", ROM0 - -ClearAllSprites:: - - ; Start clearing oam - ld a, 0 - ld b, OAM_COUNT*sizeof_OAM_ATTRS ; 40 sprites times 4 bytes per sprite - ld hl, wShadowOAM ; The start of our oam sprites in RAM - -ClearOamLoop:: - ld [hli], a - dec b - jp nz, ClearOamLoop - ld a,0 - ld [wSpritesUsed],a - - - ; from: https://github.com/eievui5/gb-sprobj-lib - ; Finally, run the following code during VBlank: - ld a, HIGH(wShadowOAM) - call hOAMDMA - - ret - -ClearRemainingSprites:: - -ClearRemainingSprites_Loop:: - - ;Get our offset address in hl - ld a,[wLastOAMAddress+0] - ld l, a - ld a, HIGH(wShadowOAM) - ld h, a - - ld a, l - cp a, 160 - ret nc - ret nc - - ; Set the y and x to be 0 - ld a, 0 - ld [hli], a - ld [hld], a - - ; Move up 4 bytes - ld a, l - add a, 4 - ld l, a - - call NextOAMSprite - - - jp ClearRemainingSprites_Loop - -; ANCHOR: reset-oam-sprite-address -ResetOAMSpriteAddress:: - - ld a, 0 - ld [wSpritesUsed], a - - ld a, LOW(wShadowOAM) - ld [wLastOAMAddress+0], a - ld a, HIGH(wShadowOAM) - ld [wLastOAMAddress+1], a - - ret -; ANCHOR_END: reset-oam-sprite-address - -; ANCHOR: next-oam-sprite -NextOAMSprite:: - - ld a, [wSpritesUsed] - inc a - ld [wSpritesUsed], a - - ld a,[wLastOAMAddress+0] - add a, sizeof_OAM_ATTRS - ld [wLastOAMAddress+0], a - ld a, HIGH(wShadowOAM) - ld [wLastOAMAddress+1], a - - - ret -; ANCHOR_END: next-oam-sprite - - \ No newline at end of file diff --git a/galactic-armada/src/main/utils/text-utils.asm b/galactic-armada/src/main/utils/text-utils.asm deleted file mode 100644 index 4bbeed14..00000000 --- a/galactic-armada/src/main/utils/text-utils.asm +++ /dev/null @@ -1,64 +0,0 @@ - -SECTION "Text", ROM0 - -textFontTileData: INCBIN "src/generated/backgrounds/text-font.2bpp" -textFontTileDataEnd: - -LoadTextFontIntoVRAM:: - ; Copy the tile data - ld de, textFontTileData ; de contains the address where data will be copied from; - ld hl, $9000 ; hl contains the address where data will be copied to; - ld bc, textFontTileDataEnd - textFontTileData ; bc contains how many bytes we have to copy. - call CopyDEintoMemoryAtHL - ret - -; ANCHOR: draw-text-tiles -DrawTextTilesLoop:: - - ; Check for the end of string character 255 - ld a, [hl] - cp 255 - ret z - - ; Write the current character (in hl) to the address - ; on the tilemap (in de) - ld a, [hl] - ld [de], a - - inc hl - inc de - - ; move to the next character and next background tile - jp DrawTextTilesLoop -; ANCHOR_END: draw-text-tiles - -; ANCHOR: typewriter-effect -DrawText_WithTypewriterEffect:: - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; Wait a small amount of time - ; Save our count in this variable - ld a, 3 - ld [wVBlankCount], a - - ; Call our function that performs the code - call WaitForVBlankFunction - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - - ; Check for the end of string character 255 - ld a, [hl] - cp 255 - ret z - - ; Write the current character (in hl) to the address - ; on the tilemap (in de) - ld a, [hl] - ld [de], a - - ; move to the next character and next background tile - inc hl - inc de - - jp DrawText_WithTypewriterEffect -; ANCHOR_END: typewriter-effect diff --git a/galactic-armada/src/main/utils/vblank-utils.asm b/galactic-armada/src/main/utils/vblank-utils.asm deleted file mode 100644 index 899c4f5d..00000000 --- a/galactic-armada/src/main/utils/vblank-utils.asm +++ /dev/null @@ -1,38 +0,0 @@ -; ANCHOR: vblank-utils -INCLUDE "src/main/utils/hardware.inc" - -SECTION "VBlankVariables", WRAM0 - -wVBlankCount:: db - -SECTION "VBlankFunctions", ROM0 - -WaitForOneVBlank:: - - ; Wait a small amount of time - ; Save our count in this variable - ld a, 1 - ld [wVBlankCount], a - -WaitForVBlankFunction:: - -WaitForVBlankFunction_Loop:: - - ld a, [rLY] ; Copy the vertical line to a - cp 144 ; Check if the vertical line (in a) is 0 - jp c, WaitForVBlankFunction_Loop ; A conditional jump. The condition is that 'c' is set, the last operation overflowed - - ld a, [wVBlankCount] - sub a, 1 - ld [wVBlankCount], a - ret z - -WaitForVBlankFunction_Loop2:: - - ld a, [rLY] ; Copy the vertical line to a - cp 144 ; Check if the vertical line (in a) is 0 - jp nc, WaitForVBlankFunction_Loop2 ; A conditional jump. The condition is that 'c' is set, the last operation overflowed - - jp WaitForVBlankFunction_Loop - -; ANCHOR_END: vblank-utils \ No newline at end of file diff --git a/galactic-armada/src/resources/backgrounds/star-field.aseprite b/galactic-armada/src/resources/backgrounds/star-field.aseprite deleted file mode 100644 index a8a08bb5..00000000 Binary files a/galactic-armada/src/resources/backgrounds/star-field.aseprite and /dev/null differ diff --git a/galactic-armada/src/resources/backgrounds/star-field.png b/galactic-armada/src/resources/backgrounds/star-field.png deleted file mode 100644 index c2e116c3..00000000 Binary files a/galactic-armada/src/resources/backgrounds/star-field.png and /dev/null differ diff --git a/galactic-armada/src/resources/backgrounds/text-font.aseprite b/galactic-armada/src/resources/backgrounds/text-font.aseprite deleted file mode 100644 index 740b0d19..00000000 Binary files a/galactic-armada/src/resources/backgrounds/text-font.aseprite and /dev/null differ diff --git a/galactic-armada/src/resources/backgrounds/text-font.png b/galactic-armada/src/resources/backgrounds/text-font.png deleted file mode 100644 index 1cf645b5..00000000 Binary files a/galactic-armada/src/resources/backgrounds/text-font.png and /dev/null differ diff --git a/galactic-armada/src/resources/backgrounds/title-screen.aseprite b/galactic-armada/src/resources/backgrounds/title-screen.aseprite deleted file mode 100644 index 3e29bd31..00000000 Binary files a/galactic-armada/src/resources/backgrounds/title-screen.aseprite and /dev/null differ diff --git a/galactic-armada/src/resources/backgrounds/title-screen.png b/galactic-armada/src/resources/backgrounds/title-screen.png deleted file mode 100644 index b99ae72d..00000000 Binary files a/galactic-armada/src/resources/backgrounds/title-screen.png and /dev/null differ diff --git a/galactic-armada/src/resources/sprites/bullet.aseprite b/galactic-armada/src/resources/sprites/bullet.aseprite deleted file mode 100644 index 59a1d68a..00000000 Binary files a/galactic-armada/src/resources/sprites/bullet.aseprite and /dev/null differ diff --git a/galactic-armada/src/resources/sprites/bullet.png b/galactic-armada/src/resources/sprites/bullet.png deleted file mode 100644 index cf648fba..00000000 Binary files a/galactic-armada/src/resources/sprites/bullet.png and /dev/null differ diff --git a/galactic-armada/src/resources/sprites/enemy-ship.aseprite b/galactic-armada/src/resources/sprites/enemy-ship.aseprite deleted file mode 100644 index 56a7dddc..00000000 Binary files a/galactic-armada/src/resources/sprites/enemy-ship.aseprite and /dev/null differ diff --git a/galactic-armada/src/resources/sprites/enemy-ship.png b/galactic-armada/src/resources/sprites/enemy-ship.png deleted file mode 100644 index 15d2188a..00000000 Binary files a/galactic-armada/src/resources/sprites/enemy-ship.png and /dev/null differ diff --git a/galactic-armada/src/resources/sprites/player-ship.aseprite b/galactic-armada/src/resources/sprites/player-ship.aseprite deleted file mode 100644 index 6c7eac55..00000000 Binary files a/galactic-armada/src/resources/sprites/player-ship.aseprite and /dev/null differ diff --git a/galactic-armada/src/resources/sprites/player-ship.png b/galactic-armada/src/resources/sprites/player-ship.png deleted file mode 100644 index 4bcde7b9..00000000 Binary files a/galactic-armada/src/resources/sprites/player-ship.png and /dev/null differ diff --git a/src/part3/bullets.md b/src/part3/bullets.md deleted file mode 100644 index 7c656581..00000000 --- a/src/part3/bullets.md +++ /dev/null @@ -1,93 +0,0 @@ -# Bullets - -Bullets are relatively simple, logic-wise. They all travel straight-forward, and de-activate themselves when they leave the screen. - -At the top of our "src/main/states/gameplay/objects/bullets.asm" file we'll setup some variables for bullets and include our tile data. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:bullets-top}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:bullets-top}} -``` - -We'll need to loop through the bullet object pool in the following sections. - -## Initiating Bullets - -In our "InitializeBullets" function, we'll copy the tile data for the bullet sprites into VRAM, and set every bullet as inactive. Each bullet is 4 bytes, the first byte signaling if the bullet is active or not. - -![BulletBytesVisualized.png](../assets/part3/img/BulletBytesVisualized.png) - -We'll iterate through bullet object pool, named "wBullets", and activate the first of the the four bytes. Then skipping the next 3 bytes, to go onto the next bullet. We'll do this until we've looped for each bullet in our pool. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:bullets-initialize}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:bullets-initialize}} -``` - -## Updating Bullets - -When we want to update each of bullets, first we should check if any bullets are active. If no bullets are active we can stop early. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:bullets-update-start}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:bullets-update-start}} -``` - -If we have active bullets, we'll reset how many bullets we've checked and set our "hl" registers to point to the first bullets address. - -When were updating each bullet, we'll check each byte, changing hl (the byte we want to read) as we go. At the start, "hl" should point to the first byte. "hl" should point to the first byte at the end too: - -> HL should point to the first byte at the end so we can easily do one of two things: -> * deactivate the bullet -> * jump to the next bullet (by simply adding 4 to hl) - -For we each bullet, we'll do the following: - -* Check if active -* Get our x position, save into b -* Get our y scaled positon, save into c (low byte), and d (high byte) -* Decrease our y position to move the bullet upwards -* Reset HL to the first byte of our bullet -* Descale the y position we have in c & d, and jump to our deactivation code if c (the low byte) is high enough -* Draw our bullet metasprit, if it wasn't previously deactivated - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:bullets-update-per}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:bullets-update-per}} -``` - -### Drawing the Bullets - -We'll draw our bullet metasprite like we drew the player, using our "DrawMetasprites" function. This function may alter the 'h' or 'l' registers, so we'll push the hl register onto the stack before hand. After drawing, we'll pop the hl register off of the stack to restore it's value. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:draw-bullets}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:draw-bullets}} -``` - -### Deactivating the Bullets - -If a bullet needs to be deactivated, we simply set it's first byte to 0. At this point in time, the "hl" registers should point at our bullets first byte. This makes deactivation a really simple task. In addition to changing the first byte, we'll decrease how many bullets we have that are active. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:deactivate-bullets}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:deactivate-bullets}} -``` - - -### Updating the next bullet - -After we've updated a single bullet, we'll increase how many bullet's we've updated. If we've updated all the bullets, we can stop our "UpdateBullets" function. Otherwise, we'll add 4 bytes to the addressed stored in "hl", and update the next bullet. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:bullets-update-loop}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:bullets-update-loop}} -``` - - -## Firing New Bullets - -During the "UpdatePlayer" function previously, when use pressed A we called the "FireNextBullet" function. - -This function will loop through each bullet in the bullet object pool. When it finds an inactive bullet, it will activate it and set it's position equal to the players. - -> Our bullets only use one 8-bit integer for their x position, so need to de-scale the player's 16-bit scaled x position - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:fire-bullets}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:fire-bullets}} -``` - -That's it for bullets logic. Next we'll cover enemies, and after that we'll step back into the world of bullets with "Bullet vs Enemy" Collision. \ No newline at end of file diff --git a/src/part3/changing-game-states.md b/src/part3/changing-game-states.md deleted file mode 100644 index 2af74161..00000000 --- a/src/part3/changing-game-states.md +++ /dev/null @@ -1,33 +0,0 @@ -# Changing Game States - -In our GalacticArmada.asm file, we'll define label called "NextGameState". Our game will have 3 game states: - -- Title Screen -- Story Screen -- Gameplay - -Here is how they will flow: - -![Game States Visualized.png](../assets/part3/img/Game_States_Visualized.png) - -When one game state wants to go to another, it will need to change our previously declared 'wGameState' variable and then jump to the "NextGameState" label. There are some common things we want to accomplish when changing game states: - -(during a Vertical Blank) - -- Turn off the LCD -- Reset our Background & Window positions -- Clear the Background -- Disable Interrupts -- Clear All Sprites -- Initiate our NEXT game state -- Jump to our NEXT game state's (looping) update logic - -> It will be the responsibility of the "init" function for each game state to turn the LCD back on. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/GalacticArmada.asm:next-game-state}} -{{#include ../../galactic-armada/src/main/GalacticArmada.asm:next-game-state}} -``` - -The goal here is to ( as much as possible) give each new game state a _blank slate_ to start with. - -That's it for the GalacticArmada.asm file. diff --git a/src/part3/collision.md b/src/part3/collision.md deleted file mode 100644 index 0c351f83..00000000 --- a/src/part3/collision.md +++ /dev/null @@ -1,32 +0,0 @@ -# Collision Detection - -Collision Detection is cruical to games. It can be a very complicated topic. In Galactic Armada, things will be kept super simple. We're going to perform a basic implementation of "Axis-Aligned Bounding Box Collision Detection": - -> One of the simpler forms of collision detection is between two rectangles that are axis aligned — meaning no rotation. The algorithm works by ensuring there is no gap between any of the 4 sides of the rectangles. Any gap means a collision does not exist.[^mdn_source] - -The easiest way to check for overlap, is to check the difference bewteen their centers. If the absolute value of their x & y differences (I'll refer to as "the absolute difference") are BOTH smaller than the sum of their half widths, we have a collision. This collision detection is run for bullets against enemies, and enemies against the player. Here's a visualization with bullets and enemies. - -![CollisionDetectionVisualized.png](../assets/part3/img/CollisionDetectionVisualized.png) - -For this, we've created a basic function called "CheckObjectPositionDifference". This function will help us check for overlap on the x or y axis. When the (absolute) difference between the first two values passed is greater than the third value passed, it jump's to the label passed in the fourth parameter. - -Here's an example of how to call this function: - -> We have the player's x & y position in registers d & e respectively. We have the enemy's x & y position in registers b & c respectively. If there is no overlap on the x or y axis, the program jumps to the "NoCollisionWithPlayer" label. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/main.asm:player-collision-label}} -{{#include ../../galactic-armada/main.asm:player-collision-label}} -``` - -When checking for collision, we'll use that function twice. Once for the x-axis, and again for the y-axis. - -> NOTE: We don't need to test the y-axis if the x-axis fails. - -The source code for that function looks like this: - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/utils/collision-utils.asm:collision-utils}} -{{#include ../../galactic-armada/src/main/utils/collision-utils.asm:collision-utils}} -``` - -[^mdn_source]: -From [mdn web docs - 2D collision detection](https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection) \ No newline at end of file diff --git a/src/part3/conclusion.md b/src/part3/conclusion.md deleted file mode 100644 index dc0b2272..00000000 --- a/src/part3/conclusion.md +++ /dev/null @@ -1,11 +0,0 @@ -# Conclusion - -If you liked this tutorial, and you want to take things to the next level, here are some ideas: - -- Add an options menu (for typewriter speed, difficulty, disable audio) -- Add Ship Select and different player ships -- Add the ability to upgrade your bullet type -- Add dialogue and "waves" of enemies -- Add different types of enemies -- Add a boss -- Add a level select \ No newline at end of file diff --git a/src/part3/enemies.md b/src/part3/enemies.md deleted file mode 100644 index b62285c8..00000000 --- a/src/part3/enemies.md +++ /dev/null @@ -1,107 +0,0 @@ -# Enemies - -Enemies in SHMUPS often come in a variety of types, and travel also in a variety of patterns. To keep things simple for this tutorial, we'll have one enemy that flys straight downward. Because of this decision, the logic for enemies is going to be similar to bullets in a way. They both travel vertically and disappear when off screeen. Some differences to point out are: - -- Enemies are not spawned by the player, so we need logic that spawns them at random times and locations. -- Enemies must check for collision against the player -- We'll check for collision against bullets in the enemy update function. - -Here are the RAM variables we'll use for our enemies: - -- wCurrentEnemyX & wCurrentEnemyY - When we check for collisions, we'll save the current enemy's position in these two variables. -- wNextEnemyXPosition - When this variable has a non-zero value, we'll spawn a new enemy at that position -- wSpawnCounter - We'll decrease this, when it reaches zero we'll spawn a new enemy (by setting 'wNextEnemyXPosition' to a non-zero value). -- wActiveEnemyCounter - This tracks how many enemies we have on screen -- wUpdateEnemiesCounter - This is used when updating enemies so we know how many we have updated. -- wUpdateEnemiesCurrentEnemyAddress - When we check for enemy v. bullet collision, we'll save the address of our current enemy here. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-start}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-start}} -``` - -Just like with bullets, we'll setup ROM data for our enemies tile data and metasprites. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-tile-metasprite}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-tile-metasprite}} -``` - -## Initializing Enemies - -When initializing the enemies (at the start of gameplay), we'll copy the enemy tile data into VRAM. Also, like with bullets, we'll loop through and make sure each enemy is set to inactive. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-initialize}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-initialize}} -``` - -## Updating Enemies - -When "UpdateEnemies" is called from gameplay, the first thing we try to do is spawn new enemies. After that, if we have no active enemies (and are not trying to spawn a new enemy), we stop the "UpdateEnemies" function. From here, like with bullets, we'll save the address of our first enemy in hl and start looping through. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-update-start}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-update-start}} -``` - -When we are looping through our enemy object pool, let's check if the current enemy is active. If it's active, we'll update it like normal. If it isn't active, the game checks if we want to spawn a new enemy. We specify we want to spawn a new enemy by setting 'wNextEnemyXPosition' to a non-zero value. If we don't want to spawn a new enemy, we'll move on to the next enemy. - -If we want to spawn a new enemy, we'll set the current inactive enemy to active. Afterwards, we'll set it's y position to zero, and it's x position to whatever was in the 'wNextEnemyXPosition' variable. After that, we'll increase our active enemy counter, and go on to update the enemy like normal. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-update-per-enemy}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-update-per-enemy}} -``` - -When We are done updating a single enemy, we'll jump to the "UpdateEnemies_Loop" label. Here we'll increase how many enemies we've updated, and end if we've done them all. If we still have more enemies left, we'll increase the address stored in hl by 6 and update the next enemy. - -> The "hl" registers should always point to the current enemies first byte when this label is reached. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-update-loop}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-update-loop}} -``` - -For updating enemies, we'll first get the enemies speed. Afterwards we'll increase the enemies 16-bit y position. Once we've done that, we'll descale the y position so we can check for collisions and draw the ennemy. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-update-per-enemy2}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-update-per-enemy2}} -``` - -## Player & Bullet Collision - -One of the differences between enemies and bullets is that enemies must check for collision against the player and also against bullets. For both of these cases, we'll use a simple Axis-Aligned Bounding Box test. We'll cover the specific logic in a later section. - -If we have a collison against the player we need to damage the player, and redraw how many lives they have. In addition, it's optional, but we'll deactivate the enemy too when they collide with the player. - -> Our "hl" registers should point to the active byte of the current enemy. We push and pop our "hl" registers to make sure we get back to that same address for later logic. - - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-update-check-collision}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-update-check-collision}} -``` - -If there is no collision with the player, we'll draw the enemies. This is done just as we did the player and bullets, with the "DrawMetasprites" function. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-update-nocollision}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-update-nocollision}} -``` - -## Deactivating Enemies - -Deactivating an enemy is just like with bullets. We'll set it's first byte to 0, and decrease our counter variable. - -> Here, we can just use the current address in HL. This is the second reason we wanted to keep the address of our first byte on the stack. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-update-deactivate}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-update-deactivate}} -``` - -## Spawning Enemies - -Randomly, we want to spawn enemies. We'll increase a counter called "wEnemyCounter". When it reaches a preset maximum value, we'll **maybe** try to spawn a new enemy. - -Firstly, We need to make sure we aren't at maximum enemy capacity, if so, we will not spawn enemy more enemies. If we are not at maximum capacity, we'll try to get a x position to spawn the enemy at. If our x position is below 24 or above 150, we'll also NOT spawn a new enemy. - -> All enemies are spawned with y position of 0, so we only need to get the x position. - -If we have a valid x position, we'll reset our spawn counter, and save that x position in the "wNextEnemyXPosition" variable. With this variable set, We'll later activate and update a enemy that we find in the inactive state. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-spawn}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-spawn}} -``` \ No newline at end of file diff --git a/src/part3/enemy-bullet-collision.md b/src/part3/enemy-bullet-collision.md deleted file mode 100644 index 87e5693c..00000000 --- a/src/part3/enemy-bullet-collision.md +++ /dev/null @@ -1,45 +0,0 @@ -# Enemy-Bullet Collision - -When we are udating enemies, we'll call a function called "CheckCurrentEnemyAgainstBullets". This will check the current enemy against all active bullets. - -This fuction needs to loop through the bullet object pool, and check if our current enemy overlaps any bullet on both the x and y axis. If so, we'll deactivate the enemy and bullet. - -Our "CheckCurrentEnemyAgainstBullets" function starts off in a manner similar to how we updated enemies & bullets. - -> This function expects "hl" points to the curent enemy. We'll save that in a variable for later usage. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm:enemy-bullet-collision-start}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm:enemy-bullet-collision-start}} -``` - -As we loop through the bullets, we need to make sure we only check active bullets. Inactive bullets will be skipped. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm:enemy-bullet-collision-per-bullet-start}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm:enemy-bullet-collision-per-bullet-start}} -``` -First, we need to check if the current enemy and current bullet are overlapping on the x axis. We'll get the enemy's x position in e, and the bullet's x position in b. From there, we'll again call our "CheckObjectPositionDifference" function. If it returns a failure (wResult=0), we'll start with the next bullet. - -> We add an offset to the x coordinates so they measure from their centers. That offset is half it's respective object's width. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm:enemy-bullet-collision-per-bullet-x-overlap}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm:enemy-bullet-collision-per-bullet-x-overlap}} -``` - -Next we restore our hl variable so we can get the y position of our current bullet. Once we have that y position, we'll get the current enemy's y position and check for an overlap on the y axis. If no overlap is found, we'll loop to the next bullet. Otherwise, we have a collision. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm:enemy-bullet-collision-per-bullet-y-overlap}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm:enemy-bullet-collision-per-bullet-y-overlap}} -``` - -If a collision was detected (overlap on x and y axis), we'll set the current active byte for that bullet to 0. Also , we'll set the active byte for the current enemy to zero. Before we end the function, we'll increase and redraw the score, and decrease how many bullets & enemies we have by one. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm:enemy-bullet-collision-per-bullet-collision}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm:enemy-bullet-collision-per-bullet-collision}} -``` - -If no collision happened, we'll continue our loop through the enemy bullets. When we've checked all the bullets, we'll end the function. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm:enemy-bullet-collision-loop}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-bullet-collision.asm:enemy-bullet-collision-loop}} -``` - diff --git a/src/part3/enemy-player-collision.md b/src/part3/enemy-player-collision.md deleted file mode 100644 index 3ffcd013..00000000 --- a/src/part3/enemy-player-collision.md +++ /dev/null @@ -1,35 +0,0 @@ -# Enemy-Player Collision - -Our enemy versus player collision detection starts with us getting our player's unscaled x position. We'll store that value in d. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-player-collision.asm:get-player-x}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-player-collision.asm:get-player-x}} -``` - -With our player's x position in d, we'll compare it against a previously saved enemy x position variable. If they are more than 16 pixels apart, we'll jump to the "NoCollisionWithPlayer" label. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-player-collision.asm:check-x-overlap}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-player-collision.asm:check-x-overlap}} -``` - -After checking the x axis, if the code gets this far there was an overlap. We'll do the same for the y axis next. - -We'll get the player's unscaled y position. We'll store that value in d for consistency. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-player-collision.asm:get-y}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-player-collision.asm:get-y}} -``` - -Just like before, we'll compare our player's unscaled y position (stored in d) against a previously saved enemy y position variable. If they are more than 16 pixels apart, we'll jump to the "NoCollisionWithPlayer" label. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-player-collision.asm:check-y-overlap}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-player-collision.asm:check-y-overlap}} -``` - -The "NoCollisionWithPlayer", just set's the "wResult" to 0 for failure. If overlap occurs on both axis, we'll isntead set 1 for success. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-player-collision.asm:result}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/collision/enemy-player-collision.asm:result}} -``` - -That's the enemy-player collision logic. Callers of the function can simply check the "wResult" variable to determine if there was collision. \ No newline at end of file diff --git a/src/part3/entry-point.md b/src/part3/entry-point.md deleted file mode 100644 index cc7fbd0e..00000000 --- a/src/part3/entry-point.md +++ /dev/null @@ -1,53 +0,0 @@ -## Entry Point - -We'll start this tutorial out like the previous, with our "header" section (at address: $100). We're also going to declare some global variables that will be used throughout the game. - -- `wLastKeys` and `wCurKeys` are used for joypad input -- `wGameState` will keep track what our current game state is - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/GalacticArmada.asm:entry-point}} -{{#include ../../galactic-armada/src/main/GalacticArmada.asm:entry-point}} -``` - -after our `EntryPoint` label, well do the following: - -- set our default game state -- initiate [gb-sprobj-lib](https://github.com/eievui5/gb-sprobj-lib), the sprite library we're going to use -- setup our display registers -- load tile data for our font into VRAM. - -The tile data we are going to load is used by all game states, which is why we'll do it here & now, for them all to use. - - - -This character-set is called “Area51”. It, and more 8x8 pixel fonts can ne found here: [https://damieng.com/typography/zx-origins/](https://damieng.com/typography/zx-origins/) . These 52 tiles will be placed at the beginning of our background/window VRAM region. - -![TextFontDiagram.png](../assets/part3/img/TextFontDiagram.png) - -One important thing to note. Character maps for each letter must be defined. This let’s RGBDS know what byte value to give a specific letter. - -For the Galactic Armada space mapping, we’re going off the “text-font.png” image. Our space character is the first character in VRAM. Our alphabet starts at 26. Special additions could be added if desired. For now, this is all that we’ll need. We'll define that map in "src/main/utils/macros/text-macros.inc". - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/utils/macros/text-macros.inc:charmap}} -{{#include ../../galactic-armada/src/main/utils/macros/text-macros.inc:charmap}} -``` - -Getting back to our entry point. Were going to wait until a vertical blank begins to do all of this. We'll also turn the LCD off before loading our tile data into VRAM.. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/GalacticArmada.asm:entry-point-end}} -{{#include ../../galactic-armada/src/main/GalacticArmada.asm:entry-point-end}} -``` - -:::tip - -Even though we haven't specifically defined a color palette. The [emulicious](https://emulicious.net/) emulator may automatically apply a default color palette if in "Automatic" or "Gameboy Color" Mode - -::: - -In the above snippet you saw use of a function called `WaitFOrOneVBLank`. We've setup some vblank utility functions in the "src/main/utils/vblank-utils.asm" file: - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/utils/vblank-utils.asm:vblank-utils}} -{{#include ../../galactic-armada/src/main/utils/vblank-utils.asm:vblank-utils}} -``` - -In the next section, we'll go on next to setup our `NextGameState` label. Which is used for changing game states. diff --git a/src/part3/game-states.md b/src/part3/game-states.md deleted file mode 100644 index 7f5d04e9..00000000 --- a/src/part3/game-states.md +++ /dev/null @@ -1,35 +0,0 @@ -# Game States - -Galactic armada comes with 3 basic game states. A title screen, a story screen, and gameplay. Each game state has different logic and are separated into their own folders. Each state has the responsibility to - -- Initiate itself -- Turn the LCD screen back on after initiating (turned off before initiating each game state) -- Poll for input -- Wait or VBlank phases -- Provide most of it’s own logic. - -The default game state is the title screen. - -![Game States Visualized.png](../assets/part3/img/Game_States_Visualized.png) - -## Common Tile Data - -All the game states utilize the tiles from the “text-font.png” image. This is a basic alphanumeric set of characters. - -![Untitled](../assets/part3/img/text-font-large.png) - - This character-set is called “Area51”. It, and more 8x8 pixel fonts can ne found here: [https://damieng.com/typography/zx-origins/](https://damieng.com/typography/zx-origins/) . These 52 tiles will be placed at the beginning of our background/window VRAM region. - -![TextFontDiagram.png](../assets/part3/img/TextFontDiagram.png) - -Because they are shared, we’ll put them in VRAM at the start and not touch them. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/main.asm:load-text-font}} -{{#include ../../galactic-armada/main.asm:load-text-font}} -``` - -Because of this, our background tilemaps will be need to use a offset of 52 tiles. Each tile is 16 bytes, so tile data also needs to start at $9440. Here’s an example for the title screen. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/main.asm:draw-title-screen}} -{{#include ../../galactic-armada/main.asm:draw-title-screen}} -``` diff --git a/src/part3/gamelay.md b/src/part3/gamelay.md deleted file mode 100644 index b287cc46..00000000 --- a/src/part3/gamelay.md +++ /dev/null @@ -1 +0,0 @@ -# Gameplay diff --git a/src/part3/gameplay.md b/src/part3/gameplay.md deleted file mode 100644 index c7f29209..00000000 --- a/src/part3/gameplay.md +++ /dev/null @@ -1,94 +0,0 @@ -# Gameplay State - -In this game state, the player will control a spaceship. Flying over a vertically scrolling space background. They’ll be able to freely move in 4 directions , and shoot oncoming alien ships. As alien ships are destroyed by bullets, the player’s score will increase. - -![rgbds-shmup-gameplay.gif](../assets/part3/img/rgbds-shmup-gameplay.gif) - -Gameplay is the core chunk of the source code. It also took the most time to create. Because of such, this game state has to be split into multiple sub-pages. Each page will explain a different gameplay concept. - -Our gameplay state defines the following data and variables: - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/gameplay-state.asm:gameplay-data-variables}} -{{#include ../../galactic-armada/src/main/states/gameplay/gameplay-state.asm:gameplay-data-variables}} -``` - -For simplicity reasons, our score uses 6 bytes. Each byte repesents one digit in the score. - -## Initiating the Gameplay Game State: - -When gameplay starts we want to do all of the following: -- reset the player's score to 0 -- reset the player's lives to 3. -- Initialize all of our gameplay elements ( background, player, bullets, and enemies) -- Enable STAT interrupts for the HUD -- Draw our "score" & "lives" on the HUD. -- Reset the window's position back to 7,0 -- Turn the LCD on with the window enabled at $9C00 - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/gameplay-state.asm:init-gameplay-state}} -{{#include ../../galactic-armada/src/main/states/gameplay/gameplay-state.asm:init-gameplay-state}} -``` - -The initialization logic for our the background, the player, the enemies, the bullets will be explained in later pages. Every game state is responsible for turning the LCD back on. The gameplay game state needs to use the window layer, so we'll make sure that's enabled before we return. - -## Updating the Gameplay Game State - -Our "UpdateGameplayState" function doesn't have very complicated logic. Most of the logic has been split into separate files for the background, player, enemies, and bullets. - -During gameplay, we do all of the following: -* Poll for input -* Reset our Shadow OAM -* Reset our current shadow OAM sprite -* Update our gameplay elements (player, background, enemies, bullets, background) -* Remove any unused sprites from the screen -* End gameplay if we've lost all of our lives -* inside of the vertical blank phase - * Apply shadow OAM sprites - * Update our background tilemap's position - -We'll poll for input like in the previous tutorial. We'll always save the previous state of the gameboy's buttons in the "wLastKeys" variable. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/gameplay-state.asm:update-gameplay-state-start}} -{{#include ../../galactic-armada/src/main/states/gameplay/gameplay-state.asm:update-gameplay-state-start}} -``` - -Next, we'll reset our Shadow OAM and reset current Shadow OAM sprite address. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/gameplay-state.asm:update-gameplay-oam}} -{{#include ../../galactic-armada/src/main/states/gameplay/gameplay-state.asm:update-gameplay-oam}} -``` - -Because we are going to be dealing with a lot of sprites on the screen, we will not be directly manipulating the gameboy's OAM sprites. We'll define a set of "shadow" (copy") OAM sprites, that all objects will use instaed. At the end of the gameplay looop, we'll copy the shadow OAM sprite objects into the hardware. - -Each object will use a random shadow OAM sprite. We need a way to keep track of what shadow OAM sprite is being used currently. For this, we've created a 16-bit pointer called "wLastOAMAddress". Defined in "src/main/utils/sprites.asm", this points to the data for the next inactive shadow OAM sprite. - -When we reset our current Shadow OAM sprite address, we just set the "mLastOAMAddress" RAM variable to point to the first shadow OAM sprite. - -> **NOTE:** We also keep a counter on how many shadow OAM sprites are used. In our "ResetOAMSpriteAddress" function, we'll reset that counter too. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/utils/sprites-utils.asm:reset-oam-sprite-address}} -{{#include ../../galactic-armada/src/main/utils/sprites-utils.asm:reset-oam-sprite-address}} -``` - -Next we'll update our gameplay elements: -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/gameplay-state.asm:update-gameplay-elements}} -{{#include ../../galactic-armada/src/main/states/gameplay/gameplay-state.asm:update-gameplay-elements}} -``` - -After all of that, at this point in time, the majority of gameplay is done for this iteration. We'll clear any remaining spirtes. This is very necessary becaus the number of active sprites changes from frame to frame. If there are any visible OAM sprites left onscreen, they will look weird and/or mislead the player. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/gameplay-state.asm:update-gameplay-clear-sprites}} -{{#include ../../galactic-armada/src/main/states/gameplay/gameplay-state.asm:update-gameplay-clear-sprites}} -``` - -The clear remaining sprites function, for all remaining shadow OAM sprites, moves the sprite offscreen so they are no longer visible. This function starts at wherever the "wLastOAMAddress" variable last left-off. - -#### End of The Gameplay loop - -At this point in time, we need to check if gameplay needs to continue. When the vertical blank phase starts, we check if the player has lost all of their lives. If so, we end gameplay. We end gameplay similar to how we started it, we'll update our 'wGameState' variable and jump to "NextGameState". - -If the player hasn't lost all of their lives, we'll copy our shadow OAM sprites over to the actual hardware OAM sprites and loop background. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/gameplay-state.asm:update-gameplay-end-update}} -{{#include ../../galactic-armada/src/main/states/gameplay/gameplay-state.asm:update-gameplay-end-update}} -``` \ No newline at end of file diff --git a/src/part3/getting-started.md b/src/part3/getting-started.md deleted file mode 100644 index e5c78ad1..00000000 --- a/src/part3/getting-started.md +++ /dev/null @@ -1,24 +0,0 @@ - - -# Introducing Galactic Armada - - - -This guide will help you create a classic shoot-em-up in RGBDS. This guide builds on knowledge from the previous tutorials, so some basic (or previously explained) concepts will not be explained. - -## Feature set - -Here's a list of features that will be included in the final product. - -- Vertical Scrolling Background -- Basic HUD (via Window) & Score -- 4-Directional Player Movement -- Enemies -- Bullets -- Enemy/Bullet Collision -- Enemy/Player Collision -- Smooth Movement via Scaled Integers - Instead of using counters, smoother motion can be achieved using 16-bit (scaled) integers. -- Multiple Game States: Title Screen, Gameplay, Story State -- STAT Interrupts - used to properly draw the HUD at the top of gameplay. -- RGBGFX & INCBIN -- Writing Text diff --git a/src/part3/heads-up-interface.md b/src/part3/heads-up-interface.md deleted file mode 100644 index ac55892a..00000000 --- a/src/part3/heads-up-interface.md +++ /dev/null @@ -1,70 +0,0 @@ -# Heads Up Interface - -The gameboy normally draws sprites over both the window and background, and the window over the background. In Galactic Armada, The background is vertically scrolling. This means the HUD (the score text and number) needs to be draw on the window, which is separate from the background. - -On our HUD, we'll draw both our score and our lives. We'll also use STAT interrupts to make sure nothing covers the HUD. - -## STAT Interrupts & the window - - -The window is not enabled by default. We can enable the window using the `LCDC` register. RGBDS comes with constants that will help us. - -> ⚠️ NOTE: The window can essentially be a copy of the background. The `LCDCF_WIN9C00|LCDCF_BG9800` portion makes the background and window use different tilemaps when drawn. -There’s only one problem. Since the window is drawn between sprites and the background. Without any extra effort, our scrolling background tilemap will be covered by our window. In addition, our sprites will be drawn over our hud. For this, we’ll need STAT interrupts. Fore more information on STAT interrupts, check out the pandocs: [https://gbdev.io/pandocs/Interrupt_Sources.html](https://gbdev.io/pandocs/Interrupt_Sources.html) - - -![InterruptsDiagram.png](../assets/part3/img/StatInterruptsVisualized.png) - -> ### **[Using the STAT interrupt](https://gbdev.io/pandocs/Interrupt_Sources.html#using-the-stat-interrupt)** -> -> One very popular use is to indicate to the user when the video hardware is about to redraw a given LCD line. This can be useful for dynamically controlling the SCX/SCY registers ($FF43/$FF42) to [perform special video effects](https://github.com/gb-archive/DeadCScroll). -> -> Example application: set LYC to WY, enable LY=LYC interrupt, and have the handler disable sprites. This can be used if you use the window for a text box (at the bottom of the screen), and you want sprites to be hidden by the text box. - - -With STAT interrupts, we can implement raster effects. in our case, we’ll enable the window and stop drawing sprites on the first 8 scanlines. Afterwards, we’ll show sprites and disable the window layer for the remaining scanlines. This makes sure nothing overlaps our HUD, and that our background is fully shown also. - -### Initiating & Disabling STAT interrupts - -In our gameplay game state, at different points in time, we initialized and disabled interrupts. Here's the logic for those functions in our "src/main/states/gameplay/hud.asm" file: - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/interrupts.asm:interrupts-start}} -{{#include ../../galactic-armada/src/main/states/gameplay/interrupts.asm:interrupts-start}} -``` - -### Defining STAT interrupts - -Our actual STAT interrupts must be located at $0048. We'll define different paths depending on what our LYC variable's value is when executed. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/interrupts.asm:interrupts-section}} -{{#include ../../galactic-armada/src/main/states/gameplay/interrupts.asm:interrupts-section}} -``` - -That should be all it takes to get a properly drawn HUD. For more details, check out the code in the repo or [ask questions](https://gbdev.io/gb-asm-tutorial/help-feedback.html) on the gbdev discord server. - -## Keeping Score and Drawing Score on the HUD - -To keep things simple, back in our gameplay game state, we used 6 different bytes to hold our score.Each byte will hold a value between 0 and 9, and represents a specific digit in the score. So it’s easy to loop through and edit the score number on the HUD: The First byte represents the left-most digit, and the last byte represents the right-most digit. - -![DrawingScoreVisualized.png](../assets/part3/img/DrawingScoreVisualized.png) - -When the score increases, we’ll increase digits on the right. As they go higher than 9, we’ll reset back to 0 and increase the previous byte . - - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/hud.asm:hud-increase-score}} -{{#include ../../galactic-armada/src/main/states/gameplay/hud.asm:hud-increase-score}} -``` - - -We can call that score whenever a bullet hits an enemy. This function however does not draw our score on the background. We do that the same way we drew text previously: - - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/hud.asm:hud-draw-score}} -{{#include ../../galactic-armada/src/main/states/gameplay/hud.asm:hud-draw-score}} -``` - -Because we'll only ever have 3 lives, drawing our lives is much easier. The numeric characters in our text font start at 10, so we just need to put on the window, our lives plus 10. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/hud.asm:hud-draw-lives}} -{{#include ../../galactic-armada/src/main/states/gameplay/hud.asm:hud-draw-lives}} -``` \ No newline at end of file diff --git a/src/part3/improving-the-game.md b/src/part3/improving-the-game.md deleted file mode 100644 index 447f1474..00000000 --- a/src/part3/improving-the-game.md +++ /dev/null @@ -1 +0,0 @@ -# Improving the Game diff --git a/src/part3/keeping-score.md b/src/part3/keeping-score.md deleted file mode 100644 index a2e52158..00000000 --- a/src/part3/keeping-score.md +++ /dev/null @@ -1 +0,0 @@ -# Keeping Score diff --git a/src/part3/object-pools.md b/src/part3/object-pools.md deleted file mode 100644 index 22fa867e..00000000 --- a/src/part3/object-pools.md +++ /dev/null @@ -1,51 +0,0 @@ -# Object Pools - -Galactic Armada will use "object pools" for bullets and enemies. A fixed amount of bytes representing a specific maximum amount of objects. Each pool is just a collection of bytes. The number of bytes per “pool” is the maximum number of objects in the pool, times the number of bytes needed for data for each object. - -Constants are also created for the size of each object, and what each byte is. These constants are in the “src/main/utils/constants.inc” file and utilize RGBDS offset constants (a really cool feature) - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/main.asm:bullet-offset-constants}} -{{#include ../../galactic-armada/main.asm:bullet-offset-constants}} -``` - -The two object types that we need to loop through are Enemies and Bullets. - -**Bytes for an Enemy:** - -1. Active - Are they active -2. X - Position: horizontal coordinate -3. Y (low) - The lower byte of their 16-bit (scaled) y position -4. Y (high) - The higher byte of their 16-bit (scaled) y position -5. Speed - How fast they move -6. Health - How many bullets they can take - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/main.asm:w-enemies}} -{{#include ../../galactic-armada/main.asm:w-enemies}} -``` - -![EnemyBytesVisualized.png](../assets/part3/img/EnemyBytesVisualized.png) - -**Bytes for a Bullet:** - -1. Active - Are they active -2. X - Position: horizontal coordinate -3. Y (low) - The lower byte of their 16-bit (scaled) y position -4. Y (high) - The higher byte of their 16-bit (scaled) y position - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/main.asm:w-bullets}} -{{#include ../../galactic-armada/main.asm:w-bullets}} -``` - -![BulletBytesVisualized.png](../assets/part3/img/BulletBytesVisualized.png) - -> ⚠️ **NOTE:** Scaled integers are used for only the y positions of bullets and enemies. Scaled Integers are a way to provide smooth “sub-pixel” movement. They only move vertically, so the x position can be 8-bit. - -When looping through an object pool, we’ll check if an object is active. If it’s active, we’ll run the logic for that object. Otherwise, we’ll skip to the start of the next object’s bytes. - -Both bullets and enemies do similar things. They move vertically until they are off the screen. In addition, enemies will check against bullets when updating. If they are found to be colliding, the bullet is destroyed and so is the enemy. - -# “Activating” a pooled object - -To Activate a pooled object, we simply loop through each object. If the first byte, which tells us if it’s active or not, is 0: then we’ll add the new item at that location and set that byte to be 1. If we loop through all possible objects and nothing is inactive, nothing happens. - -![Spawning Enemies.png](../assets/part3/img/Spawning_Enemies.png) diff --git a/src/part3/objects.md b/src/part3/objects.md deleted file mode 100644 index df394944..00000000 --- a/src/part3/objects.md +++ /dev/null @@ -1 +0,0 @@ -# Title Screen diff --git a/src/part3/project-structure.md b/src/part3/project-structure.md deleted file mode 100644 index 844991b6..00000000 --- a/src/part3/project-structure.md +++ /dev/null @@ -1,118 +0,0 @@ -# Project Structure - -This page is going to give you an idea of how the Galactic Armada project is structured. This includes the folders, resources, tools, entry point, and compilation process. - -The code can be found at https://github.com/gbdev/gb-asm-tutorial/tree/master/galactic-armada. - -## Folder Layout - -For organizational purposes, many parts of the logic are separated into reusable functions. This is to reduce duplicate code, and make logic more clear. - -Here’s a basic look at how the project is structured: - -:::tip - -Generated files should never be included in VCS repositories. It unneccessarily bloats the repo. The folders below marked with \* contains assets generated from running the Makefile and are not included in the repository. - -::: - -- `libs` - Two assembly files for input and sprites are located here. -- `src` - - `generated` - the results of RGBGFX are stored here. \* - - `resources` - Here exist some PNGs and Aseprite files for usage with RGBGFX - - `main` - All assembly files are located here, or in subfolders - - `states` - - `gameplay` - for gameplay related files - - `objects` - for gameplay objects like the player, bullets, and enemies - - collision - for collision among objects - - `story` - for our story state's related files - - `title-screen` - for our title screen's related files - - `utils` - Extra functions includes to assist with development - - `macros` -- `dist` - The final ROM file will be created here. \* -- `obj` - Intermediate files from the compile process. \* -- `Makefile` - used to create the final ROM file and intermediate files - -## Background & Sprite Resources - -The following backgrounds and sprites are used in Galactic Armada: - -- Backgrounds - - Star Field - - Title Screen - - Text Font (Tiles only) -- Sprites - - Enemy Ship - - Player Ship - - Bullet - - - - - -
- - - -
- - - - - - - - -These images were originally created in Aseprite. The original templates are also included in the repository. They were exported as a PNG **with a specific color palette**. Ater being exported as a PNG, when you run `make`, they are converted into `.2bpp` and `.tilemap` files via the RGBDS tool: RGBGFX. - -> The **`rgbgfx`** program converts PNG images into data suitable for display on the Game Boy and Game Boy Color, or vice-versa. -> -> The main function of **`rgbgfx`** is to divide the input PNG into 8×8 pixel *[squares](https://rgbds.gbdev.io/docs/v0.6.1/rgbgfx.1#squares)*, convert each of those squares into 1bpp or 2bpp tile data, and save all of the tile data in a file. It also has options to generate a tile map, attribute map, and/or palette set as well; more on that and how the conversion process can be tweaked below. - -RGBGFX can be found here: [https://rgbds.gbdev.io/docs/v0.6.1/rgbgfx.1](https://rgbds.gbdev.io/docs/v0.6.1/rgbgfx.1) - -We'll use it to convert all of our graphics to .2bpp, and .tilemap formats (binary files) - -```bash,linenos,start={{#line_no_of "" ../../galactic-armada/Makefile:generate-graphics}} -{{#include ../../galactic-armada/Makefile:generate-graphics}} -``` - -From there, INCBIN commands are used to store reference the binary tile data. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/main.asm:sprite-tile-data}} -{{#include ../../galactic-armada/main.asm:sprite-tile-data}} -``` - -:::tip Including binary files - -You probably have some graphics, level data, etc. you'd like to include. Use **`INCBIN`** to include a raw binary file as it is. If the file isn't found in the current directory, the include-path list passed to [rgbasm(1)](https://rgbds.gbdev.io/docs/v0.6.1/rgbasm.1) (see the **`-i`** option) on the command line will be searched. - -``` -INCBIN "titlepic.bin" -INCBIN "sprites/hero.bin" -``` - -You can also include only part of a file with **`INCBIN`**. The example below includes 256 bytes from data.bin, starting from byte 78. - -``` -INCBIN "data.bin",78,256 -``` - -The length argument is optional. If only the start position is specified, the bytes from the start position until the end of the file will be included. - -See also: [Including binary files - RGBASM documentation](https://rgbds.gbdev.io/docs/v0.6.1/rgbasm.5#Including_binary_files) - -::: - -## Compilation - -Compilation is done via a Makefile. This Makefile can be run using the `make` command. Make should be preinstalled on Linux and Mac systems. For Windows users, check out [cygwin](https://www.cygwin.com/). - -Without going over everything in detail, here’s what the Makefile does: - -- Clean generated folders -- Recreate generated folders -- Convert PNGs in src/resources to `.2bpp`, and `.tilemap` formats -- Convert `.asm` files to `.o` -- Use the `.o` files to build the ROM file -- Apply the RGBDS “fix” utility. diff --git a/src/part3/scrolling-background.md b/src/part3/scrolling-background.md deleted file mode 100644 index 9d19a57c..00000000 --- a/src/part3/scrolling-background.md +++ /dev/null @@ -1,30 +0,0 @@ - -# Scrolling Background - -Scrolling the background is an easy task. However, for a SMOOTH slow scrolling background: scaled integers[^1] will be used. - ->⚠️ Scaled Integers[^1] are a way to provide smooth “sub-pixel” movement. They are slightly more difficult to understand & implement than implementing a counter, but they provide smoother motion. - -## Initializing the Background - -At the start of the gameplay game state we called the initialize background function. This function shows the star field background, and resets our background scroll variables: - -> Just like with our title screen graphic, because our text font tiles are at the beginning of VRAM: we offset the tilemap values by 52 - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/gameplay-background.asm:gameplay-background-initialize}} -{{#include ../../galactic-armada/src/main/states/gameplay/gameplay-background.asm:gameplay-background-initialize}} -``` - -To scroll the background in a gameboy game, we simply need to gradually change the `SCX` or `SCX` registers. Our code is a tiny bit more complicated because of scaled integer usage. Our background's scroll position is stored in a 16-bit integer called `mBackgroundScroll`. We'l increase that 16-bit integer by a set amount. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/gameplay-background.asm:gameplay-background-update-start}} -{{#include ../../galactic-armada/src/main/states/gameplay/gameplay-background.asm:gameplay-background-update-start}} -``` - -We won't directly draw the background using this value. De-scaling a scaled integer simulates having a (more precise and useful for smooth movement) floating-point number. The value we draw our background at will be the de-scaled version of that 16-bit integer. To get that non-scaled version, we'll simply shift all of it's bit rightward 4 places. The final result will saved for when we update our background's y position. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/gameplay-background.asm:gameplay-background-update-end}} -{{#include ../../galactic-armada/src/main/states/gameplay/gameplay-background.asm:gameplay-background-update-end}} -``` - -[^1]: [Scaled Factor on Wikipedia](https://en.wikipedia.org/wiki/Scale_factor_(computer_science)) \ No newline at end of file diff --git a/src/part3/sprites-metasprites.md b/src/part3/sprites-metasprites.md deleted file mode 100644 index 8f1445f9..00000000 --- a/src/part3/sprites-metasprites.md +++ /dev/null @@ -1,47 +0,0 @@ -# Sprites & Metasprites - -Before we dive into the player, bullets, and enemies; how they are drawn using metasprites should be explained. - -For sprites, the following library is used: https://github.com/eievui5/gb-sprobj-lib - -> This is a small, lightweight library meant to facilitate the rendering of sprite objects, including Shadow OAM and OAM DMA, single-entry "simple" sprite objects, and Q12.4 fixed-point position metasprite rendering. - -All objects are drawn using "metasprites", or groups of sprites that define one single object. A custom “metasprite” implementation is used in addition. Metasprite definitions should a multiple of 4 plus one additional byte for the end. - -- Relative Y offset ( relative to the previous sprite, or the actual metasprite’s draw position) -- Relative X offset ( relative to the previous sprite, or the actual metasprite’s draw position) -- Tile to draw -- Tile Props (not used in this project) - -The logic stops drawing when it reads 128. - -An example of metasprite is the enemy ship: - - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/main.asm:enemy-metasprites}} -{{#include ../../galactic-armada/main.asm:enemy-metasprites}} -``` - -![MetaspriteDIagram.png](../assets/part3/img/MetaspriteDIagram.png) - -The Previous snippet draws two sprites. One that the object’s actual position, which uses tile 4 and 5. The second sprite is 8 pixels to the right, and uses tile 6 and 7 - ->⚠️ **NOTE**: Sprites are in 8x16 mode for this project. - -I can later draw such metasprite by calling the "DrawMetasprite" function that - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/main.asm:draw-enemy-metasprites}} -{{#include ../../galactic-armada/main.asm:draw-enemy-metasprites}} -``` - -We previously mentioned a variable called "wLastOAMAddress". The "DrawMetasprites" function can be found in the "src/main/utils/metasprites.asm" file: - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/utils/metasprites.asm}} -{{#include ../../galactic-armada/src/main/utils/metasprites.asm}} -``` - -When we call the "DrawMetasprites" function, the "wLastOAMAddress" variable will be advanced to point at the next available shadow OAM sprite. This is done using the "NextOAMSprite" function in "src/main/utils/sprites-utils.asm" - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/utils/sprites-utils.asm:next-oam-sprite}} -{{#include ../../galactic-armada/src/main/utils/sprites-utils.asm:next-oam-sprite}} -``` diff --git a/src/part3/story-screen.md b/src/part3/story-screen.md deleted file mode 100644 index ac1874ba..00000000 --- a/src/part3/story-screen.md +++ /dev/null @@ -1,65 +0,0 @@ -# Story Screen - -The story screen shows a basic story on 2 pages. Afterwards, it sends the player to the gameplay game state. - - - - - -## Initiating up the Story Screen - -In the `InitStoryState` we'll just going to turn on the LCD. Most of the game state's logic will occur in its update function. - -:::tip - -The text macros file is included so our story text has the proper character maps. - -::: - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/story/story-state.asm:init-story-state}} -{{#include ../../galactic-armada/src/main/states/story/story-state.asm:init-story-state}} -``` - -## Updating the Story Screen - -Here's the data for our story screen. We have this defined just above our `UpdateStoryState` function: - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/story/story-state.asm:story-screen-data}} -{{#include ../../galactic-armada/src/main/states/story/story-state.asm:story-screen-data}} -``` - -The story text is shown using a typewriter effect. This effect is done similarly to the “press a to play” text that was done before, but here we wait for 3 vertical blank phases between writing each letter, giving some additional delay. - -> You could bind this to a variable and make it configurable via an options screen too! - -For this effect, we've defined a function in our "src/main/utils/text-utils.asm" file: - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/utils/text-utils.asm:typewriter-effect}} -{{#include ../../galactic-armada/src/main/utils/text-utils.asm:typewriter-effect}} -``` - -We'll call the `DrawText_WithTypewriterEffect` function exactly how we called the `DrawTextTilesLoop` function. We'll pass this function which tile to start on in de, and the address of our text in hl. - -We'll do that four times for the first page, and then wait for the A button to be pressed: - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/story/story-state.asm:story-screen-page1}} -{{#include ../../galactic-armada/src/main/states/story/story-state.asm:story-screen-page1}} -``` - -Once the user presses the A button, we want to show the second page. To avoid any lingering "leftover" letters, we'll clear the background. All this function does is turn off the LCD, fill our background tilemap with the first tile, then turn back on the lcd. We've defined this function in the "src/main/utils/background.utils.asm" file: - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/utils/background-utils.asm:background-utils}} -{{#include ../../galactic-armada/src/main/utils/background-utils.asm:background-utils}} -``` - -Getting back to our Story Screen: After we've shown the first page and cleared the background, we'll do the same thing for page 2: - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/story/story-state.asm:story-screen-page2}} -{{#include ../../galactic-armada/src/main/states/story/story-state.asm:story-screen-page2}} -``` - -With our story full shown, we're ready to move onto the next game state: Gameplay. We'll end our `UpdateStoryState` function by updating our game state variable and jump back to the `NextGameState` label like previously discussed. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/story/story-state.asm:story-screen-end}} -{{#include ../../galactic-armada/src/main/states/story/story-state.asm:story-screen-end}} -``` diff --git a/src/part3/the-player.md b/src/part3/the-player.md deleted file mode 100644 index acc58fc6..00000000 --- a/src/part3/the-player.md +++ /dev/null @@ -1,93 +0,0 @@ -# The Player - -The player’s logic is pretty simple. The player can move in 4 directions and fire bullets. We update the player by checking our input directions and the A button. We’ll move in the proper direction if its associated d-pad button is pressed. If the A button is pressed, we’ll spawn a new bullet at the player’s position. - -Our player will have 3 variables: -- wePlayerPositionX - a 16-bit scaled integer -- wePlayerPositionY - a 16-bit scaled integer -- wPlayerFlash - a 16-bit integer used when the player gets damaged - -> ⚠️ **NOTE**: The player can move vertically AND horizontally. So, unlike bullets and enemies, it’s x position is a 16-bit scaled integer. - -These are declared at the top of the "src/main/states/gameplay/objects/player.asm" file - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-start}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-start}} -``` - -Well draw our player, a simple ship, using the previously discussed metasprites implementation. Here is what we have for the players metasprites and tile data: -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-data}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-data}} -``` - -## Initializing the Player - -Initializing the player is pretty simple. Here's a list of things we need to do: -* Reset oir wPlayerFlash variable -* Reset our wPlayerPositionX variable -* Reset our wPlayerPositionU variable -* Copy the player's ship into VRAM - -We'll use a constant we declared in "src/main/utils/constants.inc" to copy the player ship's tile data into VRAM. Our enemy ship and player ship both have 4 tiles (16 bytes for each tile). In the snippet below, we can define where we'll place the tile data in VRAM relative to the _VRAM constant: - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/utils/constants.inc:sprite-vram-constants}} -{{#include ../../galactic-armada/src/main/utils/constants.inc:sprite-vram-constants}} -``` - -Here's what our "InitializePlayer" function looks like. Recall, this was called when initiating the gameplay game state: - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-initialize}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-initialize}} -``` - -## Updating the Player - -We can break our player's update logic into 2 parts: -* Check for joypad input, move with the d-pad, shoot with A -* Depending on our "wPlayerFlash" variable: Draw our metasprites at our location - -Checking the joypad is done like the previous tutorials, we'll perform bitwise "and" operations with constants for each d-pad direction. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-update-start}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-update-start}} -``` - -For player movement, our X & Y are 16-bit integers. These both require two bytes. There is a little endian ordering, the first byte will be the low byte. The second byte will be the high byte. To increase/decrease these values, we add/subtract our change amount to/from the low byte. Then afterwards, we add/subtract the remainder of that operation to/from the high byte. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-movement}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-movement}} -``` - -When the player wants to shoot, we first check if the A button previously was down. If it was, we won't shoot a new bullet. This avoids bullet spamming a little. For spawning bullets, we have a function called "FireNextBullet". This function will need the new bullet's 8-bit X coordinate and 16-bit Y coordinate, both set in a variable it uses called "wNextBullet" - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-shoot}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-shoot}} -``` - -After we've potentially moved the player and/or shot a new bullet. We need to draw our player. However, to create the "flashing" effect when damaged, we'll conditionally NOT draw our player sprite. We do this based on the "wPlayerFlash" variable. - -- If the "wPlayerFlash" variable is 0, the player is not damaged, we'll skip to drawing our player sprite. -- Otherwise, decrease the "wPlayerFlash" variable by 5. - - We'll shift all the bits of the "wPlayerFlash" variable to the right 4 times - - If the result is less than 5, we'll stop flashing and draw our player metasprite. - - Otherwise, if the first bit of the decscaled "wPlayerFLash" variable is 1, we'll skip drawing the player. - -> ***NOTE:** The following resumes from where the "UpdatePlayer_HandleInput" label ended above. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-update-flashing}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-update-flashing}} -``` - -If we get past all of the "wPlayerFlash" logic, we'll draw our player using the "DrawMetasprite" function we previously discussed. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-update-sprite}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-update-sprite}} -``` - -That's the end our our "UpdatePlayer" function. The final bit of code for our player handles when they are damaged. When an enemy damages the player, we want to decrease our lives by one. We'll also start flashing by giving our 'mPlayerFlash' variable a non-zero value. In the gameplay game state, if we've lost all lives, gameplay will end. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-damage}} -{{#include ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-damage}} -``` - -That's everything for our player. Next, we'll go over bullets and then onto the enemies. \ No newline at end of file diff --git a/src/part3/title-screen.md b/src/part3/title-screen.md deleted file mode 100644 index 0b9d0a41..00000000 --- a/src/part3/title-screen.md +++ /dev/null @@ -1,65 +0,0 @@ -# Title Screen - -The title screen shows a basic title image using the background and draws text asking the player to press A. Once the user presses A, it will go to the story screen. - - - -Our title screen has 3 pieces of data: - -* The "Press A to play" text -* The title screen tile data -* The title screen tilemap - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/title-screen/title-screen-state.asm:title-screen-start}} -{{#include ../../galactic-armada/src/main/states/title-screen/title-screen-state.asm:title-screen-start}} -``` - -## Initiating the Title Screen - -In our title screen's "InitTitleScreen" function, we'll do the following: -* draw the title screen graphic -* draw our "Press A to play" -* turn on the LCD. - - -Here is what our "InitTitleScreenState" function looks like - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/title-screen/title-screen-state.asm:title-screen-init}} -{{#include ../../galactic-armada/src/main/states/title-screen/title-screen-state.asm:title-screen-init}} -``` - -In order to draw text in our game, we've created a function called "DrawTextTilesLoop". We'll pass this function which tile to start on in `de`, and the address of our text in `hl`. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/utils/text-utils.asm:draw-text-tiles}} -{{#include ../../galactic-armada/src/main/utils/text-utils.asm:draw-text-tiles}} -``` - -The "DrawTitleScreen" function puts the tiles for our title screen graphic in VRAM, and draws its tilemap to the background: - -> **NOTE:** Because of the text font, we'll add an offset of 52 to our tilemap tiles. We've created a function that adds the 52 offset, since we'll need to do so more than once. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/title-screen/title-screen-state.asm:draw-title-screen}} -{{#include ../../galactic-armada/src/main/states/title-screen/title-screen-state.asm:draw-title-screen}} -``` - -The "CopyDEintoMemoryAtHL" and "CopyDEintoMemoryAtHL_With52Offset" functions are defined in "src/main/utils/memory-utils.asm": - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/utils/memory-utils.asm:memory-utils}} -{{#include ../../galactic-armada/src/main/utils/memory-utils.asm:memory-utils}} -``` - -## Updating the Title Screen - -The title screen's update logic is the simplest of the 3. All we are going to do is wait until the A button is pressed. Afterwards, we'll go to the story screen game state. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/title-screen/title-screen-state.asm:update-title-screen}} -{{#include ../../galactic-armada/src/main/states/title-screen/title-screen-state.asm:update-title-screen}} -``` - -Our "WaitForKeyFunction" is defined in "src/main/utils/input-utils.asm". We'll poll for input and infinitely loop until the specified button is pressed down. - -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/utils/input-utils.asm:input-utils}} -{{#include ../../galactic-armada/src/main/utils/input-utils.asm:input-utils}} -``` - -That's it for our title screen. Next up is our story screen.