It is currently Tue Feb 19, 2019 3:31 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 10 posts ] 
Author Message
 Post subject: Mirroring sprites
PostPosted: Sat Nov 23, 2013 5:43 pm 
Offline

Joined: Sat Nov 23, 2013 4:23 pm
Posts: 10
Location: Papillion, Nebraska
Hello. As you can see I am new here. I have a little experience with programming on NES. I have been able to get an animated sprite on the screen that can move and jump using controller input; the basic stuff you all understand. One thing I was wondering how todo is flip the sprite when I press left (the sprites I created are oriented to the right) without having to make a completely new sprite and - as a result - waste graphic space.


Top
 Profile  
 
 Post subject: Re: Mirroring sprites
PostPosted: Sat Nov 23, 2013 5:50 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8141
Location: Seattle
When you upload your sprites to the NES's sprite control memory, one of the bits in the same byte that controls which set of colors are used will flip each 8x8 or 8x16 sprite.

See http://wiki.nesdev.com/w/index.php/OAM


Top
 Profile  
 
 Post subject: Re: Mirroring sprites
PostPosted: Sat Nov 23, 2013 6:05 pm 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11166
Location: Rio de Janeiro - Brazil
If your character is wider than 8 pixels, you'll have to worry about more than just the flip bits in the attribute byte though. Typically games make use of meta-sprites (group of hardware sprites that form a larger object), and the meta-sprite system is responsible for reading the sprite definitions and rendering them to OAM taking into consideration the object's position and direction.

Some people would rather avoid the complexity (and slowness) of a routine that automatically flips sprites and define redundant meta-sprites for all directions a character/object can face.


Top
 Profile  
 
 Post subject: Re: Mirroring sprites
PostPosted: Sat Nov 23, 2013 6:56 pm 
Offline

Joined: Sat Nov 23, 2013 4:23 pm
Posts: 10
Location: Papillion, Nebraska
My sprite takes up 16x16 pixels. After messing around a bit with the code, I successfully flipped the sprites, but they appear fragmented. How would I get the vertical 8x16 sprites to swap places so it looks normal?


Top
 Profile  
 
 Post subject: Re: Mirroring sprites
PostPosted: Sat Nov 23, 2013 7:13 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 21101
Location: NE Indiana, USA (NTSC)
In your sprite drawing routine, set a variable to 8 if the sprite is not flipped and -8 if the sprite is flipped. Add that value in that variable to the left sprite's X coordinate to get the right sprite's X coordinate.


Top
 Profile  
 
 Post subject: Re: Mirroring sprites
PostPosted: Sat Nov 23, 2013 7:28 pm 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11166
Location: Rio de Janeiro - Brazil
You have to turn the X coordinate increment into a variable, like tepples said (i.e. to move to the next column of sprites you either add 8 or subtract 8, depending on whether the object is flipped), but you have also to adjust the initial coordinate, so that if the first sprite's X coordinate would be at 231 when not flipped, it would be at 231 + (ObjectWidth - 8) when flipped.

I hope you are not using hardcoded OAM locations for your sprites and updating the coordinates of each individual sprites as your character moves, because that makes things much harder. The correct/versatile way to draw sprites is to start from the object's logical coordinate (the one you use for movement, collisions, etc.) and draw all individual sprites around that, to dynamic OAM positions (which also allows you to do sprite cycling when you need it). As long as you do it the versatile way, it's just a matter of calculating the first X coordinate and the step value based on the direction the object is facing, and use those in the loop that renders sprites.


Top
 Profile  
 
 Post subject: Re: Mirroring sprites
PostPosted: Wed Nov 27, 2013 9:31 am 
Offline

Joined: Sat Nov 23, 2013 4:23 pm
Posts: 10
Location: Papillion, Nebraska
tokumaru wrote:
I hope you are not using hardcoded OAM locations for your sprites and updating the coordinates of each individual sprites as your character moves, because that makes things much harder. The correct/versatile way to draw sprites is to start from the object's logical coordinate (the one you use for movement, collisions, etc.) and draw all individual sprites around that, to dynamic OAM positions (which also allows you to do sprite cycling when you need it). As long as you do it the versatile way, it's just a matter of calculating the first X coordinate and the step value based on the direction the object is facing, and use those in the loop that renders sprites.
I am not sure what "hardcoded" OAM is. This is what my code for the sprite drawing routine looks like:
Code:
PlayingSP:                 ; This is the code for where the sprites first appear on the screen
     ;vert tile attr horiz
  .db $B0, $00, $00, $20
  .db $B0, $01, $00, $28
  .db $B8, $02, $00, $20
  .db $B8, $03, $00, $28
Should I change it to something like this?
Code:
PlayingSP:                 ; This is the code for where the sprites first appear on the screen
     ;vert tile attr horiz
  .db $B0, $00, $00, $20
  JSR draw_PlayingSP       ; Code will exist soon
Or does it have todo with something else?


Top
 Profile  
 
 Post subject: Re: Mirroring sprites
PostPosted: Wed Nov 27, 2013 11:12 am 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11166
Location: Rio de Janeiro - Brazil
Dimeback wrote:
I am not sure what "hardcoded" OAM is.

Hardcoding an object to OAM locations would be to always have the same object use the same OAM slots. The OAM can hold 64 sprites, if your character is 16x32 pixels large (meaning it needs 8 8x8 sprites) and you always use $0200-$021F (assuming your OAM buffer is at $0200, like in most programs), that would be hardcoding sprites. This is bad because the same characters will always be displayed with the same priority, so if you line up a number of characters that adds up to more than 8 sprites, the ones with lower priority will disappear. This problem is solved by drawing the characters to different OAM slots every frame (meaning you can't hardcode them), so that their priorities cycle and you end up with flicker instead of invisible sprites.


Top
 Profile  
 
 Post subject: Re: Mirroring sprites
PostPosted: Fri Feb 08, 2019 10:36 am 
Offline

Joined: Tue Oct 17, 2017 12:13 am
Posts: 15
Sorry to bring up such an old thread.. but I figured this is better than starting a completely new one.

How can I set a single bit? This is a lame question. I want to set bit 6 to horizontally mirror a sprite.. and there has to be a better way to do this than:
Code:
  LDX #$40
  CPX $2002 (or non hardcoded address)
  BNE Flip
  JMP DontFlip
Flip:
  LDA $2002
  CLC
  ADC #$40
  STA $2002
DontFlip:

(I realize this wouldn't work on vertically flipped sprites since bit 7 would be set)

I haven't tested but maybe I could do this:
Code:
  LDA $0202
  AND #%01000000
  BEQ DontFlip
Flip:
  CLC
  ADC #$40
  STA $2002
DontFlip:


Is there a better way than this? A way I can change the switch in bit 6 without even checking if it's already set or not? In this case, I just want mirroring turned on, and it seems faster to just change that bit than to check first.

######################
EDIT: Solved, sorry to bother. The answer is to use ORA when trying to set a bit to 1, and AND when setting a bit to 0.
set bit 6 to 1:
Code:
LDA $0202
ORA #%01000000
STA $0202


set bit 6 to 0:
Code:
LDA $0202
AND #%10111111
STA $0202

######################




I hope it's okay cause I'm gonna be asking a lot of dumb questions for a while till I've got the hang.


Top
 Profile  
 
 Post subject: Re: Mirroring sprites
PostPosted: Fri Feb 08, 2019 11:30 am 
Online
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11166
Location: Rio de Janeiro - Brazil
OR (6502 ORA) is the operation used for setting bits: anything OR 1 equals 1, anything OR 0 remains unchanged.

AND is the operation used for clearing bits: anything AND 0 equals 0, anything AND 1 remains unchanged.

XOR (6502 EOR) is the operation used for inverting bits: anything XOR 1 gets inverted, anything XOR 0 remains unchanged.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group