Hi, I was wondering how one goes about adding and subtracting on the NES.
I checked the wiki and that part of the page has not yet been written.
What I want to do is move a bunch of sprites together in a grid like pattern.
So when I press right all of their horizontal positions are incremented by 32 ($20) and when I press left all of their horizontal positions are decremented by 32. ($20)
CLC and ADC
First CLC to clear the carry flag, so it doesn't add an extra 1.
Then ADC #32 to add 32 to register A.
Something like this...
Code:
ldx #0
-
lda enemyXTable,x
clc
adc #32
sta enemyXTable,x
inx
cpx numberOfEnemies
bne -
For subtraction you use SEC to SET the carry flag, not clear it, then use SBC (subtract with carry) to subtract.
Or just add a negative number (-32 = E0 = 224), they're all the same in 8-bit twos compliment number formats.
Wow, that's actually a lot simpler than I thought.
Would it be feasible to move 16 sprites as a group by adding to their horizontal or vertical position?
Or should I perhaps look into other methods?
Got my sprites moving perfectly!
Now my question is this, do I need to reset CLC or SEC in-between operation like I'm doing below?
Code:
CheckDown:
LDA #%00100000
AND justpressed
BEQ CheckLeft
LDA $0500
CMP #$BF
BEQ CheckLeft
LDA $0500 ;Move first row down
CLC
ADC #32
STA $0500
STA $0504
STA $0508
STA $050C
CLC ;Move second row down
ADC #08
STA $0510
STA $0514
STA $0518
STA $051C
CLC ;Move third row down
ADC #08
STA $0520
STA $0524
STA $0528
STA $052C
CLC ;Move fourth row down
ADC #08
STA $0530
STA $0534
STA $0538
STA $053C
Unless you are 100% positive that there are no other operations that could cause the carry flag to be set (comparison, adding, bit shifts or rotations, etc), you should always set or clear the flag before every operation.
Sometimes people try to optimize those out, and they get an unexpected addition of 1 because the carry flag was set for some unforeseen reason.
Moving 16 harcoded sprites is not the most... adequate way to go about moving big characters. Mostly because sprites are a limited resource on the NES (there are only 64, and the fact that only 8 can be displayed for scanline is a pretty big limitation too), so sprite cycling is a basic necessity for most games.
sprite cycling is basically completely randomizing which game objects get drawn with which hardware sprites every frame, so that if the sprite limitation(s) prevents an object from being displayed it gets displayed on the next frame (because it used different hardware sprites and those might have more priority than the ones used before). This is perceived by users as flickering. But even though the objects flicker, anyone can tell where they are (no objects stays invisible).
This is why always using the same sprites to represent the same character is a bad idea, you are not cycling its priority.
the ideal method would be to keep track of your object's position using variables in RAM, and every frame use those variables as the base for calculating the coordinates of the sprites that will represent that object, and always use a different section of the OAM.
If you are making a game, you should worry about this. But if it's just a simple demo or an exercise, you don't have to worry about it now. Just keep the concept in mind, and now that you'll have to think about sprite cycling when making a game.
Thanks for the great info guys!
@Dwedit: I may try to optimize a few CLC's out of my code, but I'll probably end up having more than enough time and resources than I need anyway.
@Tokumaru: I'm making a very simple puzzle game that takes place on a 16 by 16 block grid (Where each block is 4 by 4 tiles) and the cursor, the 16 sprites I'm moving in the code shown above, is the only moving object in the game. I chose to make a puzzle game first because they have the fewest moving sprites of any genre, but I'm definitely gonna save the information you provided in case I ever have to work on an action game.