
A Tiny Wolfenstein-Like Software Engine - glouwbug
https://github.com/glouw/littlewolf
======
petercooper
FWIW, this a nice miniature C project to noodle with Makefiles and some basic
C if you're new to it.

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/](https://brew.sh/)

------
LambdaComplex
> early wolfenstein and doom days.

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](http://doom.wikia.com/wiki/Doom_rendering_engine)

~~~
GrantSolar
For anyone interested in the inner workings of Doom[1], I can't recommend
Fabien Sanglard's blog enough. He also released a book on Wolfenstein 3D which
goes into tremendous detail on the code, company, and hardware of the time.

[1]
[http://fabiensanglard.net/doomIphone/doomClassicRenderer.php](http://fabiensanglard.net/doomIphone/doomClassicRenderer.php)

~~~
coldacid
He's actually working on a companion book covering the Doom / id Tech 1 engine
now, too.

------
userbinator
Related --- doing something very similar in _128 bytes_ of binary:
[https://news.ycombinator.com/item?id=7960358](https://news.ycombinator.com/item?id=7960358)

------
diimdeep
There should be Awesome List with small simple implementations of any kind,
like this.

~~~
s-macke
In principle, such a list exists. It is called Obfuscated C Code Contest

[https://www.ioccc.org/](https://www.ioccc.org/)

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.
...

~~~
s-macke
I forgot the fluid simulator in 4kB.

------
anigbrowl
Great learning project. Having it <300 lines whiles till being clear and easy
to navigate is fine work.

------
WalterGR
Can anyone recommend something similar but with more code comments?

~~~
simias
I wrote a similar code a few years ago, although it also supported textures
(including ground and skybox, unlike the original Wolfenstein). I don't know
if it'll be more to your taste but there are afew comments:
[https://bitbucket.org/simias/wolf/src/873cad46f3c8281e7d9429...](https://bitbucket.org/simias/wolf/src/873cad46f3c8281e7d94293b21af3c72e831d860/wolf.c?at=default&fileviewer=file-
view-default) the magic happens in wolf_horizontal_intersect. Note that I use
fixed point which obfuscates the arithmetic a bit (I was targeting an embedded
platform without hard float at the time).

It looks like this while running: [https://svkt.org/~simias/misc/wolf-
floor.png](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](http://lodev.org/cgtutor/raycasting.html)

~~~
diimdeep
Please add Readme with few words about project.

------
pedrow
Interesting that it passes/returns structs by value quite a lot which is not
usual in C (in my experience.) I assume there's a reason for this? e.g.

static Hero spin(Hero hero, const uint8_t* key)

[https://github.com/glouw/littlewolf/blob/339cb5624462d4f2301...](https://github.com/glouw/littlewolf/blob/339cb5624462d4f23019aaaac150de635a2a8a20/main.c#L263)

~~~
jeffreyrogers
I think it's just for simplicity, since all that copying can't be faster than
passing in a reference to it.

~~~
munificent
You might be surprised. For small structs, copying is very fast and may give
you a result with better locality. Passing around structs by pointer means
more pointer dereferencing, which has its own overhead and can cause cache
misses.

Performance of modern CPUs is _very_ nonobvious.

~~~
glouwbug
You are correct. On a much larger project with a similar software engine, if I
change all structs I pass by value to pass by reference my instruction count
shoots up by 40% according to cachegrind (flto + ofast).

Amazing how powerful pass by value can be when it comes to pod structs.

------
conmarap
This is pretty neat. I love how it fits (sanely) in a single file. I've been
meaning to get into SDL for a while now, so this will be an interesting read.

------
kedoremos
Very well written and easy to read C.

------
foota
Neat that they did it without a graphics API

~~~
voltagex_
SDL2 is the API

~~~
foota
True, I guess I meant a rasterization library. It looked like they were mostly
using SDL2 for interfacing with the OS and blitting to the screen.

(and to be more specific I really meant without opengl|directx|vulcan etc)

~~~
mhd
Interesting how meaning changes. Back when Wolfenstein was made, "without a
graphics API" just meant

    
    
        mov ax, 13h
        int 10h

~~~
Gnurou
... and even there you were using a graphics api, provided by your video
card's bios and compatible across various manufacturers.

~~~
Koshkin
Not really - you'd be mostly just writing into the video buffer.

~~~
TickleSteve
int10h is the API (BIOS)... that just causes the mode switch. What he really
meant (direct RAM access):

    
    
       void putpixel_13h(int x, int y, int color)
       {
          _farpokeb(_dos_ds, 0xA0000+y*320+x, color);
       }

~~~
Koshkin
Yeah, but nobody does that.

------
marcel-me
Beautiful

