Page 1 of 1

Addition and Subtraction?

Posted: Wed Aug 04, 2010 5:09 pm
by Zsy
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)

Posted: Wed Aug 04, 2010 5:11 pm
by Dwedit
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: Select all

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.

Posted: Wed Aug 04, 2010 5:23 pm
by Zsy
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?

Posted: Wed Aug 04, 2010 5:52 pm
by Zsy
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: Select all

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

Posted: Wed Aug 04, 2010 6:15 pm
by Dwedit
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.

Posted: Wed Aug 04, 2010 10:05 pm
by tokumaru
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.

Posted: Thu Aug 05, 2010 5:52 am
by Zsy
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.