NES Programming Blog

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

User avatar
dougeff
Posts: 2614
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: NES Programming Blog

Post by dougeff » Wed Aug 09, 2017 7:11 pm

I added a few more pages to my blog, using the neslib.

Also, the last one is a very, very simple PONG example game (with no scoreboard, since I wanted it to be as simple as possible).

https://nesdoug.com/2017/08/09/sprite-b ... sion-pong/
nesdoug.com -- blog/tutorial on programming for the NES

na_th_an
Posts: 543
Joined: Mon May 27, 2013 9:40 am

Re: NES Programming Blog

Post by na_th_an » Thu Aug 10, 2017 2:02 am

Great addition, thanks.

Have you considered Patreon? your input is really valuable.

Diskover
Posts: 213
Joined: Thu Nov 24, 2011 7:16 am
Contact:

Re: NES Programming Blog

Post by Diskover » Thu Aug 10, 2017 4:34 am

Great contribution. Impatiently await article explaining how to do large scrolling with neslib

User avatar
dougeff
Posts: 2614
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: NES Programming Blog

Post by dougeff » Fri Aug 11, 2017 6:19 am

I've been meaning to program an all direction scrolling game. Like Crystalis. My main stumbling block, is I can't think of how to compress each 'room' (16x15 set of metatiles, which expands to 256x240 pixel area).

In an ideal world, the game should only need to find the exact metatiles for the next 16 pixels to the right, but once it's compressed, there's no easy way to do that...to uncompress just the exact metatiles I need.

So, in my head, I'm going to need to uncompress 4 full rooms into the RAM at any given time (since you can stand in the corner of 4 different rooms at the same time). That's going to eat up $400 bytes of RAM + Some bytes for a buffer of tiles needed to push to the PPU the next v-blank.

Anyway. It's not very simple.

And, without compression, the game might be very small, or need lots of bank switching, which is a whole other level of complexity, that might not suit a beginning tutorial.

Edit, on second thought, I should be able to fit 64 rooms (8x8) on an NROM sized game 242x64 = 15488 (extra 2 bytes for a pointer to the start of each room). Maybe I won't compress for the example code.

Edit2, and if all the rooms were uncompressed, they wouldn't have to be loaded to the RAM. I'll think about it some more.
nesdoug.com -- blog/tutorial on programming for the NES

User avatar
tokumaru
Posts: 11466
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: NES Programming Blog

Post by tokumaru » Fri Aug 11, 2017 7:23 am

There are different types of compression that allow almost random access to individual metatiles. I particularly use metatiles (256x256) of metatiles (128x128) of metatiles (64x64) of metatiles (32x32) of metatiles (16x16). Traversing the metatile structure until the 16x16 ones isn't particularly slow. Of course this scheme isn't ideal for all kinds of maps, but I'm sure you can use something more accessible than "RLE/LZ one whole room/screen into a solid binary block".

Diskover
Posts: 213
Joined: Thu Nov 24, 2011 7:16 am
Contact:

Re: NES Programming Blog

Post by Diskover » Fri Aug 11, 2017 7:41 am

dougeff wrote:I've been meaning to program an all direction scrolling game. Like Crystalis. My main stumbling block, is I can't think of how to compress each 'room' (16x15 set of metatiles, which expands to 256x240 pixel area).

In an ideal world, the game should only need to find the exact metatiles for the next 16 pixels to the right, but once it's compressed, there's no easy way to do that...to uncompress just the exact metatiles I need.

So, in my head, I'm going to need to uncompress 4 full rooms into the RAM at any given time (since you can stand in the corner of 4 different rooms at the same time). That's going to eat up $400 bytes of RAM + Some bytes for a buffer of tiles needed to push to the PPU the next v-blank.

Anyway. It's not very simple.

And, without compression, the game might be very small, or need lots of bank switching, which is a whole other level of complexity, that might not suit a beginning tutorial.

Edit, on second thought, I should be able to fit 64 rooms (8x8) on an NROM sized game 242x64 = 15488 (extra 2 bytes for a pointer to the start of each room). Maybe I won't compress for the example code.

Edit2, and if all the rooms were uncompressed, they wouldn't have to be loaded to the RAM. I'll think about it some more.
Talk to na_th_an

The scheduled Sir Ababol when he must have found the same problem and solved. . . I believe.

tepples
Posts: 21751
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: NES Programming Blog

Post by tepples » Fri Aug 11, 2017 7:56 am

A quadtree-style scheme similar to what tokumaru proposes would take 5440 bytes:
  1. Grid of 8x8 top-level metatiles, each 256x256: 64 bytes
  2. Top left 128x128 metatile in each 256x256 metatile: 256 bytes
  3. Top right 128x128 metatile in each 256x256 metatile: 256 bytes
  4. Bottom left 128x128 metatile in each 256x256 metatile: 256 bytes
  5. Bottom right 128x128 metatile in each 256x256 metatile: 256 bytes
  6. Top left 64x64 metatile in each 128x128 metatile: 256 bytes
  7. Top right 64x64 metatile in each 128x128 metatile: 256 bytes
  8. Bottom left 64x64 metatile in each 128x128 metatile: 256 bytes
  9. Bottom right 64x64 metatile in each 128x128 metatile: 256 bytes
  10. Top left 32x32 metatile in each 64x64 metatile: 256 bytes
  11. Top right 32x32 metatile in each 64x64 metatile: 256 bytes
  12. Bottom left 32x32 metatile in each 64x64 metatile: 256 bytes
  13. Bottom right 32x32 metatile in each 64x64 metatile: 256 bytes
  14. Top left 16x16 metatile in each 32x32 metatile: 256 bytes
  15. Top right 16x16 metatile in each 32x32 metatile: 256 bytes
  16. Bottom left 16x16 metatile in each 32x32 metatile: 256 bytes
  17. Bottom right 16x16 metatile in each 32x32 metatile: 256 bytes
  18. Top left 8x8 tile in each 16x16 metatile: 256 bytes
  19. Top right 8x8 tile in each 16x16 metatile: 256 bytes
  20. Bottom left 8x8 tile in each 16x16 metatile: 256 bytes
  21. Bottom right 8x8 tile in each 16x16 metatile: 256 bytes
  22. Attribute of each 16x16 metatile: 256 bytes
Some of these tables can be made shorter based on how much repetition is in your actual map.

Another option is an object-based map, similar to how the Super Mario Bros. and Animal Crossing series represent maps. Represent the map as an (X, Y, thing) list, where the renderer calculates which objects overlap the column to be scrolled onto the screen. For an 8-way scroll, You'd probably need to sort this by (Y screen, X, Y within screen) so that you have only a couple 256-pixel-tall rows of objects to search. The advantage of objects over a quadtree is that repeated objects can be placed at arbitrary 16x16 tile offsets.

User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2032
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: NES Programming Blog

Post by FrankenGraphics » Fri Aug 11, 2017 8:12 am

Another option:
Have a seamlessly repeating background picture (size of a screen, larger, or smaller, depending on style and how well it repeats without getting worn out), have it rle-compressed in ROM and keept it relatively simple so it doesn't get too big. Or if you can afford it, keep it uncompressed. Write it to screen first (in slices as you scroll).

Then have a number of objects (kind of like metroid or what tepples said) which overwrites the basic background. You get the creative freedom/small file size-compromise of metroid but get a good looking background rather than an empty black void.
http://www.frankengraphics.com - personal NES blog

User avatar
dougeff
Posts: 2614
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: NES Programming Blog

Post by dougeff » Wed Jul 18, 2018 7:49 am

Bug fix.

Forgot to disable APU frame counter IRQ in my neslib example codes, in crt0.s

ldx #$40
stx $4017

Files have been updated.
nesdoug.com -- blog/tutorial on programming for the NES

User avatar
Banshaku
Posts: 2328
Joined: Tue Jun 24, 2008 8:38 pm
Location: Fukuoka, Japan
Contact:

Re: NES Programming Blog

Post by Banshaku » Wed Jul 18, 2018 9:08 am

Maybe I could be mistaken but Shiru samples were not deactivating it. This is one thing I added to my own code once I did the review with my original init code and the one in the samples.

User avatar
dougeff
Posts: 2614
Joined: Fri May 08, 2015 7:17 pm
Location: DIGDUG
Contact:

Re: NES Programming Blog

Post by dougeff » Tue Apr 02, 2019 10:57 am

Added Zapper and Power Pad examples.

https://nesdoug.com/2019/04/02/22-zapper-power-pad/
nesdoug.com -- blog/tutorial on programming for the NES

Pokun
Posts: 1271
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: NES Programming Blog

Post by Pokun » Thu Apr 04, 2019 4:33 am

Nice addition!
You might want to mention that the reason the Zapper is read from the NES controller II port in licensed Zapper games is because that's how the original Famicom light gun works (using the same pins in the expansion port). If a game requires reading from controller I port (like Chiller does when using two Zappers) people with Famicom like me will be unable to play your game as those pins are not available on the Famicom. So in other words, if a game only supports one Zapper it is always best to read from port 2 (or both ports) for compatibility reasons.

For the Power Pad / Family Fun Fitness, it's just incompatible with the Famicom (due to some NES pins not being available in the Famicom expansion port) IIRC. Edit: I remembered poorly. The NES version of the mat seems to use the same pins as the Zapper according to the wiki, so the same thing applies for it. It is best to be read from either port 2 or both ports for full compatibility.

Post Reply