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

Nerdy Nights week 7 subroutines, game layout, starting Pong

Feb 21, 2012 at 2:48:48 AM
glenn101 (0)
avatar
(Glenn Kirilov) < Tourian Tourist >
Posts: 37 - Joined: 02/11/2012
Victoria
Profile
I'm trying to compress my code for loading/moving paddle sprites. I'm using 6 tiles for each paddle.
In my code to move the paddles, I've made it so I run a subroutine to take care of the middle paddle sprites.
I'm using a 4 byte variable for the middle sprites, I have 2 separate variables for the top and bottom sprites which I use for collision detection with the border.
This is my current move paddle up code:

MovePaddleUp:
    LDX #$00
;;if up button pressed
    LDA buttons1 ; 3rd bit is up. Don't care about other bits.
    AND #%00001000 ; if it isn't pressed the zero flag is set so we skip.
    BEQ MovePaddleUpDone ; Up button wasn't pressed skip code.
TopPaddle
    LDA paddle1ytop
    SEC
    SBC #$01
    STA paddle1ytop

    JSR UpPaddleNext ; jump to subroutine for the inbetween paddles.

    LDA paddle1ybot
    SEC
    SBC #$01
    STA paddle1ybot
BottomPaddle
;; if paddle top > top wall
;; move paddle top and bottom up
MovePaddleUpDone:

Here is the subroutine:
    LDX #$00
UpPaddleNext:
    LDA paddle1ynext,x
    SEC
    SBC #$01
    STA paddle1ynext,x
    INX ; go to next byte in paddle1ynext?
    CPX $03
    BNE UpPaddleNext
RTS
I think the problem lies in my subroutine or my initialising of variables which is below, is it possible to access the next byte of memory stored in my variable with the above syntax?

I initialise the variables in the 4 byte variable as follows:

  LDA #$68
  STA paddle1ynext

  LDA #$70
  STA paddle1ynext+1

  LDA #$78
  STA paddle1ynext+2

  LDA #$80
  STA paddle1ynext+3

Is that correct syntax? I thought I've seen it somewhere.

Basically what is happening on screen is that some of the paddle sprite appears at the top and bottom of the screen, not a full tile just a small section. Then it goes completely offscreen, then the full paddle comes together for a second and I can move it together as I intend. But if I keep moving it up the top sprite of the paddle goes above all the rest creating a gap. Could this be related to Vblank time?


Edited: 02/21/2012 at 03:47 AM by glenn101

Feb 21, 2012 at 7:34:53 AM
muffins (0)
avatar
(I am Error.) < Tourian Tourist >
Posts: 44 - Joined: 01/31/2012
Maine
Profile
A few things: What are "TopPaddle" and "BottomPaddle"? Variables, labels? Nothing seems to be happening with them, no reference elsewhere. Maybe I don't know of an alternate syntax for what you use them for because I would think those would throw compiler errors.

Secondly, I assume you have a block of code that takes the values stored in paddle1ytop, paddle1ybot, paddle1ynext, +1, +2, +3 and then puts them into the sprite memory (i.e. at $0204, $0208, etc.) otherwise changing these variables wouldn't be helping change what is on the screen.

Lastly, and I think this is the issue - LDX #$00 should come after the UpPaddleNext: label in your subroutine. Otherwise it never clears the X register out because the JSR goes right to the label, and whatever happens to be in X is whatever you use as your starting index from there onward. I think that is what is causing the weird behavior.

Dan

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


Feb 21, 2012 at 1:12:14 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
There's something very wrong with your sprites page writes it looks like, look at it in the hex editor. Good luck finding it.


Edited: 02/21/2012 at 01:48 PM by removed04092017

Feb 21, 2012 at 1:36:51 PM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
Should it be CPX #$03 and not CPX $03?

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

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


Feb 21, 2012 at 4:06:49 PM
muffins (0)
avatar
(I am Error.) < Tourian Tourist >
Posts: 44 - Joined: 01/31/2012
Maine
Profile
Good call KHAN. Also I was wrong about the LDX comment. It does need to be cleared before looping but shouldn't be under the label you have. Rather you should be jumping to a label above the LDX #$00 instruction, then once the loop is started you loop to the label you currently have in your code.

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


Feb 21, 2012 at 6:58:06 PM
glenn101 (0)
avatar
(Glenn Kirilov) < Tourian Tourist >
Posts: 37 - Joined: 02/11/2012
Victoria
Profile
You guys are so awesome

TopPaddle and BottomPaddle were just old labels I had, I've gotten rid of them now.

I update all the sprites elsewhere in my code, exactly how you mentioned.

Good point about LDX, I'm lucky that works because X is put to #$00 before I enter that subroutine, so the way I wrote it above the label serves no purpose as you mentioned. I'll make another label there for more defensive programming, thanks for pointing that out.

Changing the compare fixed it straight away!, awesome spot! I've been caught out with that before, I'll be much more careful in the future. Thanks again guys!

Feb 21, 2012 at 7:24:14 PM
Drakon (0)
This user has been banned -- click for more information.
(Dra kon) < Meka Chicken >
Posts: 599 - Joined: 10/27/2010
Ontario
Profile
go glenn gooo! Make awesome pong and then....something even more awesome!

Feb 21, 2012 at 9:35:29 PM
glenn101 (0)
avatar
(Glenn Kirilov) < Tourian Tourist >
Posts: 37 - Joined: 02/11/2012
Victoria
Profile
Hmm, now I have a collision issue,I'm certain this time it's just a syntax thing. Am I using CMP correctly with variables? I'm sure my logic is right, because if ballx < paddle1x in my first check, the code executes as I want.

CheckPaddleCollision:
  ;;if ball x < paddle1x
  LDA ballx   
  CMP #PADDLE1X
  BCS CheckPaddleCollisionDone ; PADDLE1X=PADDLE1X-ballx, if ballx
  ;;if bally > paddleytop
  LDA bally
  CMP #paddle1ytop
  BCC CheckPaddleCollisionDone ; paddle1ytop=paddle1ytop-bally, if bally>paddletop then carry so execute code. If bally
  ;;if bally < paddleybot
  LDA bally
  CMP #paddle1ybot            
  BCS CheckPaddleCollisionDone ; paddleybot=paddleybot-bally, if bally
  ;;Bounce ball now.
  LDA #$01
  STA ballright             ; ball now moves right on next NMI.
  LDA #$00
  STA ballleft         ;;bounce, ball now moving right
CheckPaddleCollisionDone:


*EDIT*
I think I've got my subtracts around the wrong way in my comments, CMP performs a SUB the same way except it isn't stored in memory, I've thought of it back-to-front that may be the problem.

*EDIT*
Fixed!! That damn CMP got me again! I should be using CMP "varname" not CMP # "varname"


Edited: 02/21/2012 at 10:20 PM by glenn101

Feb 21, 2012 at 10:21:26 PM
muffins (0)
avatar
(I am Error.) < Tourian Tourist >
Posts: 44 - Joined: 01/31/2012
Maine
Profile
Remove the # sign and you'll be all set. It will substitute the value at that memory address for the variable, not the address of the variable itself.

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


Feb 21, 2012 at 10:30:07 PM
glenn101 (0)
avatar
(Glenn Kirilov) < Tourian Tourist >
Posts: 37 - Joined: 02/11/2012
Victoria
Profile
Your exactly right muffins, I just realised that around a minute ago!

Mar 2, 2012 at 10:45:51 AM
DomNes (0)

(Dom Cast) < Cherub >
Posts: 3 - Joined: 03/02/2012
Quebec
Profile
Sup all just want to say first that those tutorials are amazing!! thanks alot!

Now i have a couple of questions so far..

1. How can you clear the sprites?? when i come back to the title screen after any players have 15 points, the sprites are still on the screen with the title screen since i only updated the title background...

2. Now when players have 15 points, i enter the gameover state in which i just stop moving the sprites and wait for a player the press A, and in the title screen waiting to press START. The problem is if i put both Gameover and Title state to press Start.. even if you press quickly (lol) it will pass both state.. is there a way to keep START button for both screen but not passing over the title screen. Something like making sur the buttons are unpressed before you pressed START again.

Thanks!

Mar 2, 2012 at 11:03:32 AM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
Question 1: Use 2 kinds of game states, one for the logic in the infinite loop, and one for the NMI, say you call them TitleLogic/TitleNMI, PlayingLogic/PlayingNMI e.t.c.
Then you just don't transfer the sprites with DMA in the game states you don't want sprites in.

Question 2: http://www.nintendoage.com/forum/...
Nothing about it in the tutorial, but look in the source code how he handle input there.

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

Mar 2, 2012 at 11:42:05 AM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
1:
LDX #$00
Loop:
LDA #$FF
STA $0300,x (or wherever your sprites are)
INX
CPX #$FF (or however many sprites you're using)
BNE Loop
RTS

2. Just create a flag in the zero page and set it to 1 when a button is pressed. If the flag is still 1, skip the controller reading routine. When you release the button, set the flag to 0.

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

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



Edited: 03/02/2012 at 11:42 AM by KHAN Games

Mar 2, 2012 at 2:44:55 PM
DomNes (0)

(Dom Cast) < Cherub >
Posts: 3 - Joined: 03/02/2012
Quebec
Profile
1: if i understand well... putting the four settings of a sprites at $0200, x to $FF will "clear/delete" the sprites?

2: i havent looked yet at the code but i will soon.
Even with a fully working pong i dont know what is a flag :S

ty for quick reply

Mar 2, 2012 at 3:40:14 PM
MetalSlime (0)
avatar
(Thomas Hjelm) < Crack Trooper >
Posts: 140 - Joined: 08/14/2008
Japan
Profile
Originally posted by: DomNes

1: if i understand well... putting the four settings of a sprites at $0200, x to $FF will "clear/delete" the sprites?
 

Yes.  Actually, technically you only need to set the sprites' Y coordinate values to a high value so they will be offscreen.  But it's common to write #$FE or whatever to all sprite attributes because it's not worth the trouble to isolate every 4th index.


-------------------------
MetalSlime runs away

My nesdev blog: http://tummaigames.com/blog...

Mar 3, 2012 at 12:41:19 AM
DomNes (0)

(Dom Cast) < Cherub >
Posts: 3 - Joined: 03/02/2012
Quebec
Profile
ohhh great to know!!

and i have looked at the code for the joypad and basicly you just skip the instruction if you are pressing the same button as the previous frame.

Ive got an other question!
Let's say i want to make a game with a gun, the gun would shoot 1 bullet (sprite) every half second if i hold the A button... how do i do that?
I've read that their is 60 frame per second so basicly it reads the code 60 times per second??
So could i do a counter and just fire everytime the counter hit 30 then reset the count blablabla.
Or am I completly misunderstanding the situation here lol

Mar 3, 2012 at 3:53:11 AM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
No, you're right on.

;;A Held? JSR Routine

Routine:
LDA Timer
CMP #$30
BCS .Shoot
INC Timer
RTS
.Shoot:
;;shoot code
LDA #$00
STA Timer
RTS

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

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


Jul 7, 2012 at 8:32:07 PM
JC-Dragon (0)
avatar
(JC Childs) < Eggplant Wizard >
Posts: 388 - Joined: 04/24/2011
United States
Profile
it was inevitable but here I am asking for help again. I'm trying to map my controller to move sprites for the paddles. I can get a sprite to move but with the wrong button.
MovePaddleUp:
LDA buttons1
AND #$00001000 <--------- this is supposed to be the up button but NESASM throws an error at me when I do this
BEQ MovePaddleUpDone ; but if I change it to #$00000010, or #$00000001 it works but with start
LDA $0204 ; and right respectively is there something else I need to do to get this to work correctly before hand?
SEC
SBC #$01 ; if up button pressed
CMP #TOPWALL
STA $0204 ; if paddle top > top wall ; move paddle top and bottom up

-----EDIT----

figured it out  #$00001000 is supposed to be #%00001000. got the $ and the % mixed up.

-------------------------
You can't depend on your eyes when your imagination is out of focus
- Mark Twain


Edited: 07/07/2012 at 08:46 PM by JC-Dragon

Aug 2, 2012 at 7:59:38 PM
DC (0)

< Cherub >
Posts: 3 - Joined: 08/02/2012
United States
Profile
After a game over the game shortly plays and crashes. I can't get the collision date to work either.

http://pastebin.com/5X1Us01D...

Help please.

Aug 3, 2012 at 10:29:50 AM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
It would really help if you provided a ROM just so we could see what is going on rather than trying to figure out what "after a game over the game shortly plays and crashes" means.

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

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


Aug 3, 2012 at 2:21:38 PM
DC (0)

< Cherub >
Posts: 3 - Joined: 08/02/2012
United States
Profile
Ok

http://depositfiles.com/files/7gv...

Another person caught the freezing problem. The Nmi was filling up the stack. New code:

http://pastebin.com/uL1vFmDL
The collision data fails to work I can't figure out why :/.The code to make the ball bounce seems to work.


Edited: 08/03/2012 at 02:33 PM by DC

Aug 3, 2012 at 3:39:01 PM
Mario's Right Nut (352)
avatar
(Cunt Punch) < Bowser >
Posts: 6636 - Joined: 11/21/2008
Texas
Profile
I suck at fixing other people's code. Typically it doesn't work because you mess up a BCS or BCC. Like get them backwards. It helps to draw it out.

If NMI fills up the stack, you have an open JSR/RTS loop somewhere.

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

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.


Aug 3, 2012 at 4:33:54 PM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
One thing that's jumping out at me is at the end of your gamestates, you're doing a JMP straight back to your GameEngine, where you should be doing a JMP to GameEngineDone. I don't think your code is even getting to any of your other subroutines.

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

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


Aug 3, 2012 at 5:21:04 PM
DC (0)

< Cherub >
Posts: 3 - Joined: 08/02/2012
United States
Profile
I got a JMP GameEngineDone at the end of EnginePlaying.

The code:

CheckPaddleCollision:
LDA ballx
CMP #PADDLE1X+8
BCS CheckPaddleCollisionDone ;;if ball x > left wall, still on screen, skip next section
LDA bally
CMP paddle1y+2
BCS CheckPaddleCollisionDone ;;if ball y > top wall, still on screen, skip next section
LDA bally
CMP paddle1y2+2
BCC CheckPaddleCollisionDone ;;if ball y < bottom wall, still on screen, skip next section
LDA #$01
STA ballright
LDA #$00
STA ballleft ;;bounce, ball now moving right
JMP CheckPaddleCollisionDone
CheckPaddleCollisionDone:
RTS

Seems right to me.

Finished:

http://pastebin.com/cZAUUTfH
Any tips for optimization?


Edited: 08/04/2012 at 04:16 PM by DC

Sep 28, 2012 at 7:03:19 PM
Beep Boop! (1)
avatar
(Bzzt Bzzzt) < Crack Trooper >
Posts: 161 - Joined: 09/25/2012
Korea, Dem. People's Rep of
Profile
I'm at a loss... I need to display a number using a background tile on the title screen... but graphics are only uploaded to the PPU memory once on the init code (before the JMP Forever loop). Can someone help me? Do I need to reupload BG data frame-by-frame?

Edit: ooh never mind, didn't notice that you could set the PPU writing address to anywhere you wanted to. Cool


Edited: 09/28/2012 at 07:09 PM by Beep Boop!