Skip navigation
Welcome, Guest! Please Login or Join

Loading...

Nerdy Nights week 7 subroutines, game layout, starting Pong

Sep 4, 2013 at 11:01:15 PM
bunnyboy (81)
avatar
(Funktastic B) < Bowser >
Posts: 7477 - Joined: 02/28/2007
California
Profile
Originally posted by: Cowpar2

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?
In fceux run your game then open the "Name Table Viewer".  Put the mouse over where you want the score to appear in that window and the "PPU Address" will tell you the address to use.  It will be something like $205F.

Rows are $20 tiles long, so down 2 rows is $2000 + (2 * $20) = $2040.  All the way to the right is 1 less than a full row, so $2040 + ($20 - 1) = $205F.



Sep 5, 2013 at 1:20:06 PM
Cowpar2 (0)
avatar
< Cherub >
Posts: 8 - Joined: 09/03/2013
Michigan
Profile
If I do this:

DrawScore:
  LDA $2002
  LDA #$20
  STA $2006
  LDA #$5F
  STA $2006
  LDA score1
  STA $2007
  RTS

This happens:



3GenGames, I already have the background loaded, I just want to replace one tile.

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


Edited: 09/05/2013 at 01:22 PM by Cowpar2

Sep 5, 2013 at 1:37:48 PM
bunnyboy (81)
avatar
(Funktastic B) < Bowser >
Posts: 7477 - Joined: 02/28/2007
California
Profile
Looks like scrolling is off, so your PPU clean up section at the end of NMI isn't right or you are changing the PPU address after cleanup.

Sep 5, 2013 at 1:45:24 PM
KHAN Games (88)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 7784 - Joined: 06/21/2007
Florida
Profile
Also make sure you're doing that during vblank (inside your nmi code!)

Sep 5, 2013 at 2:44:15 PM
Cowpar2 (0)
avatar
< Cherub >
Posts: 8 - Joined: 09/03/2013
Michigan
Profile
My NMI code remains unchanged:

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

So, it should be jumping to my code during vblank.

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

Sep 5, 2013 at 4:45:14 PM
Cowpar2 (0)
avatar
< Cherub >
Posts: 8 - Joined: 09/03/2013
Michigan
Profile
Mystery solved!
At the end of "UpdateSprites" (which comes just before DrawScore), I forgot to put two spaces before "RTS", which caused it to skip over the RTS and go on to the "DrawScore" routine nonstop
But I fixed it and now it works perfectly.

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

Sep 5, 2013 at 7:27:50 PM
removed04092017 (0)
This user has been banned -- click for more information.
< Bowser >
Posts: 7316 - Joined: 12/04/2010
Other
Profile
As a tip, the scroll should be 100% updated at the end of your NMI! The LAST thing done, ALWAYS. 100% updated means writing $2000, too. You need to do this because $2006 and the scroll registers actually use the same values. It's complex to explain, it's not needed without mid-screen scrolling, so basically just set the scroll last and you'll never have to worry about it.

Jan 19, 2014 at 12:25:11 PM
MODERATOR
Vectrex28 (120)
avatar
(A Metroid) < Bowser >
Posts: 7234 - Joined: 07/28/2012
Switzerland
Profile
Well, I just went back to these tutos and I finally got something that's starting to look like a game Thanks for these tutos bunnyboy! Now to figure out the scoring

Oct 6, 2014 at 12:51:21 AM
lazerbeat (0)

< Cherub >
Posts: 5 - Joined: 04/12/2014
Profile
Sorry for the huger necrobump but this seems like the best place for the question. I have been working through weeks 1 to 6 with asm6 without any major problem but I hit 2 with weeks 7.

1 - When I try to compile pong1.asm I get the following error

pong1.asm(401): Missing ENDE

Line 401 refers to

.incbin "mario.chr" ;includes 8KB graphics file from SMB1

This hasnt been an issue in any of the other tutorials. I was wondering if anyone has any ideas?


2 - ASM6 doesnt seem to have and rsset / .rs1 function I have been using enum / .dsb 1 instead. Is this ok?

Thanks everyone!





.rsset $0000 ;put variables starting at 0

score1 .rs 1 ;put score for player 1 at $0000

Secondly

Oct 6, 2014 at 2:03:22 AM
lazerbeat (0)

< Cherub >
Posts: 5 - Joined: 04/12/2014
Profile
Whoops, looks like these issues are pretty closely linked.

I was missing the ".ende" after my ,dsb1's!

Still curious of there are any big differences between enum / rsset though.

Oct 6, 2014 at 9:35:49 AM
KHAN Games (88)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 7784 - Joined: 06/21/2007
Florida
Profile
Curious why you chose to go with ASM6. I can't answer your questions because I have no idea how to use that one.

Oct 6, 2014 at 10:44:19 AM
lazerbeat (0)

< Cherub >
Posts: 5 - Joined: 04/12/2014
Profile
Nothing major, just it was the first compiler I found which worked "out of the box" with linux.

Mar 1, 2015 at 1:15:06 PM
Farid (0)
avatar
(Farid Abbasi) < Cherub >
Posts: 15 - Joined: 04/03/2010
Iran (Islamic Republic of)
Profile
There are some mistakes in Controller Reading trace, the final result of trace is correct so it is not critical :



Mar 1, 2015 at 1:52:31 PM
thefox (0)
avatar
(Kalle Immonen) < Meka Chicken >
Posts: 533 - Joined: 07/08/2008
Finland
Profile
Originally posted by: lazerbeat

Still curious of there are any big differences between enum / rsset though.
No, they are quite similar.


-------------------------
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi

Aug 22 at 11:06:11 PM
brilliancenp (0)
avatar
(Nick Pruitt) < Tourian Tourist >
Posts: 34 - Joined: 08/15/2017
Kansas
Profile
Ok so this is an old thread I know, I have been going through the tutorials and have everything working except updating the score. I didn't see this explained anywhere but the comments say to update using background tiles or lots of sprites. I would figure updating using background tiles is best since the background tile numbers correspond to the numbers so '0' = $00 '1' = $01 and so on. The problem I am having is updating the background sprites. I can t seem to figure out how to do it and searching google I cant find an answer. Anyone have an example? I would figure I would need to update the background table which I can do (I think) but how to push it to the ppu correctly. Any help would be greatly appreciated.

Aug 22 at 11:13:34 PM
KHAN Games (88)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 7784 - Joined: 06/21/2007
Florida
Profile
Originally posted by: brilliancenp

Ok so this is an old thread I know, I have been going through the tutorials and have everything working except updating the score. I didn't see this explained anywhere but the comments say to update using background tiles or lots of sprites. I would figure updating using background tiles is best since the background tile numbers correspond to the numbers so '0' = $00 '1' = $01 and so on. The problem I am having is updating the background sprites. I can t seem to figure out how to do it and searching google I cant find an answer. Anyone have an example? I would figure I would need to update the background table which I can do (I think) but how to push it to the ppu correctly. Any help would be greatly appreciated.

The best way is to write it to a buffer to where it writes all your background updates in a single frame, but I won't confuse you with that just yet until you get your bearings a little more.

Basically, somewhere in the vblank (which is typically at the beginning of NMI), you have to update the background tiles. The code will look something like this:

UpdateBackgroundTile:
  LDA $2002 ;wake up PPU and let it know we are about to update stuff
  LDA #$20 ;this is the hi byte of the address you're writing to. so if the nametable tile you're updating is located at $2084, $20 is the hi byte.
  STA $2006
  LDA #$84 ;this is the low byte of the address you're writing to. I kept the same address example that I used above.
  STA $2006
  LDA #$xx ;this is the tile number of the new tile you are writing to the address you described above.
  STA $2007 ;write the tile
  RTS

Now, doing it this way is fine, but you have to understand that unless you have a flag telling it to only do it once, it's going to re-draw this tile every single frame until you tell it otherwise. And when you start developing a bigger game, you won't get far before updates like this prevent you from expanding, because vblank is a treasured commodity.

Let us know if you need further clarification, or when you're ready for more advanced solutions.

Homework is to read this: https://wiki.nesdev.com/w/index.p...

You don't need to understand the technical details of what it's doing, but at least try to give it a read and understand the concepts. We'll get there. One step at a time!

Also, welcome to NintendoAge!
 


Edited: 08/22/2017 at 11:14 PM by KHAN Games

Aug 22 at 11:40:10 PM
brilliancenp (0)
avatar
(Nick Pruitt) < Tourian Tourist >
Posts: 34 - Joined: 08/15/2017
Kansas
Profile
Thank you so much! And what a quick response. I did read up on buffers while I was away. I am a c# developer so I have programming down but this is a whole new world lol. I am grasping the concepts and the awesome tutorials. And yes updating the same thing every frame is a definite waste lol but at least this example allows me to grasp HOW to do a simple thing like updating a background tile. I have been stuck the last couple of days until I realized I might just try asking   Thanks again and yes I am glad to be here. I will read my homework!

Aug 23 at 5:34:07 AM
SoleGooseProductions (120)
avatar
(Beau ) < Ridley Wrangler >
Posts: 2783 - Joined: 04/22/2013
Indiana
Profile
It's not always a waste to do things every frame though, you can certainly lose some ease of use by over flagging stuff. Palettes have been my key example lately, thanks to some advice from Memblers. I used to do them with a complex system of flags, now I just update them every frame and skip all of the hassle of setting flag routines. It makes changing colors a breeze, and not much is lost in NMI. I think that I'd do the same with scoring BG tiles at this point too, at least for a smaller game. Drawing a few tiles every frame is well within the scope of using that time well (figure that scrolling changes at least 32 and there is still time for other things).

Just something to keep in mind perhaps as you continue on your journey; that constant trade between what you can do and what you need to do. What's that saying, beginning coders hardcode everything and so do veteran ones? Something like that.

And of course, welcome to the forums!


-------------------------
"The light that burns twice as bright burns half as long..." ~ Blade Runner

SoleGooseProductions.com



Edited: 08/23/2017 at 05:53 AM by SoleGooseProductions

Aug 25 at 8:39:17 PM
brilliancenp (0)
avatar
(Nick Pruitt) < Tourian Tourist >
Posts: 34 - Joined: 08/15/2017
Kansas
Profile
I understand the concept of buffers as explained in https://wiki.nesdev.com/w/index.p... but I dont understand how to set it up. It seems like it takes the place of setting a variable for each thing you want to keep track of, which I like, but coming from a background of higher languages it seems you would want to use an array, but in this case a collection of bytes. Just not sure how to set this up in NESASM.

Aug 25 at 8:49:23 PM
brilliancenp (0)
avatar
(Nick Pruitt) < Tourian Tourist >
Posts: 34 - Joined: 08/15/2017
Kansas
Profile
Oh wait! Do you set it up using the .db command? Im going to try that

Aug 26 at 12:58:20 AM
Mega Mario Man (58)
avatar
(Tim ) < Kraid Killer >
Posts: 2288 - Joined: 02/13/2014
Nebraska
Profile
Originally posted by: brilliancenp

Oh wait! Do you set it up using the .db command? Im going to try that





No. You would section off a part of ram. Such as:

BufferRAM .rs 64

That would reserve 64 bytes in ram just for buffering. I have never done it, but you could adjust that number according to what is needed thr most in any given frame in the game.

-------------------------
Current Project
Isometric Survival Horror

Older Projects
Tailgate Party, Power Pad Demo, Happy Hour

Links
Store, Facebook, Twitter

Aug 26 at 6:23:14 AM
SoleGooseProductions (120)
avatar
(Beau ) < Ridley Wrangler >
Posts: 2783 - Joined: 04/22/2013
Indiana
Profile
Just like MMM said you need to reserve bytes. Buffering just means that you're to pre-loading all of the data you need. A .db table would still involve the step of finding it, and not being able to quickly blast it to the PPU when you need it.

-------------------------
"The light that burns twice as bright burns half as long..." ~ Blade Runner

SoleGooseProductions.com



Edited: 08/26/2017 at 06:23 AM by SoleGooseProductions

Aug 26 at 10:38:07 AM
KHAN Games (88)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 7784 - Joined: 06/21/2007
Florida
Profile
I'm one of those people who needs to see something done to really understand it, so I'm going to give you an example of the way I do things. I'm definitely not claiming to be any sort of expert in NES programming, because I do many things the wrong way, but this will at least give you a physical example of a way it can be done.

Anytime I have a tile to update, I'll write it to the $0400 page. First I check to see if anything is written to $0400 (if so, that means I've already told it to update tile(s) this frame, so I need to skip ahead and go to the first free bytes in that page.)

In this example, let's say I want to change four background tiles beginning at $2165. The tiles will be $23, $91, $46, and $90. But earlier in the frame I decided I wanted to change background tile $2310 to tile $12.

Like the website I gave you to did, I have my buffer set up like this.

Byte 0 - Number of tiles I'm updating.
Byte.1 - Hi byte of nametable I'm updating.
Byte 2 - Lo byte of nametable I'm updating.
Bytes 3 - ? - The tiles I'm updating to that address.

Zero page variables:
NumBuffer: .rs 1
HiBuffer: .rs 1
LoBuffer: .rs 1
BufferTiles: .rs xx (however many bytes you want to set aside for buffer updates)

Current state of $0400 page (from previous routine that wants to update background tile $2310 to tile $12:

$01,$23,$10,$12

I have a subroutine somewhere that you will jump to anytime you want to load stuff into the buffer, it will look liks this:

LoadBuffer:
LDX #$00
LDY #$00
.PreLoad:
LDA $0400,x ;check to see if this is an open spot in the $0400 page
CMP #$00 ;if it is, go straight to Load.
BEQ .Load
TAY ;move the current number of bytes that this bkgd update is doing into Y so we can move ahead that many to check next open spot
.Loop:
DEY
INX
CPY #$00
BEQ .PreLoad ;we have successfully moved ahead past the current update. check next spot by jumping back to PreLoad
JMP .Loop
.Load: ;it is now safe to put our updates into this spot of $0400 page
LDA NumBuffer
STA $0400,x
LDA HiBuffer
STA $0401,x
LDA LoBuffer
STA $0402,x
LDY #$00
.ExitLoop:
LDA BufferTiles,y
STA $0403,x
INX
INY
DEC NumBuffer
LDA NumBuffer
CMP #$00
BNE .ExitLoop
RTS

Then I have a routine that happens at the beginning of NMI (and we know this is vblank time) that goes something like this. It actually loads your buffer and makes the changes you want:

RunBuffer:
LDX #$00
.Loop:
LDA $0400,x ;see if anything is set to update
CMP #$00
BEQ .End ;nothing is set to update, go to end
LDA $0400,x
TAY
LDA $0401,x
STA $2006
LDA $0402,x
STA $2006
.OutroLoop:
LDA $0403,x
STA $2007
INX
DEY
CPY #$00
BNE .OutroLoop
JMP .Loop
.End:
RTS

Now that you have your two routines down, at any point in your code to update the tiles we previously mentioned, you can just do this:

;;anywhere in game
LDA #$04 ;we are updating four tiles, like we mentioned
STA NumBuffer
LDA #$21 ;hi byte we are updating
STA HiBuffer
LDA #$65 ;lo byte we are updating
STA LoBuffer
LDA #$23 ;first of four tiles we are updating
STA BufferTiles
LDA #$91
STA BufferTiles+1
LDA #$46
STA BufferTiles+2
LDA #$90
STA BufferTiles+3
JSR LoadBuffer ;take these values and load them into our buffer
;;any code

Then when your updates are done for the frame, you probably need to figure out a way to set $0400 to #$00 so that the game knows not to run the updates the next frame. But I'll let you figure that out.  

Aug 26 at 11:12:33 AM
KHAN Games (88)
avatar
(Kevin Hanley) < Master Higgins >
Posts: 7784 - Joined: 06/21/2007
Florida
Profile
Also, I wrote all of this in one sitting while my nephews were talking my ear off, so they may need tweaking!