Object collision
Moderator: Moderators
-
- Posts: 2158
- Joined: Sun Jun 05, 2005 2:04 pm
- Location: Minneapolis, Minnesota, United States
- Contact:
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.
To add two 16-bit numbers:
You often see stuff like this in games' physics code, as they use the low byte to represent subpixel position.
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
-
- Posts: 2158
- Joined: Sun Jun 05, 2005 2:04 pm
- Location: Minneapolis, Minnesota, United States
- Contact:
Say variables turd = $80 and turd1 = $AE
Okay, so like this:
since turd1 is right after turd would load $80AE? Or would it load $AE80?
Okay, so like this:
Code: Select all
ldy #$00
lda (turd),y
-
- Posts: 2158
- Joined: Sun Jun 05, 2005 2:04 pm
- Location: Minneapolis, Minnesota, United States
- Contact:
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:
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?
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
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.
alternatively you can use ADC to add the carry to turd1:
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
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
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
Another annoyance with nesasm: no nameless labels
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.
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.
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:
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
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
-
- Posts: 2158
- Joined: Sun Jun 05, 2005 2:04 pm
- Location: Minneapolis, Minnesota, United States
- Contact:
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:
What is wrong?
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
-
- Posts: 2158
- Joined: Sun Jun 05, 2005 2:04 pm
- Location: Minneapolis, Minnesota, United States
- Contact:
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?
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 :
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 ?
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
Useless, lumbering half-wits don't scare us.
-
- Posts: 2158
- Joined: Sun Jun 05, 2005 2:04 pm
- Location: Minneapolis, Minnesota, United States
- Contact:
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.