Developer Network
  File Specs
  Source codes
  Mailing lists
  Knowledge Base

Other Games



Descent Developer Network
Descent 1/2

D1Source project

Project: Descent 1 Source code

On this page I try to collect the most important articles and knowledgement from our project, where we try to understand, improve and extend the Descent 1 Source code.

Many of these posts are taken from the Descent-Source-mailing list, which you should definitely subscribe to!

A complete archive of the posts of that mailing list is available at Here on this page I want to filter out the most important ones, creating some kind of a steadily-growing FAQ...


sign_note.gif (1726 bytes) The project to get Miner to run stable and get everything out of it has been moved to its own project.


Current downloads:


The most important links for this project:


01/25/98 18:52 - Heiko Herrmann - TASM

> I was wondering if its possible to compile the source with Turbo
>Assembler, instead of MASM? I remember TASM had many of the MASM features
>and it even has an MASM command. So it should work right? Have not use asm
>in a long time so I am not really sure.
>Jacob L.

To kinda "answer" this, let me explain you that one Sunday (a week ago), where Kevin was personally here in Germany with his laptop:

In the README there was the information, that "MASM 5.x" should do it.

Kevin and I then searched tons of MSDN (Microsoft Developer Network) CDs, the Internet (FTP-Search and the like) for different MASM versions and found MASM 5.10a and MASM 5.10b, both of them didn't compile it. Then we tried TASM of Borland Pascal 7 and also got *many* errors. We gave it up then and Kevin asked PXSoftware why our versions of MASM 5.x (as they stated they used for D1) didn't work, and they answered that it was actually "MASM 6.11". He found it then on his CDs at home (back in USA) and could finally successfully compile it...

So if you want spent more time than we already did, good luck and notify us if you had success :)...


01/25/98 22:19 - Kevin Bentley - Re: TASM

Even when I got MASM 6.11, I had a few problems. To Quote Matt Toschlog:

">We used MASM 6.1, and later 6.11. I apologize for -- I
>went a little overboard and used all these cool macros that generated
>other macros. I'm not surprised it's hard to compile."

So the bottom line is that to get it to work with MASM or something else, is the place to go. If we could rewrite many of those macros, we could probably get TASM or something else to work (Of course we would need the .MASM directive).

As far as porting the asm code to C, that probably isn't a bad idea, if the C code is written very carefully, it would perform pretty close to the asm code, and have the advantage of being more portable.


01/26/98 04:22 - Kevin Bentley - TCP/IP

I have done TCPIP in DOS using WATTCP, and it is really easy, and performs well. In fact it is the library that Kali uses.

Honestly though, there isn't anything in TCPIP that gives the player an automatic advantage over Kahn or Kali. Both use compression, and header reduction code, so native (uncompressed) IP will usually be larger than IPX using Kahn or Kali.

The advantage with native TCPIP is that the user doesn't need Kahn or Kali, but considering that a) DOS Kahn is free, and b) using any DOS TCPIP driver won't work under Win95/NT, but IPX would, I would probably stick to IPX for a while.


01/27/98 15:48 - Bryan Aamot - It compiles...

(Reply by Kevin Bentley)

>I'm using Watcom version 10.6, Masm v6.11, and MSVC's make.exe. I
>downloaded the source last night and compiled. I had to do is edit the
>d1vars.bat file to point to my compiliers and add a masm.bat file to
>satisify masm v6.11. Here's what I did:
>@echo off
>set PATH=c:\d1\;c:\ml611\bin;c:\wat10_6\binnt;c:\MSVC\BIN;%PATH%
>set INCLUDE=c:\wat10_6\h;c:\MSVC\INCLUDE;%INCLUDE%;c:\d1\lib;d:\d1\includes;
>set LIB=c:\MSVC\LIB;%LIB%
>set watcom=c:\wat10_6\
>And the masm.bat file:
>ml /nologo /c /Cp /W3 /WX %1
>I had to fix a few things to get descentr.exe to build. One problem was
>that the editor required the define "EDITOR" in order to build w/o errors.
>So, I edited the editor's makefile and added: /dEDITOR to CCFLAGS. This
>defines "segnum" in the segment structure which is used by editor. I'm not
>sure why the released compile requires the editor to begin with, but oh well.

If you just do a global search and replace over all the make files, and add the /dEDITOR as well as remove the /dRELEASE defines, the editor should build with no changes. It did for me anyway.


>Below is a list of other changes that I had to make:
> Changed matrix_scale.x to Matrix_scale.x

You had to do that because of the /Cp flag on masm, that makes the symbol case matter.

(Details from Hrvoje Velic: rod.asm in directory 3d\ in lines 315, 318, 345, 348.)

> Commented out lines with Mark_count
>I also built the editor version but the use of EDITOR, NDEBUG, and RELEASE
>defines are conflicting a bit with one another. So, I commented a few
>#ifdef's out so I could build the darn thing. I also had trouble with the
>pad files which reference functions that don't exist. And I don't have all
>the *.bbm and *.pof files to avoid the -nobm option. I also have to delete
>the player files *.plr or ibitblt.c chokes on the following line (which I've
>commented out :-)

The #define is because you need to change all the make files most likely, but I found that I had to leave out the RELEASE define to build the editor.

I can explain the problem with the pad files, parallax couldn't find the ones for D1, so they gave me the D2 editor stuff. I had to massively edit the mnu and pad files to get the editor to run at all. That is why there are lots of functions that don't exist. I only edited the files to the point that it loaded. :)

> Error( "Bitmap for ibitblt doesn't have transparency!\n" );
>Lastly, I tried the editor on two computers and both have problems with the
>video display. One doesn't refersh corrctly under the mouse, the other
>doesn't set the video mode correctly and all I get is multicolor horizontal
>lines. I've seen the editor being used at Interplay so I know what it looks
>like and what it can do, but even they complained that the program was very

Thats a weird one. Did you try running the editor that I compiled and put up
on DDR?

>If anyone else makes changes to the source (or finds bugs), then I suggest
>they be sent to this list so Kevin can keep the source up to date.

Please do! This is the best kind of feedback I can get. If someone cleans up the makefiles and sends them to me, that would be great. I spent hours and hours just getting a makefile that worked (the opus makefiles that Parallax used were incomplete, and not compatible with anything). I fought with environment variables until I was so sick of it I just put CCFLAGS and others on the top of each makefile.

I am still working on the sound code, hopefully I will have it worked out soon!


01/27/98 17:53 - John M. Aldrich - Compiler

Ok, first of all, let's put together a list of tools.

1) Specific compiler, version number, etc.
DJGPP version 2.01 is the latest full release. v2.02 is in alpha stage at the moment, and is almost certainly not ready for full-scale production.

The latest DJGPP components are all downloadable from SimTel mirrors; the main mirror site is The GNU packages have their own version numbers, but the latest ports for DJGPP can be found in the v2gnu subdirectory. I'm not entirely sure how much of this functionality we'll need, but I think the following minimum set of packages will suffice:

DJGPP installation instructions (v2/readme.1st)
DJGPP main development files (v2/
DJGPP Frequently Asked Questions list (v2/
GNU binutils (v2gnu/
GNU gcc C compiler (v2gnu/
GNU debugger (v2gnu/
GNU fileutils (v2gnu/
GNU Make (v2gnu/
GNU Info documentation reader (v2gnu/
GNU textutils (v2gnu/
CWSDPMI DPMI host (v2misc/

Additional packages that I recommend include the library sources (so we can make changes if necessary--however, see the copyright), GNU diff, GNU patch, GNU grep, and the GNU shellutils.

2) Assembler, version number, etc.
Some have said that in order to convert assembly code to run in DJGPP, we must convert it to AT&T syntax. This is not necessarily true. For inline assembly, conversion to AT&T _is_ required, but for external assembly language files, the free NASM assembler is capable of recognizing Intel syntax and compiling to COFF objects, which are what DJGPP uses. NASM is available from If you are willing to go to the effort of converting to AT&T syntax, then the assembler that comes with the GNU binutils will suffice.

3) Some documentation on the above items (FAQ, etc.)
Nearly all of DJGPP's documentation is available online from The Frequently Asked Questions list (~180 pages) is the most comprehensive document available for answering portability questions, as well as many others. The FAQ is available with the rest of the DJGPP files (in Info format), and can also be viewed online at I don't know where an NASM FAQ can be found, but it's probably part of the documentation.

4) Make program, and standard configuration for makefiles.
GNU Make is an excellent makefile handler; the Descent makefiles may require some porting but the functionality offered by GNU Make more than makes up for the hassle. I will be happy to assist with specifics if needed.

5) Suggested editors.
GNU Emacs is an excellent editor; I use it for nearly all my work. It's extensible, customizable, and has a host of features for everything from compiling to custom indentation and syntax highlighting to editing makefiles. The only thing it lacks is the ability to perform integrated debugging. This isn't a flaw of Emacs or DJGPP, just a limitation of MS-DOS.

RHIDE is another excellent IDE that was written for DJGPP. Unlike Emacs, RHIDE uses the Turbo Vision interface that is familiar to many users. There are still some bugs remaining, but it's a high-quality IDE. It does feature interactive debugging.


The DJGPP mailing list/newsgroup is a good resource; it's the best place to go for support, version announcements, and general help. The mailing list is (email for instructions), and the newsgroup is news:comp.os.msdos.djgpp.

The install instructions are simple to follow, and are contained in 'v2/readme.1st.' There is also an official (but incomplete) user's guide at


01/27/98 18:36 - Joel Hardy - GNU-ifying

John M. Aldrich wrote:
> There is (or was) such a script; I'm not sure where to find them. A
> search of the DJGPP mail archives at
> should turn up the necessary references. However, simply converting the code to AT&T isn't
> enough to make it work; a lot of hardware-specific code will probably
> need to be rewritten to follow the rules of DPMI 0.9 and DJGPP's library.

See for a *little* bit of GNU-ifying. Since this site is aimed more at a Linux port than a DJGPP port, I think there should be some #ifdefs for GNU (both Linux and DJGPP), DJGPP (for the DJGPP DOS port, obviously), and LINUX (just take a guess...). Also, I was thinking of converting the assembly to C so it will run on different hardware (just imagine Descent on an Alpha :), so you might want to #ifdef ASM or something like that.


01/28/98 01:41 - Heiko Herrmann / Kevin Bentley - Porting vs. speed

Heiko Herrmann wrote:
To those of you, who want to make the code portable... Well, I have a request to you! Make the portable C code compatible to the original ASM code. So that when you compile it for PC that the optimized and faster ASM routines can still be used!! Best is using compiler variables (like "#IFDEF PC")... That way we let the code as fast as it is, but also have the opportunity to port it to whatever system you want...

Kevin Bentley wrote:
I have to agree completely with Heiko. Converting to any non Intel assembler will lost the advantages of the original assembly anyway, so it makes sense to just write portable C code. This should be done by people who know assembly, and who know what C code looks like when it gets assembled. If this is done, it will perform pretty close to the asm code. So, if we have to change it, change it to C, not another ASM.


01/28/98 22:21 - David Holland - Patch for cfile\cfile.c

The following patch makes cfile.c compile in unix, and it shouldn't break the dos build either (your dos compilers understand forward slashes, try it!)

Index: cfile/cfile.c
RCS file: /home/cellar/dholland/games/descent/cvsrepo/descent/cfile/cfile.c,v
retrieving revision
diff -u -r1.1.1.1 cfile.c
--- cfile.c    1998/01/26 10:27:28
+++ cfile.c    1998/01/29 03:15:40
@@ -112,12 +112,9 @@
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
-#include <conio.h>
-#include <dos.h>
#include <fcntl.h>
-#include <io.h>
-#include <sys\types.h>
-#include <sys\stat.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <errno.h>
#include <string.h>


01/29/98 15:25 - dph man - dpmi.c nearly working in DJGPP

Hi there...
Ok, I've got nearly everything in bios/dpmi.c working in DJGPP (very DJGPP specific). Almost every function was rewritten so rather than reusingg int386x(0x31,...) to call dpmi functions, using the __dpmi_... functions built in. This makes the source a lot more intelligible. (Not to mention int386x calls a real mode interrupt not a protected mode interrupt under DJGPP - breaking these interrupts as they are all DPMI calls.)

The things that I haven't been able to fix are:
1) In dpmi_init, can anyone tell me what the functions extern void cdecl _GETDS(); and extern void cdecl cstart_(); do?
Anyone tell me what _chain_intr is? I think I can guess some of these, but I want to be sure. I've just commented them out for now.

2) The function int dpmi_set_pm_handler(unsigned intnum, void far * isr ) sets a protected mode interrupt handler using a dpmi function. Only problem is with the second parameter (void far * isr). DJGPP doesn't support a "far *". Presumably this is simply a pointer containing a selector and an offset. There's a nearly equivalent structure __dpmi_paddr defined in <dpmi.h>, but changing the parameter to this will require a change in anything which calls it. So do I change it?


01/29/98 19:11 - dph man - DOS specific stuff

David Holland wrote:
> I have the following suggestions for reorganization of directories:
> 1. move iff\* into 2d\. There's only the one source file in iff, and
> conceptually it belongs with pcx.c, which is in 2d\ already.
> 2. merge fix\*, vecmat\*, and div\*, and call the directory and
> library "math".
> 3. move main\editor\ to just editor\.
> 4. make a ports\ directory, with ports\dos, ports\win32, and
> ports\unix subdirectories. Move OS-specific stuff here (eg, DPMI
> stuff, DOS vs. Unix directory searching, etc.) as we find it.
> After a bit of hacking this should get all the assembly into either
> the renderer (3d\ and texmap\), the math library (math\), or
> DOS-specific stuff.

DOS specific stuff is probably only really in bios\. And trust me, most of the stuff in there is extremely DOS specific...


02/02/98 00:20 - Kevin Bentley - FRAMETIME tip

In (game.c) game_draw_hud_stuff(), remove the #ifdefs around:

if (framerate_on)

Also, remove the #ifdefs from around the actual show_framerate() function.

Then, add a cheat code called "frametime" that turns on framerate_on and thus the fps display.

It's interesting to see what kind of framerates you get with D1!

P.S. I have been working with the watcom version, mostly just getting deeper into the code. So far, I have a version with a variable packet rate, ping support, fps display, and a few other minor changes. If I can get HMI to respond to the last couple of emails I sent them, I will be able to release a version with sound.

Also, I did a bit of checking, and it appears that the GNU/DJGPP port isn't going to retain much compatability with a win32 version (at least not using MSVC, which I plan to do). So, I am working on a separate branch porting the Watcom code to win32, using MASM 6.11 and MSVC 5.0. Mostly, I only have to change a bunch of pragmas, change the way inline asm is done, and then implement directdraw and direct sound, and winsock IPX. If anyone has MSVC 5.0 and wants to help me port to it, let me know.


02/02/98 02:53 - Kevin Bentley - "ping" tip

This one is the code I added to allow user pings, like in D2 (ping:user). Here are the two functions I modified from multi.c:

multi_do_message(char *buf)
char *colon;
int pingtime; //Ping time in ms

int loc = 3;
int loc = 2;

if (((colon = strrchr(buf+loc, ':')) == NULL) || (colon-(buf+loc) < 1)) //|| (colon-(buf+loc) > CALLSIGN_LEN))
  digi_play_sample(SOUND_HUD_MESSAGE, F1_0);
  HUD_init_message("%s %s '%s'", Players[buf[1]].callsign, TXT_SAYS,buf+loc);
  if ( (!strnicmp(Players[Player_num].callsign, buf+loc, colon-(buf+loc)))

     || ((Game_mode & GM_TEAM) && ( (get_team(Player_num) == atoi(buf+loc)-1)
     || !strnicmp(Netgame.team_name[get_team(Player_num)], buf+loc,colon-(buf+loc)))) )
   digi_play_sample(SOUND_HUD_MESSAGE, F1_0);
   HUD_init_message("%s %s '%s'", Players[buf[1]].callsign, TXT_TELLS_YOU, (colon+1));
    if(!strnicmp("ping", buf+loc,4))
     //Ping message, respond!
     Network_message_reciever = buf[1];  // Send to the player who pinged you..
    if(!strnicmp("pong", buf+loc,4))
     //Pong message, print the results!
     pingtime = clock()-atoi((colon+1));
     HUD_init_message("%s %s %ums","Ping response from ",Players[buf[1]].callsign,pingtime);

void multi_send_message_end()
int iPlayerLoop;

  //Send only to the recepient in the message..
    //send only to the specified user.
    Network_message_reciever = iPlayerLoop;
    HUD_init_message("Pinging %s...",Players[iPlayerLoop].callsign);
    multi_message_index = 0;
    multi_sending_message = 0;
  //Bad username
  HUD_init_message("PING: %s doesn't exist!",Network_message+5);
  multi_message_index = 0;
  multi_sending_message = 0;
Network_message_reciever = 100;
HUD_init_message("%s '%s'", TXT_SENDING, Network_message);

multi_message_index = 0;
multi_sending_message = 0;


02/02/98 15:40 - David Gentry - Notes from source

Function prefixes

VR_ Video RAM related functions (also used in VRAM flags)
gr_ Graphics related functions (most in 2d directory)


Variable/Define prefixes

CT_ control type (defines)
MT_ movement type (defines)
AS_ animation states (defines)
SM_ screenmodes (defines) width/height/colordepth


Global Variables

grs_curcanv global canvas on which to draw
grs_curscreen global screen struct that hold grs_canvas
Controls holds info in pitch, heading, and banking time as well as info on vertical, sideways, and forward thrust times, state and count on rearview, automap, primary, secondary and bomb dropping
ConsoleObject object that is the player
GameTime time in the game (sum of FrameTime)
FrameTime time in seconds since last frame
Highest_segment_index highest index in Segments (blocks/cubes)
Awareness_events array of structs holding info segment number, position, and event type
Robot_info big list of robot types with internal info on sounds, weapons,which explosion, id number, gun points/models, mass, drag, strength, etc.
VR_offscreen_buffer offscreen data buffer


Code flow


  • calls InitArgs,
  • calls load_text (loads text messages),
  • calls check_id_checksum_and_date,
  • calls FindArgs (for help),
  • calls init_graphics (does nothing in mac source),
  • calls ReadConfigFile,
  • calls timer_init, timer_set_rate, joy_timer_set_rate, key_init, mouse_init,
  • calls digi_init (sound system)
  • calls ipx_init (if network)
  • sets up VR tracking variables if VR unit used
  • sets graphics mode (gr_set_mode), inits fonts, loads and plays title song, display title screen
  • calls g3_init (to initialize 3d system)
  • calls texmerge_init (sets up texture caching system)
  • calls init_game
  • calls RegisterPlayer (gets player name)
  • calls build_mission_list (and load mission 0 in the process)
  • if in menu mode, call create_new_mine, then call SetPlayerFromCurseg
  • if in game mode, call keyboard_update, then call game()
  • on return from game(), call WriteConfigFile and shut down


  • calls functions to init: hostages, ai system, special effects, objects, the gauge canvas, exploding walls


  • sets screen mode for the game (set_screen_mode)
  • calls init_cockpit, and init_gauges
  • sets the camera to be the player view (Viewer=ConsoleObject)
  • calls fly_init for ConsoleObject
  • calls fix_object_segs, and game_flush_inputs
  • goes into a while(1) loop
  • this while loop does a keyboard-update and then calls GameLoop with Render and Input turned on
  • when returning from GameLoop and jumping out of while loop, call digi_stop_all
  • shuts down network game (if in progress)
  • fades out


  • calls following functions: update_player_stats, do_cloak_stuff, do_invulnerability_stuff, remove_obsolete_stuck_objects,
  • calls init_cockpit
  • calls game_render_frame
  • calls calc_frame_time
  • calls ReadControls
  • updates GameTime counter by FrameTime (calculated in calc_frame_time)
  • calls digi_sync_sounds
  • calls do_exploding_wall_frame, do_special_effects, wall_frame_process, triggers_frame_process
  • calls object_move_all, powerup_grab_cheat_all
  • calls fuelcen_update_all, do_ai_frame_all
  • take care of weapons handling, damage handling, sounds, power updating, collisions,
  • if just appearing, call create_player_appearance_effect


  • calls game_render_frame_mono if not using VR device


  • does some canvas stuff
  • calls render_frame with an eye_offset of 0


  • calls g3_start_frame
  • does some vector math
  • calls g3_set_view_matrix
  • calls render_mine
  • calls g3_end_frame


  • computes aspect ratios for the canvas
  • calls init_free_points, init_interface_vars_to_assembler (for tmap interface)


  • calls render_start_frame
  • calls build_segment_list
  • calls build_object_list
  • calls set_dynamic_light
  • loops through the number of segments(most likely, just visible segments)
  • calls render_segment, with clipping


Functions of note

game calls GameLoop, called after mode selected, sets up things
GameLoop main loop in the game, takes flags for rendering and reading controls.
game_render_frame does homing sound, calls appropriate rendering module based on whether 3d glasses used or not.
init_cockpit draws view of cockpit based on front, rear or fullscreen.
calc_frame_time does the timing control, also account for turbo mode
dead_player_frame pull back camera and show ship exploding
ReadControls take care of cheats, calls control_read_all to get input, process keystrokes, do debugging of control reading and processing
control_read_all reads from joystick, mouse, keyboard, etc and puts into a control_info structure called Controls
digi_sync_sound calls digi_get_sound_loc to do panning stuff, calls digi_start_sound_object to playback, determines if a sound if finished, stops sound, changes volume, etc
do_special_effects changing textures, etc
wall_frame_process doors opening/closing/waiting
triggers_frame_process decrement time on all triggers active
object_move_all free up object slots with function call, get rid of 'dead' objects, take care of autoleveling flag, iterate throught object list, moving one at a time with call to object_move_one
object_move_one update player fuel if in fuel center, calls controls processing function depending on control type (CT_*), takes care of movement (based on MT_NONE, _PHYSICS, or _SPINNING), checks to see if any triggers set when moving from one segment to another
do_physics_sim vector motion, object collision, etc
spin_object matrix rotation
powerup_grab_cheat_all pick up powerups when certain distance away
find_connect_side find side index of connected segment
fuelcen_update_all replenish fuel supply
do_ai_frame_all calls set_player_awareness_all...and nothing else
set_player_awareness_all calls process_awareness_events, updates the player_awareness_type and _time if necessary
process_awareness_events calls pae_aux for all Segments (Highest_segment_index)
apply_damage_to_player flash, decrease shields (if not invulnerable), set 'dead' flag if needed
bump_one_object collision, do phys_apply_force
phys_apply_force changes velocity and direction if movement of the object is MT_PHYSICS
create_player_appearance_effect flash in a player (whether externally in multiplayer, or internally)
game_init_render_buffers setup canvases to draw to


Misc Notes

  • A grs_screen has a grs_canvas which has a grs_bitmap.
  • A grs_canvas also has a grs_font.
  • The entry point of the program is in INFERNO.C
  • Important directories are: 2d, 3d, bios, cfile, fix, iff, mem, misc, texmap, vecmat, main


02/07/98 12:58 - Arne de Bruijn - My DJGPP port: now with net+faster

I got the IPX network support working in my DJGPP port of Descent 1. Futher I replaced the C texturemapper with the original asm one, and replaced the gr_linear_movsd with memcpy, resulting in a nice speed boost (15-50 fps on level 1-2, on a P166+). Also I fixed the joystick problem, so that should work now too, but I can't test it since I don't have one :-(.

If you are interested, you can get this version here (to build you need DJGPP V2, GNUMake, TASM, plus the OBJ2BFD from below):

sign_download.gif (151 bytes) Download D1DJ_002 build (1288 kB)

sign_download.gif (151 bytes) Download OBJ2BFD V0.1a (103 kB)

BTW has anybody tried the debugging keys (compile without NDEBUG, RELEASE, remove #if 0 in game.c line 3711 and #endif in 3904, DEL+<key>)? I especially liked switching to a robot view (DEL+`) and then let the robot follow you as a cameraman :-)


Garry Knudson's reply:

I was able to compile this... neat. I had to fix some makefiles: changed the include directory from  ../includes to ../lib. (in 3d,fix and vecmat) Also, had to add -I../lib to the CCFLAGS for def.mak.

I was able to use the joystick in the game... I needed to have the -joypolled parameter in the commandline for it to be used though.(it would let me setup... but wasn't used without the switch). The joystick that I am using is the wingman extreme, I normally require the -joypolled for it to work right. Also, I needed to setup the configuration for keys/joystick each time I started. Last, hitting the key to see the level map dropped me out of the program (no error msg).... something else to look into.

I am using TASM 4.0 to compile with.


Newer versions:

sign_download.gif (151 bytes) Download D1DJ_003 build (1415 kB) / Update from 002 (124 kB)

sign_download.gif (151 bytes) Download D1DJ_004 build (1422 kB) / Update from 003 (15 kB)

D1DJ_005 build available some lines below.


02/08/98 06:56 - dph man - DJGPP/NASM port of timer.asm

Attached is the NASM port of timer.asm to go with the DJGPP port of descent. This is the only required asm file in the game. You can run it with only this one if you empty all the joystick functions in joyc.c (ifdef the contents out, and make the functions which return return 0), remove the joy.asm from the bios/makefile, remove soscodec.asm from main/makefile, and edit the texmap/makefile to use the C texture mappers (uncomment the two lines). You may also have to comment out some other asm files, but they are not needed at all, so just comment out the reference in the makefile.

Ok, now we have a working port of descent to entirely free compilers/assemblers (if we forget the linux version for a sec).

sign_download.gif (151 bytes) Download TIMER.ASM (14 kB)


02/09/98 19:30 - Carl B. Constantine - DJGPP/NASM port of timer.asm

Jonathan Perret wrote:
>Hmm... I know of no C compiler that allows declaring variables in
>the middle of a compound-statement (between braces). Are the files
>you are trying to compile supposed to be C++, or C ?
>Could you give a specific example ?

C++ does allow you to do this, but these are C files and many compilers do not.

Here's an example from Collide.c:

int check_effect_blowup(segment *seg,int side,vms_vector *pnt)
int tm,ec,db;

if ((tm=seg->sides[side].tmap_num2) != 0)
if ((ec=TmapInfo[tm&0x3fff].eclip_num)!=-1)
   if ((db=Effects[ec].dest_bm_num)!=-1 &&
!(Effects[ec].flags&EF_ONE_SHOT)) {
fix u,v;
grs_bitmap *bm = &GameBitmaps[Textures[tm&0x3fff].index];
int x,y,t;


//this can be blown up...did we hit it?

find_hitpoint_uv(&u,&v,pnt,seg,side,0); //evil: always say face zero

x = ((unsigned) f2i(u*bm->bm_w)) % bm->bm_w;
y = ((unsigned) f2i(v*bm->bm_h)) % bm->bm_h;

Notice that the variables u,v, x, y, t, and bm are all declared midstream. Some of these need to be fixed for the source to compile correctly with some compilers.

Another popular construct I've seen (though not necessarily in the D1 source) is this:

for (int i=1; i++; i<= 10) ...

The variable i is being declared right in the for statement.

NOTE: some C compilers will indeed allow this as an "extra" or "extension" but it depends on how strict the compiler is.

>I'm interested; I'll be porting over to BeOS, so the more platforms
>are available, the easier it will be. (starting work soon ! :)

Great. I'll keep the list posted.

Here's an update:

There are two "Effects.h" files. One in the 2D folder and one in the MAIN folder. The one in the 2D folder is taking precience at compile time. it may be safely removed. This will eliminate a an ton of "undefined identifyer" error messages if you use CodeWarrior for BeOS (I use it on Windows NT and Mac OS). I'm getting closer :-)


02/10/98 10:04 - Carl B. Constantine - Some things I found out plus some questions (Mac code)...

For those playing with the mac source code, quad.c doesn't seem to be required. it's a quadradic equation calculation that is duplicated (though refined) in NTMAP.c instead. Just FYI.

I'm almost there. there are a bunch of errors I have yet to figure out. I also have to update a bunch of MAC OS System headers as they've changed a lot since D1 was written.

Getting there, slowly but surely :-)

Again in the Mac source:

In EFFECTS.C (in the 2D folder) there is an error to the effect: "not a struct/class/union member" for a field named 'pal' of the variable: grd_curscreen in the routine gr_grey_canvas().

grd_curscreen is defined as:
extern grs_screen *grd_curscreen;  //active screen

Checking the grs_screen struct, I do not see a 'pal' field or anything that would resemble it.

here's the grs_screen struct:

typedef struct _grs_screen {     // This is a video screen
grs_canvas  sc_canvas;          // Represents the entire screen
short       sc_mode;             // Video mode number
short       sc_w, sc_h;          // Actual Width and Height
fix         sc_aspect;           // aspect ratio (w/h) for this screen
} grs_screen;

here's the code where the errors occur:

r = grd_curscreen->pal[pixel*3+0];
g = grd_curscreen->pal[pixel*3+1];
b = grd_curscreen->pal[pixel*3+2];

r,g,b are ints.

Ideas anyone?


In the Mac source, there seems to be some descrepencies that maybe someone can help me with.

First, IPX.h doesn't exist. There is a NetIPX.h and NETIPX.C, but these files do not seem to contain the same routines as the counterparts on the PC. Are they indeed supposed to be the same?

I see an #include "ipx.h" in 3 files (network.c, macnet.c, and inferno.c) but netipx.h is only included in netipx.c. File missing, or should all occurances be netipx.h?

The second discrepency is there is a variable or routine that is only referenced once, but I can't find the definition for it anywhere. Here's the snippet from effects.c in the 2D folder:

void gr_fade_canvas(int fade)
   int height, width;
   int x, y, pixel;

   height = grd_curcanv->cv_bitmap.bm_h;
   width = grd_curcanv->cv_bitmap.bm_w;

   fade = (15-fade)*256;

   for (y=0; y<height; y++ )
     for (x=0; x<width; x++ )
        pixel = gr_ugpixel( &grd_curcanv->cv_bitmap, x, y );
        gr_setcolor(bmd_fade_table[ pixel + fade ] );
        gr_upixel( x, y );

I can't find the definition or routine for bmd_fade_table. These seem to be graphic related and not sound related.

Ideas anyone? Similar problems exist for bmd_inverse_table later in the same source file.


02/15/98 18:48 - Kevin Bentley - HMI sound system and new build coming up

I now have permission from HMI to release the .h and .lib files for sound in D1. I doubt they will work with DJGPP though. So, if anyone wants to make a D1 executable for DOS with some changes using Watcom/MASM, let me know.

As far as easy to make changes, here is what I have so far:

  • Fully running D1, with the exception of Serial support.
  • Frametime cheat to display FPS, works in multi-mode.
  • ping:username message to display the ping of other players (they need the new version also).
  • "descentr -pps x" Sets the default send packet per second rate for IPX games. This will work with the existing descent, all it does is change the packet rate that you send.

I am trying to figure out how to bind DOS4GW to the exe, when I figure that out, or tonight at the latest, I will put up my executable, as well as an updated editor build, with a few fixed bugs. If anyone has any other fairly simple changes, email me and I will add them to this build.


02/15/98 22:55 - Timothy S. Singer - NASM port

I've got a NASM port of TMAP_PER.ASM and its include file, TMAP_INC.ASM.

Instructions for integrating these files into the D1 source:

  • Adjust the object file list in TEXMAP/MAKEFILE to include TMAP_PER.O
  • I keep on getting a "missing separator" error with GNU make, so I fixed it by commenting out the rule to build TMAP_PER.O.
  • In the main MAKEFILE (in the root directory of all these source files), define USE_NASM=1 and dos=1, and export both.
  • Now you need to assemble TMAP_PER.O by hand.  Use "nasmw -f coff -dDJGPP tmap_per.nas" (nasmw, which comes with NASM, is faster and can use more memory than nasm.)
  • Change SCANLINE.C, QUAD.C, and NTMAP.C so that all occurrances of "Transparency_on" are completely lowercase. Otherwise you get an "Undefined Reference" error.
  • Change NTMAP.C to use asm_tmap_scanline_per instead of c_tmap... wherever necessary.

Please e-mail me at (I'm not subscribed to descent-source) with your comments. Thanks!

sign_download.gif (151 bytes) Download Timothy's NASM port (12 kB) - 02/17/98 (already updated to the newest release)


02/17/98 00:41 - Kevin Bentley - New build

This is a specially modified version of Descent I.

It is based on version 1.5, and is fully functional, with the exception of Serial port support. This means that modem games won't work, and neither will Null-modem games, or any VR goggles/shutters.

Enjoy - Kevin Bentley (

Special Thanks to HMI for allowing me to use the sound code! If you are interested in Game programming, Check them out at

The following options have been added to this executable:

  • Variable packet rate
    Use the -PPS x command line parameter to set the packet per second rate that you send for IPX games. This is compatible with the original descent executable, as it only changes the rate that you send. For best results, most the players in your game should have this patch and select the same rate. A reccomended PPS rate for a 4 player 28.8 modem game would be 6 or 7.
  • Alternate mission directory
    Use the -missiondir xxx parameter to specify an alternate location for Descent to get the levels from. This is usefull to get around the 100 add on level maximum in Descent I. (xxx is the path to look in.)
  • Frame Rate display
    New cheat code added: FRAMETIME. This cheat code works in multiplayer games, and doesn't require cheats to be enabled. It turns on a framerate display on the screen.
  • Ping Users command
    In an IPX game, hit F8, and type ping:user, where 'user' is the nickname of the person you want to ping. They need to be running this patch also.
  • Dynamic Sockets is now enabled by default
  • New command line option "-modified".
    I don't want people running this executable without realizing that it isn't the original. Therefore, I added a message on startup that requires people to hit a key after reading a little notice on startup.
    To suppress the message, just use the -modified parameter.

sign_download.gif (151 bytes) Download Kevin's DDR_D1 release (536 kB) - 02/16/98

Also now available: New MINER release! Download (746 kB)


02/17/98 15:31 - Timothy S. Singer - Gravity

I finished the rest of the asm texture-mapping functions.

sign_download.gif (151 bytes) Download Timothy's NASM port (12 kB) - 02/17/98


02/17/98 19:57 - Bryan Aamot - Gravity

My vote would be to have an option which levels the ship along the Y axis. About 95% of all levels use Y as down already. DMB2, Devil, and Miner all start out the level this way.  The code to implement this is simple:

In Physics.c - do_physics_align_object(), just add the following lines of code just before the if (labs(vm_vec_dot(&desired_upvec,&obj->orient.fvec)) < f1_0/2) statement:

desired_upvec.x = 0;
desired_upvec.y = f1_0;
desired_upvec.z = 0;

I've tested this and it works great (IMHO).


02/18/98 06:59 - Kevin Bentley - Win32 port: what in general is needed?

>Hi, can someone more knowledgeable go over just what will need to be done to
>the code to port it to compile and run under MSVC++.  I realize memory
>pointers will need altering, but more detail would be appreciated; such as
>simple examples, where are most of these pointers in the code, and how much
>of dos extender terminology will I need to know, like that.
>Also, how much beyond memory management will need to be changed for an
>initial port: can the present sound code and libraries be used, and will
>input device & vga driver code be useable?  Thanks very much for any more
>elucidation or url pointers.

As this is the project that is sucking away most of the time from my life, let me explain....

First of all, mostly stripping a lot of the DPMI code out is needed. Actually, the Win32 code is much more simple than the Watcom code, because windows smoothly handles a lot of the details. So the extender stuff shouldn't be a problem. As far as sound and video, they need to be written new to support DirectX.

Here are the main areas of effort that I have been working on:

  • Making the code compile under MSVC: The biggest challenge here is that Watcom uses a very nice but unprofitable inline assemble pragma that allows parameters to be passed directly into a register, which makes the assembly code run very fast. MSVC doesn't have this feature, so there are two ways of going about it. 1) at the top of each function copy the parameters into the registers (i.e.. mov eax,parm1). 2) For functions with 2 or less parameters, you can use the MSVC __fastcall directive, which will put the first 2 parameters into registers for you. Next, is cleaning up issues like replacing calls to _dos_findfirst with _findfirst, etc. Then there is the matter of removing all inp, outp and int386x calls. These calls are pretty much in the video and keyboard handlers, etc. so you have to do that anyway.

  • Replacing the keyboard handler: You now need to watch for WM_KEYDOWN and WM_KEYUP, which means you need to have a message loop, and all the other Win32 goodies to replace the old interrupt driven keyboard handler. (Reply by Despot: Why not using DirectInput instead?)

  • DirectDraw: All the direct screen writes need to be converted into DirectDraw code. This part isn't as tough as it sounds, but requires the code to be otherwise mostly working.

  • Sound: Putting in the windows code for digital sounds, midi, etc.

  • Input devices: This isn't too tough either, you need to interface with windows mouse and joystick functionality. (Reply by Despot: DirectInput... DirectInput... ;-) )

So far, I have to code compiling with a message loop, and am trying to get all the keyboard stuff working correctly. I have done some background work on DirectX, but I haven't got that far yet....

If anyone wants to join my efforts, let me know what you would like to do, I would love some help! Once I have a semi working copy, I will start posting the source on the web page.


02/19/98 21:09 - Simon Fenney - Win32 port: what in general is needed? REPLY

I was thinking some more on this. Descent certainly has some good texture mapping code, but if we were to just use the Direct3D functions, we'd "automatically" be able to use features such as MMX and hardware accelerators. I was originally looking at doing a port just to the PowerVR graphics library (SGL) but one of the other software engineers here assures me that using TLVertices in DX5 would be reasonably straightforward.

I've grabbed some of his sample code that handles setup of Rendering System (i.e. MMX, Ramp Model, Hardware (HAL)) and it 'seems' relatively straight forward. If we can map all the Descent Drawing functions into the DX equivalentswe can have a simple front end to choose rendering system. It would probably be easier than trying to convert tmap_per.asm to use the DirectDraw format!!

One concern I did have is that the projected vertices structure might have to change as it doesn't store the perspective depth. If you want to use the hardware's Z buffer, you need to keep this information.

>So far, I have to code compiling with a message loop, and am trying to get all
>the keyboard stuff working correctly. I have done some background work on
>DirectX, but I haven't got that far yet....

I'm just studying DirectX myself. Hopefully I should also be able to pick the brains of the direct-X-perts here at work if I run into difficulties.

>If anyone wants to join my efforts, let me know what you would like to do, I
>would love some help! Once I have a semi working copy, I will start posting the
>source on the web page.

I can probably put in one or two nights a week [and lunch hours if I can stop myself from blasting my colleagues].


02/20/98 18:22 - Arne de Bruijn - DJGPP port version 5

I've released a new version of my DJGPP port. Changes since v0.04:

  • mouse now works
  • editor now works
  • fixed plr files not saved if callsign < 8 chars
  • assembler texmap now also used with NASM (with thanks to Timothy S. Singer for providing the .NAS files)
  • made NASM the default assembler
  • added missiondir parameter, and defaults to missions/ for add-on missions (with thanks to Matt Mueller).
  • Still missing com support...

    This might be the last version, I'm planning to merge it with the linux port.


    sign_download.gif (151 bytes) Download D1DJ_005 build (1432 kB) / Update from 004 (342 kB)

    In case you didn't already download it:


    02/21/98 05:10 - Kevin Bentley - D1 V1.7 plans

    As of late last night, I have what I think is an uncrashable version of Miner (Thats what I am going to keep calling the editor anyway). I found a few problems in dumpmine.c, object.c, and eobject.c that were causing problems in Loading/saving levels as well as switching from editor to game mode and vice versa, as well as fixed some of the monochrome monitor support (which made my life much easier when I was debugging). I will post information detailing the fixes tonight too. I am fixing the bug in the ping: command in 1.6, then I plan to re-release an editor tonight. What I would like is for anyone who has found new bugs, or bugs other than crahing when loading/saving levels to email me ASAP. This way I can get as many problems fixed as possible.

    My plans for Descent 1.7 are as follows:

    • Add a menu option in the game to switch between mission directories
    • Add a key mapping for scrolling between primary and secondary weapons (joystick support also)
    • Add auto weapon select, to work like it does in D2.

    Future plans:

    • Restricted net player games (only will work if the game master is running the new software).
    • Disallow items in net games (not sure if I can implement this without breaking the old versions, but I think I can).
    • ??? You tell me....


    02/21/98 15:31 - Timothy S. Singer - D1X extensions for briefings/endings

    I've got a modified version of main\titles.c!

    I've added the following functionality:

    • More briefing colors (if the PCX's palette supports them):
      $C0 = who knows
      $C1 = green
      $C2 = white
      $C3 = red
      $C4 = blue
      $C5 = dark gray
      $C6 = yellow
      $C7 = purple

    • Made $$ and $; display '$' and ';', respectively.  With D1v1.5 you can't
      use the dollar sign at all in briefings/endings, and you can only use the
      semicolon if it's not at the beginning of the line.  A semicolon at the
      beginning of the line comments out the whole line, but now a
      dollarsign-semicolon at the beginning of the line just prints a semicolon.
      This means you can have winking happyfaces! ;-)

    In the future, I'll add support for:

    • A $Z tag that loads a new PCX into the current section
    • A $W tag that changes the text window position/size
    • $X and $Y tags that change the display position of bbm's/textures/robots
    • Maybe support for ship/weapon/exit polymodels
    • Any (reasonable) thing else you can think of - but no custom bots,animations,etc.

    sign_download.gif (151 bytes) Download TITLES.C (35 kB)


    02/24/98 00:43 - Kevin Bentley - High framerate/Homing problem

    Well, here is the problem. Each time the frame is drawn, the homers need to be able to seek their target. This is done by calculating how much they can react. If the frame rate was 100 and they reacted the same way as they did if the framerate was 10, it would be easy to dodge them on a slow machine, but impossible on the faster machine because on the faster machine, the missiles would get to react 10 times more quickly. If you set the frametime to 6 second, the homers would never work. If you set it higher than the actual frametime, it wouldn't work either, because it wouldn't actually be able to react that often, so they would lose their target. The idea is to adjust their reaction to fit the framerate. That's what I am trying to accomplish.


    02/24/98 23:03 - Hrvoje Velic - Getting D1Source to run with Watcom V11.0

    1. I added 'void' in front of a number of functions, otherwise Watcom reported errors (BTW I don't see how this compiled on 10.6 \:I).

    2. I placed /* */ comments around all areas in code where Watcom issued warnings about '// comment continuing to the next line' -> i.e. the commented lines ending with a '\'.

    3. I added '/bt=DOS4G /zp=1' to CCFLAGS macro in makefiles in the following directories: 2d, 3d, bios, cfile, div, fix, iff, includes, lib, main, main\editor, mem, misc, texmap, ui, vecmat. BTW, only these directories are used to create the .exe.

    4. I added the following line to D1VARS.BAT: set WCC386=-5r -zq

    5. corrected matrix_scale into Matrix_scale in an .asm file (rod.asm in directory 3d\ in lines 315, 318, 345, 348)


    03/10/98 22:09 - Victor Olvera - File descriptions

    Here is some more quick reference for ya. Here is a list of all of the descriptions of the code files aka .C files:



    03/11/98 22:09 - dph man - Win32 Build 03

    Here is the first Win32 build.


    If you have new knowledge or want to reply to something above, post it to the mailing list.


    All pages (C) 1996-2000 Descent Network Team
    Everything taken from the Descent, FreeSpace, Red Faction and Summoner series games are
    Copyright Interplay Productions , THQ Inc. , Parallax Software , Volition Inc. and/or Outrage Entertainment