

Doom engine code review - franze
http://fabiensanglard.net/doomIphone/doomClassicRenderer.php

======
hapless
It's amazing that this would run halfway well on a 33 MHz 486. Doom had a 35
fps cap, and ran at 320x240 (square pixels):

2.7 million pixels per second at 35 fps (the cap).

1.4 million pixels per second at 18 fps (~50% of cap).

At the more realistic target of 18 fps, you have 24 clock cycles per pixel. A
486 averaged about 0.8 instructions per clock, so you're looking at 19
instructions per pixel. With a 33 MHz memory bus and the DRAM of the day,
you're looking at about 5 clocks for memory latency. That looks like an upper
bound of no more than 4 memory operations per pixel.

A convincing 3d renderer averaging 19 instructions and 4 memory operations per
pixel. And we're not even counting blit/video delays here. Good lord is that
savage optimization work. Carmack is famous for a reason.

P.S. The _really_ scary thought is that Doom would hypothetically run on any
386 machine -- can you imagine painting e.g. 160x120 on a cacheless 20 MHz 386
laptop?

~~~
hunterjrj
If I recall correctly, you had to shrink the view port on lower-end 486s for
playable framerates. Also, the status bar shrank the area to be rendered to
some extent.

Your point still stands, just pointing out that the target area for rendering
was often smaller than 320x240.

~~~
rograndom
I remember it was very playable on the 33mhz, 8mb 486DX machines I had at my
high school. A friend had a 50mhz 12mb 486SX-2 which was wonderful for Doom. I
sadly only had a 16mhz 386sx with 2mb of RAM. I amazingly did get Doom to
"run" on this machine through some virtual memory program for Win 3.1. I had
to shrink the screen size down to the smallest size for it to run at about
1fps.

I also remember a couple of other people that had "486" upgrades for their 386
based systems and Doom was perfectly playable on those systems as well. RAM
was the big limiting factor that I remember.

~~~
redthrowaway
Why'd you run it through Windows? I had a 33Mhz 386 and 2 (4?) MB of ram. I
made a boot disk, and it worked fine.

~~~
agazso
I also done that on a friends' 386SX 25MHz machine that had only 2MB of ram.
Doom required at least 4MB (sounds ridiculous as I am typing) and although it
used the DOS4GW dos extender that was capable of swapping, it never worked.

On the other side, Win 3.1 was also capable of swapping and ran Doom. It was
absolutely unplayable though :)

~~~
redthrowaway
You know, I still have that 386 in my mom's attic. I'm tempted to break it out
and see what it can do.

Ultima VII required a 33MHz 386DX w/ 4Mb of ram, and my computer ran it fine
with a boot disk. If memory serves (and I was 7 at the time, so it probably
doesn't), a DOS 6.22 bootdisk contained fields for page size, which leads me
to believe it had support for virtual memory. That said, I do remember the
massive stink that was made about virtual memory when Windows 95 came out, so
I could be wrong.

I'm highly tempted to break out that old box and play around with it. This
conversation tickles my nostalgia bone.

------
thibaut_barrere
The first (and only one, currently) comment brought me back years ago! A major
performance trick back then was to ensure the code and data would remain into
the (very small) cache, as well as preferring structures that would be read in
order.

====================

"Because walls were rendered as columns, wall textures were stored in memory
rotated 90 degrees to the left. This was done to reduce the amount of
computation required for texture coordinates"

The real reason is faster memory acces when reading linearly on old machine,
less cpu cache clear. It's an old trick used on smooth rotozoomer effect in
demo scene year ago.

~~~
thedjinn
Actually, rotating a texture 90 degrees in memory when making a rotozoomer
still results in large amounts of cache misses depending on the current
rotation angle. In order to get a smooth rotozoomer effect you have to use a
technique called block rendering. This means you divide the image in square
cells and render these one by one. Because the pixels in the cell are always
near eachother you can reduce cache misses. There is an old snippet from
Niklas Beisert floating around the web that explains exactly how this works.

~~~
thibaut_barrere
Yup :) Here's the code if someone is interested:

ftp://latvia.tucows.com/pub/mirror/x2ftp/msdos/programming/demosrc/pasroto.zip

(I managed to find it back thanks to hornet.org)

Edit: you can also check out the list at
ftp://latvia.tucows.com/pub/mirror/x2ftp/msdos/programming/demosrc/00index.txt

~~~
dman
Thanks for digging this up. Much appreciated.

------
light3
Link to nice doom port at bottom: <http://www.chocolate-
doom.org/wiki/index.php/Chocolate_Doom>

------
Luc
Michael Abrash' "Zen of Graphics Programming" has a good overview of many of
the tricks used during that era: [http://www.amazon.com/Zen-Graphics-
Programming-Ultimate-Writ...](http://www.amazon.com/Zen-Graphics-Programming-
Ultimate-Writing/dp/188357708X)

(now, of course, mainly to be read for nostalgic reasons).

~~~
kabdib
... and, to avoid similar architectural mistakes in the future.

History is useful. We're not at the point where we want CS students to
memorize what happened at the Battle of Algol in 1968, but it's darned close.

------
Tyrant505
Any qed users? I liked it for map editing most.

