MMC3 "3D" scrolling tricks

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

Moderator: Moderators

Celius
Posts: 2157
Joined: Sun Jun 05, 2005 2:04 pm
Location: Minneapolis, Minnesota, United States
Contact:

Post by Celius » Tue Apr 24, 2007 9:18 pm

Yeah, I was thinking of just making a maze for starters. The raycasting engine is what I care about right now. I can make a first person dungeon crawl, or a first person shooter if I want to. But that requires an engine. I think looking at the cool graphics is the best part.

I've been thinking about doing a wire frame game using the same concepts of raycasting. I keep track of points. These points are intersections for wires in the wireframe model. You take the X, Y, and Z variables, and use them to put the points where they should appear on screen. If you can get these points on screen, you can just connect the dots to make a wire frame model. That would be the hardest part about it. I know how to get the points on screen. It's just like a unit of texture on a wall. I created a Qbasic program that shows a couple points on screen that have X, Y, and Z coordinates, and I use the LINE function to connect the dots. It looks quite nice, and I'm quite confident that it's not just close-enough-to-3D. But that's a whole different story, I suppose.

User avatar
Bregalad
Posts: 7768
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Wed Apr 25, 2007 8:18 am

Just something, I really don't think 12 FPS would be good. It may be okay for a movie, but NOT for any vido game (at least not an action oriented one). The slowest you would want would be 25 FPS for a responsive video game. Anything below would have the player smach his screen with his controller out of frustration of the game's unresponsivity.

And, what will look the worst between something with utterly skipped frames, and something with utterly skipped frame where you can see the refresh scrolling lines ? That won't make a very high difference. Unless you can render a 3D image with a fixeed tileset (or a large set of different fixed tilesets) I don't see much interest in it.

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

Post by tokumaru » Wed Apr 25, 2007 10:14 am

Bregalad wrote:Just something, I really don't think 12 FPS would be good. It may be okay for a movie, but NOT for any vido game (at least not an action oriented one).
I think it is in this case because this is a game that feels like a movie (sorta). Only nowadays people are used to 3D shooters running at 120fps, but this is a game genre that allows decent gameplay at lower framerates.
The slowest you would want would be 25 FPS for a responsive video game. Anything below would have the player smach his screen with his controller out of frustration of the game's unresponsivity.
Yeah, I agree with you, if we're talking about a platformer, for example. Play with some console raycasters, such as both "Zero Tolerance" games for the Mega Drive, or "Battle Frenzy"/"Bloodshot", also for the Mega Drive. They play a bit slow (don't know the exact frame rate), but they are playable. "Duke Nukem", also for the Mega Drive plays a bit faster. Try "Wolfenstein" and "Doom" for the SNES. Or "Jurasic Park", that becomes a 3D fighting game once you get inside the building.

No console raycaster is very fluid, but they're all playable. The NES would be no exception. I believe it could run at a decent frame rate, not the best 3D experience in the world, of course, but a nice thing to see the NES doing.
And, what will look the worst between something with utterly skipped frames, and something with utterly skipped frame where you can see the refresh scrolling lines ? That won't make a very high difference.
The second option is worse, IMO.
Unless you can render a 3D image with a fixeed tileset (or a large set of different fixed tilesets) I don't see much interest in it.
My raycaster uses a fixed tileset, so that only the name and attribute tables have to be updated, while the pattern table, which is very expensive to update, is left untouched. This results in walls that are not very detailed, but are good enough so that one can recognize the shape of the maze.

Rendering pixels to the pattern tables would be an interesting way to go for a raycaster on the NES, each frame could use a different side of the table, so that we can't see it being drawn. This would allow for a more detailed image and more colors could be achieved through dithering, but the 3D view would have to be smaller, specially considering that you have to display other things, such as the status bar. A mapper that allows switching between CHR-ROM and CHR-RAM would be great for this. Any cart with more than 8KB of CHR-RAM would be good, actually. I think the speed would be much worse if rendering pixels, though.

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

Post by tepples » Wed Apr 25, 2007 10:49 am

tokumaru wrote:Play with some console raycasters, such as both "Zero Tolerance" games for the Mega Drive, or "Battle Frenzy"/"Bloodshot", also for the Mega Drive. They play a bit slow (don't know the exact frame rate), but they are playable. "Duke Nukem", also for the Mega Drive plays a bit faster. Try "Wolfenstein" and "Doom" for the SNES.
Wolf3D and Super Noah's Ark are pixel doubled, but the engine is still effective. Doom uses a coprocessor at 21 MHz.
Rendering pixels to the pattern tables would be an interesting way to go for a raycaster on the NES
At least it's what Faceball 2000 for Game Boy and Super NES appears to use.
but the 3D view would have to be smaller, specially considering that you have to display other things, such as the status bar.
You can display the status bar with sprites.
A mapper that allows switching between CHR-ROM and CHR-RAM would be great for this.
TQROM (the Pinbot board) would be the best for this.
=Any cart with more than 8KB of CHR-RAM would be good, actually.
That would be either CPROM (the Videomation board) or Squeedo, or perhaps the NES Power Pak.

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

Post by tokumaru » Wed Apr 25, 2007 11:55 am

tepples wrote:Wolf3D and Super Noah's Ark are pixel doubled, but the engine is still effective.
Yeah. My conception of the NES raycaster uses "pixels" that are 8x2 actual pixels. Not a very good resolution, but rendering much more than 28 columns would be too slow (each column represents a ray that is traced through the map, and that means a couple of multiplications, tons of additions and subtractions - depending on the distance from the wall slice). More than that would also make it impossible to use a fixed tileset, which would make it even slower.
Doom uses a coprocessor at 21 MHz.
And still slow....
At least it's what Faceball 2000 for Game Boy and Super NES appears to use.
Walls are not textured, which makes it so much easier. If the walls are not textured, you only need to render the edges of the walls with the different angles the walls can be seen at. But I think all console raycasters generate tiles on the fly... not sure.
You can display the status bar with sprites.
Yeah, if they are not used to place enemies and objects in the level. Other consoles (Genesis & SNES) seem to use the background for that, but they have many more colors in their backgrounds. And making the objects with the background on the NES would also make it impossible to use that fixed tileset.

The pre-calculated tiles I use to make the background use almost all the tileset, there are only 14 free tiles, I think. And that is after I decided not to use a random effect on the floor, which would have used all 256. If the screen could be split after the 3D window, the lower part of the screen could use the other half of the pattern table for the status bar. But sharing that with the actual sprites would be hard, as they have different zoom levels that really increase the tile count.

CHR switching would be the way to go to have a detailed status bar/interface without giving up on sprites or any feature of the 3D view (such as the number of wall colors).

User avatar
Bregalad
Posts: 7768
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Wed Apr 25, 2007 11:59 am

Getting all tiles redrawn would be awesome, but then you'd get a framerate as horrible as Final Fantasy 2's 3D world map (press B+Select after having gotten the ring).
You could use longer VBlank and stack-indexed $2007 writes à la Battletoads to get tricky and win refresh time (however I'd leave less time for the frame calculation itself).
Other than this, I have trouble seeing how you could render any ray-caster only with a CHRROM pattern table.

Oh, and I'd get for untextured walls and a higher framrate any time. It'd be a lot better if you ask me. (as long as they have a solid color, because if by "untextured" you mean wireframe, then ignore my previous senstence, because noting look as worse as wireframe does).

You could also have CHRRAM, but have a fixed tileset in the BG pattern table, and use sprites that are automatically streatched in the SPR pattern table. I think that could look good (but that would be almost impossible to do I guess). Else goes the Rad Racer way, with pre-streched sprites in the pattern table.

And something like this could definitely put the TQROM board to good use, (unlike, hem hem, Pinbot...)

EDIT :
[Tepples mode on]
No console raycaster is very fluid, but they're all playable.
My [ Instert Playstation 2 game here ] copy seems to be very fluid.
[Tepples mode off]

I'm surprised he missed this one.

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

Post by tokumaru » Wed Apr 25, 2007 12:17 pm

Bregalad wrote:You could use longer VBlank and stack-indexed $2007 writes à la Battletoads to get tricky and win refresh time (however I'd leave less time for the frame calculation itself).
It should be possible to eat a lot of time from the rendered frame, since a raycasting view is usually much wider than taller, and a status bar shouldn't use much space either, so big chunks of the screen would be avaliable at the top and at the bottom.

However, what good would it be to have a lot of time to copy pattern table data, if that time comes from the time that would be used to calculate that data?
Other than this, I have trouble seeing how you could render any ray-caster only with a CHRROM pattern table.
Image Image

You have seen these, right? The resolution is far from perfect, but you can understand what's going on. These are mockups, made from the windows version of the raycaster, but everything can be drawn with this tileset (now that I look at it again, there sem to be 16 free tiles, at the end):

Image

The limitations are that each slice can have only two shades of the same color, using a 1bpp texture. Also, no more than 3 different wall colors can be shown in the same frame, but this is dynamic and the engine will define the 3 colors as it renders the view. The levels have to be designed in a way that no more than 3 colors would be seen at once, or else something would look wrong.

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

Post by tokumaru » Wed Apr 25, 2007 12:21 pm

Bregalad wrote:[Tepples mode on]
No console raycaster is very fluid, but they're all playable.
My [ Instert Playstation 2 game here ] copy seems to be very fluid.
[Tepples mode off]
I thought he'd say that too, so I had an answer ready: They are not raycasters. =)

I even rephrased that part, as I was going to say "3D shooters", and that would have included the PS2 games.

User avatar
Bregalad
Posts: 7768
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Wed Apr 25, 2007 12:27 pm

That's really impressive. I guess 3 colors aren't so many however, but the textures are impressing.
I thought he'd say that too, so I had an answer ready: They are not raycasters. =)
That's probably why he didn't say this (or at least I hope for him).
But then, what are they ? Ray-tracers ? I trought this would be impossible unless we got 300 GHz GPUs ?

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

Post by tokumaru » Wed Apr 25, 2007 12:49 pm

Bregalad wrote:That's really impressive. I guess 3 colors aren't so many however, but the textures are impressing.
It would be possible to use more colors with MMC5, where the colors of a column would have zero impact in the colors of it's neighbour. But with regular attributes, each pair of columns must use the same palette, and the palettes must include all possible combinations of the currently seen colors.

I don't think it looks bad, specially since the floor and the sky/ceiling can have one extra color. The thing is that 2 colors are fixed in all palettes: the color for the ceiling and the floor, and the color used for shading (usually black). The other two are modified to accommodate the different walls found during rendering.

I use 3 palettes for the 3D view, the 4th one is used for the interface around it. That means I have 3 pairs of colors to use per frame. Although that would be 6 colors, I have to worry about different colors that meet inside the same attribute block, so the only way to make sure the view can be correctly rendered is limiting it to 3 wall colors, so that pairs AB, BC and AC can handle every possible encounter of colors.

And this is the reason why every pattern in the pattern table comes in two colors (red and blue in the image I posted), 'cause you may need to draw it using the first slot of the pair of colors or the second.
But then, what are they ? Ray-tracers ?
Raycasting is a way to fake 3D. As far as I know, newer 3D graphic cards (such as those used in newer consoles) work with actual 3D points and polygons, with mathematically correct formulas. I don't think that's raytracing.

EDIT: Here are two other mockups I have:
Image Image

I'd really like to see that running on a NES, but I just can't think of a good game that doesn't include enemies. "Escape from the maze" is not cool at all... I think I have figured a way to include enemies/objects that don't move (I have to check my notes), and are always in the center of a block. This is already more interesting that no enemy/object at all! =)

User avatar
Bregalad
Posts: 7768
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Thu Apr 26, 2007 9:36 am

I trought the 3 colors were for using BG color for shading and the 3 other colors for the 3 objects colors. Doing it AB, AC and BC as you said would allow two constant shading colors, instead of just one.
Or it is reserved for sky/ceiling ?

EDIT : For sprites I'd say go with enemies, and make them available at wide set of various distances. If done right, you'd need something like 6 different distances, and 2 different directions (up-left, and down-left, because up-right and down-right would just use horizontal flipping). That'd left room for a handfull of diferent enemies at a time.

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

Post by tokumaru » Thu Apr 26, 2007 10:46 am

Bregalad wrote:I trought the 3 colors were for using BG color for shading and the 3 other colors for the 3 objects colors. Doing it AB, AC and BC as you said would allow two constant shading colors, instead of just one.
Or it is reserved for sky/ceiling ?
I'm not sure I understood what you said... but I have set up the palettes (3 of them) like this:

color 0: sky/ceiling/floor
color 1: wall color 0
color 2: wall color 1
color 3: shading

Colors 0 and 3 are fixed for the entire level (unless you want to modify color 0 halfway through the frame to have different ceiling and floor colors - most likely only possible using a mapper with scanline IRQ's).

The other 2 are filled in depending on the colors of walls that meet within attribute blocks. This is done as the pairs of columns are rendered. The only way to be sure the view can be rendered is to only allow 3 colors of walls at a time. If there were 4, for example, there'd be 6 possible pairs of colors meeting, but I only have 3 palettes for these encounters.

Code: Select all

4 colors:

  A B C D
A   x x x
B     x x
C       x
D

AB, AC, AD, BC, BD and CD.

3 colors:

  A B C
A   x x
B     x
C

AB, AC and BC.
And I can't even use the color of the ceiling/floor in the walls, because the tileset has room for all variations of 2 types of walls only, one that uses color 1 shaded with color 3, and one that uses color 2, also shaded with color 3.

With MMC5 and it's extended graphics mode, using the same 3 palettes and the same tileset it would be possible to use 6 colors for walls, since the attributes for each column are independent from other columns.
EDIT : For sprites I'd say go with enemies, and make them available at wide set of various distances. If done right, you'd need something like 6 different distances, and 2 different directions (up-left, and down-left, because up-right and down-right would just use horizontal flipping). That'd left room for a handfull of diferent enemies at a time.
I believe that in such a limited environment as the NES, enemies could be done like in some versions of Wolf3D, where they were always facing you. A lot of tiles are already wasted because of scaling, and having the sprites face different directions would make it impossible to have more than 1 in the tileset, if that. Notice that in most raycasters, things are usually facing you, no matter the angle you look at them. Enemies are the main exception, usually, but this would be too heavy for the NES. No sneaking behind guards, I guess. =)

I'm starting to sound like I'm coding this thing now... O_o I have to focus on my platform engine, and then I'll code this! =)

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

Post by tepples » Thu Apr 26, 2007 2:10 pm

If you limit yourself to four enemies per screen, you can use MMC3 CHR banking to switch sprite banks every time you switch sprite cels.

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

Post by tokumaru » Thu Apr 26, 2007 2:29 pm

tepples wrote:If you limit yourself to four enemies per screen, you can use MMC3 CHR banking to switch sprite banks every time you switch sprite cels.
Yeah, I though of doing this at some point... I was avoiding this 'cause I wanted to make a NROM demo of the engine first. But I guess that CHR switching and scanline IRQ's can really help a game like this.

mic_
Posts: 917
Joined: Thu Oct 05, 2006 6:29 am

Post by mic_ » Fri Apr 27, 2007 12:54 am

It would be nice to see this on the NES. Of course the framerate may not be all that good, but that doesn't mean you can't do it just for the hell of it.
I had problems drawing more than 28 columns (I don't remember where the rows maxed out). But that didn't really have anything to do with the actual raycasting - I just ran out of vblank cycles to use for writing to the nametable.

Post Reply