[4.1.5] Sprite Cycling

AllDarnDavey

Active member
WillElm said:
At some point this modification stopped working for me. The only other modification that I made to this script was the "make bosses not reset on hurt" trick from this thread: http://www.nesmakers.com/viewtopic.php?f=40&t=2298&p=14039&hilit=timer#p14039

Any idea why this could be?

Hmm... I haven't used both these modifications together myself, but it doesn't look like they should conflict with each other, they are changing different areas of the file. It is possible though, there's weirdness like you can only jump so many lines, so adding changes might break a branch that used to work fine. It's hard to say.

Have you tried reaching out to chronicleroflegends? There's a chance they are using both modifications together and so might have a working version.
 

WillElm

New member
After putting it aside and working on other parts of my project, I remembered something really important. At one point I had disabled draw order, but had since reenabled it. However, I forgot to uncomment JSR UpdateDrawOrder at the beginning of the script. Uncommenting it fixed the sprite cycling code.
 

retrothunder

New member
Routines\Basic\ModuleScripts\HurtWinLoseDeath\HandleHurtMonster.asm(78): Unknown label.
Routines\Basic\\MainASM.asm(424): Unknown label.
Routines\Basic\\System\HandleUpdateObjects.asm(344): Unknown label.
demo.txt written.

IDK what I did wrong I removed and then replace the code
 

Attachments

  • NesM.png
    NesM.png
    151.8 KB · Views: 2,168
Check line 78 from your Routines\Basic\ModuleScripts\HurtWinLoseDeath\HandleHurtMonster.asm & line 424 from Routines\Basic\\MainASM.asm & line 344 from Routines\Basic\\System\HandleUpdateObjects.asm. It says they all have ''unknown label''. on those lines, they probably all use a constant or variable or something, and that component has an issue. it will help to know what that unknown label refers to.

in your second screenshot, that's a message that will appear when your game can't compile. it can't create the .nes file of your game, because of the previously mentionned issue.
 

AllDarnDavey

Active member
retrothunder said:
Routines\Basic\ModuleScripts\HurtWinLoseDeath\HandleHurtMonster.asm(78): Unknown label.
Routines\Basic\\MainASM.asm(424): Unknown label.
Routines\Basic\\System\HandleUpdateObjects.asm(344): Unknown label.
demo.txt written.

IDK what I did wrong I removed and then replace the code
First thing I would do is go back to your original copy (you did backup the original I hope), see if it builds then. Just to make sure it isn't some other change you made.

I've gotten this error before when I'm trying to jump to a branch but made a typo and it can't find it (or I have more then one label named the same). A label is the first part of a code block that ends in a colon.
Code:
UpdateDrawOrder:
or
Code:
doneWithSwapItem:
when you have a branch statement like
Code:
BEQ doneWithSwapItem
You're telling it to jump to that label if certain conditions are met. Now I've found out the hard way that you can only jump so many lines of code (up or down) during a branch. I once added just a few lines of code to another file and it stopped working because it suddenly couldn't find the label to branch anymore, and I had to reorder a bunch of code blocks to make it work again.

It could be something as simple as you have too many empty lines of code and now you cannot branch. Maybe try removing some of those empty lines you have. Also looking at your code compared to mine it looks like you might have accidentally removed too much. I have a whole
Code:
HandleScroll:
block you appear to be missing. Unless you rearranged things more then just adding in sprite cycling.

MissingCodeBlock.PNG
 

AllDarnDavey

Active member
Elarath said:
Bit 5 of $2002 is labeled as sprite overflow. It is flagged when there are more than 8 sprites per scanline, though the wiki states that it is buggy. I haven't tested, but do you think it would be possible to use this in conjunction to your sprite cycling code, so that the cycling only occurs when needed?

https://wiki.nesdev.com/w/index.php/PPU_registers#Controller_.28.242000.29_.3E_write

Hmm... interesting. Seems like it would be possible to query that register value and branch out early if overflow isn't triggered. I'm a little worried it gives false positives and false negatives but that might not occur often enough to be a big of a deal. I'm not sure it would gain a whole lot though. Sprites now only flicker when they're more then 8 per line. The only thing this would affect would be overlapping sprites altering which draws in front even when they don't need to cycle. The early branch would save a bit of processing too when cycling isn't needed, but the savings is probably negligible. Looking at the list of games that use sprite overflow on purpose to hide sprites when underwater, cheat going downstairs, or even do some cheeky scanline splitting, I wonder if anyone of them use any tricks to determine when to use sprite cycling and when to not.
 

vanderblade

Active member
Is there a way to activate the sprite flicker ONLY when four or more sprites appear on the same horizontal row? For me, this change causes the enemy sprites to constantly flicker regardless of how many or position.
 

AllDarnDavey

Active member
vanderblade said:
Is there a way to activate the sprite flicker ONLY when four or more sprites appear on the same horizontal row? For me, this change causes the enemy sprites to constantly flicker regardless of how many or position.

Huh... that's strange. The code doesn't actually turn drawing of sprites on or off at all. It just cycles the sprite order each frame so that IF you go over the 8 sprite per line limit then the sprites the hardware doesn't draw change every frame. If you don't have more than 8 frames in a horizontal line, you shouldn't see any change.

The only possible things I can think of that could cause your issue (provided the code is copied correctly) are: two overlapping sprites will swap which draws in front even if you are not over the limit (could cause issues with sprite layering, not really flicker, but has a similar look). Another possibility is if you're butting up against the hard limit of 64 max sprites. Besides the 8 sprites per line limit, the NES also has a total limit of 64 sprites, if you're game has so many sprites that you're hitting that limit, the cycling would still switch out which objects are turned off per frame, but the flickering would probably appear more random. Also note it's sprites, not objects. An enemy that is 2x2 eight-by-eight blocks is 4 sprites even know it is only 1 object.

Also, this was written for NesMaker 4.1.5, I have not tested or tried to port this to NesMaker 4.5 at all yet, so if you're trying to use this with the newest version of NesMaker I have no idea what it will do.
 

vanderblade

Active member
I've had better luck with Dale's version, but it has its own bugs in my game (some enemy's only appear after I fire my projectile). It doesn't matter much, since we're all moving on to 4.5. Just thought I'd share in case anybody else had a similar issue.

Code:
UpdateDrawOrder:
	;JMP DoNormalDrawOrder	;; to use the normal draw order
	JMP DoFlickeringDrawOrder	;; to use the one giving priority to the player
	
DoFlickeringDrawOrder:
	;Now with sprite cycling
	LDX #$1
OrderLoopFlickering:

	LDY drawOrder,x
	LDA Object_y_hi,y
	STA temp
	;;;; what would drawOrder-1 be?  if it is 0, would would have to become 0f.
	LDY drawOrder-1,x

	LDA Object_flags,y
	AND #%00000110		;; if it's a player or player weapon
	BNE doneWithSwapItemFlickering	;; we skip it

	;LDA Object_y_hi,y
	CMP temp
	BCS doneWithSwapItemFlickering
	LDA drawOrder,x
	STA drawOrder-1,x
	TYA
	STA drawOrder,x
doneWithSwapItemFlickering:
	INX
	CPX #TOTAL_MAX_OBJECTS
	BNE OrderLoopFlickering
	RTS

DoNormalDrawOrder:
	LDX #$1
OrderLoop:

	LDY drawOrder,x
	LDA Object_y_hi,y
	STA temp
	;;;; what would drawOrder-1 be?  if it is 0, would would have to become 0f.
	LDY drawOrder-1,x
	LDA Object_y_hi,y
	CMP temp
	BCS doneWithSwapItem
	LDA drawOrder,x
	STA drawOrder-1,x
	TYA
	STA drawOrder,x
doneWithSwapItem:
	INX
	CPX #TOTAL_MAX_OBJECTS
	BNE OrderLoop

	RTS
 

AllDarnDavey

Active member
I wasn't aware Dale had a different version of sprite cycling. Did he post it to facebook or discord rather then the forums (I'm rarely on discord, and I'm almost never on facebook)?

Dale definitively has more experience with 6502 assembly, and NesMaker in general then I do, so I'd be interested if he had a more elegant solution then the one I cobbled together. I'm also curious how some classic games handle it. I know MegaMan for example uses sprite layering for MegaMan's face, so they must've done a version that doesn't break sprite layering.
 

Levty87

New member
Hi everybody, I'm new to this all. Also I have no experience with 6502 assenbly but I have a little bit in programming. I need sprite cycling for my platform/metrovania game and came across this thread. I believe I have a newer version of nesmaker (NESmaker_4_5_9) and it seams that the script that you were supposed to edit (HandleUpdateObjects.asm) to get this effect doesn't exist in this newer version. So what is the best way to get this to work? I noticed that in the advanced brawler tutorial on thenew8bitheroes-site Joe edits doHandleObjects.asm with the exact same piece of code AllDarnDavey says you have to swap for the sprite cycling version. Is that something that could work or do I have to find another method? :)
 

dale_coop

Moderator
Staff member
Hi everybody, I'm new to this all. Also I have no experience with 6502 assenbly but I have a little bit in programming. I need sprite cycling for my platform/metrovania game and came across this thread. I believe I have a newer version of nesmaker (NESmaker_4_5_9) and it seams that the script that you were supposed to edit (HandleUpdateObjects.asm) to get this effect doesn't exist in this newer version. So what is the best way to get this to work? I noticed that in the advanced brawler tutorial on thenew8bitheroes-site Joe edits doHandleObjects.asm with the exact same piece of code AllDarnDavey says you have to swap for the sprite cycling version. Is that something that could work or do I have to find another method? :)

Check this topic (that is compatible with the 4.5.9):
 
Top Bottom