Page 7 of 7

Re: NES Programming Blog

Posted: Wed Aug 09, 2017 7:11 pm
by dougeff
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/

Re: NES Programming Blog

Posted: Thu Aug 10, 2017 2:02 am
by na_th_an
Great addition, thanks.

Have you considered Patreon? your input is really valuable.

Re: NES Programming Blog

Posted: Thu Aug 10, 2017 4:34 am
by Diskover
Great contribution. Impatiently await article explaining how to do large scrolling with neslib

Re: NES Programming Blog

Posted: Fri Aug 11, 2017 6:19 am
by dougeff
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.

Re: NES Programming Blog

Posted: Fri Aug 11, 2017 7:23 am
by tokumaru
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".

Re: NES Programming Blog

Posted: Fri Aug 11, 2017 7:41 am
by Diskover
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.

Re: NES Programming Blog

Posted: Fri Aug 11, 2017 7:56 am
by tepples
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.

Re: NES Programming Blog

Posted: Fri Aug 11, 2017 8:12 am
by FrankenGraphics
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.

Re: NES Programming Blog

Posted: Wed Jul 18, 2018 7:49 am
by dougeff
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.

Re: NES Programming Blog

Posted: Wed Jul 18, 2018 9:08 am
by Banshaku
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.

Re: NES Programming Blog

Posted: Tue Apr 02, 2019 10:57 am
by dougeff
Added Zapper and Power Pad examples.

https://nesdoug.com/2019/04/02/22-zapper-power-pad/

Re: NES Programming Blog

Posted: Thu Apr 04, 2019 4:33 am
by Pokun
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.