Metasprite position offsets in regards to player x and y?

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Metasprite position offsets in regards to player x and y

Post by Kasumi »

The offscreen check for bne would work either way, yes, but there are two high bytes involved.

To add 8bit $FF as a signed number to a 16bit number, I need to create a high byte of $FF.
To add 8bit $00 as a signed number to a 16bit number, I need to create a high byte of $00.

So instead of

Code: Select all

   lda (reserved4),y;X Position
   clc
   adc tempLo
   sta OAM+3,x
   
   lda tempHi
   adc #$00
   bne spriteOffscreen
you'd have to do:

Code: Select all

   lda (reserved4),y;X Position
   clc
   bpl positivehighbyte;If the number is positive, 0 is needed to make the result correct
;If the number is negative, FF is needed to make the result correct.
   adc tempLo
   sta OAM+3,x
   
   lda tempHi
   adc #$FF
   bne spriteOffscreen
   beq nextsprite
positivehighbyte:
   adc tempLo
   sta OAM+3,x
   
   lda tempHi
   adc #$00
   bne spriteOffscreen
nextsprite:
if you didn't know beforehand that all adds were unsigned. It's not much slower, but it could be run 128 times in a single frame. (For both X and Y, for 64 sprites.) It's also bigger, so less unroll friendly.
Edit:
But wouldn't it suffice to assume that while on-screen, the high byte is 0?
Not always. Imagine a sprite partially offscreen on the left. The leftmost sprites will be offscreen and have a high byte of $FF, the rightmost sprites will be onscreen with a high byte of $00.
Edit2: Like this:
Image
Edit3: To express that slightly better, the main position of the metasprite can have a high byte of $FF and still be partially on screen. But yes, each individual sprite that is on screen will have a high byte of $00.

Another optimization is verifying the all sprites in the metasprite will on onscreen using the maxoffsets I mentioned before drawing, and then your sprite draw code is just this:

Code: Select all

	lda (reserved4),y;X Position
	clc
	adc tempLo
	sta OAM+3,x
Having a subroutine for both totally on screen and partially on screen things is a good idea.
Last edited by Kasumi on Wed Feb 21, 2018 5:23 pm, edited 1 time in total.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Metasprite position offsets in regards to player x and y

Post by tokumaru »

FrankenGraphics wrote:The 2600 example made perfect sense! :beer: :D
The 2600 isn't the most intuitive machine when it comes to video generation, but I figured I'd make the analogy anyway.
But wouldn't it suffice to assume that while on-screen, the high byte is 0?
The high byte of the final value will be 0 if the sprite is on-screen, yeah, but I was talking about the high byte of the offset that you add to the reference point in order to find that final value. If you use 2's complement for offsets, you'll have to waste time checking whether to use $00 or $ff as the high byte, twice for each sprite, so up to 128 times per frame, like Kasumi said. With excess-128 you just use 0 every time and avoid all this logic.

EDIT: I may have expressed myself poorly when I said that the excess-128 things makes off-screen checks faster, while it actually speeds up the addition of X and Y offsets. The off-screen part is still the same either way, if the high byte of the final result is != 0, the sprite is off-screen.
CrowleyBluegrass
Posts: 42
Joined: Sun Jun 30, 2013 7:59 am

Re: Metasprite position offsets in regards to player x and y

Post by CrowleyBluegrass »

Thank you very much for the replies! Things are becoming clearer. After digesting this information a few times and tweaking my own code some more, I think I may finally get this! :)

But first, obligatory noob questions I'm afraid. I'm also afraid both are aimed at you dougeff, forgive me!
How is this > operator used in regards to the pointer and temp variables? Being that the asm6 readme says they give the lower byte of a 16-bit word, I really hope asking this is going to blow my "now I understand LOW and HIGH and .dl and .dh" achievement completely out of the water...

The other question is, why 8 entries per metasprite? I thought there'd just be 4. Or are your metasprites of a different size arrangement?

Thanks again to all of you, I will get there eventually I am determined that your help will not be in vain! :)
User avatar
dougeff
Posts: 3078
Joined: Fri May 08, 2015 7:17 pm

Re: Metasprite position offsets in regards to player x and y

Post by dougeff »

How is this > operator used in regards to the pointer and temp variables
This is mostly a copy of Shiru's code. I don't know why he used < on an 8 bit (zero page) address. (to enforce an 8 bit value ?) The assembler should do that for you. NESASM doesn't always, but asm6 should.

And, yes. Sprite data is 4 bytes per sprite.

Maybe you're confused because I copied a metasprite with 8 sprites.
nesdoug.com -- blog/tutorial on programming for the NES
Post Reply