[4.1.5] Sprite Cycling

User avatar
AllDarnDavey
Posts: 205
Joined: Sat Jan 12, 2019 6:16 am
Location: Seattle

[4.1.5] Sprite Cycling

Post by AllDarnDavey » Sun Mar 17, 2019 4:22 am

You may know that the NES can only display up to 8 sprites on a horizontal scanline. That's 8, 8x8 blocks, not 8 objects... so if enemies are just 2blocks wide after 4 in a row you get problems. Anything after the first 8 are just invisible and it isn't necessarily the first 8 left to right, it's the order they're drawn by the CPU.
Image

You probably remember the flicker many NES games had. This is caused by sprite cycling. The flicker is mildly annoying, but it's tonnes better then getting killed by enemies or projectiles you can't see. Basically, you still only see 8 sprites per scanline, but you cycle the sprites being turned off to a different one every frame.
Image

chronicleroflegends recently found and adjusted the code responsible for sprite draw order, and I used those changes as a base to add sprite cycling to it as well. I even borrowed the bit detecting the player to make it draw on top (to also keep the player from being part of the flicker cycle). It was actually a pretty small change to get it to work.

If you'd like to add Sprite Cycling to your NESmaker project.

Find the original UpdateDrawOrder section in HandleUpdateObjects.asm (around line 823, I also like to make a backup copy of the file first, just-in-case). Select the entire selection listed below:

Code: Select all

UpdateDrawOrder:
	
	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
Then replace with those lines with the new sprite cycling version.

Code: Select all

UpdateDrawOrder:
;;Now with sprite cycling	
	LDX #$1
OrderLoop:

	LDA drawOrder,x
	LDY drawOrder-1,x
	CPY player1_object ;; if previous is player object, don't swap them.
	BEQ doneWithSwapItem	
	LDA drawOrder,x
	STA drawOrder-1,x
	TYA
	STA drawOrder,x
doneWithSwapItem:
	INX
	CPX #TOTAL_MAX_OBJECTS
	BNE OrderLoop
	RTS
EDIT: was having issues with sprites of different heights, should be fixed.
EDIT2: removed unnecessary draw sorting.
Last edited by AllDarnDavey on Tue Mar 19, 2019 3:28 am, edited 3 times in total.
User avatar
Mugi
Posts: 826
Joined: Thu Dec 27, 2018 8:30 pm

Re: [4.1.5] Sprite Cycling

Post by Mugi » Sun Mar 17, 2019 5:48 am

that's pretty neat!
ways better than the whole deal with dissappearing monsters or half of them :P
"what are you up to?" "Oh, not much... just... Parallaxing"
- Raftronaut
User avatar
Bucket Mouse
Posts: 460
Joined: Wed Mar 07, 2018 2:25 am

Re: [4.1.5] Sprite Cycling

Post by Bucket Mouse » Sun Mar 17, 2019 6:40 am

AH! I've been waiting for this to get figured out! Thanks!
User avatar
dale_coop
Posts: 5752
Joined: Fri Feb 16, 2018 7:05 am
Location: France

Re: [4.1.5] Sprite Cycling

Post by dale_coop » Sun Mar 17, 2019 10:21 pm

Oh wow very useful thanks, AllDarnDavey, for sharing that code <3
-----
I know... my english is not perfect
All I need: A Damn Fine Cup of Coffee
My games: PRESS START GAME / UNDERGROUND ADVENTURE / UNDERGROUND ADVENTURE (Arcade version - Byte-Off-2019)
My son's game: KUBO 3
User avatar
chronicleroflegends
Posts: 198
Joined: Thu Sep 06, 2018 3:51 am

Re: [4.1.5] Sprite Cycling

Post by chronicleroflegends » Wed Mar 20, 2019 12:37 am

That's awesome!
Glad my draw order code got you started in the right direction. This could prove very useful.
~Do you believe in legends? ~
My Games: Nix: The Paradox Relic
User avatar
dark_crow_66
Posts: 135
Joined: Wed Apr 18, 2018 1:59 pm

Re: [4.1.5] Sprite Cycling

Post by dark_crow_66 » Thu Mar 21, 2019 4:16 am

What if I don't want the player to draw on top and I don't mind player being part of the flickering? How would I change the code. I have instances where my player goes behind sprites, such as behind bed sheets to sleep.
User avatar
SuperNatetendo
Posts: 83
Joined: Wed Aug 08, 2018 4:51 pm

Re: [4.1.5] Sprite Cycling

Post by SuperNatetendo » Fri Mar 22, 2019 12:27 am

Instant add to my project, no question.
User avatar
AllDarnDavey
Posts: 205
Joined: Sat Jan 12, 2019 6:16 am
Location: Seattle

Re: [4.1.5] Sprite Cycling

Post by AllDarnDavey » Fri Mar 22, 2019 2:45 am

dark_crow_66 wrote:
Thu Mar 21, 2019 4:16 am
What if I don't want the player to draw on top and I don't mind player being part of the flickering? How would I change the code. I have instances where my player goes behind sprites, such as behind bed sheets to sleep.
You can make the player part of the sprite cycle by just commenting out that bit of code that checks against the player.

Code: Select all

UpdateDrawOrder:
;;Now with sprite cycling	
	LDX #$1
OrderLoop:

	LDA drawOrder,x
	LDY drawOrder-1,x
	;CPY player1_object ;; if previous is player object, don't swap them.
	;BEQ doneWithSwapItem	
	;LDA drawOrder,x
	STA drawOrder-1,x
	TYA
	STA drawOrder,x
doneWithSwapItem:
	INX
	CPX #TOTAL_MAX_OBJECTS
	BNE OrderLoop
	RTS
Also, it doesn't affect the sorting with tiles, if you are using "walk behind" tiles (I use them all the time), they work just fine. I only affects sorting with other sprite objects. If your using walk behind tiles for bed sheets no change needed, if your sheets are actual sprite objects, you'd have to find a way to check against the sprite the bed sheet uses to exclude it instead.
User avatar
DanielT1985
Posts: 127
Joined: Sat Sep 01, 2018 7:44 pm

Re: [4.1.5] Sprite Cycling

Post by DanielT1985 » Sat Mar 23, 2019 12:12 am

This is awesome. I tested it in 4.1.0, and it works on that version as well. I think it actually made my game a little bit faster, with all of the entities on the screen, but I'm not sure. Either way, thanks for the code.
Last edited by DanielT1985 on Mon Mar 25, 2019 2:04 am, edited 1 time in total.
User avatar
Jacotomo
Posts: 48
Joined: Tue Sep 04, 2018 3:46 pm
Contact:

Re: [4.1.5] Sprite Cycling

Post by Jacotomo » Sat Mar 23, 2019 1:06 pm

Wow! This is very useful! Thanks a lot!
CAUTION!!!
May disappear without warning!
Post Reply