Skip navigation
NintendoAge
Welcome, Guest! Please Login or Join
Loading...

Nerdy Nights week 7 subroutines, game layout, starting Pong

Feb 7, 2012 at 2:30:53 AM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
Originally posted by: DoNotWant

Originally posted by: Mario's Right Nut

At first glance, you should be using BCC and BCS instead of BNE. But I could be wrong. BNE would only work if they are exactly on the same pixel, the others would give you a collision range.
Seems to work now. Thank you!

 

I didn't think it was this because his speed is always no more than 1, from what I could see in his code.  But if that fixed it, awesome.  Nice job!


-------------------------

gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin


Feb 7, 2012 at 1:20:21 PM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
Originally posted by: KHAN Games

Originally posted by: DoNotWant

Originally posted by: Mario's Right Nut

At first glance, you should be using BCC and BCS instead of BNE. But I could be wrong. BNE would only work if they are exactly on the same pixel, the others would give you a collision range.
Seems to work now. Thank you!

 

I didn't think it was this because his speed is always no more than 1, from what I could see in his code.  But if that fixed it, awesome.  Nice job!
 

Yeah, I had it at 2 first but changed it to 1, so I still think it's strange that it won't work with BEQ and BNE. :S


-------------------------
 

Feb 7, 2012 at 2:28:21 PM
Mario's Right Nut (352)
avatar
(Cunt Punch) < Bowser >
Posts: 6636 - Joined: 11/21/2008
Texas
Profile
Originally posted by: muffins

I have one other question which involves loading the paddle sprites using a loop. What I would like is 4 of the same tiles stacked vertically to create a paddle. My current "loop" is this:

Vertical_Offsets:
  .db 0,8,16,24
 
routine:
LDX #$00
LDY #0

loop:
LDA paddle1ytop
CLC
ADC Vertical_Offsets, y ;;update paddle sprites
STA $0204, x

LDA #$5B
STA $0205, x

LDA #$01
STA $0206, x

LDA #PADDLE1X
STA $0207, x

INX
INX
INX
INX

INY
CPY #$04
BNE loop

RTS

Where it's not really a loop because it just runs through once to display the top tile. I am not sure how to then shift everything up to the next set of addresses (which in my code would be multiplying the "x" value by 4 in each place, in addition to having to increase the paddle1ytop variable by 8 each run through the loop. Is what I'm thinking possible or do I need to restructure my loop? I'd rather not have to hard code this with no loops if possible.

This isn't exactly pretty, but it should work.


-------------------------

This is my shiny thing, and if you try to take it off me, I may have to eat you.

Check out my dev blog.


Feb 8, 2012 at 5:19:35 AM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
Seems like I still have some bugs with my paddles, how would I do
to check for a range of values in assembly? It's all
new to me, and I only know how to compare to one value
at a time, which I guess isn't very efficient. :/

-------------------------
 

Feb 8, 2012 at 12:53:06 PM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
Basically:

Routine:
LDA #$(lowest possible correct value)
BCC .End
LDA #$(highest possible correct value)
BCS .End
;;do stuff
.End:
RTS

-------------------------

gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin


Feb 8, 2012 at 3:01:14 PM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
Thanks!

Each paddle is 2 sprites, and they are stored in a variable like this:
player1 .rs 2
player2 .rs 2
So for each player I want to check the values player(sprite 1 y value) and player+4(sprite 2 y value)+8.
I tried with LDA player1+4+#$08, but obviously that didn't work.
All stuff that is easy in say C++ is really weird in assembly if you are not used to it.
Any good resource for learning that kind of essential stuff in assembly?

-------------------------
 

Feb 8, 2012 at 5:03:30 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
Add them all separately, then do the calculations. You can't find the difference between a memory location and a constant or two memory locations in one instruction. Load the width and constants, then do the memory additions. Remember (S)UB and Clear for addition.

Feb 8, 2012 at 10:42:44 PM
muffins (0)
avatar
(I am Error.) < Tourian Tourist >
Posts: 44 - Joined: 01/31/2012
Maine
Profile
Originally posted by: Mario's Right Nut

This isn't exactly pretty, but it should work.
 

Makes sense, I hadn't thought to store the offsets as data and refer to them.  And you're right, definitely not pretty as far as doing 4 INXs haha.  But, I think I can safely clean some of it up because I won't need to set tile number/attributes/x-pos every loop through NMI so I can move those out of that.  Thanks!


-------------------------


Feb 9, 2012 at 1:14:09 AM
muffins (0)
avatar
(I am Error.) < Tourian Tourist >
Posts: 44 - Joined: 01/31/2012
Maine
Profile
Having some difficulty understanding why this collision code doesn't work:

CheckPaddle1Collision:
  ;;if ball x < paddle1x
  LDA ballx
  CMP #PADDLE1X
  BCS CheckPaddle1CollisionDone
  ;;  if ball y > paddle y top
  LDA bally
  CMP paddle1ytop
  BCC CheckPaddle1CollisionDone
  ;;    if ball y < paddle y bottom
  LDA bally
  CMP paddle1ybot
  BCS CheckPaddle1CollisionDone
  ;;      bounce, ball now moving right
  LDA #$01
  STA ballright
  LDA #$00
  STA ballleft
CheckPaddle1CollisionDone:

-------------------------



Edited: 02/09/2012 at 01:42 AM by muffins

Feb 9, 2012 at 2:23:40 AM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
Originally posted by: muffins

Having some difficulty understanding why this collision code doesn't work:

CheckPaddle1Collision:
  ;;if ball x < paddle1x
  LDA ballx
  CMP #PADDLE1X
  BCS CheckPaddle1CollisionDone
  ;;  if ball y > paddle y top
  LDA bally
  CMP paddle1ytop
  BCC CheckPaddle1CollisionDone
  ;;    if ball y < paddle y bottom
  LDA bally
  CMP paddle1ybot
  BCS CheckPaddle1CollisionDone
  ;;      bounce, ball now moving right
  LDA #$01
  STA ballright
  LDA #$00
  STA ballleft
CheckPaddle1CollisionDone:
Try doing one pixel more/less and see.  Sometimes that seems to work for me. (if this doesn't work, pretend I didn't suggest it.

CheckPaddle1Collision:
  ;;if ball x < paddle1x
  LDA ballx
  CLC
  ADC #$01
  CMP #PADDLE1X
  BCS CheckPaddle1CollisionDone
  ;;  if ball y > paddle y top
  LDA bally
  SEC
  SBC #$01
  CMP paddle1ytop
  BCC CheckPaddle1CollisionDone
  ;;    if ball y < paddle y bottom
  LDA bally
  CMP paddle1ybot
  BCS CheckPaddle1CollisionDone
  ;;      bounce, ball now moving right
  LDA #$01
  STA ballright
  LDA #$00
  STA ballleft
CheckPaddle1CollisionDone:



-------------------------

gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin


Feb 9, 2012 at 5:48:05 AM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
Originally posted by: muffins

Having some difficulty understanding why this collision code doesn't work:

CheckPaddle1Collision:
  ;;if ball x < paddle1x
  LDA ballx
  CMP #PADDLE1X
  BCS CheckPaddle1CollisionDone
  ;;  if ball y > paddle y top
  LDA bally
  CMP paddle1ytop
  BCC CheckPaddle1CollisionDone
  ;;    if ball y < paddle y bottom
  LDA bally
  CMP paddle1ybot
  BCS CheckPaddle1CollisionDone
  ;;      bounce, ball now moving right
  LDA #$01
  STA ballright
  LDA #$00
  STA ballleft
CheckPaddle1CollisionDone:
This is what I have at the moment, kinda buggy, but still my best attempt yet.<br>
Player1Collisions:<br>
    LDA player1 ; paddle1 y position<br>
    CLC<br>
    ADC #$10 ; 2 sprites for every paddle, so add 16<br>
    STA ballCollY ; bottom of paddle <br><br>
    
    LDA player1<br>
    CMP ballPos+1 ; ball y position<br>
    BCS .return<br><br>
    
    LDA ballCollY<br>
    CMP ballPos+1<br>
    BCC .return<br><br>

    LDA player1+3 ; paddle 1 x position<br>
    CMP ballPos ; ball x position<br>
    BCC .return<br><br>

    LDA  #$01<br>
    STA ballDirection+1 ; bD = up, bD+1 = down, bD+2 = left, bD+3 = right, 1 is off, 0 is on<br>
    STA ballDirection+2<br>
    LDA #$00<br>
    STA ballDirection<br>
    STA ballDirection+3<br><br>

.return:<br>
    RTS

-------------------------
 

Feb 9, 2012 at 11:00:41 AM
muffins (0)
avatar
(I am Error.) < Tourian Tourist >
Posts: 44 - Joined: 01/31/2012
Maine
Profile
Thanks guys! KHAN, I ended up tweaking your suggestion a bit and it worked. Due to the sprite's width I used 8 pixels instead of one. Also had to swap the additions with subtractions. Here's the final code which works perfectly:

CheckPaddle1Collision:
  ;;if ball x < paddle1x
  LDA ballx
  SEC
  SBC #$08
  CMP #PADDLE1X
  BCS CheckPaddle1CollisionDone
  ;;  if ball y > paddle y top
  LDA bally
  CLC
  ADC #$08
  CMP paddle1ytop
  BCC CheckPaddle1CollisionDone
  ;;    if ball y < paddle y bottom
  LDA bally
  SEC
  SBC #$08
  CMP paddle1ybot
  BCS CheckPaddle1CollisionDone
  ;;      bounce, ball now moving right
  LDA #$01
  STA ballright
  LDA #$00
  STA ballleft
CheckPaddle1CollisionDone:

-------------------------



Edited: 02/09/2012 at 11:01 AM by muffins

Feb 9, 2012 at 12:38:20 PM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
Haha, that's great. I'm glad you understood it enough to make it work with your game.

-------------------------

gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin


Feb 9, 2012 at 1:29:05 PM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
Shit, thank you KHAN and muffins, I totally forgot to take the sprite width into account. >-<

-------------------------
 

Feb 9, 2012 at 3:24:28 PM
muffins (0)
avatar
(I am Error.) < Tourian Tourist >
Posts: 44 - Joined: 01/31/2012
Maine
Profile
Yeah it's definitely something to look out for. Different graphics systems use different graphics handles. The NES PPU appears to place the coordinate of the sprite in the middle, which is the easiest in my opinion. I've seen certain systems use a handle in the upper left hand corner of the graphic which is a nightmare to code for.

-------------------------


Feb 9, 2012 at 3:32:37 PM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
I thought the NES put the coordinates in the upper left corner. O_o
Hmm, maybe that is why it still is acting a little strange from time to time for me, wrong calculations.

-------------------------
 


Edited: 02/09/2012 at 03:36 PM by DoNotWant

Feb 10, 2012 at 5:15:44 PM
Mario's Right Nut (352)
avatar
(Cunt Punch) < Bowser >
Posts: 6636 - Joined: 11/21/2008
Texas
Profile
Originally posted by: DoNotWant

I thought the NES put the coordinates in the upper left corner. O_o
Hmm, maybe that is why it still is acting a little strange from time to time for me, wrong calculations.

Nope.  It is upper left.


-------------------------

This is my shiny thing, and if you try to take it off me, I may have to eat you.

Check out my dev blog.


Feb 12, 2012 at 2:26:10 PM
muffins (0)
avatar
(I am Error.) < Tourian Tourist >
Posts: 44 - Joined: 01/31/2012
Maine
Profile
Originally posted by: Mario's Right Nut

Originally posted by: DoNotWant

I thought the NES put the coordinates in the upper left corner. O_o
Hmm, maybe that is why it still is acting a little strange from time to time for me, wrong calculations.

Nope.  It is upper left.
 

My mistake!  I'm sure I would have figured it out soon enough when things started going haywire but I was thinking of it being in the middle all along. Probably would have come out in the wash in future, more complex collisions. I guess for pong it wasn't even noticeable


-------------------------


Feb 13, 2012 at 12:30:37 AM
muffins (0)
avatar
(I am Error.) < Tourian Tourist >
Posts: 44 - Joined: 01/31/2012
Maine
Profile
I've completed a functional pong game, and going through my code I can't help but feel like there's a more efficient way to code certain sections. For example, I am very much wanting for reusable functions that I can pass variables to, like in the case of reading controllers. When I press up, I want my paddle to go up. If there are two paddles, I want to pass the function a variable that identifies what controller is receiving the input, and therefore which paddle gets moved as a result. Is there a way to do this to avoid hard coding a lot of this stuff, or is what I'm asking for simply one of the reasons modern languages exist?

Here's an example of code specific for player 1 that cannot be reused for player 2 without copying the block of code and replacing all "player 1" variables with "player 2" variables:

MovePaddle1Up:
LDA buttons1
AND #%00001000
BEQ MovePaddle1UpDone ; Use BEQ because zero flag will be set if result of AND operation is false

;;if up button pressed, move paddle up
LDA paddle1ytop
SEC
SBC paddle1speed
STA paddle1ytop
LDA paddle1ybot
SEC
SBC paddle1speed
STA paddle1ybot

;; if paddle top > top wall
LDA paddle1ytop
CMP #TOPWALL
BCS MovePaddle1UpDone
LDA #TOPWALL
STA paddle1ytop ;set top tile y-coordinate to TOPWALL
CLC
ADC #$20 ;bottom of paddle is 32 pixels below TOPWALL, so have to keep it set there
STA paddle1ybot ;otherwise, bottom y-coordinate will decrease when up is pushed
MovePaddle1UpDone:

-------------------------


Feb 19, 2012 at 4:38:21 AM
glenn101 (0)
avatar
(Glenn Kirilov) < Tourian Tourist >
Posts: 37 - Joined: 02/11/2012
Victoria
Profile
Why do we enable NMI, sprites, background etc every time we enter another NMI frame? isn't it set once and stays set i.e. the bits are always a 1?
How does this clean up the PPU section?

;;:Set starting game state
LDA #STATEPLAYING
STA gamestate



LDA #%10010000 ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
STA $2000

LDA #%00011110 ; enable sprites, enable background, no clipping on left side
STA $2001

Forever:
JMP Forever ;jump back to Forever, infinite loop, waiting for NMI



NMI:
LDA #$00
STA $2003 ; set the low byte (00) of the RAM address
LDA #$02
STA $4014 ; set the high byte (02) of the RAM address, start the transfer

JSR DrawScore

;;This is the PPU clean up section, so rendering the next frame starts properly.
LDA #%10010000 ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
STA $2000
LDA #%00011110 ; enable sprites, enable background, no clipping on left side
STA $2001
LDA #$00 ;;tell the ppu there is no background scrolling
STA $2005
STA $2005

Feb 19, 2012 at 9:57:49 AM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
No, you can turn NMI and everything off when needed by just writing to $2000,$2001 again.

Feb 19, 2012 at 1:02:57 PM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
Basically if you turn off the screen anywhere in your game, to update the nametable or anything like that, it will turn everything back on in the NMI section, after everything is redrawn (hopefully). So that's why he says it's a cleanup.

If you turn the screen back on anywhere else, you'd get lots of flickering.

-------------------------

gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin


Feb 19, 2012 at 1:22:52 PM
muffins (0)
avatar
(I am Error.) < Tourian Tourist >
Posts: 44 - Joined: 01/31/2012
Maine
Profile
Is this really only necessary with background updates and not sprites? So far it's only been a noticeable help with background updates.

-------------------------


Feb 19, 2012 at 1:29:14 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
You need to set the scroll after you write to the PPU's address ($2006) register I believe. Other than that I don't believe anything else needs done.

Feb 19, 2012 at 1:55:58 PM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
As far as sprites are concerned, I basically either move them off screen or reposition them between screens, depending on what I'm trying to do. You could probably turn sprites off and back on, but I don't really see a purpose in that.

-------------------------

gauauu: look, we all paid $10K at some point in our lives for the privilege of hanging out with Kevin