views:

69

answers:

2

OK. I'm in essense trying to make my own interpretation of the NES hardware, so I can make a game that ideally would resemble what a NES game would look like. I'm currently stuck with how to adjust how to draw the playfield to the video memory (back buffer).

BACKBUFFER

The NES had restrictions on the nametable, or backbuffer. For my example, the backbuffer is 256x240pixels big, or the size of one screen. If I drew this to the TV, it would fill up the screen perfectly. Now, if I drew this to the screen with an offset of X=5, the entire image would be shifted and would wrap around the screen.

For example.....

ORIGINAL, NO OFFSET:                      DRAWN WITH OFFSET OF X=5:
ABCDEFGHIJK                               GHIJKABCDEF

DRAWN WITH OFFSET OF X=-5:
FGHIJKABCDE

The screen is split up into squares 8x8 pixels each, totalling 32x30 rows and columns. (256x240 pixels). The offset is represented in pixels - not columns; so in theory, I could offset the screen by 5 pixels and every column would be shifted to the right by five pixels.

LEVEL DESIGN

My stages are made up of screens, containing data that is represented in 16x15 rows and columns, each by 16x16 pixels. This is to emulate how many NES games stored level data - each tile holds info about what should be in each 8x8 block.

E.g.:

AA
BC     with A,B,C,D representing what 8x8 graphic should go where

Level design is represented by this as well, with each number being a different screen and - meaning nothing, null.

-----
-123-
---4-
--54-
-----

CHARACTER PLACEMENT This is easy. I already know how I can determine which table, row, and column my characters are on based on their absolute positioning. I can also determine the relative positioning within the screen.

With this info, I can easily figure out which columns are to the left and right of the character, if any (if the character is at the left side of screen 1, thered be no more level left)

SO HERE'S THE QUESTION DUN DUN DUN How do I draw my levels to the screen, so that they scroll from one to the next. It would be relatively easy to draw one full screen at a time, and when the character gets to the edge just flip to another screen.

However, the problem I'm conceptually having is that I need to 'stream' the level data onto the screen. That, lets say the character moves 24 pixels to the right. The BG needs to move as well.

So, I need to adjust the scrolling of the backbuffer by 24 pixels. However, just scrolling alone will cause the screen to wrap over, diplsaying old portion of the level. So, while scrolling I need to make sure to draw new pieces of the level to the back buffer. But before I can do that, I need to figure out which tiles need to get drawn first. And if the person goes 24 pixels to the left, I need to redraw tiles onto the backbuffer and change the offset accordingly as well.

And let's not forget that if the character moves right and there's no more level data to be drawn, there should be no offset but instead the character gets closer to the side of the screen (instead of being centered in the middle of the screen via the X axis).

Basically, I just have a lot of different numbers and values stuck in my mind right now - trying to wrap my head around many concepts and they caused my brain to turn into goo. Anyone have any perspective on how I can approach this?

EDIT: Using VB.Net. C# is applicable as well ( I program in both)

A: 

I would set up a grid of image controls and load the levels from a database that stores what column and row each picture is relative to the level. Once the image that represents the game's character gets far enough to the right (you would have to store its location in some module level variables) of the screen you would load the next column of images (while shifting all of the other images one to the left and removing the first column).

DaMartyr
+1  A: 

The way the NES did it was with 4 name tables, each 256x240. When you scrolled one off the screen, the adjacent one would scroll on. To get "worlds" bigger than 512x480, you update the name table at the positions that are offscreen.

Generally, a cartridge would have a giant table in ROM with all of the level data, and would track the overall position with 1 or 2 RAM variables. Then when the game scrolled, it would update the RAM variables, use those to lookup the level data table and copy in the new level data into the parts of the name table that were offscreen.

So actually your back buffer should be 512x480, and you only show a 256x240 portion of it.

Have you looked at the disassembly for any NES games that have large scrolling worlds? I think a partial disassembly of Metroid is out there somewhere...

...yeah, found some docs at romhacking.net

Metroid disassembly; not real well commented but with a little effort it shouldn't be too hard to figure it out.

Another disassembly that is commented better.

EDIT: In the 2nd disassembly posted above, look in MetroidGameEnginePage.txt at the "SetupRoom" routine and the "DrawRoom" routine; also the routine at label LEB4D shows how the name table is updated in one case. Also look at the extensive comments above the "GetNameTable" routine. In general, a text search for "name table" throughout the document will get you lots more.

EDIT EDIT: Also at romhacking.net; the memory map for SMB might be useful.

Bob Montgomery
As a romhacker, I approve this answer.
Kawa