SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.
SlideShare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.
Successfully reported this slideshow.
Activate your 14 day free trial to unlock unlimited reading.
From a short talk I did about a hobby project - figuring out Doom's WAD format using a hex-editor. Originally just to play the music files, I got carried away and extracted all the data, rebuild all the images and audio, and rendered the maps in OpenGL, which required some triangulation tricks. Some tidbits of historical interest were discovered.
From a short talk I did about a hobby project - figuring out Doom's WAD format using a hex-editor. Originally just to play the music files, I got carried away and extracted all the data, rebuild all the images and audio, and rendered the maps in OpenGL, which required some triangulation tricks. Some tidbits of historical interest were discovered.
2.
making our own doom WADs
(maps/levels etc) in 1994-5
a port of DEU from http://interreality.org/~tetron/technology/lde/
3.
Here is all the data!
- binary file, custom layout
- Id released specs to help modders build tools
~1994 (I went in raw though)
- IWAD and PWAD
- combines all game data
- parts of levels; { walls, floors, monsters… }
- sound effects data (proprietary format)
- music (proprietary format)
- colour palettes, images for maps, enemies,
panels…
- images with transparent bits have custom format
5.
binary sleuthing
- figure out file structure
- search for strings
- determine directory
structure
- match hex-format
address with values
- h/w arch of 1993
machines
- trial and error
e.g. directory started at
~ 00 BC C5 00
this 4-byte group says
“C4 C5 BC 00”
6.
printf() the directory
- Directory entries in block at
end of file:
- entry string (good hint)
- entry size in bytes
- entry offset from file start -
use fseek()
- I was after the music but
couldn’t resist
- “VERTEX” “LINEDEF”
“SECTOR” …
7.
LINEDEF ~walls
references 2 VERTEXES
references 1-2 SIDEDEFS
find height in SECTORS
VERTEX
has 2 (x,y) integer values
SECTOR
~floor/ceiling
bounded by SIDEDEFS
not tessellated
not always convex
have holes
8.
Walls and Floors
- Create a struct for each type of map part and
put them in arrays to do quick line->height etc.
- Walls - just extrude them up?
- lower lip
- mid (sometimes a gap)
- upper lip
- Floors - tessellation algorithm
- I used “Ear Clipping”
extended for holes
9.
Ear-Clipping Tessellation
- David Eberly’s white paper is great
https://www.geometrictools.com/
Documentation/
TriangulationByEarClipping.pdf
- breaks a simple polygon into triangles
- single region bounded by loop of edges
and verts
- a group of 3 consecutive verts is reflex
(angle > pi) or convex (angle < pi)
- convex triplet = a polygon ear
- but not if another vert is inside that triangle
- and final line is fully inside poly
- can recurse clipping until 3 vertices remain
O(n^3) … but can improve on this
The Two Ears Theorem
A polygon of >3 sides always has at
least 2 valid ears.
is_convex(
vert a, vert b, vert c );
is_in_triangle(
vert a, vert b, vert c,
vert x );
10.
Ear-Clipping Tessellation
- Loop around all n verts in polygon
- use curr-1, curr, curr+1 (modulo n)
- test all other verts - is_in_triangle()
(pre-calc current reflex/convex status per triangle
to reduce time complexity). ~O(n^2)
- if (is_ear) {
- remove curr vertex from polygon
- add triangle to a list
- decrement n.
- if n == 3 found last triangle. HALT
- https://youtu.be/9wrhIvpOKlg
shows algorithm on Doom E1M1 in steps
- src (experiment 039)
https://github.com/capnramses/opengl_expmts
11.
- extend Ear Clipping for O-shapes (hole in middle):
- outer vertices clockwise order - make inner loop CCW
- add to end of loop’s vertex list
- add a valid “cut” line between outer and inner (tricky)
- proceed as normal - now treated as a C-shape
Pool of toxic sludge inside
another sector - gets obscured
12.
modified ear clipping
worked!
(sludge pool no longer
paved over)
13.
shader for ceilings with “sky” image
texture is one half of a 180
that wraps ~ proto-skybox
mapped to 320x200 screen
pixels so hard to map to
arbitrary size/resolution
14.
Secrets of Romero’s Head
- found tiny ledges on wall
that had big daemon head
- clever way of splitting
enormous image into many
sub-images
15.
Hacking the unpublished
sound format
- Custom 8-byte header - I just ditched it
- Body is a blob of waveform data
- Guess format based on original
SoundBlaster
- Trial and error in Audacity raw data import
- unsigned 8-bit mono 11025Hz samples
- 16 bytes additional padding at front and end that can all be
trimmed, leaving raw sound data.
- Seems to work. https://youtu.be/AZxU9fNsWoU
16.
Music format
- Wasn’t MIDI! It was MIDI encoded into a proprietary format
- 9 instruments
- custom playback software (never released)
- MIDI2MUS and MUS2MIDI (MS-DOS)
- I don’t know enough about MIDI etc to work it out.
- I used DosBox and an ancient MUS2MIDI
- Sub-par results - need original playback software!
17.
“Dude, you need to stop
working on your vanity projects!”
- How do other Doom renderers deal with the sector tessellation
problem?
- They didn’t! Specially prepared .WAD [cheating!].
- Better potential solution
- try Delaunay triangulation instead
- Source code
- DeWad - https://github.com/capnramses/doom_projects
- OpenGL renderer - Blog post about it - antongerdelan.net/blog/
18.
Finding a good cut
- find rightmost inner loop vertex
- project vector right from it
- intersect all outer edges
- find closest vertex to projected
line (except if vertex is not visible
to first vertex).
- if closest point is an outer point
use this. HALT.
- otherwise search the outer edge
for valid visible vertex to first
(many tests and conditions here)
multiple holes or complex?
create hierarchies of simple
shapes, solve small, combine