Question about background scrolling with large maps

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
bjones
Posts: 19
Joined: Mon Apr 29, 2019 4:34 pm

Question about background scrolling with large maps

Post by bjones » Mon Apr 29, 2019 4:41 pm

I am probably not looking in the right place or not searching for the right terms.

Ive got the column loading going for continous scrolling but I am not sure how to store and load the data.

is a level map stored in one big byte array? or do you store it in nametable size multiple arrays?

any help pointing me in the right direction is greatly appreciated.

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

Re: Question about background scrolling with large maps

Post by tepples » Mon Apr 29, 2019 4:48 pm

"How long is a piece of string?"

Different games store map data in different ways.
  1. Often it's compressed with "metatiles", where each entry in the map refers to 16x16 pixels, and there's a separate table to translate each entry into the tile number for its top left, top right, bottom left, and bottom right. Some engines have metametatiles, where each 32x32 pixel piece is in turn made up of 16x16 pixel pieces. Blaster Master has three layers.
  2. Sometimes it's compressed with run-length encoding (RLE), where a horizontal or vertical run of tiles turns into a smaller piece of data.
  3. Sometimes it's compressed with object-based encoding, where each item in a list describes the position, size, and content of a rectangular portion of the map. The Super Mario games tend to do this.
Could you paste a vgmaps.com style picture of the map you have in mind?

bjones
Posts: 19
Joined: Mon Apr 29, 2019 4:34 pm

Re: Question about background scrolling with large maps

Post by bjones » Mon Apr 29, 2019 5:14 pm

Thanks!

my follow up question to that is. Would you use a buffer array for recontructiong these metaltiles to actual tiles or do you just load them in on the fly?


my map is just going to be a continuous gradius style map / shooter. it just scrolls in one direction.

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

Re: Question about background scrolling with large maps

Post by dougeff » Mon Apr 29, 2019 6:14 pm

If the metatile data is uncompressed, you could fill the PPU update buffers on the fly (maybe every 16 pixels of scrolling).

Attribute tables are a real headache, though. That can be loaded on the fly too, but a 16 px column can only fill half the bits.
nesdoug.com -- blog/tutorial on programming for the NES

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

Re: Question about background scrolling with large maps

Post by tokumaru » Mon Apr 29, 2019 9:18 pm

bjones wrote:my follow up question to that is. Would you use a buffer array for recontructiong these metaltiles to actual tiles or do you just load them in on the fly?
Since vblank time is really short (less than 8% of the total frame time), and that's the only time when you're allowed to write to VRAM, you should avoid running any kind of logic or data processing during that time. Most games will read and decode data from the level map (which can be in ROM or already partially decoded in RAM) and buffer the tile and attribute data beforehand, and then, during vblank, copy that data to VRAM as fast as possible.

bjones
Posts: 19
Joined: Mon Apr 29, 2019 4:34 pm

Re: Question about background scrolling with large maps

Post by bjones » Thu May 09, 2019 9:22 am

Okay I almost got it. Now it seems my column number counter will only up to 255. How do I go beyond that? multiple arrays of 255? or i missing something with the high bits?

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

Re: Question about background scrolling with large maps

Post by tokumaru » Thu May 09, 2019 10:42 am

Well, the 6502 is an 8-bit CPU without any kind of automatic handling of 16-bit values, which means it's normally constrained to the 0..255 range for most things. To get around that, programmers can combine multiple bytes in order to work with larger values. A 2-byte (16-bit) variable can go up to 65535.

The main implication of accessing more than 256 of anything is that you can't do it with simple indexing via the X or Y registers, because these registers are 8-bit. You'll most likely be using indirect indexed addressing, where a base pointer (i.e. a 16-bit address that can point anywhere between $0000 and $FFFF) is held in ZP, and an 8-bit index held in register Y is added to it in order to calculate the final address to be accessed.

In order to calculate the address of something in a big array of somethings, you can use a formula like BaseAddress + ThingIndex * ThingSize to calculate the value for the pointer you're gonna be using to access that something. From there, as long as the something is smaller than 256 bytes, you can increment just the Y register to advance to the next byte.

Post Reply