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

Nerdy Nights week 7 subroutines, game layout, starting Pong

Jan 22, 2012 at 6:16:20 PM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
Hey hey, again. Sorry for the double post,
but the edit in the last post didn't seem to get any answer, nevermind that. I'm working on a pong game, and I get the background to show up in the title screen,
but the text tiles are in the wrong place. If I press the start button,
the tiles end up in their right spot, but I can't figure out what's wrong. Here is the NMI and title screen code:


Nmi:
  LDA #$00
  STA $2003
  LDA #$02
  STA $4014


  LDA #%10010000
  STA $2000
  LDA #%00011110
  STA $2001
  LDA #$00
  STA $2005
  STA $2005
  JSR ReadController1
  JSR ReadController2
GameStates:
  LDA gameState
  CMP #GSTITLE
  BEQ TitleScreen
  LDA gameState
  CMP #GSPLAYING
  BEQ PlayScreen
  LDA gameState
  CMP #GSGAMEOVER
  BEQ GameOverScreen
GameStatesDone:
  RTI
TitleScreen:
  LDA #$00
  STA $2000
  STA $2001
  LDX #LOW(TitleBG)
  LDY #HIGH(TitleBG)
  JSR SetBGPointer
  JSR LoadBG
  LDA #%10010000
  STA $2000
  LDA #%00011110
  STA $2001
  LDA #$00
  STA $2005
  STA $2005
  LDA controller1
  AND #%00010000
  BEQ DontStartGameYet


  LDA #GSPLAYING
  STA gameState
DontStartGameYet:
  JMP GameStatesDone

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

Jan 22, 2012 at 6:28:58 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
Try adding a LDA $2002 to the beginning, as you NEED to read that to tell the PPU that you know a NMI happened. When you do the STA $2000 with the NMI enabled, you are causing another one to occur most likely. You should also look into cleaning up your program flow and take everything out of the NMI and make it it's own real program. Good luck, hope that's the problem.

Jan 22, 2012 at 10:52:59 PM
NESHomebrew (21)
avatar
(Brad Bateman - Strange Brew Games) < King Solomon >
Posts: 4266 - Joined: 04/28/2008
Saskatchewan
Profile

Yea, I'm seeing a lot of red flags in that code.  Check out this NMI document by DISCH.  It has a lot of good stuff in it.


Jan 23, 2012 at 4:17:47 AM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
Thanks guys, that sure clears up a lot.
I'll make sure to read that document and try to fix this before
bugging you again.

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

Jan 23, 2012 at 8:32:07 AM
Dennis Fleaman (8)
This user has been banned -- click for more information.
(dev 2) < Meka Chicken >
Posts: 713 - Joined: 02/13/2011
Netherland Antilles
Profile

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





WWW.RETROPLAYER.NL...
 


Jan 23, 2012 at 1:43:19 PM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
That is also very helpful, thank you.
I'm having a little trouble understanding buffering, but I will just read the NMI doc again a couple of times.
One question that arose after reading it the first time tho. In bunnyboys pong files, he have the game state
machine in the NMI, but wouldn't this code count as logic? Shouldn't it be in the infinite loop or at least
somewhere outside of the NMI?

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

Jan 23, 2012 at 1:53:00 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile

DP



Edited: 01/23/2012 at 01:54 PM by removed04092017

Jan 23, 2012 at 1:53:45 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
If you have problems you needed answered in depth you can mail me, but yes the logic is in the NMI and that isn't always terrible. But once you try to put different "engines" in programs, you'll need different NMI's to handle stuff, so some programs (All of mine, many others) just do something like this:

NMI:
BIT $2002 ;Tell PPU you acknowledged the NMI
INC Frame ;Just a frame counter variable to tell the rest of the computer it's a new frame.
RTI ;Return, hopefully the program was already waiting for the NMI to happen so it won't slow down.

And then in their programs, they just do a JSR WaitForNMI that waits for the Frame variable to be change, and when changed, then runs some logic after the JSR to the vblank wait. One bad thing is that if your calculations spill over your music will also slow down by half too, which isn't that good, but the method is still the simplest to use in the long run.

Jan 23, 2012 at 4:00:35 PM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
Thanks for the offer, and thanks for the tip, will definitely see what I can do with that.
Found something interesting here too:
http://www.nintendoage.com/forum/...
For the buffering, so if I can't fix this now, I probably should go and read a book on
computer science first. One thing tho, just to make sure I got it right. I can see in some files, like in
the sound engine(from the link), that you save the registers at the beginning of NMI and restore at the end.
This is so the code outside the NMI won't be disrupted, right?

Thanks for all the help!

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

Jan 23, 2012 at 4:16:35 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
On the IRQ/NMI, I believe the status is saved so that doesn't need pushed, but not the registers, so yes you will have to save all registers you use if you do not use the simple BIT/INC NMI routine.

Jan 24, 2012 at 6:41:29 AM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
Sorry, but the more I read, the more confused I get, so I guess I will have to spend more (of your)time
here than I thought at first. x_x
Your way to do it seems to be the simplest one, so perfect for a simplteton like me, but I still just sort of get it, which isn't much at all.
I have found some source code with different ways to handle the NMI, but none that do it the way you do it,
just stuff that at the moment is way over my head. Where would I put the drawing code if not in the NMI? In the main loop? A separate sub? What about the game states?
I'm having a lot of trouble figuring out where to put what in the program, and even tho I have been following along
the NN tutorials, some of this stuff still seems like black magic to me.
For instance, bunnyboy's pong code have the game states and the controller reading in the NMI, but I have seen some people say this is verry bad, and that that code should go in the main loop. This is all verry confusing to say the least.
Have I completely missed something here, or should I just go and get a 6502 for dummies or something?

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

Jan 24, 2012 at 6:44:28 AM
Jero (1)
avatar
(Jeroen ) < El Ripper >
Posts: 1106 - Joined: 03/02/2008
Netherlands
Profile
It all depends on what you are comfortable with vs some optimization. Technicly you could put all your game logic in the nmi as long as you make sure to update the screen first. What most people do in my experience is either tie their main logic to nmi or have a little "flag" in ram that tells the main code nmi happend and that another frame has to be processed.

Jan 24, 2012 at 7:23:35 AM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
Nah, just don't worry about those things and just go with that NN says, you'll get it later when you need to make multiple NMI's later.

Jan 24, 2012 at 1:15:49 PM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
Hey, I got the background to show up properly now, but now the controller input won't work, and I have
no idea why. http://pastebin.com/m15iLpnT...
Would be cool if anyone could take a gander at this.
Would that at least be a good way to handle the NMI? Or am I completely screwing up something else now?

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

Jan 24, 2012 at 1:28:17 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
The NMI might be a ticker, but don't keep relying on it for every part of your program. But yes, that will work for now. It seemed okay to me for P1, try looking at FCEUX's hex editor at the variables or maybe even the debugger and try to find it with those and get to know those tools well.

Jan 24, 2012 at 1:54:13 PM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
Hmm, debugging C++ code with VC++ express is no problem, so I'll figure that out.
But when I checked the hex editor my eyes went T_T and my brain went X_X.
Care to give me a hint on how it works?

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

Jan 24, 2012 at 1:57:07 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
Look at the .fns file NESASM3 makes, and find the RAM label that the controller is going to to debug it via looking at the hex editor. Then look for that piece of RAM in the hex editor. You can also set breakpoints in the debugger to reads/writes/exectues to memory, including all RAM. Use all those to find/debug problems. And don't be intimidated by the hex editor, you wrote the program to use all the bytes, that's harder than reading it.


Edited: 01/24/2012 at 01:57 PM by removed04092017

Jan 31, 2012 at 10:03:21 AM
muffins (0)
avatar
(I am Error.) < Tourian Tourist >
Posts: 44 - Joined: 01/31/2012
Maine
Profile
This is probably a bad question at this point in the game, but I'm having trouble figuring out how the background is becoming a bunch of zeroes. It appears that it is happening in this block of code:


;;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


Though I'm not sure why it is defaulting to those zeroes. Could someone shed some light on this?

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



Edited: 01/31/2012 at 10:18 AM by muffins

Jan 31, 2012 at 10:38:00 AM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
The background is becoming a bunch of zeroes because it's pulling the background from pattern table 1. The first tile of pattern table 1 is a 0, so it's placing that same tile over and over until the screen is full. He doesn't have a routine that is drawing any sort of special background. If you edit the CHR file with tile layer pro, you could change that to anything you wanted.

In later lessons you learn how to display a proper full nametable.

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

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


Jan 31, 2012 at 10:44:55 AM
muffins (0)
avatar
(I am Error.) < Tourian Tourist >
Posts: 44 - Joined: 01/31/2012
Maine
Profile
I see, so this is a default behavior when you choose a pattern table for a background. So as an alternative right now, I could hard code a background as he did from the Background tutorial. Thanks!

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


Feb 5, 2012 at 2:45:47 PM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
I'm really sorry that I'm raping this thread with questions, but I want to finish this pong clone
so I can go on and start coding for real.
The problem I'm having is with the paddle collisions. Here is my code for it.
Player1Collisions:
LDA player1
CMP ballPos+1
BNE .return

LDA player1+3
CMP ballPos
BNE .return
LDA #$01
STA ballDirection+1
STA ballDirection+2
LDA #$00
STA ballDirection
LDA ballDirection+3
.return:
RTS

And this subroutine is called in the main loop at the end, after the input is handled
and the sprites are updated. Everything I have done so far seems to work fine EXCEPT the paddle collisions.
Here is all the code, if it make things easier. http://pastebin.com/eTVKQgGx...
ballPos is x, ballPos+1 is y, player1 is y and player1+3 is x.

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

Feb 5, 2012 at 8:09:24 PM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
I won't be much help without your ROM. Maybe someone else can pipe up.

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

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


Feb 6, 2012 at 11:10:34 AM
Mario's Right Nut (352)
avatar
(Cunt Punch) < Bowser >
Posts: 6636 - Joined: 11/21/2008
Texas
Profile
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.

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

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 6, 2012 at 3:00:42 PM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 441 - Joined: 12/08/2011
Sweden
Profile
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!



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

Feb 6, 2012 at 11:23:00 PM
muffins (0)
avatar
(I am Error.) < Tourian Tourist >
Posts: 44 - Joined: 01/31/2012
Maine
Profile
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:

LDX #$00

loop:
LDA paddle1ytop, x ;;update paddle sprites
STA $0204, x

LDA #$5B
STA $0205, x

LDA #$01
STA $0206, x

LDA #PADDLE1X
STA $0207, x

INX
CPX #$01
BNE loop

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.

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