Object collision

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Celius
Posts: 2158
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

I'm a little confused on how to do 16 bit stuff, since you can only have 8 bits in the accumulator. I know you can do stuff with the carry flag, but I don't know how. Okay, I'm confused about how to like load 16 bits. I was looking at your code you supplied eariler bregalad, and I don't understand how you just randomly had the variable "pointer" and "temp2" just randomly get values. Like you didn't store anything in temp2 when you ROLd it, and you loaded pointer without even storing anything in it, did you mean pointerH? I'm sorry, I'm really confused, and i'm angry about this and my EPROMs that are all stupid. Please explain.
tepples
Posts: 22861
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

To add two 16-bit numbers:

Code: Select all

  clc
  ; add the low order bytes
  lda num1
  adc num2
  sta sum
  ; add the high order bytes
  lda num1+1
  adc num2+1
  sta sum+1
You often see stuff like this in games' physics code, as they use the low byte to represent subpixel position.
Celius
Posts: 2158
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

Say variables turd = $80 and turd1 = $AE
Okay, so like this:

Code: Select all

ldy #$00
lda (turd),y
since turd1 is right after turd would load $80AE? Or would it load $AE80?
User avatar
Memblers
Posts: 4100
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Post by Memblers »

It'd be $AE80. Just remember with 16-bit stuff that the low byte is first.
Celius
Posts: 2158
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

Okay, NESASM is being very weird, and it only makes the collision "work" when the code is lda [blah],y instead of lda (blah),y. here is my code:

Code: Select all

	lda #LOW(bg1)
	sta turd
	lda #HIGH(bg1)
	sta turd1
	lda itx
	lsr a
	lsr a
	lsr a
	sta tilex
	lda ity
	lsr a
	lsr a
	lsr a
	sta tiley
	lda tiley
	asl a
	asl a
	asl a
	asl a
	asl a
	sta vara
	lda tilex
	adc vara
	sta varb
	lda turd
	adc varb
	sta turd
	ldy #$00
	lda [turd],y
	bpl _noCollision
	lda #01
	sta colflag
	rts
I don't know how to say increment the high byte when the low reaches 00 again. How should I incorperate that in my code?
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch »

yeah Nesasm uses yukky brakets for indirection instead of parenthesis... one of my annoyances with it.

anyway... if ADC addition causes a wrap (FF->00), the C flag will be set... you can check the status of the C flag after addition and increment the high byte if it's set.

Code: Select all

 lda turd
 adc varb
 sta turd

 bcc skip_inc  ;if carry is clear, skip over... otherwise....
 inc turd1     ; increment high byte of address

skip_inc:
 ldy #$00
 lda [turd],y
 ;etc
alternatively you can use ADC to add the carry to turd1:

Code: Select all

 lda turd
 adc varb
 sta turd

 lda turd1
 adc #$00   ;add the carry flag
 sta turd1

 ldy #$00
 lda [turd],y
 ;etc
using adc avoids the use of the label, but takes 2 more bytes and is a bit slower.

Another annoyance with nesasm: no nameless labels
User avatar
Bregalad
Posts: 8104
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Post by Bregalad »

Some will say I'm highhacking a thread, but about NESASM anoyances, I think the two dish mentionned are effectively annoning, but the one that definitely make NESASM suck is how banks are organized. Everything (including PRG and CHR) is organized in 8kb banks, and that's EXTREMLY anoying.
You'll probably have to be familiar with those maths stuff and carry if you code things at a decent speed. I think that most tutorials does only mention things techinically (aka : ADC add operand with acumulator. Flags affected : C, N, Z), and does not explain things much how they'll work in practice (like 16-bit addition code). So people new at programming like Celius can miss some really basic stuff while learing some advanced ones, just because tutorials aren't focused on the right things.
Useless, lumbering half-wits don't scare us.
User avatar
Disch
Posts: 1848
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch »

Speaking of that...

I just noticed Celius isn't putting a CLC before his ADC (and it's after a crapload of ASLs, so it's possible C might be set).

@ Celius: If the C flag is set when you do ADC, an extra 1 gets added to your sum. Example:

Code: Select all

SEC
LDA #$02
ADC #$02
; A is now 5, not 4
If C is potentially set by a previous instruction (like say, ASL), and you don't want that extra 1 added, you can avoid it by putting a CLC command before the ADC
Celius
Posts: 2158
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

My collision code goes wrong at random places! Well, I'm incbining a nam file , would that cause that? Like I have a maze, which is in my opinion, the perfect testing for collision. I have squares layed out like a maze. Well I have my code so you'll decrease your position before checking for collision, so you'll press left against a block once, and you'll move a pixel. I'm fine with that for now. But I'll be pressing down when I'm sort of stuck in a wall, and there'll be a block the the collision code will skip! and there's like a few chunks that have blank spaces, but I'm colliding against them! Why? Here is my code:

Code: Select all


collision:
	lda #LOW(bg1)
	sta turd
	lda #HIGH(bg1)
	sta turd1
	lda itx
	lsr a
	lsr a
	lsr a
	sta tilex
	lda ity
	lsr a
	lsr a
	lsr a
	sta tiley
	lda tiley
	asl a
	asl a
	asl a
	asl a
	asl a
	sta vara
	clc
	lda tilex
	adc vara
	sta varb
	clc
	lda turd
	adc varb
	sta turd	
	bcc noinc1
	inc turd1
noinc1:
	ldy #$00
	lda [turd],y
	bpl _noCollision
	lda #01
	sta colflag
	rts
What is wrong?
Celius
Posts: 2158
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

I looked at FCEUXD ultra's debugger thing, and I noticed that the carry flag is NEVER set. Why? When a byte reaches 100, doesn't it store 00 in the byte, and 1 in the carry flag? I don't know too much about that, I suppose. I really need to know though, what the problem is.
tepples
Posts: 22861
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

'inc' and 'dec' do not touch the carry flag.
Celius
Posts: 2158
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

Oh, okay. By the way, this is random, but happy 500th post! I feel special when I've posted alot.
Celius
Posts: 2158
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

Okay, that still doesn't answer my question. I am having a problem. My player will collide with blank tiles, and i'm not sure why! It will skip solid tiles and read them as blank, like 4 or 5 in a row sometimes. Usually it's like 3 tiles going down, and it will skip the middle one for some reason. And it will always skip it, and it's really annoying. And my code is what I posted above, and it's really stupid that it doesn't work! Any ideas why?
User avatar
Bregalad
Posts: 8104
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Post by Bregalad »

Well, you really need to found such problems by yourself. Debugging can get *very* anoying sometimes, but debuging the code of someone else is even worse, so try to only post "main" problems, while you need to be able to found all small ones by yourself.
Note that this code can easily be optimized (stuff like lsr followed by asl can rather be made with and) but it won't change the functionality or you programm, only speed and size.
Also, you're using a variable (here Colflag) to return the exit parameters (in that case if collision is active or not).
For a such subroutine, you can use the carry flag as one bit of parameter, so you can made your routine in the way that the carry is clear if there is no collision, or set if you have a collision (or the other way arround). Then the routine calling this subroutine will simply check for the carry flag to know if there is a collision. The end of your code will look like this :

Code: Select all

lda [turd],Y
asl A                ;The bit 7 of accumulator transfers into C
rts                  ;If bit 7 was set, there is a collision, and that state is returned trough carry
You simply avoid using an useless variable, and you code is much shorter. Also, in the example you posed, you seem to write #$01 in your collflag if thereis a collision but what about if there is none ? You may forgot to paste the piece of code writing #$00 into colfag there, but who knows ?
Useless, lumbering half-wits don't scare us.
Celius
Posts: 2158
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius »

Oh, I just figured out that ASL puts stuff in the carry flag! OOPS! I thought it just put bit 7 in the land of nothingness, and put 0 in bit 0! I have to study my code now. But, I was going to ask you a question, and I really don't want to ask it, but I have to, and I appologize for making it hard for anybody, and I will try and do these things myself. Okay, so, how are you supposed to check if the carry flag has 1 in it? Oh, like BCS? Okay, I think I get it. I am seeing that in my code, I have it so I am doing an ADC right before I say BCC, and that could be causeing problems, and C would always be set right? but then I look in the Debugger, and it's NEVER set. I don't know why, and it's making me mad. If I do AND instead of ASL, how will the carry flag ever be set? will it be? I'm thinking not, and I'm wondering what I should do. Okay, well, i am going to study my code now.
Post Reply