Skip navigation
Welcome, Guest! Please Login or Join

Loading...

Nerdy Nights week 7 subroutines, game layout, starting Pong

Dec 17, 2009 at 12:51:23 PM
udisi (88)
avatar
< King Solomon >
Posts: 3261 - Joined: 11/15/2006
United States
Profile
yup write to the next loaction

LDA (Ball sprite y potision)
STA $0200
LDA (Ball sprite tile number)
STA $0201
LDA (ball palette number)
STA $0202
LDA (ball x position)
STA $0203
then you can add paddles next. depends on how big you want your paddles, probably atleast 2 sprites a paddle

LDA (paddle1 top y postion )
STA $0204
LDA (paddle sprite. You can use the same sprite for both sections)
STA $0205
LDA (paddle sprite palette number)
STA $0206
LDA (paddle1 top x position)
STA $0207

etc
etc
etc




Edited: 12/17/2009 at 12:51 PM by udisi

Dec 17, 2009 at 3:25:10 PM
themaincamarojoe (0)
avatar
(Joe Jackson) < Cherub >
Posts: 8 - Joined: 12/17/2009
California
Profile

How do we use the ReadController and the ReadControllerLoop to read the controller.  According to the post, we need to write to the appropiate bit.  So, for example, if I want one of my tiles to move up, I kow that I need to write to bit 3, or %00001000. 

bit:       7     6     5     4         3       2       1     0

button: A     B   select start  up   down  left right

I guess that if I wanted to read up I would use the following instruction.

LDA #%00001000
STA button1

What I'm confused about is where to write this?  Do I use a JSR to hop to ReadControllerLoop and then write to button one?  Before we used an instruction like this:

ReadUp:
   LDA $4016
   AND #%00000001
   BEQ ReadUpDone
   LDA $0200
   SEC
   SBC #$01
   STA $0200
ReadUpDone:

How do I combine these instructions to write to up?


Dec 17, 2009 at 3:25:24 PM
MODERATOR
KHAN Games (88)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 7760 - Joined: 06/21/2007
Florida
Profile
In the first loop, you are loading all the sprites when the screen is drawn. The second way just looks like a subroutine that is used to change the way a sprite looks when it's already on the screen.

Dec 17, 2009 at 3:31:09 PM
MODERATOR
KHAN Games (88)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 7760 - Joined: 06/21/2007
Florida
Profile
The previous post was for the previous sprite question. Sorry, hard to keep up on the iPhone.

Basically to move the paddle up, you need to look at the las thing you just typed. That subroutine is looking to see if the button is pressed, and if so, running the instructions under it. You'd just replace that stuff with:

lda $0300
sec
sbc $#01
sta $0300

that will move the sprite up one pixel per frame if the button is pressed. Make sure you're putting it after the bne pressdowndone or whatever it's called though.

Dec 17, 2009 at 3:32:21 PM
MODERATOR
KHAN Games (88)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 7760 - Joined: 06/21/2007
Florida
Profile

Dec 17, 2009 at 4:38:24 PM
themaincamarojoe (0)
avatar
(Joe Jackson) < Cherub >
Posts: 8 - Joined: 12/17/2009
California
Profile
I'm still confused. Where exactly do I put this.  Can it before or after RTI?  What's at $0300?  Would I create a ReadA, ReadB, etc section like in earlier post, or would this be done differently?  I got the controller to work before, but I'm trying to use the new savy way.

Dec 17, 2009 at 5:22:26 PM
udisi (88)
avatar
< King Solomon >
Posts: 3261 - Joined: 11/15/2006
United States
Profile
You can put this anywhere after NMI. To save space, you would probably want to put it outside your game engine loop and call it when needed.

code
code
code
JSR ReadUp (call the routine when you wanna see if you should move the paddle up
JSR ReadDown(same thing to check down)
code
code
code


;;;;;;;;;;;;;;;;;;;Outside routine;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ReadUp:
   LDA $4016
   AND #%00000001
   BEQ ReadUpDone
   LDA $0200(paddle sprite Y position)
   SEC
   SBC #$01
   STA $0200(paddle sprite Y position)
ReadUpDone:

RTS

ReadDown:
code
code
code
ReadDownDone:
RTS




The way I did it is like this. This is my Playing engine for a 1 player game. Each one of these JSR jumps to the routine outside the engine loop then returns. My MovePaddleUp sub routine is pretty much the same as yours except I do a few more things there before returning. This routine here runs once ever NMI, so 60 times a sec.

EnginePlaying1P:
 
  JSR MoveBall
  JSR movephan11
  JSR movephan12
  JSR movephan21
  JSR movephan22
  JSR MovePaddleUp
  JSR MovePaddleDown
  JSR MoveCPU
  JSR CheckPaddleCollision
  JSR check1ppower
  JSR Startgame1p

  JMP GameEngineDone

Dec 18, 2009 at 2:25:05 AM
MetalSlime (0)
avatar
(Thomas Hjelm) < Crack Trooper >
Posts: 140 - Joined: 08/14/2008
Japan
Profile
Originally posted by: themaincamarojoe

How do we use the ReadController and the ReadControllerLoop to read the controller.  According to the post, we need to write to the appropiate bit.  So, for example, if I want one of my tiles to move up, I kow that I need to write to bit 3, or %00001000. 

bit:       7     6     5     4         3       2       1     0

button: A     B   select start  up   down  left right

I guess that if I wanted to read up I would use the following instruction.

LDA #%00001000
STA button1

What I'm confused about is where to write this?  Do I use a JSR to hop to ReadControllerLoop and then write to button one?  Before we used an instruction like this:

ReadUp:
   LDA $4016
   AND #%00000001
   BEQ ReadUpDone
   LDA $0200
   SEC
   SBC #$01
   STA $0200
ReadUpDone:

How do I combine these instructions to write to up?


With the new ReadController routine you don't need to mess with ReadUp or ReadDown or anything like that ever again.

The new ReadController should be called once per frame.  It reads the button states for you and stores them in a zero page variable called "buttons1".  This variable is then available for you to peek at and see which buttons were pressed.  This is done by reading the variable, not writing.  Any time you want to check if up is pressed, you just need to check the appropriate bit in your "buttons1" variable:

;check to see if up was pressed.
    lda buttons1        ;load the current button state for controller1
    and #%00001000   ;isolate the bit representing "up", by clearing all the other bits
    beq .skip            ;if the result was 0, then the "up" bit was clear (thus not pressed), so skip the following code
    ;...
    ;code for moving paddle position up here
.skip:
    ;code continues here.

Did that help?  If anything is still unclear, please ask!

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

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

Dec 22, 2009 at 1:21:04 PM
themaincamarojoe (0)
avatar
(Joe Jackson) < Cherub >
Posts: 8 - Joined: 12/17/2009
California
Profile
Where should I put this?  Should it be a subroutine and if so, when should it be called?  You said that this needed to be done once per frame, does that mean that I need to do it after VBlank?

Dec 22, 2009 at 1:55:14 PM
udisi (88)
avatar
< King Solomon >
Posts: 3261 - Joined: 11/15/2006
United States
Profile
make it a subroutine and have a JSR to it at the end of NMI

Jan 6, 2010 at 1:55:31 PM
themaincamarojoe (0)
avatar
(Joe Jackson) < Cherub >
Posts: 8 - Joined: 12/17/2009
California
Profile

So I've created a paddle using a tile from Mario.chr.  I'm sure there's an easier way to do it, but I'll worry about that later.  I've successfully been able to make the paddle move up and down using the older routing.  This can be seen in the below link:

http://www.acsalaska.net/~themaincamarojoe/Pong_with_old_con...

This works fine, but I'd like to use the newer routing.  The below link shows this attempt.

http://www.acsalaska.net/~themaincamarojoe/Pong_with_new_Con...

Now, I know I'm doing something wrong here.

On line 204 and 205 I jump to the routine which handles ReadUp and ReadDown, which is called after ReadController1 and ReadController2.  Lines 381 through 515 are the actual subroutines.  I thought I new a decent amount about assembly, but it seems as if the 6502 and the NES archeticture is more challenging that I anticipated.

Can you all please assist in pointing out my mistake.  Thank you everyone for being so helpful.

By the way, if you all know of a better way for me to show my code, let me know.


Jan 6, 2010 at 2:10:57 PM
Mario's Right Nut (350)
avatar
(Cunt Punch) < Bowser >
Posts: 6574 - Joined: 11/21/2008
Texas
Profile

Well, assuming that all the formatting issues came from the file transfer, I found the following. Your ReadUpDone: and ReadDownDone: are outside of your "RTS" commands.

And I would say that you need to change the controller reading routine back to the old way. I've never seen it done the way you are trying to do it, that doesn't mean it won't work, it just looks confusing to me. Why change what works?

Also, why do you have so many sprites on your up and down routines?


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

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.



Edited: 01/06/2010 at 02:11 PM by Mario's Right Nut

Jan 6, 2010 at 2:18:43 PM
Jero (1)
avatar
(Jeroen ) < El Ripper >
Posts: 1106 - Joined: 03/02/2008
Netherlands
Profile
I think I once did it that way. Don't do it that way, it causes problems on pal consoles.

Jan 6, 2010 at 2:28:17 PM
themaincamarojoe (0)
avatar
(Joe Jackson) < Cherub >
Posts: 8 - Joined: 12/17/2009
California
Profile

I'd like to my code to be efficent and clean as possible.  Plus, I'd like to follow BunnyBoy's advice as layed out in this tutorial.  This is why I'd like to change my old ways and adopt new better ways.

I moved the ReadUpDone: and ReadDownDone: inside RTS and it still is not working.


Jan 6, 2010 at 3:04:58 PM
bunnyboy (81)
avatar
(Funktastic B) < Bowser >
Posts: 7474 - Joined: 02/28/2007
California
Profile
In the 2nd link, you have no code after ReadDownDone. Should have an RTS there to get back to your JSR.

Jan 6, 2010 at 3:07:45 PM
bunnyboy (81)
avatar
(Funktastic B) < Bowser >
Posts: 7474 - Joined: 02/28/2007
California
Profile
And the real problem, there is no way to get to Player1Engine. That means controllers are never read, sprites are never moved, etc.

Jan 6, 2010 at 6:00:52 PM
themaincamarojoe (0)
avatar
(Joe Jackson) < Cherub >
Posts: 8 - Joined: 12/17/2009
California
Profile

Thanks a lot everyone.  I'm still having problems.  I did notice that my sprite wasn't bouncing around.  I got rid of the Player1Engine and moved the JSR ReadController1 back to where it was in the original tutorial.  I also placed my JSR ReadUp and JSR ReadDown to the same section (lines176 to 179).  However, my paddle still does not move. 

Below is the link for my souce code.  I recommend saving it and opening it in a notepad++ (my text editor of choice).

http://www.acsalaska.net/~themaincamarojoe/post/Pong_with_ne...


Jan 6, 2010 at 6:12:24 PM
bunnyboy (81)
avatar
(Funktastic B) < Bowser >
Posts: 7474 - Joined: 02/28/2007
California
Profile
Before your controller loops, you want LDX #$08 instead of LDA #$08. Otherwise who knows how many times that loop is running, erasing the button data.

Feb 18, 2010 at 3:33:52 PM
bigjt_2 (17)
avatar
(Yeah, I'm a fat bastard.) < Meka Chicken >
Posts: 703 - Joined: 02/17/2010
Indiana
Profile
Is there a further tut somewhere covering "NEXT WEEK: Drawing graphics, more Pong" and beyond? I can't seem to find it anywhere.

-------------------------
Every thread on this forum is very offensive.  Please lock every last goddammed one of them!

"Tell him you'll break his A button pusher."
                                                  --Otto Hanson
"Unlike the Sega Genesis, which will give you cancer."
                                                  --Randy the Astonishing

Mar 2, 2010 at 5:55:30 PM
rizz (9)
avatar
(Frank Westphal) < Eggplant Wizard >
Posts: 313 - Joined: 06/29/2007
Wisconsin
Profile
I'm trying to compile a list of the various IRQ's generated during game execution. I haven't begun learning sound programming yet, so there might be various IRQ's in that section.

This is what I know so far:
SEI and CLI disables and enables ALL IRQ's
frame counter IRQ's (see $4017)
DMC IRQ's (see $4010)
MMC3 IRQ's (see $C000, C001, E000, E001)
using BRK will generate your own IRQ

Which other things will trigger an IRQ? When/how exactly is that DMC IRQ triggered?

Thanks

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

My Development Blog


Jan 12, 2012 at 7:51:42 AM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 440 - Joined: 12/08/2011
Sweden
Profile
Hey, I have a question.
What are the constant values? Is it tiles from the .chr files or have I missed something?

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

Jan 12, 2012 at 9:20:25 AM
Mario's Right Nut (350)
avatar
(Cunt Punch) < Bowser >
Posts: 6574 - Joined: 11/21/2008
Texas
Profile
Constants are there so that you can use the number in multiple places and only have to change it in one...if you need to change it.

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

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.


Jan 12, 2012 at 1:40:10 PM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 440 - Joined: 12/08/2011
Sweden
Profile
Oh, sorry if I was unclear, I meant the constants in the pong1.asm file and the significance of those values.

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

Jan 12, 2012 at 4:18:00 PM
MODERATOR
KHAN Games (88)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 7760 - Joined: 06/21/2007
Florida
Profile
Basically he's setting a specific value to each state the game is in, so you don't have to keep track of which state is which number.

It's a lot easier to program for months on end and tell the game:

"LOAD STATEGAMEOVER "

Than try to remember which value STATEGAMEOVER is.

edit: and it looks like he's doing more constants than just the game states.

The top wall of his pong game will always be at the value $20, so when he tells the game:

"Stop the ball when it goes up on the screen to the $20 value"

He can just say:

"When ball hits TOPWALL, stop and go the other direction."


Edited: 01/12/2012 at 04:19 PM by KHAN Games

Jan 12, 2012 at 4:28:58 PM
DoNotWant (1)

(Ham Sammich) < Eggplant Wizard >
Posts: 440 - Joined: 12/08/2011
Sweden
Profile
Yes, it was the TOPWALL, e.t.c. constants I was wondering about, thank you!

Edit:
Hey, another question, about the controller reading function. I understand everything except how
the A button bit ends up in the buttons carry and not only the accumulators carry.
How does the LSR A line of code transfer data into the buttons variable?

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


Edited: 01/13/2012 at 08:39 AM by DoNotWant