From 1a8511f024789e2c90cd8529f1821bdf68334d72 Mon Sep 17 00:00:00 2001 From: Larold Date: Tue, 7 May 2024 11:50:02 -0400 Subject: [PATCH] Removing 'main.asm' file, and fixing 'xor' compilation errors for #90 (#91) * initial commit for #90 * removing main.asm fixing copy/paste typo committed adding spaces for some code snippets removing unused game-states.md file adding anchor to enemies section header * fixed naked xor for #90 --- galactic-armada/main.asm | 788 ------------------ .../main/states/gameplay/objects/bullets.asm | 6 + .../main/states/gameplay/objects/enemies.asm | 18 +- .../main/states/gameplay/objects/player.asm | 2 + galactic-armada/src/main/utils/constants.inc | 2 + galactic-armada/src/main/utils/text-utils.asm | 4 + src/part3/collision.md | 6 +- src/part3/enemies.md | 8 +- src/part3/game-states.md | 35 - src/part3/object-pools.md | 12 +- src/part3/project-structure.md | 11 +- src/part3/sprites-metasprites.md | 8 +- 12 files changed, 57 insertions(+), 843 deletions(-) delete mode 100644 galactic-armada/main.asm delete mode 100644 src/part3/game-states.md 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/states/gameplay/objects/bullets.asm b/galactic-armada/src/main/states/gameplay/objects/bullets.asm index 688df09d..301c32e4 100644 --- a/galactic-armada/src/main/states/gameplay/objects/bullets.asm +++ b/galactic-armada/src/main/states/gameplay/objects/bullets.asm @@ -13,17 +13,23 @@ wActiveBulletCounter:: db ; how many bullet's we've updated wUpdateBulletsCounter: db +; ANCHOR: w-bullets + ; Bytes: active, x , y (low), y (high) wBullets:: ds MAX_BULLET_COUNT*PER_BULLET_BYTES_COUNT +; ANCHOR_END: w-bullets + SECTION "Bullets", ROM0 bulletMetasprite:: .metasprite1 db 0,0,8,0 .metaspriteEnd db 128 +; ANCHOR: bullets-tile-data bulletTileData:: INCBIN "src/generated/sprites/bullet.2bpp" bulletTileDataEnd:: +; ANCHOR_END: bullets-tile-data ; ANCHOR_END: bullets-top diff --git a/galactic-armada/src/main/states/gameplay/objects/enemies.asm b/galactic-armada/src/main/states/gameplay/objects/enemies.asm index 298f5f96..091bd1ce 100644 --- a/galactic-armada/src/main/states/gameplay/objects/enemies.asm +++ b/galactic-armada/src/main/states/gameplay/objects/enemies.asm @@ -13,21 +13,28 @@ wActiveEnemyCounter::db wUpdateEnemiesCounter:db wUpdateEnemiesCurrentEnemyAddress::dw +; 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_END: enemies-start -; ANCHOR: enemies-tile-metasprite +; ANCHOR: enemies-section-header SECTION "Enemies", ROM0 +; ANCHOR_END: enemies-section-header +; ANCHOR: enemies-tile-data enemyShipTileData:: INCBIN "src/generated/sprites/enemy-ship.2bpp" enemyShipTileDataEnd:: +; ANCHOR_END: enemies-tile-data +; ANCHOR: enemy-metasprites enemyShipMetasprite:: .metasprite1 db 0,0,4,0 .metasprite2 db 0,8,6,0 .metaspriteEnd db 128 -; ANCHOR_END: enemies-tile-metasprite +; ANCHOR_END: enemy-metasprites ; ANCHOR: enemies-initialize InitializeEnemies:: @@ -243,7 +250,7 @@ UpdateEnemies_PerEnemy_CheckPlayerCollision: UpdateEnemies_DeActivateEnemy: ; Set as inactive - xor + xor a ld [hl], a ; Decrease counter @@ -265,6 +272,9 @@ UpdateEnemies_NoCollisionWithPlayer:: push hl + +; ANCHOR: draw-enemy-metasprites + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; call the 'DrawMetasprites function. setup variables and call ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -287,6 +297,8 @@ UpdateEnemies_NoCollisionWithPlayer:: ; Actually call the 'DrawMetasprites function call DrawMetasprites +; ANCHOR_END: draw-enemy-metasprites + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/galactic-armada/src/main/states/gameplay/objects/player.asm b/galactic-armada/src/main/states/gameplay/objects/player.asm index 1ee70fa6..5dc58c7b 100644 --- a/galactic-armada/src/main/states/gameplay/objects/player.asm +++ b/galactic-armada/src/main/states/gameplay/objects/player.asm @@ -14,8 +14,10 @@ mPlayerFlash: dw ; ANCHOR: player-data SECTION "Player", ROM0 +; ANCHOR: player-tile-data playerShipTileData: INCBIN "src/generated/sprites/player-ship.2bpp" playerShipTileDataEnd: +; ANCHOR_END: player-tile-data playerTestMetaSprite:: .metasprite1 db 0,0,0,0 diff --git a/galactic-armada/src/main/utils/constants.inc b/galactic-armada/src/main/utils/constants.inc index 239a8d7f..8fbded03 100644 --- a/galactic-armada/src/main/utils/constants.inc +++ b/galactic-armada/src/main/utils/constants.inc @@ -25,6 +25,7 @@ DEF enemy_speedByte RB 1 DEF enemy_healthByte RB 1 DEF PER_ENEMY_BYTES_COUNT RB 0 +; 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 @@ -33,6 +34,7 @@ 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: sprite-vram-constants RSRESET diff --git a/galactic-armada/src/main/utils/text-utils.asm b/galactic-armada/src/main/utils/text-utils.asm index a3c554f3..40088fd0 100644 --- a/galactic-armada/src/main/utils/text-utils.asm +++ b/galactic-armada/src/main/utils/text-utils.asm @@ -3,6 +3,7 @@ SECTION "Text", ROM0 textFontTileData: INCBIN "src/generated/backgrounds/text-font.2bpp" textFontTileDataEnd: +; ANCHOR: load-text-font LoadTextFontIntoVRAM:: ; Copy the tile data @@ -10,6 +11,9 @@ LoadTextFontIntoVRAM:: 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. jp CopyDEintoMemoryAtHL + +; ANCHOR_END: load-text-font + ; ANCHOR: draw-text-tiles DrawTextTilesLoop:: diff --git a/src/part3/collision.md b/src/part3/collision.md index 0c351f83..a51800e3 100644 --- a/src/part3/collision.md +++ b/src/part3/collision.md @@ -12,10 +12,10 @@ For this, we've created a basic function called "CheckObjectPositionDifference". 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. +> We have the player's Y position in the `d` register. We'll check it's value against the y value of the current enemy, which we have in a variable named `wCurrentEnemyY`. -```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/main.asm:player-collision-label}} -{{#include ../../galactic-armada/main.asm:player-collision-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}} ``` When checking for collision, we'll use that function twice. Once for the x-axis, and again for the y-axis. diff --git a/src/part3/enemies.md b/src/part3/enemies.md index b62285c8..95dbe2fb 100644 --- a/src/part3/enemies.md +++ b/src/part3/enemies.md @@ -21,8 +21,12 @@ Here are the RAM variables we'll use for our enemies: 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}} +```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-section-header}} +{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-section-header}} + +{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-tile-data}} + +{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemy-metasprites}} ``` ## Initializing Enemies 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/object-pools.md b/src/part3/object-pools.md index 22fa867e..76d71b3e 100644 --- a/src/part3/object-pools.md +++ b/src/part3/object-pools.md @@ -4,8 +4,8 @@ Galactic Armada will use "object pools" for bullets and enemies. A fixed amount 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}} +```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/utils/constants.inc:bullet-offset-constants}} +{{#include ../../galactic-armada/src/main/utils/constants.inc:bullet-offset-constants}} ``` The two object types that we need to loop through are Enemies and Bullets. @@ -19,8 +19,8 @@ The two object types that we need to loop through are Enemies and Bullets. 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}} +```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:w-enemies}} +{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:w-enemies}} ``` ![EnemyBytesVisualized.png](../assets/part3/img/EnemyBytesVisualized.png) @@ -32,8 +32,8 @@ The two object types that we need to loop through are Enemies and Bullets. 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}} +```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:w-bullets}} +{{#include ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:w-bullets}} ``` ![BulletBytesVisualized.png](../assets/part3/img/BulletBytesVisualized.png) diff --git a/src/part3/project-structure.md b/src/part3/project-structure.md index 844991b6..f26c7b6e 100644 --- a/src/part3/project-structure.md +++ b/src/part3/project-structure.md @@ -79,8 +79,15 @@ We'll use it to convert all of our graphics to .2bpp, and .tilemap formats (bina 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}} +```rgbasm +; in src/main/states/gameplay/objects/player.asm +{{#include ../../galactic-armada/src/main/states/gameplay/objects/player.asm:player-tile-data}} + +; in src/main/states/gameplay/objects/enemies.asm +{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemies-tile-data}} + +; in src/main/states/gameplay/objects/bullets.asm +{{#include ../../galactic-armada/src/main/states/gameplay/objects/bullets.asm:bullets-tile-data}} ``` :::tip Including binary files diff --git a/src/part3/sprites-metasprites.md b/src/part3/sprites-metasprites.md index 8f1445f9..e0ddf208 100644 --- a/src/part3/sprites-metasprites.md +++ b/src/part3/sprites-metasprites.md @@ -18,8 +18,8 @@ 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}} +```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemy-metasprites}} +{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:enemy-metasprites}} ``` ![MetaspriteDIagram.png](../assets/part3/img/MetaspriteDIagram.png) @@ -30,8 +30,8 @@ The Previous snippet draws two sprites. One that the object’s actual position, 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}} +```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/objects/enemies.asm:draw-enemy-metasprites}} +{{#include ../../galactic-armada/src/main/states/gameplay/objects/enemies.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: