[SOLVED][4.5.9] Tile-based HUD in scrolling module almost working!

pigeonaut

Member
So I have been searching all over the forums & discord and have pieced together an ALMOST working tile-based background HUD for the scrolling module! I think I just need some help with updating the "scrolling loading seam" to ignore the HUD tiles at the top of the screen.

Here's how to set it up so far:

Step 1: I had to first modify the following scripts:
- In NMI.asm I added this chunk of code at about line 188 in order to check for sprite 0:
Code:
LDA camX
    STA $2005    ;reset scroll values to zero
    LDA camY
    STA $2005    ;reset scroll values to zero
   
    ;;;;;;;;;;my chunk of code! Start sprite 0 stuff;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
       LDA $0200               ;; OAM slot 0 [sprite-0]
    CMP #SPRITE_ZERO_Y         ;; check if sprite-0 is at a specific Y-coordinate
                            ;; [I have a variable for this, you can just use a static number]
    BNE skipSprite0Check
    ;;;; Do whatever exception conditionals for sprite-0 detection here:

    BIT $2002                ;; reset $2005 / $2006 latch if it's in an unknown state
    LDA #$00
    STA $2005                ;; set initial scroll positions
    STA $2005

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    LDA #%10010000           ;; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
    STA $2000               ;; start with nametable = 0 for status bar

    LDA #%00011110           ;; enable sprites, enable background, no clipping on left side
    STA $2001

WaitNotSprite0:
    BIT $2002
    BVS WaitNotSprite0        ;; wait until out of vBlank

WaitSprite0:
    BIT $2002
    BMI skipSprite0Check    ;; if vBlank is detected, we missed the sprite 0 hit somehow.
                            ;; jump out of the loop in that case. [safety net]
    BVC WaitSprite0            ;; wait until sprite 0 is hit

    LDX #01 ;hBlankTimer         ;; I have a variable for my hBlank timer. You can also use a static number.

WaitScanline:               ;; wait until the electron beam is in hBlank
    DEX
    BNE WaitScanline

    LDA camX                ;; Do scroll updates
    STA $2005
    LDA camY                ;; This method cannot create a split y-axis scroll, but we'll set the Y position anyway.
    STA $2005

    LDA soft2001
    STA $2001
   
skipSprite0Check:
;;;;;;;;;;;;;end of my chunk of code sprite zero stuff ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   



skipNMIstuff:      

   
   
    INC vBlankTimer
    INC randomSeed

- In doDrawSprite_PlatformBase.asm I added this chunk of code to the top to actually draw out the sprite 0:

Code:
;; sprite drawing routine.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; For horizontal scrolling games, extra attention has to be taken to draw
;;; sprites off screen if they are no longer in the camera render area.


;;; sprite pre draw

;;;; DRAW SPRITE ZERO FOR SPRITE ZERO HIT
    LDA gameState
    CMP #GS_MainGame  
    BNE + ;dont draw sprite zero
    ;DrawSprite #$f8, #$1e, #$7F, #%00000000, spriteOffset
                ;248   30    127   bit 5 = priority
    DrawSprite #SPRITE_ZERO_X, #SPRITE_ZERO_Y, #SPRITE_ZERO_INDEX, #%00100000, spriteOffset
    UpdateSpritePointer
;dont draw sprite zero.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+

.include SCR_DRAW_SPRITE_HUD
;;

    LDA gameHandler
    AND #%01000000
    BEQ doDrawThisSprite
    JMP doneDrawingThisSprite
doDrawThisSprite:

Step 2:

- Populate the following 'sprite 0' hud values in the nesmaker UI:
1632686721727.png

Step 3:

- Make sure you have a cube at the bottom right corner in your 'GameObjectTiles.bmp' tilesheet:
1632686827047.png

Step 4:
- This is super important! Make sure that you start your game on an even (including 0) space on your overworld!
1632686915547.png

Step 5:
- Make sure you have a HUD asset at the bottom right corner of your HUD. This is so that sprite 0 can collide with a background tile. If sprite 0 doesn't collide with a non-transparent background tile, the game will glitch out! I used the red orb for my hud asset:
1632687155830.png


Here are the resources that have helped me create this HUD so far, please check them out:
-
View: https://youtu.be/o7m4gxhgX0U

- http://www.nesmakers.com/index.php?threads/sprite-zero-detection.6973/

The HUD will follow the player as expected! However, the issue I am having now is that as I move and scroll to the next screen on my right, the HUD will get eaten by blank tiles. I am pretty sure this is because the scrolling seam overwrites the HUD tiles. I just need to find a way to have the seam updater INGNORE these top 2 rows of HUD tiles and the HUD should work like it did in 4.1.x!

I have been messing around in the doUpdateScrollColumn.asm and the doUpdateCamera.asm scripts but have not found a solution yet. But I think I am looking in the right place?

Has anyone ever modified the 'scroll seam column updater' thing before? Can anyone share any project code that might relate to this issue, such as parallax scrolling or animated tiles?

Thanks for reading!!!
 

pigeonaut

Member
I figured it out!!!! I had to make a small change in the doUpdateCamera.asm script.
Replace the following subroutine with my pasted code below:
loop_LoadNametableMeta_column

Code:
loop_LoadNametableMeta_column:
            
                LDY temp3
                LDA (temp16),y
                STA temp
                JSR doGetSingleMetaTileValues
                
;;;;;ADD THIS CODE CHUNK
LDA tempA
CMP #15
BEQ +skipDraw
CMP #14
BEQ +skipDraw
;;;;;;;
                
                LDA temp1
                STA scrollUpdateRam,x
                INX
                LDA temp2
                STA scrollUpdateRam,x
                INX
                LDA updateTile_00
                STA scrollUpdateRam,x
                INX
                
                LDA temp1
                STA scrollUpdateRam,x
                INX
                LDA temp2
                CLC
                ADC #$01
                STA scrollUpdateRam,x
                INX
                LDA updateTile_01
                STA scrollUpdateRam,x
                INX
                
                LDA temp1
                STA scrollUpdateRam,x
                INX
                LDA temp2
                CLC
                ADC #$20
                STA scrollUpdateRam,x
                INX
                LDA updateTile_02
                STA scrollUpdateRam,x
                INX
                
                LDA temp1
                STA scrollUpdateRam,x
                INX
                LDA temp2
                CLC
                ADC #$21
                STA scrollUpdateRam,x
                INX
                LDA updateTile_03
                STA scrollUpdateRam,x
                INX
;;;ADD THIS CODE CHUNK
+skipDraw
;;;
                DEC tempA
                LDA tempA
                BEQ +doneWithNtLoad
                    ;; not done with NT load.  Need more tiles.
                    ;;;;;;;;;;;;;;;;;;;;;;;;;;
                    ;; update the 16 bit position of the new place to push tiles to.
                    LDA temp2
                    CLC
                    ADC #$40
                    STA temp2
                    LDA temp1
                    ADC #$00
                    STA temp1
                    ;; update the tile read location.
                    LDA temp3
                    CLC
                    ADC #$10
                    STA temp3
                    JMP loop_LoadNametableMeta_column   
            +doneWithNtLoad


And lastly we need to make a minor change to step 1 from above:
Move the original code chunk up to about line 163 in NMI.asm:
Code:
skipScreenUpdates:   
        
    ;; always do hud update, otherwise
    ;; it's possible that updates to tiles, attributes, or palettes
    ;; will cause a skip in hud update.
    ;.include ROOT\DataLoadScripts\LoadHudData.asm

;;;;;;;;;;my chunk of code! Start sprite 0 stuff;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
       LDA $0200               ;; OAM slot 0 [sprite-0]
    CMP #SPRITE_ZERO_Y         ;; check if sprite-0 is at a specific Y-coordinate
                            ;; [I have a variable for this, you can just use a static number]
    BNE skipSprite0Check
    ;;;; Do whatever exception conditionals for sprite-0 detection here:

    BIT $2002                ;; reset $2005 / $2006 latch if it's in an unknown state
    LDA #$00
    STA $2005                ;; set initial scroll positions
    STA $2005

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    LDA #%10010000           ;; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
    STA $2000               ;; start with nametable = 0 for status bar

    LDA #%00011110           ;; enable sprites, enable background, no clipping on left side
    STA $2001

WaitNotSprite0:
    BIT $2002
    BVS WaitNotSprite0        ;; wait until out of vBlank

WaitSprite0:
    BIT $2002
    BMI skipSprite0Check    ;; if vBlank is detected, we missed the sprite 0 hit somehow.
                            ;; jump out of the loop in that case. [safety net]
    BVC WaitSprite0            ;; wait until sprite 0 is hit

    LDX #01 ;hBlankTimer         ;; I have a variable for my hBlank timer. You can also use a static number.

WaitScanline:               ;; wait until the electron beam is in hBlank
    DEX
    BNE WaitScanline

    LDA camX                ;; Do scroll updates
    STA $2005
    LDA camY                ;; This method cannot create a split y-axis scroll, but we'll set the Y position anyway.
    STA $2005

    LDA soft2001
    STA $2001
  
skipSprite0Check:
;;;;;;;;;;;;;end of my chunk of code sprite zero stuff ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    LDA camY_hi
            ASL
            ASL
            ASL
            ASL
            CLC
            ADC camX_hi
            STA camScreen
    LDA camScreen ;; bit 0, determines which nametable we are looking at.
    
    
    
    AND #%00000001
    ORA #%10010000
    
    STA $2000


Please let me know if you run into trouble or have any questions about this solution!


Background_HUD.gif
(I'll take cash and checks as payment)
 

Riyan

New member
Step 4:
- This is super important! Make sure that you start your game on an even (including 0) space on your overworld!
Hi!
The game glitches out when transitioning to an odd numbered screen, which is the same thing that happens when making the player start on an odd numbered screen.
Did you find a fix for it?
 

Eddie1thompson

New member
I figured it out!!!! I had to make a small change in the doUpdateCamera.asm script.
Replace the following subroutine with my pasted code below:
loop_LoadNametableMeta_column

Code:
loop_LoadNametableMeta_column:
           
                LDY temp3
                LDA (temp16),y
                STA temp
                JSR doGetSingleMetaTileValues
               
;;;;;ADD THIS CODE CHUNK
LDA tempA
CMP #15
BEQ +skipDraw
CMP #14
BEQ +skipDraw
;;;;;;;
               
                LDA temp1
                STA scrollUpdateRam,x
                INX
                LDA temp2
                STA scrollUpdateRam,x
                INX
                LDA updateTile_00
                STA scrollUpdateRam,x
                INX
               
                LDA temp1
                STA scrollUpdateRam,x
                INX
                LDA temp2
                CLC
                ADC #$01
                STA scrollUpdateRam,x
                INX
                LDA updateTile_01
                STA scrollUpdateRam,x
                INX
               
                LDA temp1
                STA scrollUpdateRam,x
                INX
                LDA temp2
                CLC
                ADC #$20
                STA scrollUpdateRam,x
                INX
                LDA updateTile_02
                STA scrollUpdateRam,x
                INX
               
                LDA temp1
                STA scrollUpdateRam,x
                INX
                LDA temp2
                CLC
                ADC #$21
                STA scrollUpdateRam,x
                INX
                LDA updateTile_03
                STA scrollUpdateRam,x
                INX
;;;ADD THIS CODE CHUNK
+skipDraw
;;;
                DEC tempA
                LDA tempA
                BEQ +doneWithNtLoad
                    ;; not done with NT load.  Need more tiles.
                    ;;;;;;;;;;;;;;;;;;;;;;;;;;
                    ;; update the 16 bit position of the new place to push tiles to.
                    LDA temp2
                    CLC
                    ADC #$40
                    STA temp2
                    LDA temp1
                    ADC #$00
                    STA temp1
                    ;; update the tile read location.
                    LDA temp3
                    CLC
                    ADC #$10
                    STA temp3
                    JMP loop_LoadNametableMeta_column  
            +doneWithNtLoad


And lastly we need to make a minor change to step 1 from above:
Move the original code chunk up to about line 163 in NMI.asm:
Code:
skipScreenUpdates:  
       
    ;; always do hud update, otherwise
    ;; it's possible that updates to tiles, attributes, or palettes
    ;; will cause a skip in hud update.
    ;.include ROOT\DataLoadScripts\LoadHudData.asm

;;;;;;;;;;my chunk of code! Start sprite 0 stuff;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
       LDA $0200               ;; OAM slot 0 [sprite-0]
    CMP #SPRITE_ZERO_Y         ;; check if sprite-0 is at a specific Y-coordinate
                            ;; [I have a variable for this, you can just use a static number]
    BNE skipSprite0Check
    ;;;; Do whatever exception conditionals for sprite-0 detection here:

    BIT $2002                ;; reset $2005 / $2006 latch if it's in an unknown state
    LDA #$00
    STA $2005                ;; set initial scroll positions
    STA $2005

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    LDA #%10010000           ;; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
    STA $2000               ;; start with nametable = 0 for status bar

    LDA #%00011110           ;; enable sprites, enable background, no clipping on left side
    STA $2001

WaitNotSprite0:
    BIT $2002
    BVS WaitNotSprite0        ;; wait until out of vBlank

WaitSprite0:
    BIT $2002
    BMI skipSprite0Check    ;; if vBlank is detected, we missed the sprite 0 hit somehow.
                            ;; jump out of the loop in that case. [safety net]
    BVC WaitSprite0            ;; wait until sprite 0 is hit

    LDX #01 ;hBlankTimer         ;; I have a variable for my hBlank timer. You can also use a static number.

WaitScanline:               ;; wait until the electron beam is in hBlank
    DEX
    BNE WaitScanline

    LDA camX                ;; Do scroll updates
    STA $2005
    LDA camY                ;; This method cannot create a split y-axis scroll, but we'll set the Y position anyway.
    STA $2005

    LDA soft2001
    STA $2001
 
skipSprite0Check:
;;;;;;;;;;;;;end of my chunk of code sprite zero stuff ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    LDA camY_hi
            ASL
            ASL
            ASL
            ASL
            CLC
            ADC camX_hi
            STA camScreen
    LDA camScreen ;; bit 0, determines which nametable we are looking at.
   
   
   
    AND #%00000001
    ORA #%10010000
   
    STA $2000


Please let me know if you run into trouble or have any questions about this solution!


View attachment 5475
(I'll take cash and checks as payment)
Does this work on 4.5.9? i tried your solution on the shooter module and it didn't draw the sprite zero, and every other screen the hud showed up, but scrolled across the screen
 

baardbi

Well-known member
This is a really important fix, however... Has anyone gotten this to work? I have tried several times without any success. Unfortunately this tutorial is a little unclear exactly what needs to be changed, especially since there is an update in the comment section. I also think there is something missing. If you don't add doHandleHud in Script Settings nothing shows up in the HUD area. I apologize if I'm just missing something here.

The HUD scrolls with the camera:
game_000.png
 

smilehero65

Active member
This is a really important fix, however... Has anyone gotten this to work? I have tried several times without any success. Unfortunately this tutorial is a little unclear exactly what needs to be changed, especially since there is an update in the comment section. I also think there is something missing. If you don't add doHandleHud in Script Settings nothing shows up in the HUD area. I apologize if I'm just missing something here.

The HUD scrolls with the camera:
View attachment 7811
I tried this a while back too and got the same results :(
 
This is a really important fix, however... Has anyone gotten this to work? I have tried several times without any success. Unfortunately this tutorial is a little unclear exactly what needs to be changed, especially since there is an update in the comment section. I also think there is something missing. If you don't add doHandleHud in Script Settings nothing shows up in the HUD area. I apologize if I'm just missing something here.

The HUD scrolls with the camera:
View attachment 7811
from what I've looked at from an older NESmaker build it has something to do with spriteOffset... but it doesn't seem to be in 4.5.9 at all
 

baardbi

Well-known member
from what I've looked at from an older NESmaker build it has something to do with spriteOffset... but it doesn't seem to be in 4.5.9 at all
I finally got this sort of working. The split screen works and when I include the doHandleHud file it kind of works. However, there's something strange about HUD updates. It only updates sometimes. So until I can make it more stable I can't use this in a project.
 
I finally got this sort of working. The split screen works and when I include the doHandleHud file it kind of works. However, there's something strange about HUD updates. It only updates sometimes. So until I can make it more stable I can't use this in a project.
Maybe this will solve the issue?


If not can you send me the solution you have so far regardless for me to look at?
 

baardbi

Well-known member
Maybe this will solve the issue?


If not can you send me the solution you have so far regardless for me to look at?
Thanks. But I messed up the whole project when I tried to mix the sprite HUD with the static HUD. I forgot it was a bad idea because of sprite zero lol. Oh well. I'll probably get back to this once Byte Off is over. But for now I have my hands full with my competition game.
 
I finally got this sort of working. The split screen works and when I include the doHandleHud file it kind of works. However, there's something strange about HUD updates. It only updates sometimes. So until I can make it more stable I can't use this in a project.
ALMOST HAVE THIS WORKING! the "sometimes" SEEMS to be a nametable issue where when we get the cam's seam it only updates the original nametable! not the current one!
my issue is how I tackle that
 
ALMOST HAVE THIS WORKING! the "sometimes" SEEMS to be a nametable issue where when we get the cam's seam it only updates the original nametable! not the current one!
my issue is how I tackle that
UPDATE: it has something to do with the doHandleObjects script because removing it as a factor fixes the HUD while scrolling completely... where the issue is in there I have no clue but it's time to dig
 

dale_coop

Moderator
Staff member
If I had to guess I would check around the camX or object_screen / xHold_screen,... and your tile hud.
 
SOLVED THE ISSUE! will share more details after the Byte-Off!
okay so I think it's better I support the NESMaker community and just say the answer now:
the solution is to edit this:
LDX player1_object
LDA Object_screen,x
AND #%00000001
BEQ updatesToEvenNametable
;;updates to odd nametable
LDA #$24
STA camFocus_tiles
LDA #$27
STA camFocus_att
JMP gotScreenFocus
updatesToEvenNametable:
LDA #$20
STA camFocus_tiles
LDA #$23
STA camFocus_att
to this:
LDX player1_object
LDA Object_screen,x
AND #%00000001
BEQ updatesToEvenNametable
;;updates to odd nametable
LDA #$20 <---- this line
STA camFocus_tiles
LDA #$27
STA camFocus_att
JMP gotScreenFocus
updatesToEvenNametable:
LDA #$20
STA camFocus_tiles
LDA #$23
STA camFocus_att
in doHandleUpdateScreen.asm
if there are drawbacks or issues with this PLEASE let me know but either way, it works now
View: https://youtu.be/Zeo95q431jU
 
okay so I think it's better I support the NESMaker community and just say the answer now:
the solution is to edit this:

to this:

in doHandleUpdateScreen.asm
if there are drawbacks or issues with this PLEASE let me know but either way, it works now
View: https://youtu.be/Zeo95q431jU
ran into a bit of an issue that may or may not have been caused by this, TLDR; monster's sprites aren't being shown in my current build right now... will report if I find the issue with the HUD
 
Top Bottom