Hello, I'm having trouble with timed events that rely on a RAM address for it's timer. Specifically, I'm trying to get a sprite to copy the behavior of the popular Hammer Bro sprite, where it displays it's hammer for a brief moment before actually throwing it. After much deliberation, I came to my final dead end and realized that no matter how much recoding I did, the only revision of my sprite that worked anymore was before I started all this to begin with.
In my latest revision, I'm using $1570 as my timer (!HammerTimer) and decrementing it manually, and $1534 for the flag (!ThrowCheck) that checks if it should display the sprite. Neither of these addresses are used elsewhere in the sprite as far as I'm concerned and I'm indexing them both by x as they should be. But for some reason, much of the sprite code somehow goes ignore upon spawning, including collision with Mario, until the sprite goes off screen and then comes back on, in which case it works fine until it's destroyed, at which point the game hangs.
This is the code I use to decrement the timer and set the flag (where ... is where other timer decrementing code is that's short but irrelevant):
This is where the timer is used to determine when to throw a hammer (where ThrowHammer is a label for some basic spawn extended sprite code):
And this is the graphics routine, which I more or less lifted from mikeyk's Hammer Bro, though I looked through each command and understood it, and it even works correctly, so I can't believe it's really the problem:
I also had an earlier revision where I didn't use a ThrowCheck flag, and instead just used this code at the beginning of the graphics routine:
This worked better then the later revision where I used a check flag, but it was just outright refusing to branch; the hammer tile would just always display regardless of the state of the timer (which led me to believe that BCC and BCS aren't as simple as tutorials would lead you to believe)
I have no clue what's wrong, and I would really appreciate any help given for this. I've looked through mikeyk's code on multiple occasions but I don't seem to understand what I'm doing wrong. Thanks in advance.
In my latest revision, I'm using $1570 as my timer (!HammerTimer) and decrementing it manually, and $1534 for the flag (!ThrowCheck) that checks if it should display the sprite. Neither of these addresses are used elsewhere in the sprite as far as I'm concerned and I'm indexing them both by x as they should be. But for some reason, much of the sprite code somehow goes ignore upon spawning, including collision with Mario, until the sprite goes off screen and then comes back on, in which case it works fine until it's destroyed, at which point the game hangs.
This is the code I use to decrement the timer and set the flag (where ... is where other timer decrementing code is that's short but irrelevant):
Code
LDA !HammerTimer,x BEQ + DEC !HammerTimer,x + ... LDA !HammerTimer,x CMP #$10 BNE DontSetHammer LDA #$01 STA !ThrowCheck,x DontSetHammer: RTS
This is where the timer is used to determine when to throw a hammer (where ThrowHammer is a label for some basic spawn extended sprite code):
Code
LDA !HammerTimer,x CMP #$00 BEQ GetHammer RTS GetHammer: LDA #$38 STA !HammerTimer,x STZ !ThrowCheck,x JMP ThrowHammer
And this is the graphics routine, which I more or less lifted from mikeyk's Hammer Bro, though I looked through each command and understood it, and it even works correctly, so I can't believe it's really the problem:
Code
HAMMER_OFFSET: db $F6,$0A LDA !Flash,x CMP #$00 BNE NO_SHOW LDA !ThrowCheck,x CMP #$01 BNE NO_SHOW PHX LDA $00 LDX $02 CLC ADC HAMMER_OFFSET,x STA $0300,y LDA $01 ; \ tile y position = sprite y location ($01) + tile displacement CLC ; | ADC #$F2 STA $0301,y ; / LDA #$6D ; \ store tile STA $0302,y ; / PHX TYA ; \ get index to sprite property map ($460)... LSR A ; | ...we use the sprite OAM index... LSR A ; | ...and divide by 4 because a 16x16 tile is 4 8x8 tiles TAX ; | LDA #$02 STA $0460,x ; / PLX LDA #$07 CPX #$00 BNE NO_FLIP_HAMMER ORA #$40 NO_FLIP_HAMMER: ORA $64 ; | put in level properties STA $0303,y ; / store tile properties PLX INY ; | increase index to sprite tile map ($300)... INY ; | ...we wrote 1 16x16 tile... INY ; | ...sprite OAM is 8x8... INY ; | ...so increment 4 times LDY #$02 LDA #$04 JSL $01B7B3 RTS NO_SHOW: LDY #$02 ; \ 02, because we didn't write to 460 yet LDA #$03 ; | A = number of tiles drawn - 1 JSL $01B7B3 ; / don't draw if offscreen RTS ; return
I also had an earlier revision where I didn't use a ThrowCheck flag, and instead just used this code at the beginning of the graphics routine:
Code
LDA !HammerTimer,x CMP #$02 BCC NO_SHOW CMP #$10 BCS NO_SHOW
This worked better then the later revision where I used a check flag, but it was just outright refusing to branch; the hammer tile would just always display regardless of the state of the timer (which led me to believe that BCC and BCS aren't as simple as tutorials would lead you to believe)
I have no clue what's wrong, and I would really appreciate any help given for this. I've looked through mikeyk's code on multiple occasions but I don't seem to understand what I'm doing wrong. Thanks in advance.