A Tiny Wolfenstein-Like Software Engine
github.com
github.com
If you're on macOS, just slap a quick `brew install sdl2` before the instructions and it's golden - assuming you run https://brew.sh/
Wolfenstein yes, Doom no. Wolfenstein 3D used a very simple raycasting method that just shot rays out from the player's position to render a 2D level in psuedo-3D. Doom, while still technically using raycasting, uses a much more complicated method that involves BSP trees.
A quick google search found this page, which explains it much better than I can: http://doom.wikia.com/wiki/Doom_rendering_engine
[1] http://fabiensanglard.net/doomIphone/doomClassicRenderer.php
Granted, the code is not really readable. But you can see the awesomeness.
Boot Windows 3.0 and DOS with a 4kB emulator. C compiler in 4k, which can compile itself. Global illumination renderer in 4kB. Flight simulator in 4kB. ...
It looks like this while running: https://svkt.org/~simias/misc/wolf-floor.png
That being said if you're interested in writing something like that I recommend that you use any basic tutorial on raycasting and try implementing it "from scratch" yourself, it's pretty simple and quite fun IMO. IIRC I used this one: http://lodev.org/cgtutor/raycasting.html
A text editor by the guy that made redis, in less than 1000 lines and a lot of comments.
https://github.com/s-macke/VoxelSpace
The text in the README describes the technique very well. The JavaScript code is a little bit more complicated to read because most of the source contains the usual organizational tasks around the algorithm (initialization, keyboard input, ...). But this is also true for the provided C-code of this article.
It uses a deferred rendering pipeline and currently I am trying to get light volumes to work.
static Hero spin(Hero hero, const uint8_t* key)
https://github.com/glouw/littlewolf/blob/339cb5624462d4f2301...
Given:
static void damage(const Hero* hero, const Sprite* sprite);
The const can easily dropped later in production from both entities, potentionally creating two return values.This is analougous to good use of privacy in C++ classes.
hero = spin(hero, key);
Becomes: hero.spin(key);
Where external objects dictate the private state of the hero object.Pointer aliasing is another thing. Inlining is easier with fewer pointers. A fun C++ experiment is to count your instruction and data cache points with valgrind's cachegrind with pod types both passed by value and by reference (&).
Performance of modern CPUs is very nonobvious.
Amazing how powerful pass by value can be when it comes to pod structs.
(and to be more specific I really meant without opengl|directx|vulcan etc)
mov ax, 13h
int 10h void putpixel_13h(int x, int y, int color)
{
_farpokeb(_dos_ds, 0xA0000+y*320+x, color);
}Modern graphics cards on the other hand can easily push a few million triangles every frame with decent framerates. At 10k triangles * 10 or 20 maps you could load all maps from the game simultaneously and still easily get decent fps.