New demo uploaded: Wolfenstein 3D - raycasting demo with textures

All aspects of programming on the Commander X16.
ZeroByte
Posts: 714
Joined: Wed Feb 10, 2021 2:40 pm

New demo uploaded: Wolfenstein 3D - raycasting demo with textures

Post by ZeroByte »



13 hours ago, Jeffrey said:




Having fun just thinking about this problem!



I know exactly what you mean. I'm the same way.

It's a pity that VERA doesn't have sprite scaling functionality (other than that they get scaled along with everything if you scale the display itself) - if it did, then the sprites in Wolf3d would be a cakewalk.

Ed Minchau
Posts: 503
Joined: Sat Jul 11, 2020 3:30 pm

New demo uploaded: Wolfenstein 3D - raycasting demo with textures

Post by Ed Minchau »



On 3/8/2021 at 9:20 PM, Jeffrey said:




Indeed. Thats where I got the idea from. ?



image.png.27361eed05179f0bc8511e4cd6b987b4.png



The above mentioned video says: "As there is only a finite number of possible heights, Wolfenstein code generates one routine for every possible height".



Right now I store the textures in VRAM. When I generate such a routine its simply looks something like this:



In that example it writes about 2-3 times more to the screen than it reads from the texture (which is 64x64 pixels). The nice thing about VERA is that you can do this vertically, which suits drawing columns for each ray very well.



This takes less than 8 cycles per pixel. Sometimes you read more than you write (when walls are smaller than the textures). Sometimes you write more than you read (when the walls are taller than the texture). All in all a little less than 8 cycles. I still need to optimize the smaller walls (as they dummy-load too much right now, so I probably need a secondary, smaller texture or double my stride).



For the ceiling and floor I simply have a  single routine with a whole bunch to STA VERA_DATA0's and I jump in that routine at exactly the right place (with the correct color in A). So those take only 4 cycles per pixel.



I can still speed that up a little by remembering how tall the wall (on that column) was the previous frame, so I only have to remove that old wall  and not redraw the entire ceiling or floor.



Fun stuff! ? 



 



You might want to check out the Coding Secrets channel on YouTube.  That guy did a lot of games for the Sega (ie Sonic, Toy Story 3D) and goes through the code he wrote to do all the 3d effects.

Elektron72
Posts: 137
Joined: Tue Jun 30, 2020 3:47 pm

New demo uploaded: Wolfenstein 3D - raycasting demo with textures

Post by Elektron72 »



On 3/8/2021 at 11:20 PM, Jeffrey said:




For the ceiling and floor I simply have a  single routine with a whole bunch to STA VERA_DATA0's and I jump in that routine at exactly the right place (with the correct color in A).



Considering that the ceiling and floor are just static colors, would it be possible to use either another layer or a raster interrupt halfway down the screen to create this effect?

ZeroByte
Posts: 714
Joined: Wed Feb 10, 2021 2:40 pm

New demo uploaded: Wolfenstein 3D - raycasting demo with textures

Post by ZeroByte »



7 hours ago, Elektron72 said:




Considering that the ceiling and floor are just static colors, would it be possible to use either another layer or a raster interrupt halfway down the screen to create this effect?



You'd still have to do some cleanup with the transparent pixels wherever a wall changes sizes between frames.

Sometimes the added overhead of checking for things is slower than just blitting a bunch of pixels. I ran into this when making my C64 version of Flappy Bird - I tried 2 different methods of drawing the pipes whenever the scroll register loops: go to each column where pipes are located and draw them in with one extra blank tile to the right of each pipe vs. just blit the entire screen one tile to the left and then draw the final column. It's less writes to do it the first way, but the extra logic to go through the list of pipe columns, load the height of each set of pipes, and write the different tiles at the proper heights actually ended up taking more raster time than the dumb blit routine. It even blits into the rightmost column which is about to be overwritten by the new column of tiles being scrolled in - it's faster to just "durrrr blit!" and then go overwrite one column than it is to put in code to skip every 40th tile.

If I were going to use 2 bitmap layers, I would probably do the walls in a layer and the actors in a layer (they're not really "sprites" are they?) - because you can actually do a few optimizations this way - such as not re-drawing the walls if the camera hasn't moved, and only redrawing the columns that have actors in them. (enemies still move and animate even if you're not moving the camera). Then I'd just use actual sprites for the gun you're holding, so animating that is nothing but updating the sprite pointers for the animations.

Finally, a raster IRQ to switch back to tile mode on layer1 for the HUD, and you're set.

Jeffrey
Posts: 62
Joined: Fri Feb 19, 2021 9:46 am

New demo uploaded: Wolfenstein 3D - raycasting demo with textures

Post by Jeffrey »



11 hours ago, Elektron72 said:




Considering that the ceiling and floor are just static colors, would it be possible to use either another layer or a raster interrupt halfway down the screen to create this effect?



Yes it would be possible. But as ZeroByte said, you would still have to clear parts of the walls that were drawn the previous frame and thats just as expensive as writing a single color to it. 

It would be beneficial if you only had to draw a single picture (given an empty buffer), but we have to draw over the same buffer again and again. If there was a magic "clear entire video buffer" command then it would for sure help.   

Ed Minchau
Posts: 503
Joined: Sat Jul 11, 2020 3:30 pm

New demo uploaded: Wolfenstein 3D - raycasting demo with textures

Post by Ed Minchau »



9 hours ago, Jeffrey said:




Yes it would be possible. But as ZeroByte said, you would still have to clear parts of the walls that were drawn the previous frame and thats just as expensive as writing a single color to it. 



It would be beneficial if you only had to draw a single picture (given an empty buffer), but we have to draw over the same buffer again and again. If there was a magic "clear entire video buffer" command then it would for sure help.   



How much space have you allocated for the buffer? Do you absolutely have to have square pixels,  or can you get away with stretching the screen vertically with VSCALE and draw the same number of columns but fewer pixels per column? Might be able to get two frames in memory at the same time that you can flip between... definitely if you stretch the vertical scale to half the horizontal scale. 

Jeffrey
Posts: 62
Joined: Fri Feb 19, 2021 9:46 am

New demo uploaded: Wolfenstein 3D - raycasting demo with textures

Post by Jeffrey »



28 minutes ago, Ed Minchau said:




How much space have you allocated for the buffer? Do you absolutely have to have square pixels,  or can you get away with stretching the screen vertically with VSCALE and draw the same number of columns but fewer pixels per column? Might be able to get two frames in memory at the same time that you can flip between... definitely if you stretch the vertical scale to half the horizontal scale. 



That is a good idea. ? Right now I might have enough room for two buffers (which I want to use to prevent shearing), but I won't have a lot of room for many textures (that are also in VRAM and take around 4k each). Stretching in the vertical axis will alleviate the VRAM problems and it might not look so bad. Will have to look into it. Might be a good option. 

Right now, I am still handwriting all performance critical functions into assembly. Got it mostly ported, but still some leftovers in c (which still drain the speed). I am struggling a bit with the last pieces, but I think I will get a working version (in assembly) pretty soon. I've had many weird bugs and investigating them is quite a challenge and time consuming...

Regards,

Jeffrey

Ed Minchau
Posts: 503
Joined: Sat Jul 11, 2020 3:30 pm

New demo uploaded: Wolfenstein 3D - raycasting demo with textures

Post by Ed Minchau »



3 hours ago, Jeffrey said:




That is a good idea. ? Right now I might have enough room for two buffers (which I want to use to prevent shearing), but I won't have a lot of room for many textures (that are also in VRAM and take around 4k each). Stretching in the vertical axis will alleviate the VRAM problems and it might not look so bad. Will have to look into it. Might be a good option. 



Right now, I am still handwriting all performance critical functions into assembly. Got it mostly ported, but still some leftovers in c (which still drain the speed). I am struggling a bit with the last pieces, but I think I will get a working version (in assembly) pretty soon. I've had many weird bugs and investigating them is quite a challenge and time consuming...



 



64x64 textures? They don't have to be. They can be anything you want,  since they're not being directly displayed. And if you go with half the vertical resolution on the screen you can cut those in half too. Are the top half of the textures mirror images of the bottom half? You can count down as well as up, so that could cut the textures in half as well. 

Jeffrey
Posts: 62
Joined: Fri Feb 19, 2021 9:46 am

New demo uploaded: Wolfenstein 3D - raycasting demo with textures

Post by Jeffrey »



9 hours ago, Ed Minchau said:




64x64 textures? They don't have to be. They can be anything you want,  since they're not being directly displayed. And if you go with half the vertical resolution on the screen you can cut those in half too. Are the top half of the textures mirror images of the bottom half? You can count down as well as up, so that could cut the textures in half as well. 



Most textures are not vertically mirrored. Some might me though. Good idea to exploit that where possible. ?

My goal for now (the demo) is to have the same look and feel as Wolfenstein 3D. And see how fast that runs on the x16 (and first optimizing for that). So I am using the original 64x64 textures for now and keeping with the original screen resolution. Then see how fast we can get that.

If performance is (too) low, halving the vertical screen resolution (and maybe the texture resultion) is certainly an option. Other tricks are possible as well. But those are compromises to be made later on I think.

Ed Minchau
Posts: 503
Joined: Sat Jul 11, 2020 3:30 pm

New demo uploaded: Wolfenstein 3D - raycasting demo with textures

Post by Ed Minchau »



12 hours ago, Jeffrey said:




 



Right now, I am still handwriting all performance critical functions into assembly. Got it mostly ported, but still some leftovers in c (which still drain the speed). I am struggling a bit with the last pieces, but I think I will get a working version (in assembly) pretty soon. I've had many weird bugs and investigating them is quite a challenge and time consuming...



 



There's something else that might speed things up for you on the programming side: you can write assembly language code that writes assembly language code. Lots of what you're writing is just various LDA VERA_DAT_1 and STA VERA_DAT_0 in various combinations. You could pick some vertical scale to display, say 152 pixels, and have an assembly language routine generate all of those height scale subroutines for you automatically. 

Post Reply