Celius wrote:
If I keep the room size limited to 11x11 blocks, the ray will never go a distance of over 255 (use Pythagorean Theorem to calculate the length of a ray in an 11x11 room, is about 249 sub-blocks).
Ah, this must be a very important optimization. It also explains the slightly jagged walls that appear some times. I still haven't found the ideal amount of precision for distances, but from my tests I've seen you can indeed go very low and still have things look good.
Quote:
Does it need to be fisheye-corrected?
If your walls are fisheye-corrected, I imagine that the objects have to be too. When you don't fisheye-correct the walls, looking at a wall perpendicularly will cause the center of it to bulge towards you, so the same would happen to objects. If the wall has been correct and looks straight, an uncorrected object in the center of the screen will appear larger than another one near the edge of the screen, even if both are positioned the same distance from the wall. I don't know if the difference is so terrible at such low resolutions, but there will be a disparity between the representation of walls and objects.
Quote:
My idea was that you would calculate the distance, and scale the object as if it were directly in front of you.
But that's the fisheye correction (the "as if it were directly in front of you" part), isn't it? Directly in front of you, the distortion is 0, but any other angle to the left of the right will look rounded if you don't correct the distances.
Quote:
Well, I actually have a pretty quick and dirty set up for object scaling.
Souns interesting. Can't wait to see it working.
Quote:
Also, don't forget that player projectiles and item drops are "objects", and will need to be rendered appropriately.
Well, Wolfenstein 3D didn't have visible projectiles as far as I remember, and not all weapons in Doom had them either, so you might get away with not showing bullets. Not much you can do about items though, besides not having rooms full of them like Wolfenstein 3D does.
Quote:
If you get the chance to emulate it, try pressing SELECT. You'll see what the engine renders before it XOR fills

Yeah, I saw that. I still can't tell exactly how the XOR filling is saving you time just from looking at that, so I still have some research to do. =)
BTW, I have though of a way to render the image that is somewhere between your technique and mine. The amount of detail in your demo looks great, but I'm not sure it can be turned into a game as is. My main concerns are the following:
1- With only 4 colors overall, levels might look very repetitive. That can be minimized by connecting rooms (since that's how you planned to form levels) of different colors.
2- There's no space in the pattern tables for sprites. Are you planning to draw objects using the background? That would make objects blend with the background too much, and it would be weird if they changed colors depending on the room they're in.
3- There's no space in the pattern tables for a status bar. You might be able to get away with showing the status only when the game is paused, but that would hurt the overall presentation of the game, since the average player will not understand why you can't make use of the vast blank space around the gameplay window.
4- Perpendicular walls are not shaded differently. There aren't enough colors to automatically darken textures, but if all your palettes are gradients, you might be able to manually draw darkened versions of all the textures.
To address these concerns, I have though of a different way to render the maze with a resolution that's somewhere between my demo and yours: 4x2 hardware pixels for each pixel. Each tile would have only 2 colors, one in the left and one in the right, which would allow for 16 different colors (using dithering) in 256 pre-calculated tiles (16 ^ 2 = 256). I would actually reduce the color count to 12 or 14, in order to have tiles left for drawing a status bar, and the second pattern table completely free for sprites.
Scroll changes every 2 scanlines (using the MMC3) would squeeze the picture to the desired resolution, creating a gameplay window that's 224x120 hardware pixels big (56x60 software pixels). 2 name tables would be needed for each gameplay frame, so 4 screen mirroring would be necessary to avoid tearing and having a status bar.
The top and the bottom of the gameplay frame could use different palettes, so you could design the textures (as well as the floor and the ceiling) to take advantage of that, and create more colorful scenes.
Objects would be drawn with sprites, and since thay have their own palettes that would bump the color count up a bit more. Having objects drawn with sprites will severely impact the way they are designed and positioned, because you'd have to do your best to prevent the player from getting too close to wide objects.
As I see it, every method has its drawbacks, and they might end up blocky, monochrome or slow, but I believe that the key is to balance all of those aspects and come up with something that isn't so bad in any of them. IMO, having a very high resolution isn't so good if that means a tiny gameplay window and slowness. I'd rather make things a little blockier and improve the other aspects a bit.
Celius, it's fun to see other people attempting to make something like this on the NES. Thank you for showing me what a different approach might look like. You've made me want to try different things, when I was thinking that I had found the only possible way to make a raycaster for the NES. I hope you continue to work on this, and maybe I'll try these new ideas I wrote above in a program of my own too.