From 82de7ea2bb413cfc341ea7b851827510be09492b Mon Sep 17 00:00:00 2001 From: LaroldsJubilantJunkyard Date: Sun, 17 Dec 2023 07:48:30 -0500 Subject: [PATCH] finishing the hud moving interrupts into hud --- ...ameplay-background.asm => backgrounds.asm} | 112 +++++++++--------- .../src/main/states/gameplay/hud.asm | 90 ++++++++++---- .../src/main/states/gameplay/interrupts.asm | 73 ------------ galactic-armada/src/main/utils/text-utils.asm | 25 ++++ src/part3/drawing-text.md | 4 +- src/part3/heads-up-interface.md | 55 +++++---- src/part3/scrolling-background.md | 12 +- 7 files changed, 188 insertions(+), 183 deletions(-) rename galactic-armada/src/main/states/gameplay/{gameplay-background.asm => backgrounds.asm} (95%) delete mode 100644 galactic-armada/src/main/states/gameplay/interrupts.asm diff --git a/galactic-armada/src/main/states/gameplay/gameplay-background.asm b/galactic-armada/src/main/states/gameplay/backgrounds.asm similarity index 95% rename from galactic-armada/src/main/states/gameplay/gameplay-background.asm rename to galactic-armada/src/main/states/gameplay/backgrounds.asm index 4cb32fd6..a8d98e4a 100644 --- a/galactic-armada/src/main/states/gameplay/gameplay-background.asm +++ b/galactic-armada/src/main/states/gameplay/backgrounds.asm @@ -1,57 +1,57 @@ -; ANCHOR: gameplay-background-initialize -INCLUDE "src/main/includes/hardware.inc" -INCLUDE "src/main/includes/character-mapping.inc" - -SECTION "BackgroundVariables", WRAM0 - -mBackgroundScroll:: dw - -SECTION "GameplayBackgroundSection", ROM0 - - -InitializeBackground:: - - call DrawStarFieldBackground - - 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: gameplay-background-initialize +INCLUDE "src/main/includes/hardware.inc" +INCLUDE "src/main/includes/character-mapping.inc" + +SECTION "BackgroundVariables", WRAM0 + +mBackgroundScroll:: dw + +SECTION "GameplayBackgroundSection", ROM0 + + +InitializeBackground:: + + call DrawStarFieldBackground + + 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/hud.asm b/galactic-armada/src/main/states/gameplay/hud.asm index c400f9ef..9ffda53c 100644 --- a/galactic-armada/src/main/states/gameplay/hud.asm +++ b/galactic-armada/src/main/states/gameplay/hud.asm @@ -1,7 +1,7 @@ +; ANCHOR: hud-start INCLUDE "src/main/includes/hardware.inc" - - SECTION "GameplayHUD", ROM0 +; ANCHOR_END: hud-start ; ANCHOR: hud-increase-score IncreaseScore:: @@ -42,29 +42,75 @@ IncreaseScore_Next: jp IncreaseScore_Loop ; ANCHOR_END: hud-increase-score - -; ANCHOR: hud-draw-lives -DrawBDigitsHL_OnDE:: - ; How many digits remain in b - ld a, b - and a - ret z +; ANCHOR: interrupts-start - ; Decrease b by one - dec a - ld b,a +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 - ld a, [hl] - add a, 10 ; our numeric tiles start at tile 10, so add to 10 to each bytes value - ld [de], a - ; Increase which tile we are drawing to - inc de +EndStatInterrupts: - ; Increase the tile we are drawing - inc hl + pop af - jp DrawBDigitsHL_OnDE -; ANCHOR_END: hud-draw-lives - + reti; +; ANCHOR_END: interrupts-section \ 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 51c428e2..00000000 --- a/galactic-armada/src/main/states/gameplay/interrupts.asm +++ /dev/null @@ -1,73 +0,0 @@ - -; ANCHOR: interrupts-start -INCLUDE "src/main/includes/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/utils/text-utils.asm b/galactic-armada/src/main/utils/text-utils.asm index 9fd72204..8bae2d66 100644 --- a/galactic-armada/src/main/utils/text-utils.asm +++ b/galactic-armada/src/main/utils/text-utils.asm @@ -88,3 +88,28 @@ MultilineTypewriteTextInHL_AtDE_NewLine: ; continue until we read those consecutive 255's jp MultilineTypewriteTextInHL_AtDE_NewLine ; ANCHOR_END: multiline-typewriter-effect + +; ANCHOR: draw-b-digits +DrawBDigitsHL_OnDE:: + + ; How many digits remain in b + ld a, b + and a + ret z + + ; Decrease b by one + dec a + ld b,a + + ld a, [hl] + add a, 10 ; our numeric tiles start at tile 10, so add to 10 to each bytes value + ld [de], a + + ; Increase which tile we are drawing to + inc de + + ; Increase the tile we are drawing + inc hl + + jp DrawBDigitsHL_OnDE +; ANCHOR_END: draw-b-digits \ No newline at end of file diff --git a/src/part3/drawing-text.md b/src/part3/drawing-text.md index be27048d..515ce3ad 100644 --- a/src/part3/drawing-text.md +++ b/src/part3/drawing-text.md @@ -82,8 +82,8 @@ For drawing numbers, we've created a function called `DrawBDigitsHL_OnDE`. To ca >**Note:** The numbers in our text font start at tile 10. So, for each number read, we'll add 10 to it. -```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}} +```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/utils/text-utils.asm:draw-b-digits}} +{{#include ../../galactic-armada/src/main/utils/text-utils.asm::draw-b-digits}} ``` We will later call that function like so: diff --git a/src/part3/heads-up-interface.md b/src/part3/heads-up-interface.md index ebcc4eb7..e1772f02 100644 --- a/src/part3/heads-up-interface.md +++ b/src/part3/heads-up-interface.md @@ -4,6 +4,28 @@ The gameboy normally draws sprites over both the window and background, and the 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. +**Create a new file called `hud.asm`:** + +```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/hud.asm:hud-start}} +{{#include ../../galactic-armada/src/main/states/gameplay/hud.asm:hud-start}} +``` + +## Increasing the score + +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 . + +**Add this `IncreaseScore` function to your `hud.asm` file:** + +```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. + ## STAT Interrupts & the window @@ -26,37 +48,22 @@ With STAT interrupts, we can implement raster effects. in our case, we’ll enab ### 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: +In our gameplay game state, at different points in time, we initialized and disabled interrupts. + +**Add these 2 functions to your `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}} +```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/hud.asm:interrupts-start}} +{{#include ../../galactic-armada/src/main/states/gameplay/hud.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. +**Finish the `hud.asm` file wih the following section below:** -## 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}} +```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/hud.asm:interrupts-section}} +{{#include ../../galactic-armada/src/main/states/gameplay/hud.asm:interrupts-section}} ``` - -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: - - -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. +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. diff --git a/src/part3/scrolling-background.md b/src/part3/scrolling-background.md index f0c63837..54002ca6 100644 --- a/src/part3/scrolling-background.md +++ b/src/part3/scrolling-background.md @@ -11,24 +11,24 @@ At the start of the gameplay game state we called the initialize background func **Create a file called `backgrounds.asm` and add the following code:** -```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}} +```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/backgrounds.asm:gameplay-background-initialize}} +{{#include ../../galactic-armada/src/main/states/gameplay/backgrounds.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. **Copy the `UpdateBackground` code below into your backgrounds.asm** -```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}} +```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/backgrounds.asm:gameplay-background-update-start}} +{{#include ../../galactic-armada/src/main/states/gameplay/backgrounds.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. **Copy the code below into your backgrounds.asm** -```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}} +```rgbasm,linenos,start={{#line_no_of "" ../../galactic-armada/src/main/states/gameplay/backgrounds.asm:gameplay-background-update-end}} +{{#include ../../galactic-armada/src/main/states/gameplay/backgrounds.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