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

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".

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.

A quadtree-style scheme similar to what tokumaru proposes would take 5440 bytes:

Grid of 8x8 top-level metatiles, each 256x256: 64 bytes

Top left 128x128 metatile in each 256x256 metatile: 256 bytes

Top right 128x128 metatile in each 256x256 metatile: 256 bytes

Bottom left 128x128 metatile in each 256x256 metatile: 256 bytes

Bottom right 128x128 metatile in each 256x256 metatile: 256 bytes

Top left 64x64 metatile in each 128x128 metatile: 256 bytes

Top right 64x64 metatile in each 128x128 metatile: 256 bytes

Bottom left 64x64 metatile in each 128x128 metatile: 256 bytes

Bottom right 64x64 metatile in each 128x128 metatile: 256 bytes

Top left 32x32 metatile in each 64x64 metatile: 256 bytes

Top right 32x32 metatile in each 64x64 metatile: 256 bytes

Bottom left 32x32 metatile in each 64x64 metatile: 256 bytes

Bottom right 32x32 metatile in each 64x64 metatile: 256 bytes

Top left 16x16 metatile in each 32x32 metatile: 256 bytes

Top right 16x16 metatile in each 32x32 metatile: 256 bytes

Bottom left 16x16 metatile in each 32x32 metatile: 256 bytes

Bottom right 16x16 metatile in each 32x32 metatile: 256 bytes

Top left 8x8 tile in each 16x16 metatile: 256 bytes

Top right 8x8 tile in each 16x16 metatile: 256 bytes

Bottom left 8x8 tile in each 16x16 metatile: 256 bytes

Bottom right 8x8 tile in each 16x16 metatile: 256 bytes

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.

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.

Who is online

Users browsing this forum: Google Adsense [Bot] and 5 guests

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum