Strange graphical glitch 4.5

After finally getting my forcefield to work yesterday, I've been encountering a strange graphical glitch with the projectiles, as shown in the link below. I am unsure of how this happened, but the problem started last night. Worth noting that's also when I incorporated the Handle Hud script. I haven't updated the projectile animation code in a while, so I'm stumped. It seems to happen randomly upon soft resets.

Project Eruca Graphical Glitch
 
Which scripts do you think may be causing the glitch????
I'm not sure, but it started happening either after I got the forcefield parry working (object collisions and doDrawSprites), or after I enabled the Hud script (Handle Hud). I'm not sure which one caused the issue, but it's likely one of them. Most likely the sprite drawing or hud drawing scripts. I don't think object collisions would be the issue.
 

tbizzle

Well-known member
Try putting this bit of code at the beginning of that projectile script:

Code:
LDA updateScreenData
AND #%0000100
BEQ +continue
    RTS
+continue:
 

tbizzle

Well-known member
You can also try putting it at one of the other two scripts, just only use it once on one of the scripts though.
 

tbizzle

Well-known member
You can also try this right before the "Create_Object" macro inside of your projectile script:

Code:
    JSR doWaitFrame
 

tbizzle

Well-known member
Glad it helped! Remember, use those to pieces of stuff as a buffer when things start to get glitchy. The official "band-aids" of NESmaker!
 
Glad it helped! Remember, use those to pieces of stuff as a buffer when things start to get glitchy. The official "band-aids" of NESmaker!
Uh hi so I'm coming back to say apparently it didn't work and I've just been extremely lucky in not triggering it lol. Gonna try your other suggestion now
 

baardbi

Well-known member
Like tbizzle said, it would help if we could see your shoot projectile input script, and it would also be interesting to know what modifications you made to the doDrawSprites script.
 
Like tbizzle said, it would help if we could see your shoot projectile input script, and it would also be interesting to know what modifications you made to the doDrawSprites script.
The projectile code (monster projectile code is basically the same)
Code:
;;; Create a Projectile.
;;; Assumes that the projectile you want to create is in GameObject Slot 01.
    ;; We count the projectiles already on screen to see if can Shoot another one :
    CountObjects #%00000100, #$00   ;; count player weapon on screen  ;; the variable used to count is monsterCounter
    CLC
    CMP #$01        ;; compare to 2
    BCC +canShoot           ;; if less than 2 on screen we can create a projectile
    RTS         ;; else we quit   
    +canShoot
    ;; else, the script continues:
    PlaySound #sfx_laser
TXA
PHA
TYA
PHA
LDX player1_object
LDA Object_x_hi,x ; get player x coord
STA tempA
LDA Object_y_hi,x; get player y coord
STA tempB

LDA Object_screen,x
STA tempC
CreateObjectOnScreen tempA, tempB, #$03, #$00, tempC
;;; x, y, object, starting action.
;;; and now with that object, copy the player's
;;; direction and start it moving that way.

PLA
TAY
PLA
TAX

RTS
As for my doDrawSprite script, it's completely overhauled. It wasn't just changed, it was completely remade.
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.
LDA gameHandler
    AND #%01000000
    BEQ doDrawThisSprite
    JMP doneDrawingThisSprite
doDrawThisSprite:
    ;;;; loaded into x is the object drawing this routine.
    LDA Object_x_hi,x
    STA tempA
    
    LDA Object_y_hi,x
    STA tempB
    
    LDA Object_type,x
    BEQ +isPlayerObject
        JMP +isNotPlayerObject
    +isPlayerObject
    ;;; DRAW PLAYER OBJECT
        DrawSprite tempA, tempB, #$00, #%00000000
            LDA tempA
            CLC
            ADC #$08
            STA temp1
        DrawSprite temp1, tempB, #$00, #%01000000
            LDA tempB
            CLC
            ADC #$08
            STA temp2
        DrawSprite tempA, temp2, #$10, #%00000000
        DrawSprite temp1, temp2, #$10, #%01000000
        LDA Object_vulnerability,x ;; loads vulnerability byte for Player object
    AND #%00001000  ;; checks if "Action Step Flag 02" is checked, assumes this is your invincible toggle;;
    ;;remember you can relabel these to keep track in Project Settings->project labels->Player Action Step Flags
    BNE +MakeShield ;; if invincible, make shield
    JMP +canHurtPlayer
       ;;else skip
       +MakeShield
        ;;; DRAW SHIELD
        DrawSprite tempA, tempB, #$13, #%00000000
            LDA tempA
            CLC
            ADC #$08
            STA temp1
        DrawSprite temp1, tempB, #$13, #%01000000
            LDA tempB
            CLC
            ADC #$08
            STA temp2
        DrawSprite tempA, temp2, #$13, #%10000000
        DrawSprite temp1, temp2, #$13, #%11000000
        +canHurtPlayer
        JMP doneDrawingThisSprite
    +isNotPlayerObject
        ;;; CHECK OTHER OBJECTS.
    CMP #$03
    BEQ +isLaser
        JMP +isNotLaser
    +isLaser
    LDA vBlankTimer
    AND #%00000100
    BEQ +isEvenFrame
    JMP +isNotEvenFrame
    +isEvenFrame
    ;;; DRAW PROJECTILE
        DrawSprite tempA, tempB, #$06, #%00000000
            
        JMP doneDrawingThisSprite
    +isNotEvenFrame
        DrawSprite tempA, tempB, #$06, #%00000011
            
        JMP doneDrawingThisSprite
    +isNotLaser
    CMP #$08
    BEQ +isMonsterWeapon
        JMP +isNotMonsterWeapon
    +isMonsterWeapon
    LDA vBlankTimer
    AND #%00000100
    BEQ +isEvenFrame
    JMP +isNotEvenFrame
    +isEvenFrame
    ;;; DRAW ENEMY PROJECTILE
        DrawSprite tempA, tempB, #$06, #%00000001
            
        JMP doneDrawingThisSprite
    +isNotEvenFrame
        DrawSprite tempA, tempB, #$06, #%00000010
    
        JMP doneDrawingThisSprite
    +isNotMonsterWeapon
    CMP #$11
    BEQ +isEnemy
        JMP +isNotEnemy
    +isEnemy
    ;;; DRAW ENEMY
        DrawSprite tempA, tempB, #$85, #%01000010
            LDA tempA
            CLC
            ADC #$08
            STA temp1
        DrawSprite temp1, tempB, #$85, #%00000010
            LDA tempB
            CLC
            ADC #$08
            STA temp2
        DrawSprite tempA, temp2, #$95, #%01000010
        DrawSprite temp1, temp2, #$95, #%00000010
        JMP doneDrawingThisSprite
    +isNotEnemy
    CMP #$02
    BEQ +isShield
        JMP +isNotShield
    +isShield
    ;;; DRAW SHIELD
        DrawSprite tempA, tempB, #$13, #%00000000
            LDA tempA
            CLC
            ADC #$08
            STA temp1
        DrawSprite temp1, tempB, #$13, #%01000000
            LDA tempB
            CLC
            ADC #$08
            STA temp2
        DrawSprite tempA, temp2, #$13, #%10000000
        DrawSprite temp1, temp2, #$13, #%11000000
        JMP doneDrawingThisSprite
    +isNotShield
    CMP #$09
    BEQ +isExplode
        JMP +isNotExplode
    +isExplode
    TXA
    STA temp
    GetActionStep temp
    CMP #$00
    BEQ +isEvenFrame
    JMP +isNotEvenFrame
    +isEvenFrame
    ;;; DRAW EXPLODE
        DrawSprite tempA, tempB, #$03, #%00000001
            LDA tempA
            CLC
            ADC #$08
            STA temp1
        DrawSprite temp1, tempB, #$03, #%01000001
            LDA tempB
            CLC
            ADC #$08
            STA temp2
        DrawSprite tempA, temp2, #$03, #%10000001
        DrawSprite temp1, temp2, #$03, #%11000001
        JMP doneDrawingThisSprite
    +isNotEvenFrame
        DrawSprite tempA, tempB, #$05, #%00000001
            LDA tempA
            CLC
            ADC #$08
            STA temp1
        DrawSprite temp1, tempB, #$05, #%01000001
            LDA tempB
            CLC
            ADC #$08
            STA temp2
        DrawSprite tempA, temp2, #$05, #%10000001
        DrawSprite temp1, temp2, #$05, #%11000001
        
        JMP doneDrawingThisSprite
    +isNotExplode
doneDrawingThisSprite:
LDA updateScreenData
AND #%0000100
BEQ +continue
    RTS
+continue:
    RTS
The shield part was particularly tricky, and that's when I started noticing the glitch, so I'm wondering if that has anything to do with it.
 

baardbi

Well-known member
The projectile code (monster projectile code is basically the same)
Code:
;;; Create a Projectile.
;;; Assumes that the projectile you want to create is in GameObject Slot 01.
    ;; We count the projectiles already on screen to see if can Shoot another one :
    CountObjects #%00000100, #$00   ;; count player weapon on screen  ;; the variable used to count is monsterCounter
    CLC
    CMP #$01        ;; compare to 2
    BCC +canShoot           ;; if less than 2 on screen we can create a projectile
    RTS         ;; else we quit  
    +canShoot
    ;; else, the script continues:
    PlaySound #sfx_laser
TXA
PHA
TYA
PHA
LDX player1_object
LDA Object_x_hi,x ; get player x coord
STA tempA
LDA Object_y_hi,x; get player y coord
STA tempB

LDA Object_screen,x
STA tempC
CreateObjectOnScreen tempA, tempB, #$03, #$00, tempC
;;; x, y, object, starting action.
;;; and now with that object, copy the player's
;;; direction and start it moving that way.

PLA
TAY
PLA
TAX

RTS
As for my doDrawSprite script, it's completely overhauled. It wasn't just changed, it was completely remade.
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.
LDA gameHandler
    AND #%01000000
    BEQ doDrawThisSprite
    JMP doneDrawingThisSprite
doDrawThisSprite:
    ;;;; loaded into x is the object drawing this routine.
    LDA Object_x_hi,x
    STA tempA
   
    LDA Object_y_hi,x
    STA tempB
   
    LDA Object_type,x
    BEQ +isPlayerObject
        JMP +isNotPlayerObject
    +isPlayerObject
    ;;; DRAW PLAYER OBJECT
        DrawSprite tempA, tempB, #$00, #%00000000
            LDA tempA
            CLC
            ADC #$08
            STA temp1
        DrawSprite temp1, tempB, #$00, #%01000000
            LDA tempB
            CLC
            ADC #$08
            STA temp2
        DrawSprite tempA, temp2, #$10, #%00000000
        DrawSprite temp1, temp2, #$10, #%01000000
        LDA Object_vulnerability,x ;; loads vulnerability byte for Player object
    AND #%00001000  ;; checks if "Action Step Flag 02" is checked, assumes this is your invincible toggle;;
    ;;remember you can relabel these to keep track in Project Settings->project labels->Player Action Step Flags
    BNE +MakeShield ;; if invincible, make shield
    JMP +canHurtPlayer
       ;;else skip
       +MakeShield
        ;;; DRAW SHIELD
        DrawSprite tempA, tempB, #$13, #%00000000
            LDA tempA
            CLC
            ADC #$08
            STA temp1
        DrawSprite temp1, tempB, #$13, #%01000000
            LDA tempB
            CLC
            ADC #$08
            STA temp2
        DrawSprite tempA, temp2, #$13, #%10000000
        DrawSprite temp1, temp2, #$13, #%11000000
        +canHurtPlayer
        JMP doneDrawingThisSprite
    +isNotPlayerObject
        ;;; CHECK OTHER OBJECTS.
    CMP #$03
    BEQ +isLaser
        JMP +isNotLaser
    +isLaser
    LDA vBlankTimer
    AND #%00000100
    BEQ +isEvenFrame
    JMP +isNotEvenFrame
    +isEvenFrame
    ;;; DRAW PROJECTILE
        DrawSprite tempA, tempB, #$06, #%00000000
           
        JMP doneDrawingThisSprite
    +isNotEvenFrame
        DrawSprite tempA, tempB, #$06, #%00000011
           
        JMP doneDrawingThisSprite
    +isNotLaser
    CMP #$08
    BEQ +isMonsterWeapon
        JMP +isNotMonsterWeapon
    +isMonsterWeapon
    LDA vBlankTimer
    AND #%00000100
    BEQ +isEvenFrame
    JMP +isNotEvenFrame
    +isEvenFrame
    ;;; DRAW ENEMY PROJECTILE
        DrawSprite tempA, tempB, #$06, #%00000001
           
        JMP doneDrawingThisSprite
    +isNotEvenFrame
        DrawSprite tempA, tempB, #$06, #%00000010
   
        JMP doneDrawingThisSprite
    +isNotMonsterWeapon
    CMP #$11
    BEQ +isEnemy
        JMP +isNotEnemy
    +isEnemy
    ;;; DRAW ENEMY
        DrawSprite tempA, tempB, #$85, #%01000010
            LDA tempA
            CLC
            ADC #$08
            STA temp1
        DrawSprite temp1, tempB, #$85, #%00000010
            LDA tempB
            CLC
            ADC #$08
            STA temp2
        DrawSprite tempA, temp2, #$95, #%01000010
        DrawSprite temp1, temp2, #$95, #%00000010
        JMP doneDrawingThisSprite
    +isNotEnemy
    CMP #$02
    BEQ +isShield
        JMP +isNotShield
    +isShield
    ;;; DRAW SHIELD
        DrawSprite tempA, tempB, #$13, #%00000000
            LDA tempA
            CLC
            ADC #$08
            STA temp1
        DrawSprite temp1, tempB, #$13, #%01000000
            LDA tempB
            CLC
            ADC #$08
            STA temp2
        DrawSprite tempA, temp2, #$13, #%10000000
        DrawSprite temp1, temp2, #$13, #%11000000
        JMP doneDrawingThisSprite
    +isNotShield
    CMP #$09
    BEQ +isExplode
        JMP +isNotExplode
    +isExplode
    TXA
    STA temp
    GetActionStep temp
    CMP #$00
    BEQ +isEvenFrame
    JMP +isNotEvenFrame
    +isEvenFrame
    ;;; DRAW EXPLODE
        DrawSprite tempA, tempB, #$03, #%00000001
            LDA tempA
            CLC
            ADC #$08
            STA temp1
        DrawSprite temp1, tempB, #$03, #%01000001
            LDA tempB
            CLC
            ADC #$08
            STA temp2
        DrawSprite tempA, temp2, #$03, #%10000001
        DrawSprite temp1, temp2, #$03, #%11000001
        JMP doneDrawingThisSprite
    +isNotEvenFrame
        DrawSprite tempA, tempB, #$05, #%00000001
            LDA tempA
            CLC
            ADC #$08
            STA temp1
        DrawSprite temp1, tempB, #$05, #%01000001
            LDA tempB
            CLC
            ADC #$08
            STA temp2
        DrawSprite tempA, temp2, #$05, #%10000001
        DrawSprite temp1, temp2, #$05, #%11000001
       
        JMP doneDrawingThisSprite
    +isNotExplode
doneDrawingThisSprite:
LDA updateScreenData
AND #%0000100
BEQ +continue
    RTS
+continue:
    RTS
The shield part was particularly tricky, and that's when I started noticing the glitch, so I'm wondering if that has anything to do with it.
Sorry. I don't have time to look at this code today. I'll take a look at it tomorrow and get back to you.
 

baardbi

Well-known member
OK. I've looked at the code. I couldn't see anything obvious that would cause this issue. There's a lot to troubleshoot here, so it's hard to know where to start checking. It looks like the bottom of the player sprite is being drawn with the projectiles when the issue happens. It would be helpful if we could confirm that it's that sprite tile or if it's another similar sprite tile. That way we have a sprite tile number to work with in the troubleshooting. Another thing you could do is to have the Tile Viewer in Mesen open during testing to see if the tilesets look the same with and without the glitch or if something gets corrupted.

Since you have a suspicion that the HUD might be the culprit it would be interesting to take a look at that as well.
 
OK. I've looked at the code. I couldn't see anything obvious that would cause this issue. There's a lot to troubleshoot here, so it's hard to know where to start checking. It looks like the bottom of the player sprite is being drawn with the projectiles when the issue happens. It would be helpful if we could confirm that it's that sprite tile or if it's another similar sprite tile. That way we have a sprite tile number to work with in the troubleshooting. Another thing you could do is to have the Tile Viewer in Mesen open during testing to see if the tilesets look the same with and without the glitch or if something gets corrupted.

Since you have a suspicion that the HUD might be the culprit it would be interesting to take a look at that as well.

I don't think it's the bottom player sprite, because 1. the color would be different and 2. the bottom sprite is more than just the line. I don't think I have any sprite that looks like that.
 
OK. I've looked at the code. I couldn't see anything obvious that would cause this issue. There's a lot to troubleshoot here, so it's hard to know where to start checking. It looks like the bottom of the player sprite is being drawn with the projectiles when the issue happens. It would be helpful if we could confirm that it's that sprite tile or if it's another similar sprite tile. That way we have a sprite tile number to work with in the troubleshooting. Another thing you could do is to have the Tile Viewer in Mesen open during testing to see if the tilesets look the same with and without the glitch or if something gets corrupted.

Since you have a suspicion that the HUD might be the culprit it would be interesting to take a look at that as well.
After experimenting (haven't had time to do anything these past couple days) I found out that it is definitely the hud, because it caused another glitch as well. I moved everything inward and created a border, since I found out that most CRTs cut of a good chunk of the screen.Screenshot 2024-03-03 140031.png

However, when I test it, it looks like this:

Screenshot 2024-03-03 140206.png


After setting the hud script back to blank, it looks perfectly fine. I'm not really sure what the problem is though. This is my hud script:
Code:
;;;; handle hud

    SwitchBank #$18
        JSR doDrawHud_bank18
        ;JSR doDrawSpriteHud_bank18
    ReturnBank
            
        
        
    ; ;;; DrawTilesDirect macro is good for:
    ; ;;; Drawing static text
    ; ;;; Drawing an image.
    ; ;;; Arguments are:
        ; ;; bank, string/label, x compared to box0, y compared to box0, and offset of tiles being drawn (#HUD_OFFSET for hud stuff, 0 otherwise).
    ; DrawTilesDirect #$00, HUD_Health, #$02, #$02, #HUD_OFFSET
    
    ; ;;; Draw variable tiles is good for drawing a "bar" or "meter"
    ; ;; Draws a "max value" with one particular tile id
    ; ;; and a variable level with another tile id.
    
    ; ;DrawVariableTiles x, y, full length, tile, fill amount, tile.
    ; ; changes are the "amount" will be a variable, like my health or my magic or something.
    ; DrawVariableTiles #$10, #$02, #$08, #$C0, #$04, #$D0
    
    ; ;;; Draw numbers is good for drawing the value of a variable.  For drawing static, should stll use draw tiles direct.
    ; ;;; DrawNumbers root variable, number of places.
    ; DrawNumbers #$02, #$04, myScore, #$04
    
        
    LDA gameHandler
    AND #%00100000
    BEQ doDrawHudUpdates
        JMP skipHudUpdates
    doDrawHudUpdates
    .include GameData\HUD_INCLUDES.dat
    skipHudUpdates:
 

baardbi

Well-known member
After experimenting (haven't had time to do anything these past couple days) I found out that it is definitely the hud, because it caused another glitch as well. I moved everything inward and created a border, since I found out that most CRTs cut of a good chunk of the screen.View attachment 7985

However, when I test it, it looks like this:

View attachment 7986


After setting the hud script back to blank, it looks perfectly fine. I'm not really sure what the problem is though. This is my hud script:
Code:
;;;; handle hud

    SwitchBank #$18
        JSR doDrawHud_bank18
        ;JSR doDrawSpriteHud_bank18
    ReturnBank
           
       
       
    ; ;;; DrawTilesDirect macro is good for:
    ; ;;; Drawing static text
    ; ;;; Drawing an image.
    ; ;;; Arguments are:
        ; ;; bank, string/label, x compared to box0, y compared to box0, and offset of tiles being drawn (#HUD_OFFSET for hud stuff, 0 otherwise).
    ; DrawTilesDirect #$00, HUD_Health, #$02, #$02, #HUD_OFFSET
   
    ; ;;; Draw variable tiles is good for drawing a "bar" or "meter"
    ; ;; Draws a "max value" with one particular tile id
    ; ;; and a variable level with another tile id.
   
    ; ;DrawVariableTiles x, y, full length, tile, fill amount, tile.
    ; ; changes are the "amount" will be a variable, like my health or my magic or something.
    ; DrawVariableTiles #$10, #$02, #$08, #$C0, #$04, #$D0
   
    ; ;;; Draw numbers is good for drawing the value of a variable.  For drawing static, should stll use draw tiles direct.
    ; ;;; DrawNumbers root variable, number of places.
    ; DrawNumbers #$02, #$04, myScore, #$04
   
       
    LDA gameHandler
    AND #%00100000
    BEQ doDrawHudUpdates
        JMP skipHudUpdates
    doDrawHudUpdates
    .include GameData\HUD_INCLUDES.dat
    skipHudUpdates:
Looks like you're using a standard HUD script. What module are you using?
 

dale_coop

Moderator
Staff member
After experimenting (haven't had time to do anything these past couple days) I found out that it is definitely the hud, because it caused another glitch as well. I moved everything inward and created a border, since I found out that most CRTs cut of a good chunk of the screen.View attachment 7985

However, when I test it, it looks like this:

View attachment 7986


After setting the hud script back to blank, it looks perfectly fine. I'm not really sure what the problem is though. This is my hud script:
Code:
;;;; handle hud

    SwitchBank #$18
        JSR doDrawHud_bank18
        ;JSR doDrawSpriteHud_bank18
    ReturnBank
           
       
       
    ; ;;; DrawTilesDirect macro is good for:
    ; ;;; Drawing static text
    ; ;;; Drawing an image.
    ; ;;; Arguments are:
        ; ;; bank, string/label, x compared to box0, y compared to box0, and offset of tiles being drawn (#HUD_OFFSET for hud stuff, 0 otherwise).
    ; DrawTilesDirect #$00, HUD_Health, #$02, #$02, #HUD_OFFSET
   
    ; ;;; Draw variable tiles is good for drawing a "bar" or "meter"
    ; ;; Draws a "max value" with one particular tile id
    ; ;; and a variable level with another tile id.
   
    ; ;DrawVariableTiles x, y, full length, tile, fill amount, tile.
    ; ; changes are the "amount" will be a variable, like my health or my magic or something.
    ; DrawVariableTiles #$10, #$02, #$08, #$C0, #$04, #$D0
   
    ; ;;; Draw numbers is good for drawing the value of a variable.  For drawing static, should stll use draw tiles direct.
    ; ;;; DrawNumbers root variable, number of places.
    ; DrawNumbers #$02, #$04, myScore, #$04
   
       
    LDA gameHandler
    AND #%00100000
    BEQ doDrawHudUpdates
        JMP skipHudUpdates
    doDrawHudUpdates
    .include GameData\HUD_INCLUDES.dat
    skipHudUpdates:

Are you using the standard HUD settings ? I mean, do you set up the "HUD & boxes > Elements" and use the "UpdateHudElement" marcro in your code (like you should do)?
Or do you draw your HUD tiles directly like the lines I see in those comments (which is a really bad idea, because you would do that every frame and would cause glitches)
 
Are you using the standard HUD settings ? I mean, do you set up the "HUD & boxes > Elements" and use the "UpdateHudElement" marcro in your code (like you should do)?
Or do you draw your HUD tiles directly like the lines I see in those comments (which is a really bad idea, because you would do that every frame and would cause glitches)
Not sure, this is just the default HUD script. I didn’t make any changes to it. I do use UpdateHudElement in my hurt scripts whenever it increases the score or decreases lives
 
Top Bottom