Page 1 of 3
I'm an idiot (failure to create pong "bouncing" ball)
Posted: Wed Jun 01, 2016 7:42 am
by Drew Sebastino
I've been putting this off indefinitely and now that I have absolutely no excuse because it's the summer, I thought I'd have a crack at making a simple pong demo. I was trying to take baby steps by at first having an 8x8 ball that goes down and changes direction at the same speed and figured I'd do an eor #$FFFF on the velocity which should kind of make it a negative number, and it does flip it, but it makes the ball travel 2 pixels instead of one and it also exits the screen I thought I could just check to see if the ball's x position was over 248 (256 - 8) and 216 (224 - 8) and then do the eor there, and although it stops it the first time around, it doesn't stop it on the way back when the ball's position wraps to 65536, which is also over 0, probably because it's going back two and then adding one. Why is this phenomenon even happening? I figured adding #$FFFE would be the same thing as subtracting #$0001.
Code: Select all
lda BallXPosition
cmp #248
bcc continue_finding_ball_x_position
lda BallXVelocity
eor #$FFFF
sta BallXVelocity
continue_finding_ball_x_position:
lda BallXPosition
clc
adc BallXVelocity
sta BallXPosition
lda BallYPosition
cmp #216
bcc continue_finding_ball_y_position
lda BallYVelocity
eor #$FFFF
sta BallYVelocity
continue_finding_ball_y_position:
lda BallYPosition
clc
adc BallYVelocity
sta BallYPosition
I can always add more code I made, but I think this is enough.
Re: I'm biggest idiot (failure to create pong "bouncing" bal
Posted: Wed Jun 01, 2016 8:12 am
by Revenant
$FFFE is equal to -2, so you most likely want $FFFF (-1) instead. Adding 1 to the value after the
eor #$FFFF will get you the value you want ($0001 to $FFFF and vice-versa) for both the positive and negative direction (this is how
two's complement negation works).
Re: I'm biggest idiot (failure to create pong "bouncing" bal
Posted: Wed Jun 01, 2016 8:30 am
by adam_smasher
Don't be so hard on yourself, dude, no idiot could even get this far with 65816 assembly language
Adding $FFFF, not $FFFE, is the same as subtracting one (because $FFFF is the two's complement 16-bit representation of -1, and adding -1 is the same as subtracting 1, blah blah blah...)
EOR #$FFFF followed by INC A is the same as negation (it's not clear whether you know this, you probably do but just sayin').
I'm not sure what's wrong - based on your code, if the X velocity starts at 1, it gets flipped - 1 once X = 249. Then the velocity = -2, so on subsequent iterations X = 247, 245...1, -1 = $FFFF. Then the X velocity should get flipped - 1 again, so it'll equal 1 again, so then X = 0 and things should start over...
I will say, as a rule, once your velocities start getting a little more unruly the safest thing to do is force the X position back to a known state on collision. So once you bounce on the left, just STZ BallXPosition and be done with it, and likewise on the right just set it to the max value (248). That probably won't fix your problem here, though.
Try stepping through it in a debugger?
Re: I'm biggest idiot (failure to create pong "bouncing" bal
Posted: Wed Jun 01, 2016 8:32 am
by rainwarrior
Is there any reason why you didn't consider just doing v = 0 - v for negation? I mean, maybe you can save a cycle or two by futzing with bitwise stuff, but if you were wondering why that didn't work, why not take the simple approach first? (i.e. Get it working before you pursue optimization.)
Though the other problem you might run into is that simply negating is not entirely stable either; if the negated velocity is not enough to reject the ball from collision in a single step, it would get negated again on the next frame, and from that point it would end up trapped. The simple solution is to negate only when the position is below the floor AND the velocity is greater than or 0. Won't come up if your velocity is always sufficiently large at collision, though.
Another way to solve that issue is to move the ball out of collision first, and dampen the velocity a bit, so that the loss of velocity compensates for this gain in energy from moving it out of collision, but this is only really applicable if you want a ball that loses height with each bounce.
Though it sounds like you're not using gravity / parabolic motion anyway, so ignore that last bit.
Re: I'm biggest idiot (failure to create pong "bouncing" bal
Posted: Wed Jun 01, 2016 2:55 pm
by Drew Sebastino
adam_smasher wrote:Don't be so hard on yourself, dude, no idiot could even get this far with 65816 assembly language
What's funny, is that I found out I made a grammatical error in the title, and I'm a native English speaker.
adam_smasher wrote:Adding $FFFF, not $FFFE, is the same as subtracting one (because $FFFF is the two's complement 16-bit representation of -1, and adding -1 is the same as subtracting 1, blah blah blah...)EOR #$FFFF followed by INC A is the same as negation (it's not clear whether you know this, you probably do but just sayin').
Oh, I didn't actually think about that...
Yeah, it works now.
rainwarrior wrote:Is there any reason why you didn't consider just doing v = 0 - v for negation? I mean, maybe you can save a cycle or two by futzing with bitwise stuff, but if you were wondering why that didn't work, why not take the simple approach first? (i.e. Get it working before you pursue optimization.)
I don't get it. The reason I'm doing the bitwise stuff is that the velocity flips no matter what direction the ball is traveling.
Re: I'm biggest idiot (failure to create pong "bouncing" bal
Posted: Wed Jun 01, 2016 3:27 pm
by rainwarrior
Espozo wrote:rainwarrior wrote:Is there any reason why you didn't consider just doing v = 0 - v for negation? I mean, maybe you can save a cycle or two by futzing with bitwise stuff, but if you were wondering why that didn't work, why not take the simple approach first? (i.e. Get it working before you pursue optimization.)
I don't get it. The reason I'm doing the bitwise stuff is that the velocity flips no matter what direction the ball is traveling.
The part you quoted has nothing to do with the initial direction. Maybe the stuff that followed was confusing, but what I meant by this particular paragraph was that if you want to flip velocity...
You have: velocity
You want: -velocity
So: velocity = 0 - velocity
Code: Select all
lda #0
sec
sbc velocity
sta velocity
I was just trying to suggest that this is the simplest way of thinking about negation. Requires no knowledge of two's complement, only how to subtract. I was asking if you considered this or at all, or whether you thought negation must be a bitwise operation only?
Code: Select all
lda velocity
eor #$FFFF
inc
sta velocity
The bitwise version works too, of course, but you started this thread because it's a little harder to get correct, right?
Re: I'm an idiot (failure to create pong "bouncing" ball)
Posted: Wed Jun 01, 2016 3:42 pm
by tepples
I agree that you should use SBC where it's clearer.
In-register negation with EOR and INC is more useful if you're trying to negate the result of a previous calculation rather than what's currently in a variable, such as calculating -f(y) or v - f(y). You could store f(y) and then load 0 or v and then subtract f(y), but the in-register method avoids the sort of
round trips to memory that make psycopathicteen cry.
Re: I'm an idiot (failure to create pong "bouncing" ball)
Posted: Wed Jun 01, 2016 3:59 pm
by rainwarrior
I'm not arguing that you should do one or the other.
I'm just trying to point out a solution that Espozo seemed to be unaware of.
Re: I'm an idiot (failure to create pong "bouncing" ball)
Posted: Sat Jun 04, 2016 9:55 am
by Drew Sebastino
I'm pissed, I wanted to create a simple Pong demo to "prove my worthiness", but it ended up being a total disaster. Bad organization, near zero optimization, but the worst part is, is that there are a heap of bugs. Sometimes, the ball goes backwards through a paddle when "serving" it, and sometimes, the ball just goes outright through a paddle instead of bouncing back. I did a ton of lazy programming, like only checking the very surface of the paddle for collisions, and this is where it got me.
Maybe I was lazy because I knew I wouldn't be using this later anyway. Whatever. It would be much easier with an Object setup like I had going.
The velocity of the ball when serving it is the same as when it hits the wall, so I have no clue how it's doing the thing where it goes backwards. Also, I tried to implement a pause feature, but then I realized that it pauses on and off every frame, but I was too lazy to get rid of it.
This is sad, but the fact that it's LoROM is kind of bugging me... I just don't want to make something in LoROM and then need the extra 32Mb later, but the odds of me getting there are looking increasingly slim...
Re: I'm an idiot (failure to create pong "bouncing" ball)
Posted: Sat Jun 04, 2016 10:01 am
by psycopathicteen
How do you control player 2 on a computer?
Re: I'm an idiot (failure to create pong "bouncing" ball)
Posted: Sat Jun 04, 2016 10:01 am
by nicklausw
My pong game on the NES is nothing special (its physics are not as complex as you're designing at all) but maybe it can give some inspiration:
https://github.com/nicklausw/pong-conso ... master/nes
Re: I'm an idiot (failure to create pong "bouncing" ball)
Posted: Sat Jun 04, 2016 10:28 am
by Drew Sebastino
psycopathicteen wrote:How do you control player 2 on a computer?
Assign different inputs for the second player. How else?
nicklausw wrote:(its physics are not as complex as you're designing at all)
I wouldn't exactly call this "complex". I originally tried to have it to where the ball's trajectory was influenced by the direction the paddle was traveling when it was hit by the ball, but that was kind of ridiculous. I also wanted it to act differently if the ball hit the edges and bottom part of the paddle. If I make a run and gun ever, I've always wanted to have it to where interactive explosions actually push enemies in the direction the blast is going and also do damage according to how close the object is to the center of the explosion, (I'd do another circular collision check after the original box) but I'm doubtful I'll get there.
Somehow, I feel like I've actually gotten worse at programming. The HiROM thing is driving me insane for no reason, so I think I'll suck it up and try to at least get the screen to appear in HiROM. All I'd really have to convert is the initialization routine, and the Vblank handler, if I'm not mistaken, to get it to where I can turn the screen white. (Well, and that snippet of code of course.)
Re: I'm an idiot (failure to create pong "bouncing" ball)
Posted: Sat Jun 04, 2016 4:17 pm
by Nicole
Espozo wrote:I just don't want to make something in LoROM and then need the extra 32Mb later
Oh, LoROM and HiROM don't have anything to do with maximum ROM size. Both have a maximum of 4 MB.
The difference is just that LoROM gives you 128 banks of 32 KB, whereas HiROM gives you 64 banks of 64 KB. It adds up to the same size, it's just a different layout is all.
Take another look at
this diagram I made earlier. Notice how each "ROM" rectangle (which represents a mirror of the same 4 MB ROM) has the same area; they're just laid out differently.
Re: I'm an idiot (failure to create pong "bouncing" ball)
Posted: Sat Jun 04, 2016 4:50 pm
by Drew Sebastino
Well, I mean, it's not actually HiROM. I think it's like Mode 25, which is identical to HiROM except one of the parts that is normally mirrored is unique rom. I just won't use that part in HiROM, and if I need more rom, I'll switch to Mode 25 and they utilize the space. I believe I could potentially use this much space because I'm more interested in doing extra stuff than decompressing graphics. I probably couldn't store them in ram either, because you're kind of limited in terms of space. (Hell, the Splatoon idea would actually need more than 128KB of ram.)
Re: I'm an idiot (failure to create pong "bouncing" ball)
Posted: Sat Jun 04, 2016 7:11 pm
by koitsu
You aren't going to need 32mbit, or anywhere close to it, for a pong game. Please stop getting hung up on this. Your brain has created intentional blockades as a way to avoid accomplishing your goal; ignore your brain. Just use mode 20 and accomplish your goal. A substantial number of commercial games are all mode 20 (example: Super Mario World). Once you accomplish that fully, then you can go back and try something like converting your game from mode 20 to mode 21 as a learning experience.