I'm an idiot (failure to create pong "bouncing" ball)

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

I'm an idiot (failure to create pong "bouncing" ball)

Post 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.
Last edited by Drew Sebastino on Wed Jun 01, 2016 2:56 pm, edited 1 time in total.
Revenant
Posts: 455
Joined: Sat Apr 25, 2015 1:47 pm
Location: FL

Re: I'm biggest idiot (failure to create pong "bouncing" bal

Post 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).
adam_smasher
Posts: 271
Joined: Sun Mar 27, 2011 10:49 am
Location: Victoria, BC

Re: I'm biggest idiot (failure to create pong "bouncing" bal

Post 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?
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: I'm biggest idiot (failure to create pong "bouncing" bal

Post 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.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: I'm biggest idiot (failure to create pong "bouncing" bal

Post 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. :lol:
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.
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: I'm biggest idiot (failure to create pong "bouncing" bal

Post 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?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post 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.
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post 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.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post 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.
SNES Pong.zip
(1.09 MiB) Downloaded 119 times
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...
psycopathicteen
Posts: 3001
Joined: Wed May 19, 2010 6:12 pm

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post by psycopathicteen »

How do you control player 2 on a computer?
User avatar
nicklausw
Posts: 376
Joined: Sat Jan 03, 2015 5:58 pm
Location: ...
Contact:

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post 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
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post 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.)
Nicole
Posts: 218
Joined: Sun Mar 27, 2016 7:56 pm

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post 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.
User avatar
Drew Sebastino
Formerly Espozo
Posts: 3496
Joined: Mon Sep 15, 2014 4:35 pm
Location: Richmond, Virginia

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post 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.)
User avatar
koitsu
Posts: 4203
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: I'm an idiot (failure to create pong "bouncing" ball)

Post 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.
Post Reply