[4.5] Warping to Game over Screen compile error

offparkway

Active member
I'm using the code that JFranco posted for health and lives. It runs great, and I wanted to add the code to warp to a game over screen. I added the warp code, but now I get an error when compiling on line 21 (BEQ +skiphurt) saying it's out of range. What did I miss?


Code:
	;;;;;;;;;;;;;;;;;; Presumes there is a variable called myLives defined in user variables.
	;;;;;;;;;;;;;;;;;; You could also create your own variable for this.
	LDA gameHandler
	AND #%10000000
	BEQ +canHurtPlayer
		JMP +skipHurt
+canHurtPlayer:

PlaySound #sfx_damage

;;;;;;;;;;;;;;;;;;;;;
;;;; Player takes health damage - custom code
;;;;;;;;;;;;;;;;;;;;;

    LDX player1_object					; load player1 object into x
    TXA									; transfer x to accumulator
    STA temp							; store accumulator value into 'temp' variable
	GetActionStep temp					; run GetActionStep macro, 'temp' contains player1 object (aka "what is player 1's current Action state?")
	CMP #$07                    		; are we in ActionState #7 (aka: 'Hurt' mode). My hurt ActionState might be different than yours. adjust accordingly.
	BEQ +skipHurt						; yes? then exit this script
		
		ChangeActionStep temp, #$07   	; no? then change action state to 'hurt'
		LDA #$70						; I'm not sure why this is important -- i think it's the amount of time to stay hurt?
		STA Object_action_timer,x		; stay hurt for this amount of time
	
	
	DEC playerHealth            ;decrease player health by one
	
	UpdateHudElement #$07       ;update HUD -- myHealth is assigned to HUD element 7 in my game. it may be different in yours. adjust accordingly
	
	LDA playerHealth            ;load player health into accumulator
	BEQ +loseLife               ;if player health equals zero, lose a life
		JMP +skipHurt           ;else, exit this script

+loseLife:

;;;;;;;;;;;;;;;;;;;;;
;;;;; End of custom code
;;;;;;;;;;;;;;;;;;;;;

	
	
	Dec myLives
	LDA myLives
	BNE myLivesNotZero
		;;JMP RESET ;; game over.
        ;;;; also could warp to game over screen here instead.
WarpToScreen #$00, #GAME_OVER_SCREEN, #$01
	;;arg0 = warp to map. 0-map1. 1=map2.
	;;arg1 = screen to warp to.
	;;arg2 = screen transition type - usually use 1 here as 1=warp
JMP +skipHurt


myLivesNotZero:


;;;;;;;;;;;;;;;;;;;;;;;;;
;;; When Player begins new life, refresh health back to 9 - custom code
;;;;;;;;;;;;;;;;;;;;;;;;;

	LDA #$09					;load '9' into accumulator
	STA playerHealth			;update playerHealth to 9
	UpdateHudElement #$07       ;update HUD -- myHealth is assigned to HUD element 7 in my game. it may be different in yours. adjust accordingly

;;;;;;;;;;;;;;;;;;;;;;;;;
;;; End of custom code
;;;;;;;;;;;;;;;;;;;;;;;;;
 

mouse spirit

Well-known member
Probly means it's too far. A JMP goes so many lines i think. A BEQ BNE to blah:, i'm not sure. So most likely it means you tried to jump too far.
Also when you say BNE +blah, or JMP +blah, you should have a +blah: , that they jump to.

Example thing:

Code:
If "whatever"
JMP +super
RTS


+super:
"Now i am here instead of the "RTS" line."

Try putting +skipHurt: in a good spot. Or try changing JMP +skipHurt to +skipHurt
 

offparkway

Active member
I love the sarcastic approach! As a non-coder, I'm trying to follow it. It sounds like what I thought it could be, but I don't know enough to follow it. Also, I still don't know (really) what BNE or BEQ even means. It's glossed-over in the tutorials. At this point, I'm just following visual patterns.

So I agree that it's probably a matter of putting +skipHurt in the right location, but I have no idea where that might be. I'll try removing the JMP, although I thought JMP meant "skip to something, regardless of how many lines of code" (didn't know there was a "too far").

You said "try putting +skipHurt in a good spot"... I have no clue what "a good spot" means. lol. Where is "a good spot"?

My confusion comes from the fact that 1 section of code works just fine, and the 2nd code works just fine. But when I transplant a piece of code to another, it breaks... and logically I can't figure out why. Again, it's probably as simple as not closing a phrase or something, All I tried to do was replace "JMP Reset" with "WarpToScreen…"

**edit: removing one JMP let the game compile correctly, but every hit took away a life (rather than health). So I DID see the game over screen that I wanted to see, but it negated everything I was trying to accomplish. Removing the next JMP just made the game reset the screen every time I get hit, with no impact on health or lives.

--edit 2: adding +skipHurt in various places produces various results. Most of the time, the game will compile and run (yay) but it screws up everything I'm trying to do.
 

offparkway

Active member
To try to clarify, this section of code worked well for me already:

Dec myLives
LDA myLives
BNE myLivesNotZero
;;JMP RESET ;; game over.
;;;; also could warp to game over screen here instead.
WarpToScreen #$00, #GAME_OVER_SCREEN, #$01
;;arg0 = warp to map. 0-map1. 1=map2.
;;arg1 = screen to warp to.
;;arg2 = screen transition type - usually use 1 here as 1=warp
JMP +skipHurt

But when I added it to a more complex script, in the place that it seemed like it should go, the code broke. Clearly a disconnect somewhere.
 

mouse spirit

Well-known member
Ha My bad dude,i was pretty vague. If somethig is ; that means its just a comment. When you see alot of green text in code,thats a comment. So when its saying arg0, that means you actually put an argument there. BNE means not equal BEQ means equal.
Only jmp to +skiphurt,if you are skipping getting hurt and put +skiphurt: directly afterthe code that say, you get hurt. I believe you are skipping other things .

Edit: So what is the original script? And what were all the "+skipHurt"'s before "+skiphurt" ?

Possibly start fresh and only do the health and life thus far. And dont put any extra jmps in there yet.

Check line 32 also line 47 here. also starting at line 58 i believe this code is running all the time,not just when you want it to. Like refreshing to 9 health always?
Lastly in all those places where the comment says ;; exit script? Maybe that line should say RTS? Or atleast jmp to the very end of the script.
I added comments on the lines i mentioned,i hope this helps at all. I am not versed in 4.5.1 but i should be right on most of these accounts.

This is all asuming that your variables are set up correctly.Maybe rewatch the vids and slow Joe down.

Code:
	;;;;;;;;;;;;;;;;;; Presumes there is a variable called myLives defined in user variables.
	;;;;;;;;;;;;;;;;;; You could also create your own variable for this.
	LDA gameHandler
	AND #%10000000
	BEQ +canHurtPlayer ;;;goes to will hurt you
		JMP +skipHurt;; goes to will not hurt you
+canHurtPlayer:;; here is where now it will hurt you below

PlaySound #sfx_damage

;;;;;;;;;;;;;;;;;;;;;
;;;; Player takes health damage - custom code
;;;;;;;;;;;;;;;;;;;;;

    LDX player1_object					; load player1 object into x
    TXA									; transfer x to accumulator
    STA temp							; store accumulator value into 'temp' variable
	GetActionStep temp					; run GetActionStep macro, 'temp' contains player1 object (aka "what is player 1's current Action state?")
	CMP #$07                    		; are we in ActionState #7 (aka: 'Hurt' mode). My hurt ActionState might be different than yours. adjust accordingly.
	BEQ +skipHurt						; yes? then exit this script
		
		ChangeActionStep temp, #$07   	; no? then change action state to 'hurt'
		LDA #$70						; I'm not sure why this is important -- i think it's the amount of time to stay hurt?
		STA Object_action_timer,x		; stay hurt for this amount of time
	
	
	DEC playerHealth            ;decrease player health by one
	
	UpdateHudElement #$07       ;update HUD -- myHealth is assigned to HUD element 7 in my game. it may be different in yours. adjust accordingly
	
	LDA playerHealth       	    ;load player health into accumulator
   ;;;Like here<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  RIGHT HERE it looks like you are missing a CMP, to 
	BEQ +loseLife               ;if player health equals zero, lose a life      <<<<<<<<<<<<<<<<compare Health after LDA "loading" it
		
		JMP +skipHurt           ;else, exit this script                           

+loseLife:

;;;;;;;;;;;;;;;;;;;;;
;;;;; End of custom code
;;;;;;;;;;;;;;;;;;;;;

	
	
	Dec myLives
	LDA myLives
	;;I think also here should be something like a CMP, to compare against 0 lives
	BNE myLivesNotZero
		;;JMP RESET ;; game over.
        ;;;; also could warp to game over screen here instead.
WarpToScreen #$00, #GAME_OVER_SCREEN, #$01
	;;arg0 = warp to map. 0-map1. 1=map2.
	;;arg1 = screen to warp to.
	;;arg2 = screen transition type - usually use 1 here as 1=warp


JMP +skipHurt   ;;this is wrong, probly should be +skipHurt:<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
myLivesNotZero:


;;;;;;;;;;;;;;;;;;;;;;;;;
;;; When Player begins new life, refresh health back to 9 - custom code
;;;;;;;;;;;;;;;;;;;;;;;;;

	LDA #$09					;load '9' into accumulator
	STA playerHealth			;update playerHealth to 9
	UpdateHudElement #$07       ;update HUD -- myHealth is assigned to HUD element 7 in my game. it may be different in yours. adjust accordingly

;;;;;;;;;;;;;;;;;;;;;;;;;
;;; End of custom code
;;;;;;;;;;;;;;;;;;;;;;;;;

Take this code below for example: you load player object,save player in temp,ask whats in temp"player", and then is it in action state 7?, if true, go to +skiphurt:
If untrue, continue to the next line of code.
Soooo Load up, save into temp(4.5),ask what you want to know and compare, then compare it, then say ok do this or that.
That is what this part of code is saying, so use this for a reference.

Code:
LDX player1_object					; load player1 object into x
    TXA									; transfer x to accumulator
    STA temp							; store accumulator value into 'temp' variable
	GetActionStep temp					; run GetActionStep macro, 'temp' contains player1 object (aka "what is player 1's current Action state?")
	CMP #$07                    		; are we in ActionState #7 (aka: 'Hurt' mode). My hurt ActionState might be different than yours. adjust accordingly.
	BEQ +skipHurt
 

offparkway

Active member
This does help explain some things in general, thanks!

What I posted is the original script that runs lives and health (works), but I commented out the JMP Reset and added the WarpToScreen line (which worked in another script I was using). But when I added the WarpToScreen line to this script, the code breaks... and I get a line 21 out of range error. That's my issue.

I’ll try some of your suggestions, but what confuses me is that the code worked fine without the CMPs you suggested. Health and lives operated as they should. All I’m trying to do with this code is warp to a game over screen when myLives = 0. That’s it. I figured that would be a simple thing to do.

I had a working script for that, which I just copy/pasted into this one (replacing JMP Reset) and it wont compile. So I’m not following why I’d need more CMPs when they weren’t needed before.

If I remove the WarpToScreen line, and un-comment the JMP Reset, the code runs just fine. So why does it break when I use WarpToScreen?

(and BEQ +skipHurt is where the compiler says I have an error... line 21)

EDIT: I removed the "JMP" that you said was wrong, and the game DOES run. But none of the code does anything. If I get hit by an enemy, all health and lives are ignored, and the screen just restarts. I'm confused, because in my original code the "JMP" is included, and that code runs fine.
 

offparkway

Active member
Also, I apologize... the end of the code didn't copy over apparently. Here's the full thing:

Code:
	;;;;;;;;;;;;;;;;;; Presumes there is a variable called myLives defined in user variables.
	;;;;;;;;;;;;;;;;;; You could also create your own variable for this.
	LDA gameHandler
	AND #%10000000
	BEQ +canHurtPlayer
		JMP +skipHurt
+canHurtPlayer:

PlaySound #sfx_damage

;;;;;;;;;;;;;;;;;;;;;
;;;; Player takes health damage - custom code
;;;;;;;;;;;;;;;;;;;;;

    LDX player1_object					; load player1 object into x
    TXA									; transfer x to accumulator
    STA temp							; store accumulator value into 'temp' variable
	GetActionStep temp					; run GetActionStep macro, 'temp' contains player1 object (aka "what is player 1's current Action state?")
	CMP #$07                    		; are we in ActionState #7 (aka: 'Hurt' mode). My hurt ActionState might be different than yours. adjust accordingly.
	BEQ +skipHurt						; yes? then exit this script
		
		ChangeActionStep temp, #$07   	; no? then change action state to 'hurt'
		LDA #$70						; I'm not sure why this is important -- i think it's the amount of time to stay hurt?
		STA Object_action_timer,x		; stay hurt for this amount of time
	
	
	DEC playerHealth            ;decrease player health by one
	
	UpdateHudElement #$07       ;update HUD -- myHealth is assigned to HUD element 7 in my game. it may be different in yours. adjust accordingly
	
	LDA playerHealth            ;load player health into accumulator

	BEQ +loseLife               ;if player health equals zero, lose a life
		JMP +skipHurt           ;else, exit this script

+loseLife:

;;;;;;;;;;;;;;;;;;;;;
;;;;; End of custom code
;;;;;;;;;;;;;;;;;;;;;

	
	
	Dec myLives
	LDA myLives
	BNE myLivesNotZero
		;;JMP RESET ;; game over.
        ;;;; also could warp to game over screen here instead.
WarpToScreen #$00, #GAME_OVER_SCREEN, #$01
	;;arg0 = warp to map. 0-map1. 1=map2.
	;;arg1 = screen to warp to.
	;;arg2 = screen transition type - usually use 1 here as 1=warp
JMP +skipHurt


myLivesNotZero:


;;;;;;;;;;;;;;;;;;;;;;;;;
;;; When Player begins new life, refresh health back to 9 - custom code
;;;;;;;;;;;;;;;;;;;;;;;;;

	LDA #$09					;load '9' into accumulator
	STA playerHealth			;update playerHealth to 9
	UpdateHudElement #$07       ;update HUD -- myHealth is assigned to HUD element 7 in my game. it may be different in yours. adjust accordingly



;;;;;;;;;;;;;;;;;;;;;;;;;
;;; End of custom code
;;;;;;;;;;;;;;;;;;;;;;;;;

	LDA continueMap
	STA warpMap
	
	LDA continueScreen
	STA currentNametable
	
	LDX player1_object
	STA Object_screen,x
	
	LDA #$02 ;; this is continue type warp.
	STA screenTransitionType ;; is of warp type

	
	LDA gameHandler
	ORA #%10000000
	STA gameHandler ;; this will set the next game loop to update the screen.

+skipHurt
 

chronosv2

New member
A simple solution for any 'Branch out of Range' errors:
Branch out of Range does indeed mean that the processor is having to jump too far to the label you're jumping to.
The easiest way to fix this is to reverse the condition, add a new label to branch to and do a JMP instead for the big jump.

So in this case...
Code:
	CMP #$07                    		; are we in ActionState #7 (aka: 'Hurt' mode). My hurt ActionState might be different than yours. adjust accordingly.
	BEQ +skipHurt						; yes? then exit this script

		
		ChangeActionStep temp, #$07   	; no? then change action state to 'hurt'
		LDA #$70						; I'm not sure why this is important -- i think it's the amount of time to stay hurt?
;; ...
;; The code leading up to +skipHurt is more then +127 bytes away, thus the error we get.
Would become
Code:
    CMP #$07                    		; are we in ActionState #7 (aka: 'Hurt' mode). My hurt ActionState might be different than yours. adjust accordingly.
    BNE +doHurt                         ; Before this change, +skipHurt was more than 127 bytes away, causing a branch out of range error. Now the branch is a 3-byte jump.
    JMP +skipHurt                       ; JMP goes to a memory address directly, so we don't have the -128 to 127 byte branch limitation.
+doHurt:
	
		ChangeActionStep temp, #$07   	; no? then change action state to 'hurt'
		LDA #$70						; I'm not sure why this is important -- i think it's the amount of time to stay hurt?
;; ...
;; Since we're doing a JMP, so long as the code is in the same bank (it is) we can do it.

Hopefully this proves to be useful!
 

offparkway

Active member
hey I think we're in business! Game compiles, and it looks like lives and health operate they way I want them to. And it goes to a game over screen!

The game over screen shows a random letter G near the top for some reason, which isn't supposed to be there, but it's mostly working lol.

Thank you both for the help. If you have any idea why a random G might be showing up all of a sudden, feel free to toss me ideas!
 

offparkway

Active member
It's in the HUD area. I'm using a combination of text and graphics in the HUD, so maybe I screwed something up doing that. The screen is set to hide the HUD though, so I dunno.

Now if only someone can help me with getting a specific monster to drop a key when destroyed (or unlocking a lock block when destroyed) I'll be on my way!
 

offparkway

Active member
oh, spoke too soon. I tried starting the game from the beginning and the main screen (after the start screen) shows all black with no sprites or graphics. just the first screen.
 

mouse spirit

Well-known member
Yup thats out of my reach.Maybe watch the vids again.I know this sounds redundant, but the more we try stuff and mess up, then the more we rewatch those vids, the better we understand each time we watch.
Im including us all in this to make it sound awesome. I was frustrated at myself, joe and his non existent secretary, at nesmaker. But i am at a point now where i am many times better than when i started. And i just messed up a bunch, rewatched a bunch, and i feel i did ask a bunch. Which i bet gets old. So now i am trying to help a bunch. But we all have been there.
Even watch the other vids that dont apply to 4.5.
And go ahead and look through the forum where people have probly had questions that you have right now.Like the post are all breadcrumbs to follow so we dont have to struggle through many mistakes and you'll see dale_coop's name alot(always read his suggestions) among other nice people here.
Granted, i have alot of time and will to make an nes game. But nesmaker has helped make this so much easier, after understanding all the quirks and limitations including my own, and rewatching alot because those vids are most of the only "documentation" you will find about nesmaker from the official creator. Meaning he is the gatekeeper to the way it works. Although people are knowledgable about it now. Joe truly knows whats up, so dont take any of those videos for granted.( im not saying other wonderful people are not involved, thank you to all involved)
 

chronosv2

New member
Glad the branch fix helped solve your issue!

As for the random "G," I'm not quite sure why that would be happening.
The only suggestion I can make is to double-check your game over screen for any accidental tiles.

Edit: Oh heck. Missed a lot of new posts.
I'm not so sure about the other problems offhand, as I haven't gotten around to completing all the tutorials myself. The Branch out of range issue is 6502 specific rather than NESMaker, so I knew the answer for that one.
 

dale_coop

Moderator
Staff member
About the random "G" issue, could it be your HUD? Have you tried to set the "hide hud" screen flag on your game over screen?
 

offparkway

Active member
Hey Dale,

Yes I chose to hide the HUD on all my special screens (the box is checked). Looking at my screen on the overworld, the game over screen looks as it should. But when the game is running, the "G" shows up in the HUD area. I'm using both huds... I added a sprite based hud to show hearts along with the text.

The two issues I'm having are 1) the G that shows up, and 2) I can't seem to hide the hearts from the sprite based hud. they show up on all screens, even the start screen.

Do we need a new code/screen flag that hides a sprite based hud?
 

dale_coop

Moderator
Staff member
You should use the code I made... AND uncheck the "hide hud" on all your normal screens... use the "hide hud" screen flag only for your special screens (game over, cutscene, ...)
Because yes, your "G" is the hud that is showing, because you need a flag on your screens to say if you want or not the sprite hud, on them.
 
Top Bottom