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

Nerdy Nights week 7 subroutines, game layout, starting Pong

Dec 23, 2012 at 11:54:03 PM
JKeefe56 (55)
avatar
(Jim K) < Meka Chicken >
Posts: 883 - Joined: 12/05/2011
New York
Profile
Sorry, I've been stuck here for almost a week.

"Title State:
if start button pressed
turn screen off
load game screen
set paddle/ball position
go to Playing State
turn screen on"

I can't figure out this one. How does one turn the screen off? And, back on again?


-------------------------
This space intentionally left mostly blank.

Dec 23, 2012 at 11:57:37 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
You use the PPUMask ($2001) register. You disable rendering in vblank. (Outside of vblank will cause cheap and shitty looking screen tearing) (NOTE: You must stop background AND sprite rendering, not one or the other) But then you upload the other screen (the nametable) and then wait for vblank and turn on the screen again with PPUMask. Make sense?

Dec 24, 2012 at 12:05:45 AM
JKeefe56 (55)
avatar
(Jim K) < Meka Chicken >
Posts: 883 - Joined: 12/05/2011
New York
Profile
Hahahaha not entirely, but if I look at the examples, they must all be turning the screen on to start? so I have a general idea of where to go...I think! Thank you.


-------------------------
This space intentionally left mostly blank.

Dec 24, 2012 at 12:09:49 AM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
WHat don't you get? The reason you have to shut off the screen, though, is because write to $2007 during rendering get trashed, so you can't do it. So you have to turn the screen off. : And to start, yeah, they do I believe. Just look at it I guess. Need any help just post.

Dec 24, 2012 at 12:18:06 AM
JKeefe56 (55)
avatar
(Jim K) < Meka Chicken >
Posts: 883 - Joined: 12/05/2011
New York
Profile
Well, so, I'm thinking it would be:

LDA #%00000000
STA $2001

To turn it off? Or is that just "changing the settings" for lack of knowing a better term?

-------------------------
This space intentionally left mostly blank.

Dec 24, 2012 at 12:25:21 AM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
Yeah, that's all ya do.

Dec 24, 2012 at 12:26:55 AM
JKeefe56 (55)
avatar
(Jim K) < Meka Chicken >
Posts: 883 - Joined: 12/05/2011
New York
Profile
Thanks! appreciate the help!

-------------------------
This space intentionally left mostly blank.

Dec 27, 2012 at 3:33:49 PM
KennyB (14)
avatar
(No Go ogle result) < Eggplant Wizard >
Posts: 466 - Joined: 09/06/2006
Belgium
Profile
Can anyone help me (or point me in the right direction):

I changed the ball speed to 2/3/4/5/6 to make it go faster.
But at these higher speeds, the ball will change direction before or after the "walls" I programmed.
They seem to have an offset. For the right and top wall it will change direction before it should hit the wall. And for the left and bottom wall it will change direction after it should hit the wall.

(I think) I know why it does this ==> If the ball is, for example, 1 pixel before the wall ==> No collision ==> Increase the position of the ball with 5 (speed of the ball).
This means that the ball will be bounced and shown 4 pixels beyond the wall. But I don't know why the ball will change direction before hitting the right and top wall, but it will most likely have something to do with the difference in subtracting (right/top wall) and adding (left and bottom wall) the speed ?


My first thought (and attempt to fix it) was to create a loop for the movement + collision checking and have it repeat X amount of times.

Pseudo code:
While x not equal to speed
Move by 1 pixel (left/right/up/down)
Check collision (if wall is hit ==> reverse directions)
Increase X

This code would make the sprite move by 1 pixel a time and check every time if it hit's a wall and change direction.
So I tried to code it but it didn't seem to work (or I implemented it wrong)

Is this the correct way to solve my problem ? (before I put a lot of time figuring out how to implement the code correctly) 
Also; at which frequency will my game run ? At 50/60 fps (when the NMI resets) ? Is it then usefull to create the loop ? 





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


Edited: 12/27/2012 at 03:45 PM by KennyB

Dec 27, 2012 at 4:50:59 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
Games will run at 50Hz on a PAL NES, and 60HZ on a NTSC NES.

As for it being after the wall, make sure you're doing your compares right. It's possible it's doing it because at 6 pixels, it's a far distance to cover each frame so it won't actually be seen hitting the wall when it goes past it.

Dec 27, 2012 at 7:01:45 PM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
If you're moving the ball 5 pixels per frame, it may miss your compare completely if you're doing a branch if equal. Make sure you're doing a branch if greater/less than!

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

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


Dec 28, 2012 at 6:24:45 AM
KennyB (14)
avatar
(No Go ogle result) < Eggplant Wizard >
Posts: 466 - Joined: 09/06/2006
Belgium
Profile
Originally posted by: 3GenGames

Games will run at 50Hz on a PAL NES, and 60HZ on a NTSC NES.

As for it being after the wall, make sure you're doing your compares right. It's possible it's doing it because at 6 pixels, it's a far distance to cover each frame so it won't actually be seen hitting the wall when it goes past it.
Originally posted by: KHAN Games

If you're moving the ball 5 pixels per frame, it may miss your compare completely if you're doing a branch if equal. Make sure you're doing a branch if greater/less than!

I used the BCC and BCS instructions after a CMP. So they will branch if greater/less than. 

 CheckCollisionRight:
  LDA boxRightXre">
  CMP #RIGHTWALL
  BCC CheckCollisionRightSkipper ; if A < RIGHTWALL ==> Carry is set to 0 ==>jump to label and skip over the direction change. If A >= RIGHTWALL ==> Carry = 1 ==> No jump to label and run change direction code
  LDA #$00
  STA ballright
  LDA #$01
  STA ballleft   
  CheckCollisionRightSkipper:
  JMP CheckCollisionRightDonere">
  
CheckCollisionLeft:
  LDA boxLeftX
  CMP #LEFTWALL
  BCS CheckCollisionLeftSkipper    if A >=  RIGHTWALL ==> Carry is set to 1 ==>jump to label and skip over the direction change. If A < RIGHTWALL ==> Carry = 0 ==> No jump to label and run change direction code
  LDA #$01
  STA ballright
  LDA #$00
  STA ballleft 
  CheckCollisionLeftSkipper:
  JMP CheckCollisionLeftDonere">


So the ball always bounces. But at the higher speeds, it often bounces to soon or to late. I'm thinking that it's impossible to eliminate this problem as it only updates at 50/60 Hz.
If the ball is 1 pixel before the wall in frame 1 ==> no hit ==> no change of direction.
In the next frame the ball will be 4 pixels behind the wall ==> it will branch ==> change direction. But it will still update the sprite for that frame and it will show it 4 pixels behind the wall. 

And If I create a loop which will update the location of the ball one pixel a time, it will slow down my ball :
==> frame 1 ==> loop 1 ==> 1 pixel moved 
==> frame 2 ==> loop 2 ==> 1 pixel moved
==> frame 3 ==> loop 3 ==> 1 pixel moved
==> frame 4 ==> loop 4 ==> 1 pixel moved
==> frame 5 ==> loop 5 ==> 1 pixel moved

So in the end we still need 5 frames to perform 5 loops and we move only 5 pixels ==> which is exactly the same as moving 1 pixel a frame (or at a speed of 1 instead of 5).



 

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

Dec 28, 2012 at 1:06:29 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
Yeah, it's happening because the movement is so great that you don't see it hit, but it hit anyway because it went past the paddle anyway.

Jan 3, 2013 at 11:45:05 PM
LucasWeatherby (42)
avatar
(Lucas Weatherby) < El Ripper >
Posts: 1284 - Joined: 03/18/2011
Florida
Profile
After a very long hiatus, I am back again to take another stab at programming. I have control of the paddles and the collision detection working. I am really struggling here with drawing the score to the background. After my UpdateSprites routine I have:

DrawScore:

LDX #$01
LDA palette, x
STA $2007
RTS


where the palette looks like this:

palette:
.db $00,$01,$02,$03, $22,$36,$17,$0F, $22,$30,$21,$0F, $22,$27,$17,$0F ;;background palette
.db $22,$1C,$15,$14, $22,$02,$38,$3C, $22,$1C,$15,$14, $22,$02,$38,$3C ;;sprite palette


It draws the number 1 to the background like I wanted. (eventually ill add the logic for the score instead of statically loading it) but right now I am struggling with the location of the score. For some reason it ends up in the bottom left corner. I cant figure out how to specify the location of a tile for the background. In the previous tutorial, you could specify the background locations by how the palettes were arranged but it was like a one time load and it wasnt changing. This is why I am confused

Jan 3, 2013 at 11:59:09 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
Are you properly setting the location to PPU RAM/Screen RAM that you want it to display at? Plus that could be written as palette+1 since there's no loop, you don't need X. I don't exactly get what the palette means, though, as...it should be written to 3F00 inside PPU RAM, and then that's it. You don't need to touch the palette data after that. You need to display tiles, not colors. To put a score to a where it's just a single digit in two places where Score is an array of 2 bytes in RAM,byte 0 being the left player:

PPUAddr=$2006;
PPUData=$2007
LDA #$20;Screen location for first digit of score
STA PPUAddr
LDA #$4E;Location. Locations $204F and $2050 are both going to be either blank, or a DASH to seperate the digits
LDX Score
LDA ScoreDigitTiles,X
STA PPUData ;Store to 1st character to screen.
LDA PPUData 
LDA PPUData;Move 2 bytes of the screen location.
LDA Score+1
LDA ScoreDigitTiles,X
STA PPUData ;Store 2nd character to screen.
(RTS,JMP,Other code, anything to keep it seperate) 

(Code data)
ScoreDigitTIles:
  .db $ZeroTileNumber,$OneTileNumber ;Etc. You'd need to fill this out.

Or if you have the tiles in ROM that start at a number and go from 0 to 9, then you could also do this:

LDA Score
CLC
ADC #$00 ;TIle start number here.

which will produce the right digit.


Edited: 01/04/2013 at 12:14 AM by removed04092017

Jan 4, 2013 at 1:11:13 AM
LucasWeatherby (42)
avatar
(Lucas Weatherby) < El Ripper >
Posts: 1284 - Joined: 03/18/2011
Florida
Profile


I definitely understand for the most part what your code is trying to accomplish. I was easily able to add it to my code. However, it still puts that score in the bottom left corner. Thats exactly where I was writing the numbers to before. I see how 'LDA PPUData' allows for horizontal adjustment. But I'm really trying to get this score to the top of the screen. Is there more information on the vertical adjustment somewhere.

Jan 4, 2013 at 1:13:02 AM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
How about upload a clear background with a border. Make sure that your scrolling is correct. check fceux in windows, because if that code doesn't put it on the top of your screen after you modify it but keep the location, then your scroll is off.

Jan 4, 2013 at 11:22:32 AM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
You would have to be writing to like $2300 for your score to be writing way down there.

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

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


Feb 5, 2013 at 12:50:11 PM
m308gunner (63)
avatar
(Jason ) < King Solomon >
Posts: 3639 - Joined: 05/07/2012
Connecticut
Profile
Would some kind soul be able to send me an asm file with all the missing sections of code filled in for the first pong program? I'm hoping to kind of "reverse engineer" the completed file to see how it is supposed to work.

  EDIT: Never mind! Good thing no one gave me what I wanted or I would have missed out on some hard earned know-how!

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


Edited: 02/06/2013 at 02:00 PM by m308gunner

Apr 2, 2013 at 12:42:58 AM
LucasWeatherby (42)
avatar
(Lucas Weatherby) < El Ripper >
Posts: 1284 - Joined: 03/18/2011
Florida
Profile
Ok, I know I'm the most sporatic visitor to this page but whatever.  I still do try when I have the time.

Originally sent by: 3GenGames

Yeah, you have to set $2000 and $2005 each frame. Writing to $2006 basically rewrites the scroll because of how the PPU reuses some bits, so after you do $2006 write, you HAVE to rewrite $2000 (Nametable selection/NMI enable) and then the 2x $2005 writes, or else the scroll will be wrong.
3Gen gave me some advice, but I am pretty sure I have done this as you can see in the code snippets below:

Hmmm...Ive tried uploading my code in an attached file but NA seems to be having some problems with that. So I will paste the important parts:


[This is the NMI Section]
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
    
  ;;;all graphics updates done by here, run game engine
 
 
  JSR ReadController1  ;;get the current button data for player 1
  JSR ReadController2  ;;get the current button data for player 2
  
GameEngine:  
  LDA gamestate
  CMP #STATETITLE
  BEQ EngineTitle    ;;game is displaying title screen
    
  LDA gamestate
  CMP #STATEGAMEOVER
  BEQ EngineGameOver  ;;game is displaying ending screen
  
  LDA gamestate
  CMP #STATEPLAYING
  BEQ EnginePlaying   ;;game is playing
GameEngineDone:  
  
  JSR UpdateSprites  ;;set ball/paddle sprites from positions
  RTI             ; return from interrupt

[Now Here is the DrawScore Subroutine]


DrawScore:
  ;;;;;;;;;;;What I originally tried
  ;LDX #$01       
  ;LDA ScoreDigitTiles, x        ; load data from address (palette + the value in x)
                          ; 1st time through loop it will load palette+0
                          ; 2nd time through loop it will load palette+1
                          ; 3rd time through loop it will load palette+2
                          ; etc
  ;STA $2007             ; write to PPU
  
  ;;;;;;;;;;;END OF What I originally tried
  
  
  
  ;hardcode to set the scores
  LDA #$01
  STA score1;set player 1 score to 1
  STA score2;set player 2 score to 1
  
  ;3gengames method
  LDA #$20;Screen location for first digit of score
  STA $2006
  LDA #$4E;Location. Locations $204F and $2050 are both going to be either blank, or a DASH to seperate the digits
  LDX score1
  LDA ScoreDigitTiles,X
  STA $2007 ;Store to 1st character to screen.
  LDA $2007 
  LDA $2007;Move 2 bytes of the screen location.
  LDX score2
  LDA ScoreDigitTiles,X
  STA $2007 ;Store 2nd character to screen.
  
  RTS


 

[Finally, here is the tile loading stuff]



ScoreDigitTiles:
  .db $00,$01,$02,$03, $22,$36,$17,$0F,  $22,$30,$21,$0F,  $22,$27,$17,$0F   ;
 
 
I am at a loss for why my score still shows up in the same place as the picture I posted above. I feel like I've reset the scrolling correctly. If anyone has any idea please let me know.

Apr 2, 2013 at 10:30:41 AM
KHAN Games (89)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 8126 - Joined: 06/21/2007
Florida
Profile
To me it doesn't look like you're writing correctly.

It should be:

LDX score1
LDA $2002
LDA #$20 ;hi bit of place you're writing
STA $2006
LDA ScoreDigitTiles,x ;low bit of place you're writing
STA $2006
LDA NewTileNumber
STA $2007

LDX score2
LDA $2002
LDA #$20 ;hi bit of place you're writing
STA $2006
LDA ScoreDigitTiles,x ;low bit of place you're writing
STA $2006
LDA NewTileNumber ;tile of the new information you're writing
STA $2007
RTS

Now that I can kind of make sense of your code, try this:

  LDA $2002 ;YOU WERE FORGETTING THIS
  LDA #$20;Screen location for first digit of score
  STA $2006
  LDA #$4E;Location. Locations $204F and $2050 are both going to be either blank, or a DASH to seperate the digits
  STA $2006 ;YOU WERE FORGETTING THIS
  LDX score1
  LDA ScoreDigitTiles,X
  STA $2007 ;Store to 1st character to screen.
  LDA $2007 
  LDA $2007;Move 2 bytes of the screen location. ;I HAD NO IDEA YOU COULD DO THIS.  IF IT STILL DOESNT WORK, THIS IS YOUR CULPRIT
  LDX score2
  LDA ScoreDigitTiles,X
  STA $2007 ;Store 2nd character to screen.
  
  RTS

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

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



Edited: 04/02/2013 at 10:59 AM by KHAN Games

Apr 2, 2013 at 1:18:13 PM
LucasWeatherby (42)
avatar
(Lucas Weatherby) < El Ripper >
Posts: 1284 - Joined: 03/18/2011
Florida
Profile
Khan, you solved my problem. I am forever in your debt.

Sep 4, 2013 at 8:07:24 PM
Cowpar2 (0)
avatar
< Cherub >
Posts: 8 - Joined: 09/03/2013
Michigan
Profile
Can someone please help me?
I can't for the life of me figure out how to display a score.

So I got how to make the paddle, and I can make the ball collide with it.
I added a pleasant looking background, fixed the colors just right, and even changed the sprites to look more like what they're supposed to represent.
I have the looping background loader, which gets its hex values from a .db .
I know that the digits have to be in the background, so how do I change the background tiles to be the digits I want them to be?

-------------------------
Never eat soggy waffles.

Sep 4, 2013 at 8:11:33 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
You find out the score in decimal, you save that somewhere, you then add a background changing routine to the NMI, and you write the score on the screen, probably in the $2042-$205E area of the background, if you're using NT1. How can you get a whole background to display, but not do that? That's simple compared to understanding how to load a whole background.

Sep 4, 2013 at 10:47:23 PM
Cowpar2 (0)
avatar
< Cherub >
Posts: 8 - Joined: 09/03/2013
Michigan
Profile
Ok, I'm still not exactly sure what I'm doing, but "JSR Drawscore" is already in the NMI.
So if I add the following into the code (after "UpdateSprites"), it DOES make the score appear, but ONLY in the top left-hand corner:

DrawScore:
LDA $2002 ;read PPU to reset the latch
LDA #$20
STA $2006 ;set the high part
LDA #$20
STA $2006 ;then the low part
LDA score1
STA $2007 ;store the score (after 15 it will start to do letters)
RTS

If I change the low part of the latch to anything past #$40 it will mess with the screen, but anything less then #$20 the score doesn't even appear.
How do I get it to appear, say, 16 px down and all the way to the right?

-------------------------
Never eat soggy waffles.

Sep 4, 2013 at 10:51:11 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
Uhhh, add one at a time to the hex number instead of 32 each time? The low part can change in 1 step pieces, this is how you set each block, just increment it what you need, which isn't by 32 like you said you did above. ($20->$40=32 steps.) Remember TV safe zones,you should put the score in the $2040 area to be super safe it'll show. Top and bottom 16px, and then left and right 8px are not safe to rely for information to appear on.

And after 0x09 on the score, it will display crap, you have to have a program that turns the hex value to the right text numbers.


Edited: 09/04/2013 at 10:51 PM by removed04092017