shithub: choc

Download patch

ref: 66a2cc66d7504c9b64e1c461e62ad2a9d964fa95
author: Simon Howard <fraggle@gmail.com>
date: Sat Jul 23 12:19:41 EDT 2005

Initial revision

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 4

--- /dev/null
+++ b/.gitignore
@@ -1,0 +1,17 @@
+
+# These are the default patterns globally ignored by Subversion:
+*.o
+*.lo
+*.la
+*.al
+.libs
+*.so
+*.so.[0-9]*
+*.a
+*.pyc
+*.pyo
+*.rej
+*~
+.#*
+.*.swp
+.DS_store
--- /dev/null
+++ b/src/am_map.c
@@ -1,0 +1,1352 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: am_map.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:44  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:  the automap code
+//
+//-----------------------------------------------------------------------------
+
+static const char rcsid[] = "$Id: am_map.c 4 2005-07-23 16:19:41Z fraggle $";
+
+#include <stdio.h>
+
+
+#include "z_zone.h"
+#include "doomdef.h"
+#include "st_stuff.h"
+#include "p_local.h"
+#include "w_wad.h"
+
+#include "m_cheat.h"
+#include "i_system.h"
+
+// Needs access to LFB.
+#include "v_video.h"
+
+// State.
+#include "doomstat.h"
+#include "r_state.h"
+
+// Data.
+#include "dstrings.h"
+
+#include "am_map.h"
+
+
+// For use if I do walls with outsides/insides
+#define REDS		(256-5*16)
+#define REDRANGE	16
+#define BLUES		(256-4*16+8)
+#define BLUERANGE	8
+#define GREENS		(7*16)
+#define GREENRANGE	16
+#define GRAYS		(6*16)
+#define GRAYSRANGE	16
+#define BROWNS		(4*16)
+#define BROWNRANGE	16
+#define YELLOWS		(256-32+7)
+#define YELLOWRANGE	1
+#define BLACK		0
+#define WHITE		(256-47)
+
+// Automap colors
+#define BACKGROUND	BLACK
+#define YOURCOLORS	WHITE
+#define YOURRANGE	0
+#define WALLCOLORS	REDS
+#define WALLRANGE	REDRANGE
+#define TSWALLCOLORS	GRAYS
+#define TSWALLRANGE	GRAYSRANGE
+#define FDWALLCOLORS	BROWNS
+#define FDWALLRANGE	BROWNRANGE
+#define CDWALLCOLORS	YELLOWS
+#define CDWALLRANGE	YELLOWRANGE
+#define THINGCOLORS	GREENS
+#define THINGRANGE	GREENRANGE
+#define SECRETWALLCOLORS WALLCOLORS
+#define SECRETWALLRANGE WALLRANGE
+#define GRIDCOLORS	(GRAYS + GRAYSRANGE/2)
+#define GRIDRANGE	0
+#define XHAIRCOLORS	GRAYS
+
+// drawing stuff
+#define	FB		0
+
+#define AM_PANDOWNKEY	KEY_DOWNARROW
+#define AM_PANUPKEY	KEY_UPARROW
+#define AM_PANRIGHTKEY	KEY_RIGHTARROW
+#define AM_PANLEFTKEY	KEY_LEFTARROW
+#define AM_ZOOMINKEY	'='
+#define AM_ZOOMOUTKEY	'-'
+#define AM_STARTKEY	KEY_TAB
+#define AM_ENDKEY	KEY_TAB
+#define AM_GOBIGKEY	'0'
+#define AM_FOLLOWKEY	'f'
+#define AM_GRIDKEY	'g'
+#define AM_MARKKEY	'm'
+#define AM_CLEARMARKKEY	'c'
+
+#define AM_NUMMARKPOINTS 10
+
+// scale on entry
+#define INITSCALEMTOF (.2*FRACUNIT)
+// how much the automap moves window per tic in frame-buffer coordinates
+// moves 140 pixels in 1 second
+#define F_PANINC	4
+// how much zoom-in per tic
+// goes to 2x in 1 second
+#define M_ZOOMIN        ((int) (1.02*FRACUNIT))
+// how much zoom-out per tic
+// pulls out to 0.5x in 1 second
+#define M_ZOOMOUT       ((int) (FRACUNIT/1.02))
+
+// translates between frame-buffer and map distances
+#define FTOM(x) FixedMul(((x)<<16),scale_ftom)
+#define MTOF(x) (FixedMul((x),scale_mtof)>>16)
+// translates between frame-buffer and map coordinates
+#define CXMTOF(x)  (f_x + MTOF((x)-m_x))
+#define CYMTOF(y)  (f_y + (f_h - MTOF((y)-m_y)))
+
+// the following is crap
+#define LINE_NEVERSEE ML_DONTDRAW
+
+typedef struct
+{
+    int x, y;
+} fpoint_t;
+
+typedef struct
+{
+    fpoint_t a, b;
+} fline_t;
+
+typedef struct
+{
+    fixed_t		x,y;
+} mpoint_t;
+
+typedef struct
+{
+    mpoint_t a, b;
+} mline_t;
+
+typedef struct
+{
+    fixed_t slp, islp;
+} islope_t;
+
+
+
+//
+// The vector graphics for the automap.
+//  A line drawing of the player pointing right,
+//   starting from the middle.
+//
+#define R ((8*PLAYERRADIUS)/7)
+mline_t player_arrow[] = {
+    { { -R+R/8, 0 }, { R, 0 } }, // -----
+    { { R, 0 }, { R-R/2, R/4 } },  // ----->
+    { { R, 0 }, { R-R/2, -R/4 } },
+    { { -R+R/8, 0 }, { -R-R/8, R/4 } }, // >---->
+    { { -R+R/8, 0 }, { -R-R/8, -R/4 } },
+    { { -R+3*R/8, 0 }, { -R+R/8, R/4 } }, // >>--->
+    { { -R+3*R/8, 0 }, { -R+R/8, -R/4 } }
+};
+#undef R
+#define NUMPLYRLINES (sizeof(player_arrow)/sizeof(mline_t))
+
+#define R ((8*PLAYERRADIUS)/7)
+mline_t cheat_player_arrow[] = {
+    { { -R+R/8, 0 }, { R, 0 } }, // -----
+    { { R, 0 }, { R-R/2, R/6 } },  // ----->
+    { { R, 0 }, { R-R/2, -R/6 } },
+    { { -R+R/8, 0 }, { -R-R/8, R/6 } }, // >----->
+    { { -R+R/8, 0 }, { -R-R/8, -R/6 } },
+    { { -R+3*R/8, 0 }, { -R+R/8, R/6 } }, // >>----->
+    { { -R+3*R/8, 0 }, { -R+R/8, -R/6 } },
+    { { -R/2, 0 }, { -R/2, -R/6 } }, // >>-d--->
+    { { -R/2, -R/6 }, { -R/2+R/6, -R/6 } },
+    { { -R/2+R/6, -R/6 }, { -R/2+R/6, R/4 } },
+    { { -R/6, 0 }, { -R/6, -R/6 } }, // >>-dd-->
+    { { -R/6, -R/6 }, { 0, -R/6 } },
+    { { 0, -R/6 }, { 0, R/4 } },
+    { { R/6, R/4 }, { R/6, -R/7 } }, // >>-ddt->
+    { { R/6, -R/7 }, { R/6+R/32, -R/7-R/32 } },
+    { { R/6+R/32, -R/7-R/32 }, { R/6+R/10, -R/7 } }
+};
+#undef R
+#define NUMCHEATPLYRLINES (sizeof(cheat_player_arrow)/sizeof(mline_t))
+
+#define R (FRACUNIT)
+mline_t triangle_guy[] = {
+    { { -.867*R, -.5*R }, { .867*R, -.5*R } },
+    { { .867*R, -.5*R } , { 0, R } },
+    { { 0, R }, { -.867*R, -.5*R } }
+};
+#undef R
+#define NUMTRIANGLEGUYLINES (sizeof(triangle_guy)/sizeof(mline_t))
+
+#define R (FRACUNIT)
+mline_t thintriangle_guy[] = {
+    { { -.5*R, -.7*R }, { R, 0 } },
+    { { R, 0 }, { -.5*R, .7*R } },
+    { { -.5*R, .7*R }, { -.5*R, -.7*R } }
+};
+#undef R
+#define NUMTHINTRIANGLEGUYLINES (sizeof(thintriangle_guy)/sizeof(mline_t))
+
+
+
+
+static int 	cheating = 0;
+static int 	grid = 0;
+
+static int 	leveljuststarted = 1; 	// kluge until AM_LevelInit() is called
+
+boolean    	automapactive = false;
+static int 	finit_width = SCREENWIDTH;
+static int 	finit_height = SCREENHEIGHT - 32;
+
+// location of window on screen
+static int 	f_x;
+static int	f_y;
+
+// size of window on screen
+static int 	f_w;
+static int	f_h;
+
+static int 	lightlev; 		// used for funky strobing effect
+static byte*	fb; 			// pseudo-frame buffer
+static int 	amclock;
+
+static mpoint_t m_paninc; // how far the window pans each tic (map coords)
+static fixed_t 	mtof_zoommul; // how far the window zooms in each tic (map coords)
+static fixed_t 	ftom_zoommul; // how far the window zooms in each tic (fb coords)
+
+static fixed_t 	m_x, m_y;   // LL x,y where the window is on the map (map coords)
+static fixed_t 	m_x2, m_y2; // UR x,y where the window is on the map (map coords)
+
+//
+// width/height of window on map (map coords)
+//
+static fixed_t 	m_w;
+static fixed_t	m_h;
+
+// based on level size
+static fixed_t 	min_x;
+static fixed_t	min_y; 
+static fixed_t 	max_x;
+static fixed_t  max_y;
+
+static fixed_t 	max_w; // max_x-min_x,
+static fixed_t  max_h; // max_y-min_y
+
+// based on player size
+static fixed_t 	min_w;
+static fixed_t  min_h;
+
+
+static fixed_t 	min_scale_mtof; // used to tell when to stop zooming out
+static fixed_t 	max_scale_mtof; // used to tell when to stop zooming in
+
+// old stuff for recovery later
+static fixed_t old_m_w, old_m_h;
+static fixed_t old_m_x, old_m_y;
+
+// old location used by the Follower routine
+static mpoint_t f_oldloc;
+
+// used by MTOF to scale from map-to-frame-buffer coords
+static fixed_t scale_mtof = INITSCALEMTOF;
+// used by FTOM to scale from frame-buffer-to-map coords (=1/scale_mtof)
+static fixed_t scale_ftom;
+
+static player_t *plr; // the player represented by an arrow
+
+static patch_t *marknums[10]; // numbers used for marking by the automap
+static mpoint_t markpoints[AM_NUMMARKPOINTS]; // where the points are
+static int markpointnum = 0; // next point to be assigned
+
+static int followplayer = 1; // specifies whether to follow the player around
+
+static unsigned char cheat_amap_seq[] = { 0xb2, 0x26, 0x26, 0x2e, 0xff };
+static cheatseq_t cheat_amap = { cheat_amap_seq, 0 };
+
+static boolean stopped = true;
+
+extern boolean viewactive;
+//extern byte screens[][SCREENWIDTH*SCREENHEIGHT];
+
+
+
+void
+V_MarkRect
+( int	x,
+  int	y,
+  int	width,
+  int	height );
+
+// Calculates the slope and slope according to the x-axis of a line
+// segment in map coordinates (with the upright y-axis n' all) so
+// that it can be used with the brain-dead drawing stuff.
+
+void
+AM_getIslope
+( mline_t*	ml,
+  islope_t*	is )
+{
+    int dx, dy;
+
+    dy = ml->a.y - ml->b.y;
+    dx = ml->b.x - ml->a.x;
+    if (!dy) is->islp = (dx<0?-MAXINT:MAXINT);
+    else is->islp = FixedDiv(dx, dy);
+    if (!dx) is->slp = (dy<0?-MAXINT:MAXINT);
+    else is->slp = FixedDiv(dy, dx);
+
+}
+
+//
+//
+//
+void AM_activateNewScale(void)
+{
+    m_x += m_w/2;
+    m_y += m_h/2;
+    m_w = FTOM(f_w);
+    m_h = FTOM(f_h);
+    m_x -= m_w/2;
+    m_y -= m_h/2;
+    m_x2 = m_x + m_w;
+    m_y2 = m_y + m_h;
+}
+
+//
+//
+//
+void AM_saveScaleAndLoc(void)
+{
+    old_m_x = m_x;
+    old_m_y = m_y;
+    old_m_w = m_w;
+    old_m_h = m_h;
+}
+
+//
+//
+//
+void AM_restoreScaleAndLoc(void)
+{
+
+    m_w = old_m_w;
+    m_h = old_m_h;
+    if (!followplayer)
+    {
+	m_x = old_m_x;
+	m_y = old_m_y;
+    } else {
+	m_x = plr->mo->x - m_w/2;
+	m_y = plr->mo->y - m_h/2;
+    }
+    m_x2 = m_x + m_w;
+    m_y2 = m_y + m_h;
+
+    // Change the scaling multipliers
+    scale_mtof = FixedDiv(f_w<<FRACBITS, m_w);
+    scale_ftom = FixedDiv(FRACUNIT, scale_mtof);
+}
+
+//
+// adds a marker at the current location
+//
+void AM_addMark(void)
+{
+    markpoints[markpointnum].x = m_x + m_w/2;
+    markpoints[markpointnum].y = m_y + m_h/2;
+    markpointnum = (markpointnum + 1) % AM_NUMMARKPOINTS;
+
+}
+
+//
+// Determines bounding box of all vertices,
+// sets global variables controlling zoom range.
+//
+void AM_findMinMaxBoundaries(void)
+{
+    int i;
+    fixed_t a;
+    fixed_t b;
+
+    min_x = min_y =  MAXINT;
+    max_x = max_y = -MAXINT;
+  
+    for (i=0;i<numvertexes;i++)
+    {
+	if (vertexes[i].x < min_x)
+	    min_x = vertexes[i].x;
+	else if (vertexes[i].x > max_x)
+	    max_x = vertexes[i].x;
+    
+	if (vertexes[i].y < min_y)
+	    min_y = vertexes[i].y;
+	else if (vertexes[i].y > max_y)
+	    max_y = vertexes[i].y;
+    }
+  
+    max_w = max_x - min_x;
+    max_h = max_y - min_y;
+
+    min_w = 2*PLAYERRADIUS; // const? never changed?
+    min_h = 2*PLAYERRADIUS;
+
+    a = FixedDiv(f_w<<FRACBITS, max_w);
+    b = FixedDiv(f_h<<FRACBITS, max_h);
+  
+    min_scale_mtof = a < b ? a : b;
+    max_scale_mtof = FixedDiv(f_h<<FRACBITS, 2*PLAYERRADIUS);
+
+}
+
+
+//
+//
+//
+void AM_changeWindowLoc(void)
+{
+    if (m_paninc.x || m_paninc.y)
+    {
+	followplayer = 0;
+	f_oldloc.x = MAXINT;
+    }
+
+    m_x += m_paninc.x;
+    m_y += m_paninc.y;
+
+    if (m_x + m_w/2 > max_x)
+	m_x = max_x - m_w/2;
+    else if (m_x + m_w/2 < min_x)
+	m_x = min_x - m_w/2;
+  
+    if (m_y + m_h/2 > max_y)
+	m_y = max_y - m_h/2;
+    else if (m_y + m_h/2 < min_y)
+	m_y = min_y - m_h/2;
+
+    m_x2 = m_x + m_w;
+    m_y2 = m_y + m_h;
+}
+
+
+//
+//
+//
+void AM_initVariables(void)
+{
+    int pnum;
+    static event_t st_notify = { ev_keyup, AM_MSGENTERED };
+
+    automapactive = true;
+    fb = screens[0];
+
+    f_oldloc.x = MAXINT;
+    amclock = 0;
+    lightlev = 0;
+
+    m_paninc.x = m_paninc.y = 0;
+    ftom_zoommul = FRACUNIT;
+    mtof_zoommul = FRACUNIT;
+
+    m_w = FTOM(f_w);
+    m_h = FTOM(f_h);
+
+    // find player to center on initially
+    if (!playeringame[pnum = consoleplayer])
+	for (pnum=0;pnum<MAXPLAYERS;pnum++)
+	    if (playeringame[pnum])
+		break;
+  
+    plr = &players[pnum];
+    m_x = plr->mo->x - m_w/2;
+    m_y = plr->mo->y - m_h/2;
+    AM_changeWindowLoc();
+
+    // for saving & restoring
+    old_m_x = m_x;
+    old_m_y = m_y;
+    old_m_w = m_w;
+    old_m_h = m_h;
+
+    // inform the status bar of the change
+    ST_Responder(&st_notify);
+
+}
+
+//
+// 
+//
+void AM_loadPics(void)
+{
+    int i;
+    char namebuf[9];
+  
+    for (i=0;i<10;i++)
+    {
+	sprintf(namebuf, "AMMNUM%d", i);
+	marknums[i] = W_CacheLumpName(namebuf, PU_STATIC);
+    }
+
+}
+
+void AM_unloadPics(void)
+{
+    int i;
+  
+    for (i=0;i<10;i++)
+	Z_ChangeTag(marknums[i], PU_CACHE);
+
+}
+
+void AM_clearMarks(void)
+{
+    int i;
+
+    for (i=0;i<AM_NUMMARKPOINTS;i++)
+	markpoints[i].x = -1; // means empty
+    markpointnum = 0;
+}
+
+//
+// should be called at the start of every level
+// right now, i figure it out myself
+//
+void AM_LevelInit(void)
+{
+    leveljuststarted = 0;
+
+    f_x = f_y = 0;
+    f_w = finit_width;
+    f_h = finit_height;
+
+    AM_clearMarks();
+
+    AM_findMinMaxBoundaries();
+    scale_mtof = FixedDiv(min_scale_mtof, (int) (0.7*FRACUNIT));
+    if (scale_mtof > max_scale_mtof)
+	scale_mtof = min_scale_mtof;
+    scale_ftom = FixedDiv(FRACUNIT, scale_mtof);
+}
+
+
+
+
+//
+//
+//
+void AM_Stop (void)
+{
+    static event_t st_notify = { 0, ev_keyup, AM_MSGEXITED };
+
+    AM_unloadPics();
+    automapactive = false;
+    ST_Responder(&st_notify);
+    stopped = true;
+}
+
+//
+//
+//
+void AM_Start (void)
+{
+    static int lastlevel = -1, lastepisode = -1;
+
+    if (!stopped) AM_Stop();
+    stopped = false;
+    if (lastlevel != gamemap || lastepisode != gameepisode)
+    {
+	AM_LevelInit();
+	lastlevel = gamemap;
+	lastepisode = gameepisode;
+    }
+    AM_initVariables();
+    AM_loadPics();
+}
+
+//
+// set the window scale to the maximum size
+//
+void AM_minOutWindowScale(void)
+{
+    scale_mtof = min_scale_mtof;
+    scale_ftom = FixedDiv(FRACUNIT, scale_mtof);
+    AM_activateNewScale();
+}
+
+//
+// set the window scale to the minimum size
+//
+void AM_maxOutWindowScale(void)
+{
+    scale_mtof = max_scale_mtof;
+    scale_ftom = FixedDiv(FRACUNIT, scale_mtof);
+    AM_activateNewScale();
+}
+
+
+//
+// Handle events (user inputs) in automap mode
+//
+boolean
+AM_Responder
+( event_t*	ev )
+{
+
+    int rc;
+    static int cheatstate=0;
+    static int bigstate=0;
+    static char buffer[20];
+
+    rc = false;
+
+    if (!automapactive)
+    {
+	if (ev->type == ev_keydown && ev->data1 == AM_STARTKEY)
+	{
+	    AM_Start ();
+	    viewactive = false;
+	    rc = true;
+	}
+    }
+
+    else if (ev->type == ev_keydown)
+    {
+
+	rc = true;
+	switch(ev->data1)
+	{
+	  case AM_PANRIGHTKEY: // pan right
+	    if (!followplayer) m_paninc.x = FTOM(F_PANINC);
+	    else rc = false;
+	    break;
+	  case AM_PANLEFTKEY: // pan left
+	    if (!followplayer) m_paninc.x = -FTOM(F_PANINC);
+	    else rc = false;
+	    break;
+	  case AM_PANUPKEY: // pan up
+	    if (!followplayer) m_paninc.y = FTOM(F_PANINC);
+	    else rc = false;
+	    break;
+	  case AM_PANDOWNKEY: // pan down
+	    if (!followplayer) m_paninc.y = -FTOM(F_PANINC);
+	    else rc = false;
+	    break;
+	  case AM_ZOOMOUTKEY: // zoom out
+	    mtof_zoommul = M_ZOOMOUT;
+	    ftom_zoommul = M_ZOOMIN;
+	    break;
+	  case AM_ZOOMINKEY: // zoom in
+	    mtof_zoommul = M_ZOOMIN;
+	    ftom_zoommul = M_ZOOMOUT;
+	    break;
+	  case AM_ENDKEY:
+	    bigstate = 0;
+	    viewactive = true;
+	    AM_Stop ();
+	    break;
+	  case AM_GOBIGKEY:
+	    bigstate = !bigstate;
+	    if (bigstate)
+	    {
+		AM_saveScaleAndLoc();
+		AM_minOutWindowScale();
+	    }
+	    else AM_restoreScaleAndLoc();
+	    break;
+	  case AM_FOLLOWKEY:
+	    followplayer = !followplayer;
+	    f_oldloc.x = MAXINT;
+	    plr->message = followplayer ? AMSTR_FOLLOWON : AMSTR_FOLLOWOFF;
+	    break;
+	  case AM_GRIDKEY:
+	    grid = !grid;
+	    plr->message = grid ? AMSTR_GRIDON : AMSTR_GRIDOFF;
+	    break;
+	  case AM_MARKKEY:
+	    sprintf(buffer, "%s %d", AMSTR_MARKEDSPOT, markpointnum);
+	    plr->message = buffer;
+	    AM_addMark();
+	    break;
+	  case AM_CLEARMARKKEY:
+	    AM_clearMarks();
+	    plr->message = AMSTR_MARKSCLEARED;
+	    break;
+	  default:
+	    cheatstate=0;
+	    rc = false;
+	}
+	if (!deathmatch && cht_CheckCheat(&cheat_amap, ev->data1))
+	{
+	    rc = false;
+	    cheating = (cheating+1) % 3;
+	}
+    }
+
+    else if (ev->type == ev_keyup)
+    {
+	rc = false;
+	switch (ev->data1)
+	{
+	  case AM_PANRIGHTKEY:
+	    if (!followplayer) m_paninc.x = 0;
+	    break;
+	  case AM_PANLEFTKEY:
+	    if (!followplayer) m_paninc.x = 0;
+	    break;
+	  case AM_PANUPKEY:
+	    if (!followplayer) m_paninc.y = 0;
+	    break;
+	  case AM_PANDOWNKEY:
+	    if (!followplayer) m_paninc.y = 0;
+	    break;
+	  case AM_ZOOMOUTKEY:
+	  case AM_ZOOMINKEY:
+	    mtof_zoommul = FRACUNIT;
+	    ftom_zoommul = FRACUNIT;
+	    break;
+	}
+    }
+
+    return rc;
+
+}
+
+
+//
+// Zooming
+//
+void AM_changeWindowScale(void)
+{
+
+    // Change the scaling multipliers
+    scale_mtof = FixedMul(scale_mtof, mtof_zoommul);
+    scale_ftom = FixedDiv(FRACUNIT, scale_mtof);
+
+    if (scale_mtof < min_scale_mtof)
+	AM_minOutWindowScale();
+    else if (scale_mtof > max_scale_mtof)
+	AM_maxOutWindowScale();
+    else
+	AM_activateNewScale();
+}
+
+
+//
+//
+//
+void AM_doFollowPlayer(void)
+{
+
+    if (f_oldloc.x != plr->mo->x || f_oldloc.y != plr->mo->y)
+    {
+	m_x = FTOM(MTOF(plr->mo->x)) - m_w/2;
+	m_y = FTOM(MTOF(plr->mo->y)) - m_h/2;
+	m_x2 = m_x + m_w;
+	m_y2 = m_y + m_h;
+	f_oldloc.x = plr->mo->x;
+	f_oldloc.y = plr->mo->y;
+
+	//  m_x = FTOM(MTOF(plr->mo->x - m_w/2));
+	//  m_y = FTOM(MTOF(plr->mo->y - m_h/2));
+	//  m_x = plr->mo->x - m_w/2;
+	//  m_y = plr->mo->y - m_h/2;
+
+    }
+
+}
+
+//
+//
+//
+void AM_updateLightLev(void)
+{
+    static nexttic = 0;
+    //static int litelevels[] = { 0, 3, 5, 6, 6, 7, 7, 7 };
+    static int litelevels[] = { 0, 4, 7, 10, 12, 14, 15, 15 };
+    static int litelevelscnt = 0;
+   
+    // Change light level
+    if (amclock>nexttic)
+    {
+	lightlev = litelevels[litelevelscnt++];
+	if (litelevelscnt == sizeof(litelevels)/sizeof(int)) litelevelscnt = 0;
+	nexttic = amclock + 6 - (amclock % 6);
+    }
+
+}
+
+
+//
+// Updates on Game Tick
+//
+void AM_Ticker (void)
+{
+
+    if (!automapactive)
+	return;
+
+    amclock++;
+
+    if (followplayer)
+	AM_doFollowPlayer();
+
+    // Change the zoom if necessary
+    if (ftom_zoommul != FRACUNIT)
+	AM_changeWindowScale();
+
+    // Change x,y location
+    if (m_paninc.x || m_paninc.y)
+	AM_changeWindowLoc();
+
+    // Update light level
+    // AM_updateLightLev();
+
+}
+
+
+//
+// Clear automap frame buffer.
+//
+void AM_clearFB(int color)
+{
+    memset(fb, color, f_w*f_h);
+}
+
+
+//
+// Automap clipping of lines.
+//
+// Based on Cohen-Sutherland clipping algorithm but with a slightly
+// faster reject and precalculated slopes.  If the speed is needed,
+// use a hash algorithm to handle  the common cases.
+//
+boolean
+AM_clipMline
+( mline_t*	ml,
+  fline_t*	fl )
+{
+    enum
+    {
+	LEFT	=1,
+	RIGHT	=2,
+	BOTTOM	=4,
+	TOP	=8
+    };
+    
+    register	outcode1 = 0;
+    register	outcode2 = 0;
+    register	outside;
+    
+    fpoint_t	tmp;
+    int		dx;
+    int		dy;
+
+    
+#define DOOUTCODE(oc, mx, my) \
+    (oc) = 0; \
+    if ((my) < 0) (oc) |= TOP; \
+    else if ((my) >= f_h) (oc) |= BOTTOM; \
+    if ((mx) < 0) (oc) |= LEFT; \
+    else if ((mx) >= f_w) (oc) |= RIGHT;
+
+    
+    // do trivial rejects and outcodes
+    if (ml->a.y > m_y2)
+	outcode1 = TOP;
+    else if (ml->a.y < m_y)
+	outcode1 = BOTTOM;
+
+    if (ml->b.y > m_y2)
+	outcode2 = TOP;
+    else if (ml->b.y < m_y)
+	outcode2 = BOTTOM;
+    
+    if (outcode1 & outcode2)
+	return false; // trivially outside
+
+    if (ml->a.x < m_x)
+	outcode1 |= LEFT;
+    else if (ml->a.x > m_x2)
+	outcode1 |= RIGHT;
+    
+    if (ml->b.x < m_x)
+	outcode2 |= LEFT;
+    else if (ml->b.x > m_x2)
+	outcode2 |= RIGHT;
+    
+    if (outcode1 & outcode2)
+	return false; // trivially outside
+
+    // transform to frame-buffer coordinates.
+    fl->a.x = CXMTOF(ml->a.x);
+    fl->a.y = CYMTOF(ml->a.y);
+    fl->b.x = CXMTOF(ml->b.x);
+    fl->b.y = CYMTOF(ml->b.y);
+
+    DOOUTCODE(outcode1, fl->a.x, fl->a.y);
+    DOOUTCODE(outcode2, fl->b.x, fl->b.y);
+
+    if (outcode1 & outcode2)
+	return false;
+
+    while (outcode1 | outcode2)
+    {
+	// may be partially inside box
+	// find an outside point
+	if (outcode1)
+	    outside = outcode1;
+	else
+	    outside = outcode2;
+	
+	// clip to each side
+	if (outside & TOP)
+	{
+	    dy = fl->a.y - fl->b.y;
+	    dx = fl->b.x - fl->a.x;
+	    tmp.x = fl->a.x + (dx*(fl->a.y))/dy;
+	    tmp.y = 0;
+	}
+	else if (outside & BOTTOM)
+	{
+	    dy = fl->a.y - fl->b.y;
+	    dx = fl->b.x - fl->a.x;
+	    tmp.x = fl->a.x + (dx*(fl->a.y-f_h))/dy;
+	    tmp.y = f_h-1;
+	}
+	else if (outside & RIGHT)
+	{
+	    dy = fl->b.y - fl->a.y;
+	    dx = fl->b.x - fl->a.x;
+	    tmp.y = fl->a.y + (dy*(f_w-1 - fl->a.x))/dx;
+	    tmp.x = f_w-1;
+	}
+	else if (outside & LEFT)
+	{
+	    dy = fl->b.y - fl->a.y;
+	    dx = fl->b.x - fl->a.x;
+	    tmp.y = fl->a.y + (dy*(-fl->a.x))/dx;
+	    tmp.x = 0;
+	}
+
+	if (outside == outcode1)
+	{
+	    fl->a = tmp;
+	    DOOUTCODE(outcode1, fl->a.x, fl->a.y);
+	}
+	else
+	{
+	    fl->b = tmp;
+	    DOOUTCODE(outcode2, fl->b.x, fl->b.y);
+	}
+	
+	if (outcode1 & outcode2)
+	    return false; // trivially outside
+    }
+
+    return true;
+}
+#undef DOOUTCODE
+
+
+//
+// Classic Bresenham w/ whatever optimizations needed for speed
+//
+void
+AM_drawFline
+( fline_t*	fl,
+  int		color )
+{
+    register int x;
+    register int y;
+    register int dx;
+    register int dy;
+    register int sx;
+    register int sy;
+    register int ax;
+    register int ay;
+    register int d;
+    
+    static fuck = 0;
+
+    // For debugging only
+    if (      fl->a.x < 0 || fl->a.x >= f_w
+	   || fl->a.y < 0 || fl->a.y >= f_h
+	   || fl->b.x < 0 || fl->b.x >= f_w
+	   || fl->b.y < 0 || fl->b.y >= f_h)
+    {
+	fprintf(stderr, "fuck %d \r", fuck++);
+	return;
+    }
+
+#define PUTDOT(xx,yy,cc) fb[(yy)*f_w+(xx)]=(cc)
+
+    dx = fl->b.x - fl->a.x;
+    ax = 2 * (dx<0 ? -dx : dx);
+    sx = dx<0 ? -1 : 1;
+
+    dy = fl->b.y - fl->a.y;
+    ay = 2 * (dy<0 ? -dy : dy);
+    sy = dy<0 ? -1 : 1;
+
+    x = fl->a.x;
+    y = fl->a.y;
+
+    if (ax > ay)
+    {
+	d = ay - ax/2;
+	while (1)
+	{
+	    PUTDOT(x,y,color);
+	    if (x == fl->b.x) return;
+	    if (d>=0)
+	    {
+		y += sy;
+		d -= ax;
+	    }
+	    x += sx;
+	    d += ay;
+	}
+    }
+    else
+    {
+	d = ax - ay/2;
+	while (1)
+	{
+	    PUTDOT(x, y, color);
+	    if (y == fl->b.y) return;
+	    if (d >= 0)
+	    {
+		x += sx;
+		d -= ay;
+	    }
+	    y += sy;
+	    d += ax;
+	}
+    }
+}
+
+
+//
+// Clip lines, draw visible part sof lines.
+//
+void
+AM_drawMline
+( mline_t*	ml,
+  int		color )
+{
+    static fline_t fl;
+
+    if (AM_clipMline(ml, &fl))
+	AM_drawFline(&fl, color); // draws it on frame buffer using fb coords
+}
+
+
+
+//
+// Draws flat (floor/ceiling tile) aligned grid lines.
+//
+void AM_drawGrid(int color)
+{
+    fixed_t x, y;
+    fixed_t start, end;
+    mline_t ml;
+
+    // Figure out start of vertical gridlines
+    start = m_x;
+    if ((start-bmaporgx)%(MAPBLOCKUNITS<<FRACBITS))
+	start += (MAPBLOCKUNITS<<FRACBITS)
+	    - ((start-bmaporgx)%(MAPBLOCKUNITS<<FRACBITS));
+    end = m_x + m_w;
+
+    // draw vertical gridlines
+    ml.a.y = m_y;
+    ml.b.y = m_y+m_h;
+    for (x=start; x<end; x+=(MAPBLOCKUNITS<<FRACBITS))
+    {
+	ml.a.x = x;
+	ml.b.x = x;
+	AM_drawMline(&ml, color);
+    }
+
+    // Figure out start of horizontal gridlines
+    start = m_y;
+    if ((start-bmaporgy)%(MAPBLOCKUNITS<<FRACBITS))
+	start += (MAPBLOCKUNITS<<FRACBITS)
+	    - ((start-bmaporgy)%(MAPBLOCKUNITS<<FRACBITS));
+    end = m_y + m_h;
+
+    // draw horizontal gridlines
+    ml.a.x = m_x;
+    ml.b.x = m_x + m_w;
+    for (y=start; y<end; y+=(MAPBLOCKUNITS<<FRACBITS))
+    {
+	ml.a.y = y;
+	ml.b.y = y;
+	AM_drawMline(&ml, color);
+    }
+
+}
+
+//
+// Determines visible lines, draws them.
+// This is LineDef based, not LineSeg based.
+//
+void AM_drawWalls(void)
+{
+    int i;
+    static mline_t l;
+
+    for (i=0;i<numlines;i++)
+    {
+	l.a.x = lines[i].v1->x;
+	l.a.y = lines[i].v1->y;
+	l.b.x = lines[i].v2->x;
+	l.b.y = lines[i].v2->y;
+	if (cheating || (lines[i].flags & ML_MAPPED))
+	{
+	    if ((lines[i].flags & LINE_NEVERSEE) && !cheating)
+		continue;
+	    if (!lines[i].backsector)
+	    {
+		AM_drawMline(&l, WALLCOLORS+lightlev);
+	    }
+	    else
+	    {
+		if (lines[i].special == 39)
+		{ // teleporters
+		    AM_drawMline(&l, WALLCOLORS+WALLRANGE/2);
+		}
+		else if (lines[i].flags & ML_SECRET) // secret door
+		{
+		    if (cheating) AM_drawMline(&l, SECRETWALLCOLORS + lightlev);
+		    else AM_drawMline(&l, WALLCOLORS+lightlev);
+		}
+		else if (lines[i].backsector->floorheight
+			   != lines[i].frontsector->floorheight) {
+		    AM_drawMline(&l, FDWALLCOLORS + lightlev); // floor level change
+		}
+		else if (lines[i].backsector->ceilingheight
+			   != lines[i].frontsector->ceilingheight) {
+		    AM_drawMline(&l, CDWALLCOLORS+lightlev); // ceiling level change
+		}
+		else if (cheating) {
+		    AM_drawMline(&l, TSWALLCOLORS+lightlev);
+		}
+	    }
+	}
+	else if (plr->powers[pw_allmap])
+	{
+	    if (!(lines[i].flags & LINE_NEVERSEE)) AM_drawMline(&l, GRAYS+3);
+	}
+    }
+}
+
+
+//
+// Rotation in 2D.
+// Used to rotate player arrow line character.
+//
+void
+AM_rotate
+( fixed_t*	x,
+  fixed_t*	y,
+  angle_t	a )
+{
+    fixed_t tmpx;
+
+    tmpx =
+	FixedMul(*x,finecosine[a>>ANGLETOFINESHIFT])
+	- FixedMul(*y,finesine[a>>ANGLETOFINESHIFT]);
+    
+    *y   =
+	FixedMul(*x,finesine[a>>ANGLETOFINESHIFT])
+	+ FixedMul(*y,finecosine[a>>ANGLETOFINESHIFT]);
+
+    *x = tmpx;
+}
+
+void
+AM_drawLineCharacter
+( mline_t*	lineguy,
+  int		lineguylines,
+  fixed_t	scale,
+  angle_t	angle,
+  int		color,
+  fixed_t	x,
+  fixed_t	y )
+{
+    int		i;
+    mline_t	l;
+
+    for (i=0;i<lineguylines;i++)
+    {
+	l.a.x = lineguy[i].a.x;
+	l.a.y = lineguy[i].a.y;
+
+	if (scale)
+	{
+	    l.a.x = FixedMul(scale, l.a.x);
+	    l.a.y = FixedMul(scale, l.a.y);
+	}
+
+	if (angle)
+	    AM_rotate(&l.a.x, &l.a.y, angle);
+
+	l.a.x += x;
+	l.a.y += y;
+
+	l.b.x = lineguy[i].b.x;
+	l.b.y = lineguy[i].b.y;
+
+	if (scale)
+	{
+	    l.b.x = FixedMul(scale, l.b.x);
+	    l.b.y = FixedMul(scale, l.b.y);
+	}
+
+	if (angle)
+	    AM_rotate(&l.b.x, &l.b.y, angle);
+	
+	l.b.x += x;
+	l.b.y += y;
+
+	AM_drawMline(&l, color);
+    }
+}
+
+void AM_drawPlayers(void)
+{
+    int		i;
+    player_t*	p;
+    static int 	their_colors[] = { GREENS, GRAYS, BROWNS, REDS };
+    int		their_color = -1;
+    int		color;
+
+    if (!netgame)
+    {
+	if (cheating)
+	    AM_drawLineCharacter
+		(cheat_player_arrow, NUMCHEATPLYRLINES, 0,
+		 plr->mo->angle, WHITE, plr->mo->x, plr->mo->y);
+	else
+	    AM_drawLineCharacter
+		(player_arrow, NUMPLYRLINES, 0, plr->mo->angle,
+		 WHITE, plr->mo->x, plr->mo->y);
+	return;
+    }
+
+    for (i=0;i<MAXPLAYERS;i++)
+    {
+	their_color++;
+	p = &players[i];
+
+	if ( (deathmatch && !singledemo) && p != plr)
+	    continue;
+
+	if (!playeringame[i])
+	    continue;
+
+	if (p->powers[pw_invisibility])
+	    color = 246; // *close* to black
+	else
+	    color = their_colors[their_color];
+	
+	AM_drawLineCharacter
+	    (player_arrow, NUMPLYRLINES, 0, p->mo->angle,
+	     color, p->mo->x, p->mo->y);
+    }
+
+}
+
+void
+AM_drawThings
+( int	colors,
+  int 	colorrange)
+{
+    int		i;
+    mobj_t*	t;
+
+    for (i=0;i<numsectors;i++)
+    {
+	t = sectors[i].thinglist;
+	while (t)
+	{
+	    AM_drawLineCharacter
+		(thintriangle_guy, NUMTHINTRIANGLEGUYLINES,
+		 16<<FRACBITS, t->angle, colors+lightlev, t->x, t->y);
+	    t = t->snext;
+	}
+    }
+}
+
+void AM_drawMarks(void)
+{
+    int i, fx, fy, w, h;
+
+    for (i=0;i<AM_NUMMARKPOINTS;i++)
+    {
+	if (markpoints[i].x != -1)
+	{
+	    //      w = SHORT(marknums[i]->width);
+	    //      h = SHORT(marknums[i]->height);
+	    w = 5; // because something's wrong with the wad, i guess
+	    h = 6; // because something's wrong with the wad, i guess
+	    fx = CXMTOF(markpoints[i].x);
+	    fy = CYMTOF(markpoints[i].y);
+	    if (fx >= f_x && fx <= f_w - w && fy >= f_y && fy <= f_h - h)
+		V_DrawPatch(fx, fy, FB, marknums[i]);
+	}
+    }
+
+}
+
+void AM_drawCrosshair(int color)
+{
+    fb[(f_w*(f_h+1))/2] = color; // single point for now
+
+}
+
+void AM_Drawer (void)
+{
+    if (!automapactive) return;
+
+    AM_clearFB(BACKGROUND);
+    if (grid)
+	AM_drawGrid(GRIDCOLORS);
+    AM_drawWalls();
+    AM_drawPlayers();
+    if (cheating==2)
+	AM_drawThings(THINGCOLORS, THINGRANGE);
+    AM_drawCrosshair(XHAIRCOLORS);
+
+    AM_drawMarks();
+
+    V_MarkRect(f_x, f_y, f_w, f_h);
+
+}
--- /dev/null
+++ b/src/am_map.h
@@ -1,0 +1,55 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: am_map.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//  AutoMap module.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef __AMMAP_H__
+#define __AMMAP_H__
+
+// Used by ST StatusBar stuff.
+#define AM_MSGHEADER (('a'<<24)+('m'<<16))
+#define AM_MSGENTERED (AM_MSGHEADER | ('e'<<8))
+#define AM_MSGEXITED (AM_MSGHEADER | ('x'<<8))
+
+
+// Called by main loop.
+boolean AM_Responder (event_t* ev);
+
+// Called by main loop.
+void AM_Ticker (void);
+
+// Called by main loop,
+// called instead of view drawer if automap active.
+void AM_Drawer (void);
+
+// Called to force the automap to quit
+// if the level is completed while it is up.
+void AM_Stop (void);
+
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:44  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/d_englsh.h
@@ -1,0 +1,704 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: d_englsh.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//	Printed strings for translation.
+//	English language support (default).
+//
+//-----------------------------------------------------------------------------
+
+#ifndef __D_ENGLSH__
+#define __D_ENGLSH__
+
+//
+//	Printed strings for translation
+//
+
+//
+// D_Main.C
+//
+#define D_DEVSTR	"Development mode ON.\n"
+#define D_CDROM	"CD-ROM Version: default.cfg from c:\\doomdata\n"
+
+//
+//	M_Menu.C
+//
+#define PRESSKEY 	"press a key."
+#define PRESSYN 	"press y or n."
+#define QUITMSG	"are you sure you want to\nquit this great game?"
+#define LOADNET 	"you can't do load while in a net game!\n\n"PRESSKEY
+#define QLOADNET	"you can't quickload during a netgame!\n\n"PRESSKEY
+#define QSAVESPOT	"you haven't picked a quicksave slot yet!\n\n"PRESSKEY
+#define SAVEDEAD 	"you can't save if you aren't playing!\n\n"PRESSKEY
+#define QSPROMPT 	"quicksave over your game named\n\n'%s'?\n\n"PRESSYN
+#define QLPROMPT	"do you want to quickload the game named\n\n'%s'?\n\n"PRESSYN
+
+#define NEWGAME	\
+"you can't start a new game\n"\
+"while in a network game.\n\n"PRESSKEY
+
+#define NIGHTMARE	\
+"are you sure? this skill level\n"\
+"isn't even remotely fair.\n\n"PRESSYN
+
+#define SWSTRING	\
+"this is the shareware version of doom.\n\n"\
+"you need to order the entire trilogy.\n\n"PRESSKEY
+
+#define MSGOFF	"Messages OFF"
+#define MSGON		"Messages ON"
+#define NETEND	"you can't end a netgame!\n\n"PRESSKEY
+#define ENDGAME	"are you sure you want to end the game?\n\n"PRESSYN
+
+#define DOSY		"(press y to quit)"
+
+#define DETAILHI	"High detail"
+#define DETAILLO	"Low detail"
+#define GAMMALVL0	"Gamma correction OFF"
+#define GAMMALVL1	"Gamma correction level 1"
+#define GAMMALVL2	"Gamma correction level 2"
+#define GAMMALVL3	"Gamma correction level 3"
+#define GAMMALVL4	"Gamma correction level 4"
+#define EMPTYSTRING	"empty slot"
+
+//
+//	P_inter.C
+//
+#define GOTARMOR	"Picked up the armor."
+#define GOTMEGA	"Picked up the MegaArmor!"
+#define GOTHTHBONUS	"Picked up a health bonus."
+#define GOTARMBONUS	"Picked up an armor bonus."
+#define GOTSTIM	"Picked up a stimpack."
+#define GOTMEDINEED	"Picked up a medikit that you REALLY need!"
+#define GOTMEDIKIT	"Picked up a medikit."
+#define GOTSUPER	"Supercharge!"
+
+#define GOTBLUECARD	"Picked up a blue keycard."
+#define GOTYELWCARD	"Picked up a yellow keycard."
+#define GOTREDCARD	"Picked up a red keycard."
+#define GOTBLUESKUL	"Picked up a blue skull key."
+#define GOTYELWSKUL	"Picked up a yellow skull key."
+#define GOTREDSKULL	"Picked up a red skull key."
+
+#define GOTINVUL	"Invulnerability!"
+#define GOTBERSERK	"Berserk!"
+#define GOTINVIS	"Partial Invisibility"
+#define GOTSUIT	"Radiation Shielding Suit"
+#define GOTMAP	"Computer Area Map"
+#define GOTVISOR	"Light Amplification Visor"
+#define GOTMSPHERE	"MegaSphere!"
+
+#define GOTCLIP	"Picked up a clip."
+#define GOTCLIPBOX	"Picked up a box of bullets."
+#define GOTROCKET	"Picked up a rocket."
+#define GOTROCKBOX	"Picked up a box of rockets."
+#define GOTCELL	"Picked up an energy cell."
+#define GOTCELLBOX	"Picked up an energy cell pack."
+#define GOTSHELLS	"Picked up 4 shotgun shells."
+#define GOTSHELLBOX	"Picked up a box of shotgun shells."
+#define GOTBACKPACK	"Picked up a backpack full of ammo!"
+
+#define GOTBFG9000	"You got the BFG9000!  Oh, yes."
+#define GOTCHAINGUN	"You got the chaingun!"
+#define GOTCHAINSAW	"A chainsaw!  Find some meat!"
+#define GOTLAUNCHER	"You got the rocket launcher!"
+#define GOTPLASMA	"You got the plasma gun!"
+#define GOTSHOTGUN	"You got the shotgun!"
+#define GOTSHOTGUN2	"You got the super shotgun!"
+
+//
+// P_Doors.C
+//
+#define PD_BLUEO	"You need a blue key to activate this object"
+#define PD_REDO	"You need a red key to activate this object"
+#define PD_YELLOWO	"You need a yellow key to activate this object"
+#define PD_BLUEK	"You need a blue key to open this door"
+#define PD_REDK	"You need a red key to open this door"
+#define PD_YELLOWK	"You need a yellow key to open this door"
+
+//
+//	G_game.C
+//
+#define GGSAVED	"game saved."
+
+//
+//	HU_stuff.C
+//
+#define HUSTR_MSGU	"[Message unsent]"
+
+#define HUSTR_E1M1	"E1M1: Hangar"
+#define HUSTR_E1M2	"E1M2: Nuclear Plant"
+#define HUSTR_E1M3	"E1M3: Toxin Refinery"
+#define HUSTR_E1M4	"E1M4: Command Control"
+#define HUSTR_E1M5	"E1M5: Phobos Lab"
+#define HUSTR_E1M6	"E1M6: Central Processing"
+#define HUSTR_E1M7	"E1M7: Computer Station"
+#define HUSTR_E1M8	"E1M8: Phobos Anomaly"
+#define HUSTR_E1M9	"E1M9: Military Base"
+
+#define HUSTR_E2M1	"E2M1: Deimos Anomaly"
+#define HUSTR_E2M2	"E2M2: Containment Area"
+#define HUSTR_E2M3	"E2M3: Refinery"
+#define HUSTR_E2M4	"E2M4: Deimos Lab"
+#define HUSTR_E2M5	"E2M5: Command Center"
+#define HUSTR_E2M6	"E2M6: Halls of the Damned"
+#define HUSTR_E2M7	"E2M7: Spawning Vats"
+#define HUSTR_E2M8	"E2M8: Tower of Babel"
+#define HUSTR_E2M9	"E2M9: Fortress of Mystery"
+
+#define HUSTR_E3M1	"E3M1: Hell Keep"
+#define HUSTR_E3M2	"E3M2: Slough of Despair"
+#define HUSTR_E3M3	"E3M3: Pandemonium"
+#define HUSTR_E3M4	"E3M4: House of Pain"
+#define HUSTR_E3M5	"E3M5: Unholy Cathedral"
+#define HUSTR_E3M6	"E3M6: Mt. Erebus"
+#define HUSTR_E3M7	"E3M7: Limbo"
+#define HUSTR_E3M8	"E3M8: Dis"
+#define HUSTR_E3M9	"E3M9: Warrens"
+
+#define HUSTR_E4M1	"E4M1: Hell Beneath"
+#define HUSTR_E4M2	"E4M2: Perfect Hatred"
+#define HUSTR_E4M3	"E4M3: Sever The Wicked"
+#define HUSTR_E4M4	"E4M4: Unruly Evil"
+#define HUSTR_E4M5	"E4M5: They Will Repent"
+#define HUSTR_E4M6	"E4M6: Against Thee Wickedly"
+#define HUSTR_E4M7	"E4M7: And Hell Followed"
+#define HUSTR_E4M8	"E4M8: Unto The Cruel"
+#define HUSTR_E4M9	"E4M9: Fear"
+
+#define HUSTR_1	"level 1: entryway"
+#define HUSTR_2	"level 2: underhalls"
+#define HUSTR_3	"level 3: the gantlet"
+#define HUSTR_4	"level 4: the focus"
+#define HUSTR_5	"level 5: the waste tunnels"
+#define HUSTR_6	"level 6: the crusher"
+#define HUSTR_7	"level 7: dead simple"
+#define HUSTR_8	"level 8: tricks and traps"
+#define HUSTR_9	"level 9: the pit"
+#define HUSTR_10	"level 10: refueling base"
+#define HUSTR_11	"level 11: 'o' of destruction!"
+
+#define HUSTR_12	"level 12: the factory"
+#define HUSTR_13	"level 13: downtown"
+#define HUSTR_14	"level 14: the inmost dens"
+#define HUSTR_15	"level 15: industrial zone"
+#define HUSTR_16	"level 16: suburbs"
+#define HUSTR_17	"level 17: tenements"
+#define HUSTR_18	"level 18: the courtyard"
+#define HUSTR_19	"level 19: the citadel"
+#define HUSTR_20	"level 20: gotcha!"
+
+#define HUSTR_21	"level 21: nirvana"
+#define HUSTR_22	"level 22: the catacombs"
+#define HUSTR_23	"level 23: barrels o' fun"
+#define HUSTR_24	"level 24: the chasm"
+#define HUSTR_25	"level 25: bloodfalls"
+#define HUSTR_26	"level 26: the abandoned mines"
+#define HUSTR_27	"level 27: monster condo"
+#define HUSTR_28	"level 28: the spirit world"
+#define HUSTR_29	"level 29: the living end"
+#define HUSTR_30	"level 30: icon of sin"
+
+#define HUSTR_31	"level 31: wolfenstein"
+#define HUSTR_32	"level 32: grosse"
+
+#define PHUSTR_1	"level 1: congo"
+#define PHUSTR_2	"level 2: well of souls"
+#define PHUSTR_3	"level 3: aztec"
+#define PHUSTR_4	"level 4: caged"
+#define PHUSTR_5	"level 5: ghost town"
+#define PHUSTR_6	"level 6: baron's lair"
+#define PHUSTR_7	"level 7: caughtyard"
+#define PHUSTR_8	"level 8: realm"
+#define PHUSTR_9	"level 9: abattoire"
+#define PHUSTR_10	"level 10: onslaught"
+#define PHUSTR_11	"level 11: hunted"
+
+#define PHUSTR_12	"level 12: speed"
+#define PHUSTR_13	"level 13: the crypt"
+#define PHUSTR_14	"level 14: genesis"
+#define PHUSTR_15	"level 15: the twilight"
+#define PHUSTR_16	"level 16: the omen"
+#define PHUSTR_17	"level 17: compound"
+#define PHUSTR_18	"level 18: neurosphere"
+#define PHUSTR_19	"level 19: nme"
+#define PHUSTR_20	"level 20: the death domain"
+
+#define PHUSTR_21	"level 21: slayer"
+#define PHUSTR_22	"level 22: impossible mission"
+#define PHUSTR_23	"level 23: tombstone"
+#define PHUSTR_24	"level 24: the final frontier"
+#define PHUSTR_25	"level 25: the temple of darkness"
+#define PHUSTR_26	"level 26: bunker"
+#define PHUSTR_27	"level 27: anti-christ"
+#define PHUSTR_28	"level 28: the sewers"
+#define PHUSTR_29	"level 29: odyssey of noises"
+#define PHUSTR_30	"level 30: the gateway of hell"
+
+#define PHUSTR_31	"level 31: cyberden"
+#define PHUSTR_32	"level 32: go 2 it"
+
+#define THUSTR_1	"level 1: system control"
+#define THUSTR_2	"level 2: human bbq"
+#define THUSTR_3	"level 3: power control"
+#define THUSTR_4	"level 4: wormhole"
+#define THUSTR_5	"level 5: hanger"
+#define THUSTR_6	"level 6: open season"
+#define THUSTR_7	"level 7: prison"
+#define THUSTR_8	"level 8: metal"
+#define THUSTR_9	"level 9: stronghold"
+#define THUSTR_10	"level 10: redemption"
+#define THUSTR_11	"level 11: storage facility"
+
+#define THUSTR_12	"level 12: crater"
+#define THUSTR_13	"level 13: nukage processing"
+#define THUSTR_14	"level 14: steel works"
+#define THUSTR_15	"level 15: dead zone"
+#define THUSTR_16	"level 16: deepest reaches"
+#define THUSTR_17	"level 17: processing area"
+#define THUSTR_18	"level 18: mill"
+#define THUSTR_19	"level 19: shipping/respawning"
+#define THUSTR_20	"level 20: central processing"
+
+#define THUSTR_21	"level 21: administration center"
+#define THUSTR_22	"level 22: habitat"
+#define THUSTR_23	"level 23: lunar mining project"
+#define THUSTR_24	"level 24: quarry"
+#define THUSTR_25	"level 25: baron's den"
+#define THUSTR_26	"level 26: ballistyx"
+#define THUSTR_27	"level 27: mount pain"
+#define THUSTR_28	"level 28: heck"
+#define THUSTR_29	"level 29: river styx"
+#define THUSTR_30	"level 30: last call"
+
+#define THUSTR_31	"level 31: pharaoh"
+#define THUSTR_32	"level 32: caribbean"
+
+#define HUSTR_CHATMACRO1	"I'm ready to kick butt!"
+#define HUSTR_CHATMACRO2	"I'm OK."
+#define HUSTR_CHATMACRO3	"I'm not looking too good!"
+#define HUSTR_CHATMACRO4	"Help!"
+#define HUSTR_CHATMACRO5	"You suck!"
+#define HUSTR_CHATMACRO6	"Next time, scumbag..."
+#define HUSTR_CHATMACRO7	"Come here!"
+#define HUSTR_CHATMACRO8	"I'll take care of it."
+#define HUSTR_CHATMACRO9	"Yes"
+#define HUSTR_CHATMACRO0	"No"
+
+#define HUSTR_TALKTOSELF1	"You mumble to yourself"
+#define HUSTR_TALKTOSELF2	"Who's there?"
+#define HUSTR_TALKTOSELF3	"You scare yourself"
+#define HUSTR_TALKTOSELF4	"You start to rave"
+#define HUSTR_TALKTOSELF5	"You've lost it..."
+
+#define HUSTR_MESSAGESENT	"[Message Sent]"
+
+// The following should NOT be changed unless it seems
+// just AWFULLY necessary
+
+#define HUSTR_PLRGREEN	"Green: "
+#define HUSTR_PLRINDIGO	"Indigo: "
+#define HUSTR_PLRBROWN	"Brown: "
+#define HUSTR_PLRRED		"Red: "
+
+#define HUSTR_KEYGREEN	'g'
+#define HUSTR_KEYINDIGO	'i'
+#define HUSTR_KEYBROWN	'b'
+#define HUSTR_KEYRED	'r'
+
+//
+//	AM_map.C
+//
+
+#define AMSTR_FOLLOWON	"Follow Mode ON"
+#define AMSTR_FOLLOWOFF	"Follow Mode OFF"
+
+#define AMSTR_GRIDON	"Grid ON"
+#define AMSTR_GRIDOFF	"Grid OFF"
+
+#define AMSTR_MARKEDSPOT	"Marked Spot"
+#define AMSTR_MARKSCLEARED	"All Marks Cleared"
+
+//
+//	ST_stuff.C
+//
+
+#define STSTR_MUS		"Music Change"
+#define STSTR_NOMUS		"IMPOSSIBLE SELECTION"
+#define STSTR_DQDON		"Degreelessness Mode On"
+#define STSTR_DQDOFF	"Degreelessness Mode Off"
+
+#define STSTR_KFAADDED	"Very Happy Ammo Added"
+#define STSTR_FAADDED	"Ammo (no keys) Added"
+
+#define STSTR_NCON		"No Clipping Mode ON"
+#define STSTR_NCOFF		"No Clipping Mode OFF"
+
+#define STSTR_BEHOLD	"inVuln, Str, Inviso, Rad, Allmap, or Lite-amp"
+#define STSTR_BEHOLDX	"Power-up Toggled"
+
+#define STSTR_CHOPPERS	"... doesn't suck - GM"
+#define STSTR_CLEV		"Changing Level..."
+
+//
+//	F_Finale.C
+//
+#define E1TEXT \
+"Once you beat the big badasses and\n"\
+"clean out the moon base you're supposed\n"\
+"to win, aren't you? Aren't you? Where's\n"\
+"your fat reward and ticket home? What\n"\
+"the hell is this? It's not supposed to\n"\
+"end this way!\n"\
+"\n" \
+"It stinks like rotten meat, but looks\n"\
+"like the lost Deimos base.  Looks like\n"\
+"you're stuck on The Shores of Hell.\n"\
+"The only way out is through.\n"\
+"\n"\
+"To continue the DOOM experience, play\n"\
+"The Shores of Hell and its amazing\n"\
+"sequel, Inferno!\n"
+
+
+#define E2TEXT \
+"You've done it! The hideous cyber-\n"\
+"demon lord that ruled the lost Deimos\n"\
+"moon base has been slain and you\n"\
+"are triumphant! But ... where are\n"\
+"you? You clamber to the edge of the\n"\
+"moon and look down to see the awful\n"\
+"truth.\n" \
+"\n"\
+"Deimos floats above Hell itself!\n"\
+"You've never heard of anyone escaping\n"\
+"from Hell, but you'll make the bastards\n"\
+"sorry they ever heard of you! Quickly,\n"\
+"you rappel down to  the surface of\n"\
+"Hell.\n"\
+"\n" \
+"Now, it's on to the final chapter of\n"\
+"DOOM! -- Inferno."
+
+
+#define E3TEXT \
+"The loathsome spiderdemon that\n"\
+"masterminded the invasion of the moon\n"\
+"bases and caused so much death has had\n"\
+"its ass kicked for all time.\n"\
+"\n"\
+"A hidden doorway opens and you enter.\n"\
+"You've proven too tough for Hell to\n"\
+"contain, and now Hell at last plays\n"\
+"fair -- for you emerge from the door\n"\
+"to see the green fields of Earth!\n"\
+"Home at last.\n" \
+"\n"\
+"You wonder what's been happening on\n"\
+"Earth while you were battling evil\n"\
+"unleashed. It's good that no Hell-\n"\
+"spawn could have come through that\n"\
+"door with you ..."
+
+
+#define E4TEXT \
+"the spider mastermind must have sent forth\n"\
+"its legions of hellspawn before your\n"\
+"final confrontation with that terrible\n"\
+"beast from hell.  but you stepped forward\n"\
+"and brought forth eternal damnation and\n"\
+"suffering upon the horde as a true hero\n"\
+"would in the face of something so evil.\n"\
+"\n"\
+"besides, someone was gonna pay for what\n"\
+"happened to daisy, your pet rabbit.\n"\
+"\n"\
+"but now, you see spread before you more\n"\
+"potential pain and gibbitude as a nation\n"\
+"of demons run amok among our cities.\n"\
+"\n"\
+"next stop, hell on earth!"
+
+
+// after level 6, put this:
+
+#define C1TEXT \
+"YOU HAVE ENTERED DEEPLY INTO THE INFESTED\n" \
+"STARPORT. BUT SOMETHING IS WRONG. THE\n" \
+"MONSTERS HAVE BROUGHT THEIR OWN REALITY\n" \
+"WITH THEM, AND THE STARPORT'S TECHNOLOGY\n" \
+"IS BEING SUBVERTED BY THEIR PRESENCE.\n" \
+"\n"\
+"AHEAD, YOU SEE AN OUTPOST OF HELL, A\n" \
+"FORTIFIED ZONE. IF YOU CAN GET PAST IT,\n" \
+"YOU CAN PENETRATE INTO THE HAUNTED HEART\n" \
+"OF THE STARBASE AND FIND THE CONTROLLING\n" \
+"SWITCH WHICH HOLDS EARTH'S POPULATION\n" \
+"HOSTAGE."
+
+// After level 11, put this:
+
+#define C2TEXT \
+"YOU HAVE WON! YOUR VICTORY HAS ENABLED\n" \
+"HUMANKIND TO EVACUATE EARTH AND ESCAPE\n"\
+"THE NIGHTMARE.  NOW YOU ARE THE ONLY\n"\
+"HUMAN LEFT ON THE FACE OF THE PLANET.\n"\
+"CANNIBAL MUTATIONS, CARNIVOROUS ALIENS,\n"\
+"AND EVIL SPIRITS ARE YOUR ONLY NEIGHBORS.\n"\
+"YOU SIT BACK AND WAIT FOR DEATH, CONTENT\n"\
+"THAT YOU HAVE SAVED YOUR SPECIES.\n"\
+"\n"\
+"BUT THEN, EARTH CONTROL BEAMS DOWN A\n"\
+"MESSAGE FROM SPACE: \"SENSORS HAVE LOCATED\n"\
+"THE SOURCE OF THE ALIEN INVASION. IF YOU\n"\
+"GO THERE, YOU MAY BE ABLE TO BLOCK THEIR\n"\
+"ENTRY.  THE ALIEN BASE IS IN THE HEART OF\n"\
+"YOUR OWN HOME CITY, NOT FAR FROM THE\n"\
+"STARPORT.\" SLOWLY AND PAINFULLY YOU GET\n"\
+"UP AND RETURN TO THE FRAY."
+
+
+// After level 20, put this:
+
+#define C3TEXT \
+"YOU ARE AT THE CORRUPT HEART OF THE CITY,\n"\
+"SURROUNDED BY THE CORPSES OF YOUR ENEMIES.\n"\
+"YOU SEE NO WAY TO DESTROY THE CREATURES'\n"\
+"ENTRYWAY ON THIS SIDE, SO YOU CLENCH YOUR\n"\
+"TEETH AND PLUNGE THROUGH IT.\n"\
+"\n"\
+"THERE MUST BE A WAY TO CLOSE IT ON THE\n"\
+"OTHER SIDE. WHAT DO YOU CARE IF YOU'VE\n"\
+"GOT TO GO THROUGH HELL TO GET TO IT?"
+
+
+// After level 29, put this:
+
+#define C4TEXT \
+"THE HORRENDOUS VISAGE OF THE BIGGEST\n"\
+"DEMON YOU'VE EVER SEEN CRUMBLES BEFORE\n"\
+"YOU, AFTER YOU PUMP YOUR ROCKETS INTO\n"\
+"HIS EXPOSED BRAIN. THE MONSTER SHRIVELS\n"\
+"UP AND DIES, ITS THRASHING LIMBS\n"\
+"DEVASTATING UNTOLD MILES OF HELL'S\n"\
+"SURFACE.\n"\
+"\n"\
+"YOU'VE DONE IT. THE INVASION IS OVER.\n"\
+"EARTH IS SAVED. HELL IS A WRECK. YOU\n"\
+"WONDER WHERE BAD FOLKS WILL GO WHEN THEY\n"\
+"DIE, NOW. WIPING THE SWEAT FROM YOUR\n"\
+"FOREHEAD YOU BEGIN THE LONG TREK BACK\n"\
+"HOME. REBUILDING EARTH OUGHT TO BE A\n"\
+"LOT MORE FUN THAN RUINING IT WAS.\n"
+
+
+
+// Before level 31, put this:
+
+#define C5TEXT \
+"CONGRATULATIONS, YOU'VE FOUND THE SECRET\n"\
+"LEVEL! LOOKS LIKE IT'S BEEN BUILT BY\n"\
+"HUMANS, RATHER THAN DEMONS. YOU WONDER\n"\
+"WHO THE INMATES OF THIS CORNER OF HELL\n"\
+"WILL BE."
+
+
+// Before level 32, put this:
+
+#define C6TEXT \
+"CONGRATULATIONS, YOU'VE FOUND THE\n"\
+"SUPER SECRET LEVEL!  YOU'D BETTER\n"\
+"BLAZE THROUGH THIS ONE!\n"
+
+
+// after map 06	
+
+#define P1TEXT  \
+"You gloat over the steaming carcass of the\n"\
+"Guardian.  With its death, you've wrested\n"\
+"the Accelerator from the stinking claws\n"\
+"of Hell.  You relax and glance around the\n"\
+"room.  Damn!  There was supposed to be at\n"\
+"least one working prototype, but you can't\n"\
+"see it. The demons must have taken it.\n"\
+"\n"\
+"You must find the prototype, or all your\n"\
+"struggles will have been wasted. Keep\n"\
+"moving, keep fighting, keep killing.\n"\
+"Oh yes, keep living, too."
+
+
+// after map 11
+
+#define P2TEXT \
+"Even the deadly Arch-Vile labyrinth could\n"\
+"not stop you, and you've gotten to the\n"\
+"prototype Accelerator which is soon\n"\
+"efficiently and permanently deactivated.\n"\
+"\n"\
+"You're good at that kind of thing."
+
+
+// after map 20
+
+#define P3TEXT \
+"You've bashed and battered your way into\n"\
+"the heart of the devil-hive.  Time for a\n"\
+"Search-and-Destroy mission, aimed at the\n"\
+"Gatekeeper, whose foul offspring is\n"\
+"cascading to Earth.  Yeah, he's bad. But\n"\
+"you know who's worse!\n"\
+"\n"\
+"Grinning evilly, you check your gear, and\n"\
+"get ready to give the bastard a little Hell\n"\
+"of your own making!"
+
+// after map 30
+
+#define P4TEXT \
+"The Gatekeeper's evil face is splattered\n"\
+"all over the place.  As its tattered corpse\n"\
+"collapses, an inverted Gate forms and\n"\
+"sucks down the shards of the last\n"\
+"prototype Accelerator, not to mention the\n"\
+"few remaining demons.  You're done. Hell\n"\
+"has gone back to pounding bad dead folks \n"\
+"instead of good live ones.  Remember to\n"\
+"tell your grandkids to put a rocket\n"\
+"launcher in your coffin. If you go to Hell\n"\
+"when you die, you'll need it for some\n"\
+"final cleaning-up ..."
+
+// before map 31
+
+#define P5TEXT \
+"You've found the second-hardest level we\n"\
+"got. Hope you have a saved game a level or\n"\
+"two previous.  If not, be prepared to die\n"\
+"aplenty. For master marines only."
+
+// before map 32
+
+#define P6TEXT \
+"Betcha wondered just what WAS the hardest\n"\
+"level we had ready for ya?  Now you know.\n"\
+"No one gets out alive."
+
+
+#define T1TEXT \
+"You've fought your way out of the infested\n"\
+"experimental labs.   It seems that UAC has\n"\
+"once again gulped it down.  With their\n"\
+"high turnover, it must be hard for poor\n"\
+"old UAC to buy corporate health insurance\n"\
+"nowadays..\n"\
+"\n"\
+"Ahead lies the military complex, now\n"\
+"swarming with diseased horrors hot to get\n"\
+"their teeth into you. With luck, the\n"\
+"complex still has some warlike ordnance\n"\
+"laying around."
+
+
+#define T2TEXT \
+"You hear the grinding of heavy machinery\n"\
+"ahead.  You sure hope they're not stamping\n"\
+"out new hellspawn, but you're ready to\n"\
+"ream out a whole herd if you have to.\n"\
+"They might be planning a blood feast, but\n"\
+"you feel about as mean as two thousand\n"\
+"maniacs packed into one mad killer.\n"\
+"\n"\
+"You don't plan to go down easy."
+
+
+#define T3TEXT \
+"The vista opening ahead looks real damn\n"\
+"familiar. Smells familiar, too -- like\n"\
+"fried excrement. You didn't like this\n"\
+"place before, and you sure as hell ain't\n"\
+"planning to like it now. The more you\n"\
+"brood on it, the madder you get.\n"\
+"Hefting your gun, an evil grin trickles\n"\
+"onto your face. Time to take some names."
+
+#define T4TEXT \
+"Suddenly, all is silent, from one horizon\n"\
+"to the other. The agonizing echo of Hell\n"\
+"fades away, the nightmare sky turns to\n"\
+"blue, the heaps of monster corpses start \n"\
+"to evaporate along with the evil stench \n"\
+"that filled the air. Jeeze, maybe you've\n"\
+"done it. Have you really won?\n"\
+"\n"\
+"Something rumbles in the distance.\n"\
+"A blue light begins to glow inside the\n"\
+"ruined skull of the demon-spitter."
+
+
+#define T5TEXT \
+"What now? Looks totally different. Kind\n"\
+"of like King Tut's condo. Well,\n"\
+"whatever's here can't be any worse\n"\
+"than usual. Can it?  Or maybe it's best\n"\
+"to let sleeping gods lie.."
+
+
+#define T6TEXT \
+"Time for a vacation. You've burst the\n"\
+"bowels of hell and by golly you're ready\n"\
+"for a break. You mutter to yourself,\n"\
+"Maybe someone else can kick Hell's ass\n"\
+"next time around. Ahead lies a quiet town,\n"\
+"with peaceful flowing water, quaint\n"\
+"buildings, and presumably no Hellspawn.\n"\
+"\n"\
+"As you step off the transport, you hear\n"\
+"the stomp of a cyberdemon's iron shoe."
+
+
+
+//
+// Character cast strings F_FINALE.C
+//
+#define CC_ZOMBIE	"ZOMBIEMAN"
+#define CC_SHOTGUN	"SHOTGUN GUY"
+#define CC_HEAVY	"HEAVY WEAPON DUDE"
+#define CC_IMP	"IMP"
+#define CC_DEMON	"DEMON"
+#define CC_LOST	"LOST SOUL"
+#define CC_CACO	"CACODEMON"
+#define CC_HELL	"HELL KNIGHT"
+#define CC_BARON	"BARON OF HELL"
+#define CC_ARACH	"ARACHNOTRON"
+#define CC_PAIN	"PAIN ELEMENTAL"
+#define CC_REVEN	"REVENANT"
+#define CC_MANCU	"MANCUBUS"
+#define CC_ARCH	"ARCH-VILE"
+#define CC_SPIDER	"THE SPIDER MASTERMIND"
+#define CC_CYBER	"THE CYBERDEMON"
+#define CC_HERO	"OUR HERO"
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:01  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/d_event.h
@@ -1,0 +1,125 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: d_event.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//
+//    
+//-----------------------------------------------------------------------------
+
+
+#ifndef __D_EVENT__
+#define __D_EVENT__
+
+
+#include "doomtype.h"
+
+
+//
+// Event handling.
+//
+
+// Input event types.
+typedef enum
+{
+    ev_keydown,
+    ev_keyup,
+    ev_mouse,
+    ev_joystick
+} evtype_t;
+
+// Event structure.
+typedef struct
+{
+    evtype_t	type;
+    int		data1;		// keys / mouse/joystick buttons
+    int		data2;		// mouse/joystick x move
+    int		data3;		// mouse/joystick y move
+} event_t;
+
+ 
+typedef enum
+{
+    ga_nothing,
+    ga_loadlevel,
+    ga_newgame,
+    ga_loadgame,
+    ga_savegame,
+    ga_playdemo,
+    ga_completed,
+    ga_victory,
+    ga_worlddone,
+    ga_screenshot
+} gameaction_t;
+
+
+
+//
+// Button/action code definitions.
+//
+typedef enum
+{
+    // Press "Fire".
+    BT_ATTACK		= 1,
+    // Use button, to open doors, activate switches.
+    BT_USE		= 2,
+
+    // Flag: game events, not really buttons.
+    BT_SPECIAL		= 128,
+    BT_SPECIALMASK	= 3,
+    
+    // Flag, weapon change pending.
+    // If true, the next 3 bits hold weapon num.
+    BT_CHANGE		= 4,
+    // The 3bit weapon mask and shift, convenience.
+    BT_WEAPONMASK	= (8+16+32),
+    BT_WEAPONSHIFT	= 3,
+
+    // Pause the game.
+    BTS_PAUSE		= 1,
+    // Save the game at each console.
+    BTS_SAVEGAME	= 2,
+
+    // Savegame slot numbers
+    //  occupy the second byte of buttons.    
+    BTS_SAVEMASK	= (4+8+16),
+    BTS_SAVESHIFT 	= 2,
+  
+} buttoncode_t;
+
+
+
+
+//
+// GLOBAL VARIABLES
+//
+#define MAXEVENTS		64
+
+extern  event_t		events[MAXEVENTS];
+extern  int             eventhead;
+extern	int		eventtail;
+
+extern  gameaction_t    gameaction;
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:19:44  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/d_french.h
@@ -1,0 +1,436 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: d_french.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//	Printed strings, french translation.
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __D_FRENCH__
+#define __D_FRENCH__
+
+//
+// D_Main.C
+//
+#define D_DEVSTR	"MODE DEVELOPPEMENT ON.\n"
+#define D_CDROM		"VERSION CD-ROM: DEFAULT.CFG DANS C:\\DOOMDATA\n"
+
+//
+//	M_Menu.C
+//
+#define PRESSKEY 	"APPUYEZ SUR UNE TOUCHE."
+#define PRESSYN 	"APPUYEZ SUR Y OU N"
+#define QUITMSG		"VOUS VOULEZ VRAIMENT\nQUITTER CE SUPER JEU?"
+#define LOADNET 	"VOUS NE POUVEZ PAS CHARGER\nUN JEU EN RESEAU!\n\n"PRESSKEY
+#define QLOADNET	"CHARGEMENT RAPIDE INTERDIT EN RESEAU!\n\n"PRESSKEY
+#define QSAVESPOT	"VOUS N'AVEZ PAS CHOISI UN EMPLACEMENT!\n\n"PRESSKEY
+#define SAVEDEAD 	"VOUS NE POUVEZ PAS SAUVER SI VOUS NE JOUEZ "\
+"PAS!\n\n"PRESSKEY
+#define QSPROMPT 	"SAUVEGARDE RAPIDE DANS LE FICHIER \n\n'%s'?\n\n"PRESSYN
+#define QLPROMPT	"VOULEZ-VOUS CHARGER LA SAUVEGARDE"\
+"\n\n'%s'?\n\n"PRESSYN
+#define NEWGAME		"VOUS NE POUVEZ PAS LANCER\n"\
+"UN NOUVEAU JEU SUR RESEAU.\n\n"PRESSKEY
+#define NIGHTMARE	"VOUS CONFIRMEZ? CE NIVEAU EST\n"\
+"VRAIMENT IMPITOYABLE!n"PRESSYN
+#define SWSTRING	"CECI EST UNE VERSION SHAREWARE DE DOOM.\n\n"\
+"VOUS DEVRIEZ COMMANDER LA TRILOGIE COMPLETE.\n\n"PRESSKEY
+#define MSGOFF		"MESSAGES OFF"
+#define MSGON		"MESSAGES ON"
+#define NETEND		"VOUS NE POUVEZ PAS METTRE FIN A UN JEU SUR "\
+"RESEAU!\n\n"PRESSKEY
+#define ENDGAME		"VOUS VOULEZ VRAIMENT METTRE FIN AU JEU?\n\n"PRESSYN
+
+#define DOSY		"(APPUYEZ SUR Y POUR REVENIR AU OS.)"
+
+#define DETAILHI	"GRAPHISMES MAXIMUM "
+#define DETAILLO	"GRAPHISMES MINIMUM "
+#define GAMMALVL0	"CORRECTION GAMMA OFF"
+#define GAMMALVL1	"CORRECTION GAMMA NIVEAU 1"
+#define GAMMALVL2	"CORRECTION GAMMA NIVEAU 2"
+#define GAMMALVL3	"CORRECTION GAMMA NIVEAU 3"
+#define GAMMALVL4	"CORRECTION GAMMA NIVEAU 4"
+#define EMPTYSTRING	"EMPLACEMENT VIDE"
+
+//
+//	P_inter.C
+//
+#define GOTARMOR	"ARMURE RECUPEREE."
+#define GOTMEGA		"MEGA-ARMURE RECUPEREE!"
+#define GOTHTHBONUS	"BONUS DE SANTE RECUPERE."
+#define GOTARMBONUS	"BONUS D'ARMURE RECUPERE."
+#define GOTSTIM		"STIMPACK RECUPERE."
+#define GOTMEDINEED	"MEDIKIT RECUPERE. VOUS EN AVEZ VRAIMENT BESOIN!"
+#define GOTMEDIKIT	"MEDIKIT RECUPERE."
+#define GOTSUPER	"SUPERCHARGE!"
+
+#define GOTBLUECARD	"CARTE MAGNETIQUE BLEUE RECUPEREE."
+#define GOTYELWCARD	"CARTE MAGNETIQUE JAUNE RECUPEREE."
+#define GOTREDCARD	"CARTE MAGNETIQUE ROUGE RECUPEREE."
+#define GOTBLUESKUL	"CLEF CRANE BLEUE RECUPEREE."
+#define GOTYELWSKUL	"CLEF CRANE JAUNE RECUPEREE."
+#define GOTREDSKULL	"CLEF CRANE ROUGE RECUPEREE."
+
+#define GOTINVUL	"INVULNERABILITE!"
+#define GOTBERSERK	"BERSERK!"
+#define GOTINVIS	"INVISIBILITE PARTIELLE "
+#define GOTSUIT		"COMBINAISON ANTI-RADIATIONS "
+#define GOTMAP		"CARTE INFORMATIQUE "
+#define GOTVISOR	"VISEUR A AMPLIFICATION DE LUMIERE "
+#define GOTMSPHERE	"MEGASPHERE!"
+
+#define GOTCLIP		"CHARGEUR RECUPERE."
+#define GOTCLIPBOX	"BOITE DE BALLES RECUPEREE."
+#define GOTROCKET	"ROQUETTE RECUPEREE."
+#define GOTROCKBOX	"CAISSE DE ROQUETTES RECUPEREE."
+#define GOTCELL		"CELLULE D'ENERGIE RECUPEREE."
+#define GOTCELLBOX	"PACK DE CELLULES D'ENERGIE RECUPERE."
+#define GOTSHELLS	"4 CARTOUCHES RECUPEREES."
+#define GOTSHELLBOX	"BOITE DE CARTOUCHES RECUPEREE."
+#define GOTBACKPACK	"SAC PLEIN DE MUNITIONS RECUPERE!"
+
+#define GOTBFG9000	"VOUS AVEZ UN BFG9000!  OH, OUI!"
+#define GOTCHAINGUN	"VOUS AVEZ LA MITRAILLEUSE!"
+#define GOTCHAINSAW	"UNE TRONCONNEUSE!"
+#define GOTLAUNCHER	"VOUS AVEZ UN LANCE-ROQUETTES!"
+#define GOTPLASMA	"VOUS AVEZ UN FUSIL A PLASMA!"
+#define GOTSHOTGUN	"VOUS AVEZ UN FUSIL!"
+#define GOTSHOTGUN2	"VOUS AVEZ UN SUPER FUSIL!"
+
+//
+// P_Doors.C
+//
+#define PD_BLUEO	"IL VOUS FAUT UNE CLEF BLEUE"
+#define PD_REDO		"IL VOUS FAUT UNE CLEF ROUGE"
+#define PD_YELLOWO	"IL VOUS FAUT UNE CLEF JAUNE"
+#define PD_BLUEK	PD_BLUEO
+#define PD_REDK		PD_REDO
+#define PD_YELLOWK	PD_YELLOWO
+
+//
+//	G_game.C
+//
+#define GGSAVED		"JEU SAUVEGARDE."
+
+//
+//	HU_stuff.C
+//
+#define HUSTR_MSGU	"[MESSAGE NON ENVOYE]"
+
+#define HUSTR_E1M1	"E1M1: HANGAR"
+#define HUSTR_E1M2	"E1M2: USINE NUCLEAIRE "
+#define HUSTR_E1M3	"E1M3: RAFFINERIE DE TOXINES "
+#define HUSTR_E1M4	"E1M4: CENTRE DE CONTROLE "
+#define HUSTR_E1M5	"E1M5: LABORATOIRE PHOBOS "
+#define HUSTR_E1M6	"E1M6: TRAITEMENT CENTRAL "
+#define HUSTR_E1M7	"E1M7: CENTRE INFORMATIQUE "
+#define HUSTR_E1M8	"E1M8: ANOMALIE PHOBOS "
+#define HUSTR_E1M9	"E1M9: BASE MILITAIRE "
+
+#define HUSTR_E2M1	"E2M1: ANOMALIE DEIMOS "
+#define HUSTR_E2M2	"E2M2: ZONE DE CONFINEMENT "
+#define HUSTR_E2M3	"E2M3: RAFFINERIE"
+#define HUSTR_E2M4	"E2M4: LABORATOIRE DEIMOS "
+#define HUSTR_E2M5	"E2M5: CENTRE DE CONTROLE "
+#define HUSTR_E2M6	"E2M6: HALLS DES DAMNES "
+#define HUSTR_E2M7	"E2M7: CUVES DE REPRODUCTION "
+#define HUSTR_E2M8	"E2M8: TOUR DE BABEL "
+#define HUSTR_E2M9	"E2M9: FORTERESSE DU MYSTERE "
+
+#define HUSTR_E3M1	"E3M1: DONJON DE L'ENFER "
+#define HUSTR_E3M2	"E3M2: BOURBIER DU DESESPOIR "
+#define HUSTR_E3M3	"E3M3: PANDEMONIUM"
+#define HUSTR_E3M4	"E3M4: MAISON DE LA DOULEUR "
+#define HUSTR_E3M5	"E3M5: CATHEDRALE PROFANE "
+#define HUSTR_E3M6	"E3M6: MONT EREBUS"
+#define HUSTR_E3M7	"E3M7: LIMBES"
+#define HUSTR_E3M8	"E3M8: DIS"
+#define HUSTR_E3M9	"E3M9: CLAPIERS"
+
+#define HUSTR_1		"NIVEAU 1: ENTREE "
+#define HUSTR_2		"NIVEAU 2: HALLS SOUTERRAINS "
+#define HUSTR_3		"NIVEAU 3: LE FEU NOURRI "
+#define HUSTR_4		"NIVEAU 4: LE FOYER "
+#define HUSTR_5		"NIVEAU 5: LES EGOUTS "
+#define HUSTR_6		"NIVEAU 6: LE BROYEUR "
+#define HUSTR_7		"NIVEAU 7: L'HERBE DE LA MORT"
+#define HUSTR_8		"NIVEAU 8: RUSES ET PIEGES "
+#define HUSTR_9		"NIVEAU 9: LE PUITS "
+#define HUSTR_10	"NIVEAU 10: BASE DE RAVITAILLEMENT "
+#define HUSTR_11	"NIVEAU 11: LE CERCLE DE LA MORT!"
+
+#define HUSTR_12	"NIVEAU 12: L'USINE "
+#define HUSTR_13	"NIVEAU 13: LE CENTRE VILLE"
+#define HUSTR_14	"NIVEAU 14: LES ANTRES PROFONDES "
+#define HUSTR_15	"NIVEAU 15: LA ZONE INDUSTRIELLE "
+#define HUSTR_16	"NIVEAU 16: LA BANLIEUE"
+#define HUSTR_17	"NIVEAU 17: LES IMMEUBLES"
+#define HUSTR_18	"NIVEAU 18: LA COUR "
+#define HUSTR_19	"NIVEAU 19: LA CITADELLE "
+#define HUSTR_20	"NIVEAU 20: JE T'AI EU!"
+
+#define HUSTR_21	"NIVEAU 21: LE NIRVANA"
+#define HUSTR_22	"NIVEAU 22: LES CATACOMBES "
+#define HUSTR_23	"NIVEAU 23: LA GRANDE FETE "
+#define HUSTR_24	"NIVEAU 24: LE GOUFFRE "
+#define HUSTR_25	"NIVEAU 25: LES CHUTES DE SANG"
+#define HUSTR_26	"NIVEAU 26: LES MINES ABANDONNEES "
+#define HUSTR_27	"NIVEAU 27: CHEZ LES MONSTRES "
+#define HUSTR_28	"NIVEAU 28: LE MONDE DE L'ESPRIT "
+#define HUSTR_29	"NIVEAU 29: LA LIMITE "
+#define HUSTR_30	"NIVEAU 30: L'ICONE DU PECHE "
+
+#define HUSTR_31	"NIVEAU 31: WOLFENSTEIN"
+#define HUSTR_32	"NIVEAU 32: LE MASSACRE"
+
+
+#define HUSTR_CHATMACRO1	"JE SUIS PRET A LEUR EN FAIRE BAVER!"
+#define HUSTR_CHATMACRO2	"JE VAIS BIEN."
+#define HUSTR_CHATMACRO3	"JE N'AI PAS L'AIR EN FORME!"
+#define HUSTR_CHATMACRO4	"AU SECOURS!"
+#define HUSTR_CHATMACRO5	"TU CRAINS!"
+#define HUSTR_CHATMACRO6	"LA PROCHAINE FOIS, MINABLE..."
+#define HUSTR_CHATMACRO7	"VIENS ICI!"
+#define HUSTR_CHATMACRO8	"JE VAIS M'EN OCCUPER."
+#define HUSTR_CHATMACRO9	"OUI"
+#define HUSTR_CHATMACRO0	"NON"
+
+#define HUSTR_TALKTOSELF1	"VOUS PARLEZ TOUT SEUL "
+#define HUSTR_TALKTOSELF2	"QUI EST LA?"
+#define HUSTR_TALKTOSELF3	"VOUS VOUS FAITES PEUR "
+#define HUSTR_TALKTOSELF4	"VOUS COMMENCEZ A DELIRER "
+#define HUSTR_TALKTOSELF5	"VOUS ETES LARGUE..."
+
+#define HUSTR_MESSAGESENT	"[MESSAGE ENVOYE]"
+
+// The following should NOT be changed unless it seems
+// just AWFULLY necessary
+
+#define HUSTR_PLRGREEN	"VERT: "
+#define HUSTR_PLRINDIGO	"INDIGO: "
+#define HUSTR_PLRBROWN	"BRUN: "
+#define HUSTR_PLRRED		"ROUGE: "
+
+#define HUSTR_KEYGREEN	'g'	// french key should be "V"
+#define HUSTR_KEYINDIGO	'i'	
+#define HUSTR_KEYBROWN	'b'	
+#define HUSTR_KEYRED		'r'
+
+//
+//	AM_map.C
+//
+
+#define AMSTR_FOLLOWON		"MODE POURSUITE ON"
+#define AMSTR_FOLLOWOFF		"MODE POURSUITE OFF"
+
+#define AMSTR_GRIDON		"GRILLE ON"
+#define AMSTR_GRIDOFF		"GRILLE OFF"
+
+#define AMSTR_MARKEDSPOT	"REPERE MARQUE "
+#define AMSTR_MARKSCLEARED	"REPERES EFFACES "
+
+//
+//	ST_stuff.C
+//
+
+#define STSTR_MUS		"CHANGEMENT DE MUSIQUE "
+#define STSTR_NOMUS		"IMPOSSIBLE SELECTION"
+#define STSTR_DQDON		"INVULNERABILITE ON "
+#define STSTR_DQDOFF		"INVULNERABILITE OFF"
+
+#define STSTR_KFAADDED		"ARMEMENT MAXIMUM! "
+#define STSTR_FAADDED		"ARMES (SAUF CLEFS) AJOUTEES"
+
+#define STSTR_NCON		"BARRIERES ON"
+#define STSTR_NCOFF		"BARRIERES OFF"
+
+#define STSTR_BEHOLD		" inVuln, Str, Inviso, Rad, Allmap, or Lite-amp"
+#define STSTR_BEHOLDX		"AMELIORATION ACTIVEE"
+
+#define STSTR_CHOPPERS		"... DOESN'T SUCK - GM"
+#define STSTR_CLEV		"CHANGEMENT DE NIVEAU..."
+
+//
+//	F_Finale.C
+//
+#define E1TEXT	"APRES AVOIR VAINCU LES GROS MECHANTS\n"\
+"ET NETTOYE LA BASE LUNAIRE, VOUS AVEZ\n"\
+"GAGNE, NON? PAS VRAI? OU EST DONC VOTRE\n"\
+" RECOMPENSE ET VOTRE BILLET DE\n"\
+"RETOUR? QU'EST-QUE CA VEUT DIRE?CE"\
+"N'EST PAS LA FIN ESPEREE!\n"\
+"\n" \
+"CA SENT LA VIANDE PUTREFIEE, MAIS\n"\
+"ON DIRAIT LA BASE DEIMOS. VOUS ETES\n"\
+"APPAREMMENT BLOQUE AUX PORTES DE L'ENFER.\n"\
+"LA SEULE ISSUE EST DE L'AUTRE COTE.\n"\
+"\n"\
+"POUR VIVRE LA SUITE DE DOOM, JOUEZ\n"\
+"A 'AUX PORTES DE L'ENFER' ET A\n"\
+"L'EPISODE SUIVANT, 'L'ENFER'!\n"
+				
+#define E2TEXT	"VOUS AVEZ REUSSI. L'INFAME DEMON\n"\
+"QUI CONTROLAIT LA BASE LUNAIRE DE\n"\
+"DEIMOS EST MORT, ET VOUS AVEZ\n"\
+"TRIOMPHE! MAIS... OU ETES-VOUS?\n"\
+"VOUS GRIMPEZ JUSQU'AU BORD DE LA\n"\
+"LUNE ET VOUS DECOUVREZ L'ATROCE\n"\
+"VERITE.\n" \
+"\n"\
+"DEIMOS EST AU-DESSUS DE L'ENFER!\n"\
+"VOUS SAVEZ QUE PERSONNE NE S'EN\n"\
+"EST JAMAIS ECHAPPE, MAIS CES FUMIERS\n"\
+"VONT REGRETTER DE VOUS AVOIR CONNU!\n"\
+"VOUS REDESCENDEZ RAPIDEMENT VERS\n"\
+"LA SURFACE DE L'ENFER.\n"\
+"\n" \
+"VOICI MAINTENANT LE CHAPITRE FINAL DE\n"\
+"DOOM! -- L'ENFER."
+
+#define E3TEXT	"LE DEMON ARACHNEEN ET REPUGNANT\n"\
+"QUI A DIRIGE L'INVASION DES BASES\n"\
+"LUNAIRES ET SEME LA MORT VIENT DE SE\n"\
+"FAIRE PULVERISER UNE FOIS POUR TOUTES.\n"\
+"\n"\
+"UNE PORTE SECRETE S'OUVRE. VOUS ENTREZ.\n"\
+"VOUS AVEZ PROUVE QUE VOUS POUVIEZ\n"\
+"RESISTER AUX HORREURS DE L'ENFER.\n"\
+"IL SAIT ETRE BEAU JOUEUR, ET LORSQUE\n"\
+"VOUS SORTEZ, VOUS REVOYEZ LES VERTES\n"\
+"PRAIRIES DE LA TERRE, VOTRE PLANETE.\n"\
+"\n"\
+"VOUS VOUS DEMANDEZ CE QUI S'EST PASSE\n"\
+"SUR TERRE PENDANT QUE VOUS AVEZ\n"\
+"COMBATTU LE DEMON. HEUREUSEMENT,\n"\
+"AUCUN GERME DU MAL N'A FRANCHI\n"\
+"CETTE PORTE AVEC VOUS..."
+
+
+
+// after level 6, put this:
+
+#define C1TEXT	"VOUS ETES AU PLUS PROFOND DE L'ASTROPORT\n" \
+"INFESTE DE MONSTRES, MAIS QUELQUE CHOSE\n" \
+"NE VA PAS. ILS ONT APPORTE LEUR PROPRE\n" \
+"REALITE, ET LA TECHNOLOGIE DE L'ASTROPORT\n" \
+"EST AFFECTEE PAR LEUR PRESENCE.\n" \
+"\n"\
+"DEVANT VOUS, VOUS VOYEZ UN POSTE AVANCE\n" \
+"DE L'ENFER, UNE ZONE FORTIFIEE. SI VOUS\n" \
+"POUVEZ PASSER, VOUS POURREZ PENETRER AU\n" \
+"COEUR DE LA BASE HANTEE ET TROUVER \n" \
+"L'INTERRUPTEUR DE CONTROLE QUI GARDE LA \n" \
+"POPULATION DE LA TERRE EN OTAGE."
+
+// After level 11, put this:
+
+#define C2TEXT	"VOUS AVEZ GAGNE! VOTRE VICTOIRE A PERMIS\n" \
+"A L'HUMANITE D'EVACUER LA TERRE ET \n"\
+"D'ECHAPPER AU CAUCHEMAR. VOUS ETES \n"\
+"MAINTENANT LE DERNIER HUMAIN A LA SURFACE \n"\
+"DE LA PLANETE. VOUS ETES ENTOURE DE \n"\
+"MUTANTS CANNIBALES, D'EXTRATERRESTRES \n"\
+"CARNIVORES ET D'ESPRITS DU MAL. VOUS \n"\
+"ATTENDEZ CALMEMENT LA MORT, HEUREUX \n"\
+"D'AVOIR PU SAUVER VOTRE RACE.\n"\
+"MAIS UN MESSAGE VOUS PARVIENT SOUDAIN\n"\
+"DE L'ESPACE: \"NOS CAPTEURS ONT LOCALISE\n"\
+"LA SOURCE DE L'INVASION EXTRATERRESTRE.\n"\
+"SI VOUS Y ALLEZ, VOUS POURREZ PEUT-ETRE\n"\
+"LES ARRETER. LEUR BASE EST SITUEE AU COEUR\n"\
+"DE VOTRE VILLE NATALE, PRES DE L'ASTROPORT.\n"\
+"VOUS VOUS RELEVEZ LENTEMENT ET PENIBLEMENT\n"\
+"ET VOUS REPARTEZ POUR LE FRONT."
+
+// After level 20, put this:
+
+#define C3TEXT	"VOUS ETES AU COEUR DE LA CITE CORROMPUE,\n"\
+"ENTOURE PAR LES CADAVRES DE VOS ENNEMIS.\n"\
+"VOUS NE VOYEZ PAS COMMENT DETRUIRE LA PORTE\n"\
+"DES CREATURES DE CE COTE. VOUS SERREZ\n"\
+"LES DENTS ET PLONGEZ DANS L'OUVERTURE.\n"\
+"\n"\
+"IL DOIT Y AVOIR UN MOYEN DE LA FERMER\n"\
+"DE L'AUTRE COTE. VOUS ACCEPTEZ DE\n"\
+"TRAVERSER L'ENFER POUR LE FAIRE?"
+
+// After level 29, put this:
+
+#define C4TEXT	"LE VISAGE HORRIBLE D'UN DEMON D'UNE\n"\
+"TAILLE INCROYABLE S'EFFONDRE DEVANT\n"\
+"VOUS LORSQUE VOUS TIREZ UNE SALVE DE\n"\
+"ROQUETTES DANS SON CERVEAU. LE MONSTRE\n"\
+"SE RATATINE, SES MEMBRES DECHIQUETES\n"\
+"SE REPANDANT SUR DES CENTAINES DE\n"\
+"KILOMETRES A LA SURFACE DE L'ENFER.\n"\
+"\n"\
+"VOUS AVEZ REUSSI. L'INVASION N'AURA.\n"\
+"PAS LIEU. LA TERRE EST SAUVEE. L'ENFER\n"\
+"EST ANEANTI. EN VOUS DEMANDANT OU IRONT\n"\
+"MAINTENANT LES DAMNES, VOUS ESSUYEZ\n"\
+"VOTRE FRONT COUVERT DE SUEUR ET REPARTEZ\n"\
+"VERS LA TERRE. SA RECONSTRUCTION SERA\n"\
+"BEAUCOUP PLUS DROLE QUE SA DESTRUCTION.\n"
+
+// Before level 31, put this:
+
+#define C5TEXT	"FELICITATIONS! VOUS AVEZ TROUVE LE\n"\
+"NIVEAU SECRET! IL SEMBLE AVOIR ETE\n"\
+"CONSTRUIT PAR LES HUMAINS. VOUS VOUS\n"\
+"DEMANDEZ QUELS PEUVENT ETRE LES\n"\
+"HABITANTS DE CE COIN PERDU DE L'ENFER."
+
+// Before level 32, put this:
+
+#define C6TEXT	"FELICITATIONS! VOUS AVEZ DECOUVERT\n"\
+"LE NIVEAU SUPER SECRET! VOUS FERIEZ\n"\
+"MIEUX DE FONCER DANS CELUI-LA!\n"
+
+//
+// Character cast strings F_FINALE.C
+//
+#define CC_ZOMBIE	"ZOMBIE"
+#define CC_SHOTGUN	"TYPE AU FUSIL"
+#define CC_HEAVY	"MEC SUPER-ARME"
+#define CC_IMP		"DIABLOTIN"
+#define CC_DEMON	"DEMON"
+#define CC_LOST		"AME PERDUE"
+#define CC_CACO		"CACODEMON"
+#define CC_HELL		"CHEVALIER DE L'ENFER"
+#define CC_BARON	"BARON DE L'ENFER"
+#define CC_ARACH	"ARACHNOTRON"
+#define CC_PAIN		"ELEMENTAIRE DE LA DOULEUR"
+#define CC_REVEN	"REVENANT"
+#define CC_MANCU	"MANCUBUS"
+#define CC_ARCH		"ARCHI-INFAME"
+#define CC_SPIDER	"L'ARAIGNEE CERVEAU"
+#define CC_CYBER	"LE CYBERDEMON"
+#define CC_HERO		"NOTRE HEROS"
+
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:04  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
+
+
--- /dev/null
+++ b/src/d_items.c
@@ -1,0 +1,141 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: d_items.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:28  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//
+//-----------------------------------------------------------------------------
+
+static const char
+rcsid[] = "$Id: d_items.c 4 2005-07-23 16:19:41Z fraggle $";
+
+// We are referring to sprite numbers.
+#include "info.h"
+
+#ifdef __GNUG__
+#pragma implementation "d_items.h"
+#endif
+#include "d_items.h"
+
+
+//
+// PSPRITE ACTIONS for waepons.
+// This struct controls the weapon animations.
+//
+// Each entry is:
+//   ammo/amunition type
+//  upstate
+//  downstate
+// readystate
+// atkstate, i.e. attack/fire/hit frame
+// flashstate, muzzle flash
+//
+weaponinfo_t	weaponinfo[NUMWEAPONS] =
+{
+    {
+	// fist
+	am_noammo,
+	S_PUNCHUP,
+	S_PUNCHDOWN,
+	S_PUNCH,
+	S_PUNCH1,
+	S_NULL
+    },	
+    {
+	// pistol
+	am_clip,
+	S_PISTOLUP,
+	S_PISTOLDOWN,
+	S_PISTOL,
+	S_PISTOL1,
+	S_PISTOLFLASH
+    },	
+    {
+	// shotgun
+	am_shell,
+	S_SGUNUP,
+	S_SGUNDOWN,
+	S_SGUN,
+	S_SGUN1,
+	S_SGUNFLASH1
+    },
+    {
+	// chaingun
+	am_clip,
+	S_CHAINUP,
+	S_CHAINDOWN,
+	S_CHAIN,
+	S_CHAIN1,
+	S_CHAINFLASH1
+    },
+    {
+	// missile launcher
+	am_misl,
+	S_MISSILEUP,
+	S_MISSILEDOWN,
+	S_MISSILE,
+	S_MISSILE1,
+	S_MISSILEFLASH1
+    },
+    {
+	// plasma rifle
+	am_cell,
+	S_PLASMAUP,
+	S_PLASMADOWN,
+	S_PLASMA,
+	S_PLASMA1,
+	S_PLASMAFLASH1
+    },
+    {
+	// bfg 9000
+	am_cell,
+	S_BFGUP,
+	S_BFGDOWN,
+	S_BFG,
+	S_BFG1,
+	S_BFGFLASH1
+    },
+    {
+	// chainsaw
+	am_noammo,
+	S_SAWUP,
+	S_SAWDOWN,
+	S_SAW,
+	S_SAW1,
+	S_NULL
+    },
+    {
+	// super shotgun
+	am_shell,
+	S_DSGUNUP,
+	S_DSGUNDOWN,
+	S_DSGUN,
+	S_DSGUN1,
+	S_DSGUNFLASH1
+    },	
+};
+
+
+
+
+
+
+
+
--- /dev/null
+++ b/src/d_items.h
@@ -1,0 +1,55 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: d_items.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//	Items: key cards, artifacts, weapon, ammunition.
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __D_ITEMS__
+#define __D_ITEMS__
+
+#include "doomdef.h"
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+
+// Weapon info: sprite frames, ammunition use.
+typedef struct
+{
+    ammotype_t	ammo;
+    int		upstate;
+    int		downstate;
+    int		readystate;
+    int		atkstate;
+    int		flashstate;
+
+} weaponinfo_t;
+
+extern  weaponinfo_t    weaponinfo[NUMWEAPONS];
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:28  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/d_main.c
@@ -1,0 +1,1174 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: d_main.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:34  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//	DOOM main program (D_DoomMain) and game loop (D_DoomLoop),
+//	plus functions to determine game mode (shareware, registered),
+//	parse command line parameters, configure game parameters (turbo),
+//	and call the startup functions.
+//
+//-----------------------------------------------------------------------------
+
+
+static const char rcsid[] = "$Id: d_main.c 4 2005-07-23 16:19:41Z fraggle $";
+
+#define	BGCOLOR		7
+#define	FGCOLOR		8
+
+
+#ifdef NORMALUNIX
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#endif
+
+
+#include "doomdef.h"
+#include "doomstat.h"
+
+#include "dstrings.h"
+#include "sounds.h"
+
+
+#include "z_zone.h"
+#include "w_wad.h"
+#include "s_sound.h"
+#include "v_video.h"
+
+#include "f_finale.h"
+#include "f_wipe.h"
+
+#include "m_argv.h"
+#include "m_misc.h"
+#include "m_menu.h"
+
+#include "i_system.h"
+#include "i_sound.h"
+#include "i_video.h"
+
+#include "g_game.h"
+
+#include "hu_stuff.h"
+#include "wi_stuff.h"
+#include "st_stuff.h"
+#include "am_map.h"
+
+#include "p_setup.h"
+#include "r_local.h"
+
+
+#include "d_main.h"
+
+//
+// D-DoomLoop()
+// Not a globally visible function,
+//  just included for source reference,
+//  called by D_DoomMain, never exits.
+// Manages timing and IO,
+//  calls all ?_Responder, ?_Ticker, and ?_Drawer,
+//  calls I_GetTime, I_StartFrame, and I_StartTic
+//
+void D_DoomLoop (void);
+
+
+char*		wadfiles[MAXWADFILES];
+
+
+boolean		devparm;	// started game with -devparm
+boolean         nomonsters;	// checkparm of -nomonsters
+boolean         respawnparm;	// checkparm of -respawn
+boolean         fastparm;	// checkparm of -fast
+
+boolean         drone;
+
+boolean		singletics = false; // debug flag to cancel adaptiveness
+
+
+
+//extern int soundVolume;
+//extern  int	sfxVolume;
+//extern  int	musicVolume;
+
+extern  boolean	inhelpscreens;
+
+skill_t		startskill;
+int             startepisode;
+int		startmap;
+boolean		autostart;
+
+FILE*		debugfile;
+
+boolean		advancedemo;
+
+
+
+
+char		wadfile[1024];		// primary wad file
+char		mapdir[1024];           // directory of development maps
+char		basedefault[1024];      // default file
+
+
+void D_CheckNetGame (void);
+void D_ProcessEvents (void);
+void G_BuildTiccmd (ticcmd_t* cmd);
+void D_DoAdvanceDemo (void);
+
+
+//
+// EVENT HANDLING
+//
+// Events are asynchronous inputs generally generated by the game user.
+// Events can be discarded if no responder claims them
+//
+event_t         events[MAXEVENTS];
+int             eventhead;
+int 		eventtail;
+
+
+//
+// D_PostEvent
+// Called by the I/O functions when input is detected
+//
+void D_PostEvent (event_t* ev)
+{
+    events[eventhead] = *ev;
+    eventhead = (++eventhead)&(MAXEVENTS-1);
+}
+
+
+//
+// D_ProcessEvents
+// Send all the events of the given timestamp down the responder chain
+//
+void D_ProcessEvents (void)
+{
+    event_t*	ev;
+	
+    // IF STORE DEMO, DO NOT ACCEPT INPUT
+    if ( ( gamemode == commercial )
+	 && (W_CheckNumForName("map01")<0) )
+      return;
+	
+    for ( ; eventtail != eventhead ; eventtail = (++eventtail)&(MAXEVENTS-1) )
+    {
+	ev = &events[eventtail];
+	if (M_Responder (ev))
+	    continue;               // menu ate the event
+	G_Responder (ev);
+    }
+}
+
+
+
+
+//
+// D_Display
+//  draw current display, possibly wiping it from the previous
+//
+
+// wipegamestate can be set to -1 to force a wipe on the next draw
+gamestate_t     wipegamestate = GS_DEMOSCREEN;
+extern  boolean setsizeneeded;
+extern  int             showMessages;
+void R_ExecuteSetViewSize (void);
+
+void D_Display (void)
+{
+    static  boolean		viewactivestate = false;
+    static  boolean		menuactivestate = false;
+    static  boolean		inhelpscreensstate = false;
+    static  boolean		fullscreen = false;
+    static  gamestate_t		oldgamestate = -1;
+    static  int			borderdrawcount;
+    int				nowtime;
+    int				tics;
+    int				wipestart;
+    int				y;
+    boolean			done;
+    boolean			wipe;
+    boolean			redrawsbar;
+
+    if (nodrawers)
+	return;                    // for comparative timing / profiling
+		
+    redrawsbar = false;
+    
+    // change the view size if needed
+    if (setsizeneeded)
+    {
+	R_ExecuteSetViewSize ();
+	oldgamestate = -1;                      // force background redraw
+	borderdrawcount = 3;
+    }
+
+    // save the current screen if about to wipe
+    if (gamestate != wipegamestate)
+    {
+	wipe = true;
+	wipe_StartScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);
+    }
+    else
+	wipe = false;
+
+    if (gamestate == GS_LEVEL && gametic)
+	HU_Erase();
+    
+    // do buffered drawing
+    switch (gamestate)
+    {
+      case GS_LEVEL:
+	if (!gametic)
+	    break;
+	if (automapactive)
+	    AM_Drawer ();
+	if (wipe || (viewheight != 200 && fullscreen) )
+	    redrawsbar = true;
+	if (inhelpscreensstate && !inhelpscreens)
+	    redrawsbar = true;              // just put away the help screen
+	ST_Drawer (viewheight == 200, redrawsbar );
+	fullscreen = viewheight == 200;
+	break;
+
+      case GS_INTERMISSION:
+	WI_Drawer ();
+	break;
+
+      case GS_FINALE:
+	F_Drawer ();
+	break;
+
+      case GS_DEMOSCREEN:
+	D_PageDrawer ();
+	break;
+    }
+    
+    // draw buffered stuff to screen
+    I_UpdateNoBlit ();
+    
+    // draw the view directly
+    if (gamestate == GS_LEVEL && !automapactive && gametic)
+	R_RenderPlayerView (&players[displayplayer]);
+
+    if (gamestate == GS_LEVEL && gametic)
+	HU_Drawer ();
+    
+    // clean up border stuff
+    if (gamestate != oldgamestate && gamestate != GS_LEVEL)
+	I_SetPalette (W_CacheLumpName ("PLAYPAL",PU_CACHE));
+
+    // see if the border needs to be initially drawn
+    if (gamestate == GS_LEVEL && oldgamestate != GS_LEVEL)
+    {
+	viewactivestate = false;        // view was not active
+	R_FillBackScreen ();    // draw the pattern into the back screen
+    }
+
+    // see if the border needs to be updated to the screen
+    if (gamestate == GS_LEVEL && !automapactive && scaledviewwidth != 320)
+    {
+	if (menuactive || menuactivestate || !viewactivestate)
+	    borderdrawcount = 3;
+	if (borderdrawcount)
+	{
+	    R_DrawViewBorder ();    // erase old menu stuff
+	    borderdrawcount--;
+	}
+
+    }
+
+    menuactivestate = menuactive;
+    viewactivestate = viewactive;
+    inhelpscreensstate = inhelpscreens;
+    oldgamestate = wipegamestate = gamestate;
+    
+    // draw pause pic
+    if (paused)
+    {
+	if (automapactive)
+	    y = 4;
+	else
+	    y = viewwindowy+4;
+	V_DrawPatchDirect(viewwindowx+(scaledviewwidth-68)/2,
+			  y,0,W_CacheLumpName ("M_PAUSE", PU_CACHE));
+    }
+
+
+    // menus go directly to the screen
+    M_Drawer ();          // menu is drawn even on top of everything
+    NetUpdate ();         // send out any new accumulation
+
+
+    // normal update
+    if (!wipe)
+    {
+	I_FinishUpdate ();              // page flip or blit buffer
+	return;
+    }
+    
+    // wipe update
+    wipe_EndScreen(0, 0, SCREENWIDTH, SCREENHEIGHT);
+
+    wipestart = I_GetTime () - 1;
+
+    do
+    {
+	do
+	{
+	    nowtime = I_GetTime ();
+	    tics = nowtime - wipestart;
+	} while (!tics);
+	wipestart = nowtime;
+	done = wipe_ScreenWipe(wipe_Melt
+			       , 0, 0, SCREENWIDTH, SCREENHEIGHT, tics);
+	I_UpdateNoBlit ();
+	M_Drawer ();                            // menu is drawn even on top of wipes
+	I_FinishUpdate ();                      // page flip or blit buffer
+    } while (!done);
+}
+
+
+
+//
+//  D_DoomLoop
+//
+extern  boolean         demorecording;
+
+void D_DoomLoop (void)
+{
+    if (demorecording)
+	G_BeginRecording ();
+		
+    if (M_CheckParm ("-debugfile"))
+    {
+	char    filename[20];
+	sprintf (filename,"debug%i.txt",consoleplayer);
+	printf ("debug output to: %s\n",filename);
+	debugfile = fopen (filename,"w");
+    }
+	
+    I_InitGraphics ();
+
+    while (1)
+    {
+	// frame syncronous IO operations
+	I_StartFrame ();                
+	
+	// process one or more tics
+	if (singletics)
+	{
+	    I_StartTic ();
+	    D_ProcessEvents ();
+	    G_BuildTiccmd (&netcmds[consoleplayer][maketic%BACKUPTICS]);
+	    if (advancedemo)
+		D_DoAdvanceDemo ();
+	    M_Ticker ();
+	    G_Ticker ();
+	    gametic++;
+	    maketic++;
+	}
+	else
+	{
+	    TryRunTics (); // will run at least one tic
+	}
+		
+	S_UpdateSounds (players[consoleplayer].mo);// move positional sounds
+
+	// Update display, next frame, with current state.
+	D_Display ();
+
+#ifndef SNDSERV
+	// Sound mixing for the buffer is snychronous.
+	I_UpdateSound();
+#endif	
+	// Synchronous sound output is explicitly called.
+#ifndef SNDINTR
+	// Update sound output.
+	I_SubmitSound();
+#endif
+    }
+}
+
+
+
+//
+//  DEMO LOOP
+//
+int             demosequence;
+int             pagetic;
+char                    *pagename;
+
+
+//
+// D_PageTicker
+// Handles timing for warped projection
+//
+void D_PageTicker (void)
+{
+    if (--pagetic < 0)
+	D_AdvanceDemo ();
+}
+
+
+
+//
+// D_PageDrawer
+//
+void D_PageDrawer (void)
+{
+    V_DrawPatch (0,0, 0, W_CacheLumpName(pagename, PU_CACHE));
+}
+
+
+//
+// D_AdvanceDemo
+// Called after each demo or intro demosequence finishes
+//
+void D_AdvanceDemo (void)
+{
+    advancedemo = true;
+}
+
+
+//
+// This cycles through the demo sequences.
+// FIXME - version dependend demo numbers?
+//
+ void D_DoAdvanceDemo (void)
+{
+    players[consoleplayer].playerstate = PST_LIVE;  // not reborn
+    advancedemo = false;
+    usergame = false;               // no save / end game here
+    paused = false;
+    gameaction = ga_nothing;
+
+    if ( gamemode == retail )
+      demosequence = (demosequence+1)%7;
+    else
+      demosequence = (demosequence+1)%6;
+    
+    switch (demosequence)
+    {
+      case 0:
+	if ( gamemode == commercial )
+	    pagetic = 35 * 11;
+	else
+	    pagetic = 170;
+	gamestate = GS_DEMOSCREEN;
+	pagename = "TITLEPIC";
+	if ( gamemode == commercial )
+	  S_StartMusic(mus_dm2ttl);
+	else
+	  S_StartMusic (mus_intro);
+	break;
+      case 1:
+	G_DeferedPlayDemo ("demo1");
+	break;
+      case 2:
+	pagetic = 200;
+	gamestate = GS_DEMOSCREEN;
+	pagename = "CREDIT";
+	break;
+      case 3:
+	G_DeferedPlayDemo ("demo2");
+	break;
+      case 4:
+	gamestate = GS_DEMOSCREEN;
+	if ( gamemode == commercial)
+	{
+	    pagetic = 35 * 11;
+	    pagename = "TITLEPIC";
+	    S_StartMusic(mus_dm2ttl);
+	}
+	else
+	{
+	    pagetic = 200;
+
+	    if ( gamemode == retail )
+	      pagename = "CREDIT";
+	    else
+	      pagename = "HELP2";
+	}
+	break;
+      case 5:
+	G_DeferedPlayDemo ("demo3");
+	break;
+        // THE DEFINITIVE DOOM Special Edition demo
+      case 6:
+	G_DeferedPlayDemo ("demo4");
+	break;
+    }
+}
+
+
+
+//
+// D_StartTitle
+//
+void D_StartTitle (void)
+{
+    gameaction = ga_nothing;
+    demosequence = -1;
+    D_AdvanceDemo ();
+}
+
+
+
+
+//      print title for every printed line
+char            title[128];
+
+
+
+//
+// D_AddFile
+//
+void D_AddFile (char *file)
+{
+    int     numwadfiles;
+    char    *newfile;
+	
+    for (numwadfiles = 0 ; wadfiles[numwadfiles] ; numwadfiles++)
+	;
+
+    newfile = malloc (strlen(file)+1);
+    strcpy (newfile, file);
+	
+    wadfiles[numwadfiles] = newfile;
+}
+
+//
+// IdentifyVersion
+// Checks availability of IWAD files by name,
+// to determine whether registered/commercial features
+// should be executed (notably loading PWAD's).
+//
+void IdentifyVersion (void)
+{
+
+    char*	doom1wad;
+    char*	doomwad;
+    char*	doomuwad;
+    char*	doom2wad;
+
+    char*	doom2fwad;
+    char*	plutoniawad;
+    char*	tntwad;
+
+#ifdef NORMALUNIX
+    char *home;
+    char *doomwaddir;
+    doomwaddir = getenv("DOOMWADDIR");
+    if (!doomwaddir)
+	doomwaddir = ".";
+
+    // Commercial.
+    doom2wad = malloc(strlen(doomwaddir)+1+9+1);
+    sprintf(doom2wad, "%s/doom2.wad", doomwaddir);
+
+    // Retail.
+    doomuwad = malloc(strlen(doomwaddir)+1+8+1);
+    sprintf(doomuwad, "%s/doomu.wad", doomwaddir);
+    
+    // Registered.
+    doomwad = malloc(strlen(doomwaddir)+1+8+1);
+    sprintf(doomwad, "%s/doom.wad", doomwaddir);
+    
+    // Shareware.
+    doom1wad = malloc(strlen(doomwaddir)+1+9+1);
+    sprintf(doom1wad, "%s/doom1.wad", doomwaddir);
+
+     // Bug, dear Shawn.
+    // Insufficient malloc, caused spurious realloc errors.
+    plutoniawad = malloc(strlen(doomwaddir)+1+/*9*/12+1);
+    sprintf(plutoniawad, "%s/plutonia.wad", doomwaddir);
+
+    tntwad = malloc(strlen(doomwaddir)+1+9+1);
+    sprintf(tntwad, "%s/tnt.wad", doomwaddir);
+
+
+    // French stuff.
+    doom2fwad = malloc(strlen(doomwaddir)+1+10+1);
+    sprintf(doom2fwad, "%s/doom2f.wad", doomwaddir);
+
+    home = getenv("HOME");
+    if (!home)
+      I_Error("Please set $HOME to your home directory");
+    sprintf(basedefault, "%s/.doomrc", home);
+#endif
+
+    if (M_CheckParm ("-shdev"))
+    {
+	gamemode = shareware;
+	devparm = true;
+	D_AddFile (DEVDATA"doom1.wad");
+	D_AddFile (DEVMAPS"data_se/texture1.lmp");
+	D_AddFile (DEVMAPS"data_se/pnames.lmp");
+	strcpy (basedefault,DEVDATA"default.cfg");
+	return;
+    }
+
+    if (M_CheckParm ("-regdev"))
+    {
+	gamemode = registered;
+	devparm = true;
+	D_AddFile (DEVDATA"doom.wad");
+	D_AddFile (DEVMAPS"data_se/texture1.lmp");
+	D_AddFile (DEVMAPS"data_se/texture2.lmp");
+	D_AddFile (DEVMAPS"data_se/pnames.lmp");
+	strcpy (basedefault,DEVDATA"default.cfg");
+	return;
+    }
+
+    if (M_CheckParm ("-comdev"))
+    {
+	gamemode = commercial;
+	devparm = true;
+	/* I don't bother
+	if(plutonia)
+	    D_AddFile (DEVDATA"plutonia.wad");
+	else if(tnt)
+	    D_AddFile (DEVDATA"tnt.wad");
+	else*/
+	    D_AddFile (DEVDATA"doom2.wad");
+	    
+	D_AddFile (DEVMAPS"cdata/texture1.lmp");
+	D_AddFile (DEVMAPS"cdata/pnames.lmp");
+	strcpy (basedefault,DEVDATA"default.cfg");
+	return;
+    }
+
+    if ( !access (doom2fwad,R_OK) )
+    {
+	gamemode = commercial;
+	// C'est ridicule!
+	// Let's handle languages in config files, okay?
+	language = french;
+	printf("French version\n");
+	D_AddFile (doom2fwad);
+	return;
+    }
+
+    if ( !access (doom2wad,R_OK) )
+    {
+	gamemode = commercial;
+	D_AddFile (doom2wad);
+	return;
+    }
+
+    if ( !access (plutoniawad, R_OK ) )
+    {
+      gamemode = commercial;
+      D_AddFile (plutoniawad);
+      return;
+    }
+
+    if ( !access ( tntwad, R_OK ) )
+    {
+      gamemode = commercial;
+      D_AddFile (tntwad);
+      return;
+    }
+
+    if ( !access (doomuwad,R_OK) )
+    {
+      gamemode = retail;
+      D_AddFile (doomuwad);
+      return;
+    }
+
+    if ( !access (doomwad,R_OK) )
+    {
+      gamemode = registered;
+      D_AddFile (doomwad);
+      return;
+    }
+
+    if ( !access (doom1wad,R_OK) )
+    {
+      gamemode = shareware;
+      D_AddFile (doom1wad);
+      return;
+    }
+
+    printf("Game mode indeterminate.\n");
+    gamemode = indetermined;
+
+    // We don't abort. Let's see what the PWAD contains.
+    //exit(1);
+    //I_Error ("Game mode indeterminate\n");
+}
+
+//
+// Find a Response File
+//
+void FindResponseFile (void)
+{
+    int             i;
+#define MAXARGVS        100
+	
+    for (i = 1;i < myargc;i++)
+	if (myargv[i][0] == '@')
+	{
+	    FILE *          handle;
+	    int             size;
+	    int             k;
+	    int             index;
+	    int             indexinfile;
+	    char    *infile;
+	    char    *file;
+	    char    *moreargs[20];
+	    char    *firstargv;
+			
+	    // READ THE RESPONSE FILE INTO MEMORY
+	    handle = fopen (&myargv[i][1],"rb");
+	    if (!handle)
+	    {
+		printf ("\nNo such response file!");
+		exit(1);
+	    }
+	    printf("Found response file %s!\n",&myargv[i][1]);
+	    fseek (handle,0,SEEK_END);
+	    size = ftell(handle);
+	    fseek (handle,0,SEEK_SET);
+	    file = malloc (size);
+	    fread (file,size,1,handle);
+	    fclose (handle);
+			
+	    // KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG
+	    for (index = 0,k = i+1; k < myargc; k++)
+		moreargs[index++] = myargv[k];
+			
+	    firstargv = myargv[0];
+	    myargv = malloc(sizeof(char *)*MAXARGVS);
+	    memset(myargv,0,sizeof(char *)*MAXARGVS);
+	    myargv[0] = firstargv;
+			
+	    infile = file;
+	    indexinfile = k = 0;
+	    indexinfile++;  // SKIP PAST ARGV[0] (KEEP IT)
+	    do
+	    {
+		myargv[indexinfile++] = infile+k;
+		while(k < size &&
+		      ((*(infile+k)>= ' '+1) && (*(infile+k)<='z')))
+		    k++;
+		*(infile+k) = 0;
+		while(k < size &&
+		      ((*(infile+k)<= ' ') || (*(infile+k)>'z')))
+		    k++;
+	    } while(k < size);
+			
+	    for (k = 0;k < index;k++)
+		myargv[indexinfile++] = moreargs[k];
+	    myargc = indexinfile;
+	
+	    // DISPLAY ARGS
+	    printf("%d command-line args:\n",myargc);
+	    for (k=1;k<myargc;k++)
+		printf("%s\n",myargv[k]);
+
+	    break;
+	}
+}
+
+
+//
+// D_DoomMain
+//
+void D_DoomMain (void)
+{
+    int             p;
+    char                    file[256];
+
+    FindResponseFile ();
+	
+    IdentifyVersion ();
+	
+    setbuf (stdout, NULL);
+    modifiedgame = false;
+	
+    nomonsters = M_CheckParm ("-nomonsters");
+    respawnparm = M_CheckParm ("-respawn");
+    fastparm = M_CheckParm ("-fast");
+    devparm = M_CheckParm ("-devparm");
+    if (M_CheckParm ("-altdeath"))
+	deathmatch = 2;
+    else if (M_CheckParm ("-deathmatch"))
+	deathmatch = 1;
+
+    switch ( gamemode )
+    {
+      case retail:
+	sprintf (title,
+		 "                         "
+		 "The Ultimate DOOM Startup v%i.%i"
+		 "                           ",
+		 VERSION/100,VERSION%100);
+	break;
+      case shareware:
+	sprintf (title,
+		 "                            "
+		 "DOOM Shareware Startup v%i.%i"
+		 "                           ",
+		 VERSION/100,VERSION%100);
+	break;
+      case registered:
+	sprintf (title,
+		 "                            "
+		 "DOOM Registered Startup v%i.%i"
+		 "                           ",
+		 VERSION/100,VERSION%100);
+	break;
+      case commercial:
+	sprintf (title,
+		 "                         "
+		 "DOOM 2: Hell on Earth v%i.%i"
+		 "                           ",
+		 VERSION/100,VERSION%100);
+	break;
+/*FIXME
+       case pack_plut:
+	sprintf (title,
+		 "                   "
+		 "DOOM 2: Plutonia Experiment v%i.%i"
+		 "                           ",
+		 VERSION/100,VERSION%100);
+	break;
+      case pack_tnt:
+	sprintf (title,
+		 "                     "
+		 "DOOM 2: TNT - Evilution v%i.%i"
+		 "                           ",
+		 VERSION/100,VERSION%100);
+	break;
+*/
+      default:
+	sprintf (title,
+		 "                     "
+		 "Public DOOM - v%i.%i"
+		 "                           ",
+		 VERSION/100,VERSION%100);
+	break;
+    }
+    
+    printf ("%s\n",title);
+
+    if (devparm)
+	printf(D_DEVSTR);
+    
+    if (M_CheckParm("-cdrom"))
+    {
+	printf(D_CDROM);
+	mkdir("c:\\doomdata",0);
+	strcpy (basedefault,"c:/doomdata/default.cfg");
+    }	
+    
+    // turbo option
+    if ( (p=M_CheckParm ("-turbo")) )
+    {
+	int     scale = 200;
+	extern int forwardmove[2];
+	extern int sidemove[2];
+	
+	if (p<myargc-1)
+	    scale = atoi (myargv[p+1]);
+	if (scale < 10)
+	    scale = 10;
+	if (scale > 400)
+	    scale = 400;
+	printf ("turbo scale: %i%%\n",scale);
+	forwardmove[0] = forwardmove[0]*scale/100;
+	forwardmove[1] = forwardmove[1]*scale/100;
+	sidemove[0] = sidemove[0]*scale/100;
+	sidemove[1] = sidemove[1]*scale/100;
+    }
+    
+    // add any files specified on the command line with -file wadfile
+    // to the wad list
+    //
+    // convenience hack to allow -wart e m to add a wad file
+    // prepend a tilde to the filename so wadfile will be reloadable
+    p = M_CheckParm ("-wart");
+    if (p)
+    {
+	myargv[p][4] = 'p';     // big hack, change to -warp
+
+	// Map name handling.
+	switch (gamemode )
+	{
+	  case shareware:
+	  case retail:
+	  case registered:
+	    sprintf (file,"~"DEVMAPS"E%cM%c.wad",
+		     myargv[p+1][0], myargv[p+2][0]);
+	    printf("Warping to Episode %s, Map %s.\n",
+		   myargv[p+1],myargv[p+2]);
+	    break;
+	    
+	  case commercial:
+	  default:
+	    p = atoi (myargv[p+1]);
+	    if (p<10)
+	      sprintf (file,"~"DEVMAPS"cdata/map0%i.wad", p);
+	    else
+	      sprintf (file,"~"DEVMAPS"cdata/map%i.wad", p);
+	    break;
+	}
+	D_AddFile (file);
+    }
+	
+    p = M_CheckParm ("-file");
+    if (p)
+    {
+	// the parms after p are wadfile/lump names,
+	// until end of parms or another - preceded parm
+	modifiedgame = true;            // homebrew levels
+	while (++p != myargc && myargv[p][0] != '-')
+	    D_AddFile (myargv[p]);
+    }
+
+    p = M_CheckParm ("-playdemo");
+
+    if (!p)
+	p = M_CheckParm ("-timedemo");
+
+    if (p && p < myargc-1)
+    {
+	sprintf (file,"%s.lmp", myargv[p+1]);
+	D_AddFile (file);
+	printf("Playing demo %s.lmp.\n",myargv[p+1]);
+    }
+    
+    // get skill / episode / map from parms
+    startskill = sk_medium;
+    startepisode = 1;
+    startmap = 1;
+    autostart = false;
+
+		
+    p = M_CheckParm ("-skill");
+    if (p && p < myargc-1)
+    {
+	startskill = myargv[p+1][0]-'1';
+	autostart = true;
+    }
+
+    p = M_CheckParm ("-episode");
+    if (p && p < myargc-1)
+    {
+	startepisode = myargv[p+1][0]-'0';
+	startmap = 1;
+	autostart = true;
+    }
+	
+    p = M_CheckParm ("-timer");
+    if (p && p < myargc-1 && deathmatch)
+    {
+	int     time;
+	time = atoi(myargv[p+1]);
+	printf("Levels will end after %d minute",time);
+	if (time>1)
+	    printf("s");
+	printf(".\n");
+    }
+
+    p = M_CheckParm ("-avg");
+    if (p && p < myargc-1 && deathmatch)
+	printf("Austin Virtual Gaming: Levels will end after 20 minutes\n");
+
+    p = M_CheckParm ("-warp");
+    if (p && p < myargc-1)
+    {
+	if (gamemode == commercial)
+	    startmap = atoi (myargv[p+1]);
+	else
+	{
+	    startepisode = myargv[p+1][0]-'0';
+	    startmap = myargv[p+2][0]-'0';
+	}
+	autostart = true;
+    }
+    
+    // init subsystems
+    printf ("V_Init: allocate screens.\n");
+    V_Init ();
+
+    printf ("M_LoadDefaults: Load system defaults.\n");
+    M_LoadDefaults ();              // load before initing other systems
+
+    printf ("Z_Init: Init zone memory allocation daemon. \n");
+    Z_Init ();
+
+    printf ("W_Init: Init WADfiles.\n");
+    W_InitMultipleFiles (wadfiles);
+    
+
+    // Check for -file in shareware
+    if (modifiedgame)
+    {
+	// These are the lumps that will be checked in IWAD,
+	// if any one is not present, execution will be aborted.
+	char name[23][8]=
+	{
+	    "e2m1","e2m2","e2m3","e2m4","e2m5","e2m6","e2m7","e2m8","e2m9",
+	    "e3m1","e3m3","e3m3","e3m4","e3m5","e3m6","e3m7","e3m8","e3m9",
+	    "dphoof","bfgga0","heada1","cybra1","spida1d1"
+	};
+	int i;
+	
+	if ( gamemode == shareware)
+	    I_Error("\nYou cannot -file with the shareware "
+		    "version. Register!");
+
+	// Check for fake IWAD with right name,
+	// but w/o all the lumps of the registered version. 
+	if (gamemode == registered)
+	    for (i = 0;i < 23; i++)
+		if (W_CheckNumForName(name[i])<0)
+		    I_Error("\nThis is not the registered version.");
+    }
+    
+    // Iff additonal PWAD files are used, print modified banner
+    if (modifiedgame)
+    {
+	/*m*/printf (
+	    "===========================================================================\n"
+	    "ATTENTION:  This version of DOOM has been modified.  If you would like to\n"
+	    "get a copy of the original game, call 1-800-IDGAMES or see the readme file.\n"
+	    "        You will not receive technical support for modified games.\n"
+	    "                      press enter to continue\n"
+	    "===========================================================================\n"
+	    );
+	getchar ();
+    }
+	
+
+    // Check and print which version is executed.
+    switch ( gamemode )
+    {
+      case shareware:
+      case indetermined:
+	printf (
+	    "===========================================================================\n"
+	    "                                Shareware!\n"
+	    "===========================================================================\n"
+	);
+	break;
+      case registered:
+      case retail:
+      case commercial:
+	printf (
+	    "===========================================================================\n"
+	    "                 Commercial product - do not distribute!\n"
+	    "         Please report software piracy to the SPA: 1-800-388-PIR8\n"
+	    "===========================================================================\n"
+	);
+	break;
+	
+      default:
+	// Ouch.
+	break;
+    }
+
+    printf ("M_Init: Init miscellaneous info.\n");
+    M_Init ();
+
+    printf ("R_Init: Init DOOM refresh daemon - ");
+    R_Init ();
+
+    printf ("\nP_Init: Init Playloop state.\n");
+    P_Init ();
+
+    printf ("I_Init: Setting up machine state.\n");
+    I_Init ();
+
+    printf ("D_CheckNetGame: Checking network game status.\n");
+    D_CheckNetGame ();
+
+    printf ("S_Init: Setting up sound.\n");
+    S_Init (snd_SfxVolume /* *8 */, snd_MusicVolume /* *8*/ );
+
+    printf ("HU_Init: Setting up heads up display.\n");
+    HU_Init ();
+
+    printf ("ST_Init: Init status bar.\n");
+    ST_Init ();
+
+    // check for a driver that wants intermission stats
+    p = M_CheckParm ("-statcopy");
+    if (p && p<myargc-1)
+    {
+	// for statistics driver
+	extern  void*	statcopy;                            
+
+	statcopy = (void*)atoi(myargv[p+1]);
+	printf ("External statistics registered.\n");
+    }
+    
+    // start the apropriate game based on parms
+    p = M_CheckParm ("-record");
+
+    if (p && p < myargc-1)
+    {
+	G_RecordDemo (myargv[p+1]);
+	autostart = true;
+    }
+	
+    p = M_CheckParm ("-playdemo");
+    if (p && p < myargc-1)
+    {
+	singledemo = true;              // quit after one demo
+	G_DeferedPlayDemo (myargv[p+1]);
+	D_DoomLoop ();  // never returns
+    }
+	
+    p = M_CheckParm ("-timedemo");
+    if (p && p < myargc-1)
+    {
+	G_TimeDemo (myargv[p+1]);
+	D_DoomLoop ();  // never returns
+    }
+	
+    p = M_CheckParm ("-loadgame");
+    if (p && p < myargc-1)
+    {
+	if (M_CheckParm("-cdrom"))
+	    sprintf(file, "c:\\doomdata\\"SAVEGAMENAME"%c.dsg",myargv[p+1][0]);
+	else
+	    sprintf(file, SAVEGAMENAME"%c.dsg",myargv[p+1][0]);
+	G_LoadGame (file);
+    }
+	
+
+    if ( gameaction != ga_loadgame )
+    {
+	if (autostart || netgame)
+	    G_InitNew (startskill, startepisode, startmap);
+	else
+	    D_StartTitle ();                // start up intro loop
+
+    }
+
+    D_DoomLoop ();  // never returns
+}
--- /dev/null
+++ b/src/d_main.h
@@ -1,0 +1,67 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: d_main.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:34  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//	System specific interface stuff.
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __D_MAIN__
+#define __D_MAIN__
+
+#include "d_event.h"
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+
+
+#define MAXWADFILES             20
+extern char*		wadfiles[MAXWADFILES];
+
+void D_AddFile (char *file);
+
+
+
+//
+// D_DoomMain()
+// Not a globally visible function, just included for source reference,
+// calls all startup code, parses command line options.
+// If not overrided by user input, calls N_AdvanceDemo.
+//
+void D_DoomMain (void);
+
+// Called by IO functions when input is detected.
+void D_PostEvent (event_t* ev);
+
+	
+
+//
+// BASE LEVEL
+//
+void D_PageTicker (void);
+void D_PageDrawer (void);
+void D_AdvanceDemo (void);
+void D_StartTitle (void);
+
+#endif
--- /dev/null
+++ b/src/d_net.c
@@ -1,0 +1,770 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: d_net.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:50  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//	DOOM Network game communication and protocol,
+//	all OS independend parts.
+//
+//-----------------------------------------------------------------------------
+
+
+static const char rcsid[] = "$Id: d_net.c 4 2005-07-23 16:19:41Z fraggle $";
+
+
+#include "m_menu.h"
+#include "i_system.h"
+#include "i_video.h"
+#include "i_net.h"
+#include "g_game.h"
+#include "doomdef.h"
+#include "doomstat.h"
+
+#define	NCMD_EXIT		0x80000000
+#define	NCMD_RETRANSMIT		0x40000000
+#define	NCMD_SETUP		0x20000000
+#define	NCMD_KILL		0x10000000	// kill game
+#define	NCMD_CHECKSUM	 	0x0fffffff
+
+ 
+doomcom_t*	doomcom;	
+doomdata_t*	netbuffer;		// points inside doomcom
+
+
+//
+// NETWORKING
+//
+// gametic is the tic about to (or currently being) run
+// maketic is the tick that hasn't had control made for it yet
+// nettics[] has the maketics for all players 
+//
+// a gametic cannot be run until nettics[] > gametic for all players
+//
+#define	RESENDCOUNT	10
+#define	PL_DRONE	0x80	// bit flag in doomdata->player
+
+ticcmd_t	localcmds[BACKUPTICS];
+
+ticcmd_t        netcmds[MAXPLAYERS][BACKUPTICS];
+int         	nettics[MAXNETNODES];
+boolean		nodeingame[MAXNETNODES];		// set false as nodes leave game
+boolean		remoteresend[MAXNETNODES];		// set when local needs tics
+int		resendto[MAXNETNODES];			// set when remote needs tics
+int		resendcount[MAXNETNODES];
+
+int		nodeforplayer[MAXPLAYERS];
+
+int             maketic;
+int		lastnettic;
+int		skiptics;
+int		ticdup;		
+int		maxsend;	// BACKUPTICS/(2*ticdup)-1
+
+
+void D_ProcessEvents (void); 
+void G_BuildTiccmd (ticcmd_t *cmd); 
+void D_DoAdvanceDemo (void);
+ 
+boolean		reboundpacket;
+doomdata_t	reboundstore;
+
+
+
+//
+//
+//
+int NetbufferSize (void)
+{
+    return (int)&(((doomdata_t *)0)->cmds[netbuffer->numtics]); 
+}
+
+//
+// Checksum 
+//
+unsigned NetbufferChecksum (void)
+{
+    unsigned		c;
+    int		i,l;
+
+    c = 0x1234567;
+
+    // FIXME -endianess?
+#ifdef NORMALUNIX
+    return 0;			// byte order problems
+#endif
+
+    l = (NetbufferSize () - (int)&(((doomdata_t *)0)->retransmitfrom))/4;
+    for (i=0 ; i<l ; i++)
+	c += ((unsigned *)&netbuffer->retransmitfrom)[i] * (i+1);
+
+    return c & NCMD_CHECKSUM;
+}
+
+//
+//
+//
+int ExpandTics (int low)
+{
+    int	delta;
+	
+    delta = low - (maketic&0xff);
+	
+    if (delta >= -64 && delta <= 64)
+	return (maketic&~0xff) + low;
+    if (delta > 64)
+	return (maketic&~0xff) - 256 + low;
+    if (delta < -64)
+	return (maketic&~0xff) + 256 + low;
+		
+    I_Error ("ExpandTics: strange value %i at maketic %i",low,maketic);
+    return 0;
+}
+
+
+
+//
+// HSendPacket
+//
+void
+HSendPacket
+ (int	node,
+  int	flags )
+{
+    netbuffer->checksum = NetbufferChecksum () | flags;
+
+    if (!node)
+    {
+	reboundstore = *netbuffer;
+	reboundpacket = true;
+	return;
+    }
+
+    if (demoplayback)
+	return;
+
+    if (!netgame)
+	I_Error ("Tried to transmit to another node");
+		
+    doomcom->command = CMD_SEND;
+    doomcom->remotenode = node;
+    doomcom->datalength = NetbufferSize ();
+	
+    if (debugfile)
+    {
+	int		i;
+	int		realretrans;
+	if (netbuffer->checksum & NCMD_RETRANSMIT)
+	    realretrans = ExpandTics (netbuffer->retransmitfrom);
+	else
+	    realretrans = -1;
+
+	fprintf (debugfile,"send (%i + %i, R %i) [%i] ",
+		 ExpandTics(netbuffer->starttic),
+		 netbuffer->numtics, realretrans, doomcom->datalength);
+	
+	for (i=0 ; i<doomcom->datalength ; i++)
+	    fprintf (debugfile,"%i ",((byte *)netbuffer)[i]);
+
+	fprintf (debugfile,"\n");
+    }
+
+    I_NetCmd ();
+}
+
+//
+// HGetPacket
+// Returns false if no packet is waiting
+//
+boolean HGetPacket (void)
+{	
+    if (reboundpacket)
+    {
+	*netbuffer = reboundstore;
+	doomcom->remotenode = 0;
+	reboundpacket = false;
+	return true;
+    }
+
+    if (!netgame)
+	return false;
+
+    if (demoplayback)
+	return false;
+		
+    doomcom->command = CMD_GET;
+    I_NetCmd ();
+    
+    if (doomcom->remotenode == -1)
+	return false;
+
+    if (doomcom->datalength != NetbufferSize ())
+    {
+	if (debugfile)
+	    fprintf (debugfile,"bad packet length %i\n",doomcom->datalength);
+	return false;
+    }
+	
+    if (NetbufferChecksum () != (netbuffer->checksum&NCMD_CHECKSUM) )
+    {
+	if (debugfile)
+	    fprintf (debugfile,"bad packet checksum\n");
+	return false;
+    }
+
+    if (debugfile)
+    {
+	int		realretrans;
+	int	i;
+			
+	if (netbuffer->checksum & NCMD_SETUP)
+	    fprintf (debugfile,"setup packet\n");
+	else
+	{
+	    if (netbuffer->checksum & NCMD_RETRANSMIT)
+		realretrans = ExpandTics (netbuffer->retransmitfrom);
+	    else
+		realretrans = -1;
+	    
+	    fprintf (debugfile,"get %i = (%i + %i, R %i)[%i] ",
+		     doomcom->remotenode,
+		     ExpandTics(netbuffer->starttic),
+		     netbuffer->numtics, realretrans, doomcom->datalength);
+
+	    for (i=0 ; i<doomcom->datalength ; i++)
+		fprintf (debugfile,"%i ",((byte *)netbuffer)[i]);
+	    fprintf (debugfile,"\n");
+	}
+    }
+    return true;	
+}
+
+
+//
+// GetPackets
+//
+char    exitmsg[80];
+
+void GetPackets (void)
+{
+    int		netconsole;
+    int		netnode;
+    ticcmd_t	*src, *dest;
+    int		realend;
+    int		realstart;
+				 
+    while ( HGetPacket() )
+    {
+	if (netbuffer->checksum & NCMD_SETUP)
+	    continue;		// extra setup packet
+			
+	netconsole = netbuffer->player & ~PL_DRONE;
+	netnode = doomcom->remotenode;
+	
+	// to save bytes, only the low byte of tic numbers are sent
+	// Figure out what the rest of the bytes are
+	realstart = ExpandTics (netbuffer->starttic);		
+	realend = (realstart+netbuffer->numtics);
+	
+	// check for exiting the game
+	if (netbuffer->checksum & NCMD_EXIT)
+	{
+	    if (!nodeingame[netnode])
+		continue;
+	    nodeingame[netnode] = false;
+	    playeringame[netconsole] = false;
+	    strcpy (exitmsg, "Player 1 left the game");
+	    exitmsg[7] += netconsole;
+	    players[consoleplayer].message = exitmsg;
+	    if (demorecording)
+		G_CheckDemoStatus ();
+	    continue;
+	}
+	
+	// check for a remote game kill
+	if (netbuffer->checksum & NCMD_KILL)
+	    I_Error ("Killed by network driver");
+
+	nodeforplayer[netconsole] = netnode;
+	
+	// check for retransmit request
+	if ( resendcount[netnode] <= 0 
+	     && (netbuffer->checksum & NCMD_RETRANSMIT) )
+	{
+	    resendto[netnode] = ExpandTics(netbuffer->retransmitfrom);
+	    if (debugfile)
+		fprintf (debugfile,"retransmit from %i\n", resendto[netnode]);
+	    resendcount[netnode] = RESENDCOUNT;
+	}
+	else
+	    resendcount[netnode]--;
+	
+	// check for out of order / duplicated packet		
+	if (realend == nettics[netnode])
+	    continue;
+			
+	if (realend < nettics[netnode])
+	{
+	    if (debugfile)
+		fprintf (debugfile,
+			 "out of order packet (%i + %i)\n" ,
+			 realstart,netbuffer->numtics);
+	    continue;
+	}
+	
+	// check for a missed packet
+	if (realstart > nettics[netnode])
+	{
+	    // stop processing until the other system resends the missed tics
+	    if (debugfile)
+		fprintf (debugfile,
+			 "missed tics from %i (%i - %i)\n",
+			 netnode, realstart, nettics[netnode]);
+	    remoteresend[netnode] = true;
+	    continue;
+	}
+
+	// update command store from the packet
+        {
+	    int		start;
+
+	    remoteresend[netnode] = false;
+		
+	    start = nettics[netnode] - realstart;		
+	    src = &netbuffer->cmds[start];
+
+	    while (nettics[netnode] < realend)
+	    {
+		dest = &netcmds[netconsole][nettics[netnode]%BACKUPTICS];
+		nettics[netnode]++;
+		*dest = *src;
+		src++;
+	    }
+	}
+    }
+}
+
+
+//
+// NetUpdate
+// Builds ticcmds for console player,
+// sends out a packet
+//
+int      gametime;
+
+void NetUpdate (void)
+{
+    int             nowtime;
+    int             newtics;
+    int				i,j;
+    int				realstart;
+    int				gameticdiv;
+    
+    // check time
+    nowtime = I_GetTime ()/ticdup;
+    newtics = nowtime - gametime;
+    gametime = nowtime;
+	
+    if (newtics <= 0) 	// nothing new to update
+	goto listen; 
+
+    if (skiptics <= newtics)
+    {
+	newtics -= skiptics;
+	skiptics = 0;
+    }
+    else
+    {
+	skiptics -= newtics;
+	newtics = 0;
+    }
+	
+		
+    netbuffer->player = consoleplayer;
+    
+    // build new ticcmds for console player
+    gameticdiv = gametic/ticdup;
+    for (i=0 ; i<newtics ; i++)
+    {
+	I_StartTic ();
+	D_ProcessEvents ();
+	if (maketic - gameticdiv >= BACKUPTICS/2-1)
+	    break;          // can't hold any more
+	
+	//printf ("mk:%i ",maketic);
+	G_BuildTiccmd (&localcmds[maketic%BACKUPTICS]);
+	maketic++;
+    }
+
+
+    if (singletics)
+	return;         // singletic update is syncronous
+    
+    // send the packet to the other nodes
+    for (i=0 ; i<doomcom->numnodes ; i++)
+	if (nodeingame[i])
+	{
+	    netbuffer->starttic = realstart = resendto[i];
+	    netbuffer->numtics = maketic - realstart;
+	    if (netbuffer->numtics > BACKUPTICS)
+		I_Error ("NetUpdate: netbuffer->numtics > BACKUPTICS");
+
+	    resendto[i] = maketic - doomcom->extratics;
+
+	    for (j=0 ; j< netbuffer->numtics ; j++)
+		netbuffer->cmds[j] = 
+		    localcmds[(realstart+j)%BACKUPTICS];
+					
+	    if (remoteresend[i])
+	    {
+		netbuffer->retransmitfrom = nettics[i];
+		HSendPacket (i, NCMD_RETRANSMIT);
+	    }
+	    else
+	    {
+		netbuffer->retransmitfrom = 0;
+		HSendPacket (i, 0);
+	    }
+	}
+    
+    // listen for other packets
+  listen:
+    GetPackets ();
+}
+
+
+
+//
+// CheckAbort
+//
+void CheckAbort (void)
+{
+    event_t *ev;
+    int		stoptic;
+	
+    stoptic = I_GetTime () + 2; 
+    while (I_GetTime() < stoptic) 
+	I_StartTic (); 
+	
+    I_StartTic ();
+    for ( ; eventtail != eventhead 
+	      ; eventtail = (++eventtail)&(MAXEVENTS-1) ) 
+    { 
+	ev = &events[eventtail]; 
+	if (ev->type == ev_keydown && ev->data1 == KEY_ESCAPE)
+	    I_Error ("Network game synchronization aborted.");
+    } 
+}
+
+
+//
+// D_ArbitrateNetStart
+//
+void D_ArbitrateNetStart (void)
+{
+    int		i;
+    boolean	gotinfo[MAXNETNODES];
+	
+    autostart = true;
+    memset (gotinfo,0,sizeof(gotinfo));
+	
+    if (doomcom->consoleplayer)
+    {
+	// listen for setup info from key player
+	printf ("listening for network start info...\n");
+	while (1)
+	{
+	    CheckAbort ();
+	    if (!HGetPacket ())
+		continue;
+	    if (netbuffer->checksum & NCMD_SETUP)
+	    {
+		if (netbuffer->player != VERSION)
+		    I_Error ("Different DOOM versions cannot play a net game!");
+		startskill = netbuffer->retransmitfrom & 15;
+		deathmatch = (netbuffer->retransmitfrom & 0xc0) >> 6;
+		nomonsters = (netbuffer->retransmitfrom & 0x20) > 0;
+		respawnparm = (netbuffer->retransmitfrom & 0x10) > 0;
+		startmap = netbuffer->starttic & 0x3f;
+		startepisode = netbuffer->starttic >> 6;
+		return;
+	    }
+	}
+    }
+    else
+    {
+	// key player, send the setup info
+	printf ("sending network start info...\n");
+	do
+	{
+	    CheckAbort ();
+	    for (i=0 ; i<doomcom->numnodes ; i++)
+	    {
+		netbuffer->retransmitfrom = startskill;
+		if (deathmatch)
+		    netbuffer->retransmitfrom |= (deathmatch<<6);
+		if (nomonsters)
+		    netbuffer->retransmitfrom |= 0x20;
+		if (respawnparm)
+		    netbuffer->retransmitfrom |= 0x10;
+		netbuffer->starttic = startepisode * 64 + startmap;
+		netbuffer->player = VERSION;
+		netbuffer->numtics = 0;
+		HSendPacket (i, NCMD_SETUP);
+	    }
+
+#if 1
+	    for(i = 10 ; i  &&  HGetPacket(); --i)
+	    {
+		if((netbuffer->player&0x7f) < MAXNETNODES)
+		    gotinfo[netbuffer->player&0x7f] = true;
+	    }
+#else
+	    while (HGetPacket ())
+	    {
+		gotinfo[netbuffer->player&0x7f] = true;
+	    }
+#endif
+
+	    for (i=1 ; i<doomcom->numnodes ; i++)
+		if (!gotinfo[i])
+		    break;
+	} while (i < doomcom->numnodes);
+    }
+}
+
+//
+// D_CheckNetGame
+// Works out player numbers among the net participants
+//
+extern	int			viewangleoffset;
+
+void D_CheckNetGame (void)
+{
+    int             i;
+	
+    for (i=0 ; i<MAXNETNODES ; i++)
+    {
+	nodeingame[i] = false;
+       	nettics[i] = 0;
+	remoteresend[i] = false;	// set when local needs tics
+	resendto[i] = 0;		// which tic to start sending
+    }
+	
+    // I_InitNetwork sets doomcom and netgame
+    I_InitNetwork ();
+    if (doomcom->id != DOOMCOM_ID)
+	I_Error ("Doomcom buffer invalid!");
+    
+    netbuffer = &doomcom->data;
+    consoleplayer = displayplayer = doomcom->consoleplayer;
+    if (netgame)
+	D_ArbitrateNetStart ();
+
+    printf ("startskill %i  deathmatch: %i  startmap: %i  startepisode: %i\n",
+	    startskill, deathmatch, startmap, startepisode);
+	
+    // read values out of doomcom
+    ticdup = doomcom->ticdup;
+    maxsend = BACKUPTICS/(2*ticdup)-1;
+    if (maxsend<1)
+	maxsend = 1;
+			
+    for (i=0 ; i<doomcom->numplayers ; i++)
+	playeringame[i] = true;
+    for (i=0 ; i<doomcom->numnodes ; i++)
+	nodeingame[i] = true;
+	
+    printf ("player %i of %i (%i nodes)\n",
+	    consoleplayer+1, doomcom->numplayers, doomcom->numnodes);
+
+}
+
+
+//
+// D_QuitNetGame
+// Called before quitting to leave a net game
+// without hanging the other players
+//
+void D_QuitNetGame (void)
+{
+    int             i, j;
+	
+    if (debugfile)
+	fclose (debugfile);
+		
+    if (!netgame || !usergame || consoleplayer == -1 || demoplayback)
+	return;
+	
+    // send a bunch of packets for security
+    netbuffer->player = consoleplayer;
+    netbuffer->numtics = 0;
+    for (i=0 ; i<4 ; i++)
+    {
+	for (j=1 ; j<doomcom->numnodes ; j++)
+	    if (nodeingame[j])
+		HSendPacket (j, NCMD_EXIT);
+	I_WaitVBL (1);
+    }
+}
+
+
+
+//
+// TryRunTics
+//
+int	frametics[4];
+int	frameon;
+int	frameskip[4];
+int	oldnettics;
+
+extern	boolean	advancedemo;
+
+void TryRunTics (void)
+{
+    int		i;
+    int		lowtic;
+    int		entertic;
+    static int	oldentertics;
+    int		realtics;
+    int		availabletics;
+    int		counts;
+    int		numplaying;
+    
+    // get real tics		
+    entertic = I_GetTime ()/ticdup;
+    realtics = entertic - oldentertics;
+    oldentertics = entertic;
+    
+    // get available tics
+    NetUpdate ();
+	
+    lowtic = MAXINT;
+    numplaying = 0;
+    for (i=0 ; i<doomcom->numnodes ; i++)
+    {
+	if (nodeingame[i])
+	{
+	    numplaying++;
+	    if (nettics[i] < lowtic)
+		lowtic = nettics[i];
+	}
+    }
+    availabletics = lowtic - gametic/ticdup;
+    
+    // decide how many tics to run
+    if (realtics < availabletics-1)
+	counts = realtics+1;
+    else if (realtics < availabletics)
+	counts = realtics;
+    else
+	counts = availabletics;
+    
+    if (counts < 1)
+	counts = 1;
+		
+    frameon++;
+
+    if (debugfile)
+	fprintf (debugfile,
+		 "=======real: %i  avail: %i  game: %i\n",
+		 realtics, availabletics,counts);
+
+    if (!demoplayback)
+    {	
+	// ideally nettics[0] should be 1 - 3 tics above lowtic
+	// if we are consistantly slower, speed up time
+	for (i=0 ; i<MAXPLAYERS ; i++)
+	    if (playeringame[i])
+		break;
+	if (consoleplayer == i)
+	{
+	    // the key player does not adapt
+	}
+	else
+	{
+	    if (nettics[0] <= nettics[nodeforplayer[i]])
+	    {
+		gametime--;
+		// printf ("-");
+	    }
+	    frameskip[frameon&3] = (oldnettics > nettics[nodeforplayer[i]]);
+	    oldnettics = nettics[0];
+	    if (frameskip[0] && frameskip[1] && frameskip[2] && frameskip[3])
+	    {
+		skiptics = 1;
+		// printf ("+");
+	    }
+	}
+    }// demoplayback
+	
+    // wait for new tics if needed
+    while (lowtic < gametic/ticdup + counts)	
+    {
+	NetUpdate ();   
+	lowtic = MAXINT;
+	
+	for (i=0 ; i<doomcom->numnodes ; i++)
+	    if (nodeingame[i] && nettics[i] < lowtic)
+		lowtic = nettics[i];
+	
+	if (lowtic < gametic/ticdup)
+	    I_Error ("TryRunTics: lowtic < gametic");
+				
+	// don't stay in here forever -- give the menu a chance to work
+	if (I_GetTime ()/ticdup - entertic >= 20)
+	{
+	    M_Ticker ();
+	    return;
+	} 
+    }
+    
+    // run the count * ticdup dics
+    while (counts--)
+    {
+	for (i=0 ; i<ticdup ; i++)
+	{
+	    if (gametic/ticdup > lowtic)
+		I_Error ("gametic>lowtic");
+	    if (advancedemo)
+		D_DoAdvanceDemo ();
+	    M_Ticker ();
+	    G_Ticker ();
+	    gametic++;
+	    
+	    // modify command for duplicated tics
+	    if (i != ticdup-1)
+	    {
+		ticcmd_t	*cmd;
+		int			buf;
+		int			j;
+				
+		buf = (gametic/ticdup)%BACKUPTICS; 
+		for (j=0 ; j<MAXPLAYERS ; j++)
+		{
+		    cmd = &netcmds[j][buf];
+		    cmd->chatchar = 0;
+		    if (cmd->buttons & BT_SPECIAL)
+			cmd->buttons = 0;
+		}
+	    }
+	}
+	NetUpdate ();	// check for new console commands
+    }
+}
--- /dev/null
+++ b/src/d_net.h
@@ -1,0 +1,152 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: d_net.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//	Networking stuff.
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __D_NET__
+#define __D_NET__
+
+#include "d_player.h"
+
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+
+//
+// Network play related stuff.
+// There is a data struct that stores network
+//  communication related stuff, and another
+//  one that defines the actual packets to
+//  be transmitted.
+//
+
+#define DOOMCOM_ID		0x12345678l
+
+// Max computers/players in a game.
+#define MAXNETNODES		8
+
+
+// Networking and tick handling related.
+#define BACKUPTICS		12
+
+typedef enum
+{
+    CMD_SEND	= 1,
+    CMD_GET	= 2
+
+} command_t;
+
+
+//
+// Network packet data.
+//
+typedef struct
+{
+    // High bit is retransmit request.
+    unsigned		checksum;
+    // Only valid if NCMD_RETRANSMIT.
+    byte		retransmitfrom;
+    
+    byte		starttic;
+    byte		player;
+    byte		numtics;
+    ticcmd_t		cmds[BACKUPTICS];
+
+} doomdata_t;
+
+
+
+
+typedef struct
+{
+    // Supposed to be DOOMCOM_ID?
+    long		id;
+    
+    // DOOM executes an int to execute commands.
+    short		intnum;		
+    // Communication between DOOM and the driver.
+    // Is CMD_SEND or CMD_GET.
+    short		command;
+    // Is dest for send, set by get (-1 = no packet).
+    short		remotenode;
+    
+    // Number of bytes in doomdata to be sent
+    short		datalength;
+
+    // Info common to all nodes.
+    // Console is allways node 0.
+    short		numnodes;
+    // Flag: 1 = no duplication, 2-5 = dup for slow nets.
+    short		ticdup;
+    // Flag: 1 = send a backup tic in every packet.
+    short		extratics;
+    // Flag: 1 = deathmatch.
+    short		deathmatch;
+    // Flag: -1 = new game, 0-5 = load savegame
+    short		savegame;
+    short		episode;	// 1-3
+    short		map;		// 1-9
+    short		skill;		// 1-5
+
+    // Info specific to this node.
+    short		consoleplayer;
+    short		numplayers;
+    
+    // These are related to the 3-display mode,
+    //  in which two drones looking left and right
+    //  were used to render two additional views
+    //  on two additional computers.
+    // Probably not operational anymore.
+    // 1 = left, 0 = center, -1 = right
+    short		angleoffset;
+    // 1 = drone
+    short		drone;		
+
+    // The packet data to be sent.
+    doomdata_t		data;
+    
+} doomcom_t;
+
+
+
+// Create any new ticcmds and broadcast to other players.
+void NetUpdate (void);
+
+// Broadcasts special packets to other players
+//  to notify of game exit
+void D_QuitNetGame (void);
+
+//? how many ticks to run?
+void TryRunTics (void);
+
+
+#endif
+
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:50  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
+
--- /dev/null
+++ b/src/d_player.h
@@ -1,0 +1,222 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: d_player.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __D_PLAYER__
+#define __D_PLAYER__
+
+
+// The player data structure depends on a number
+// of other structs: items (internal inventory),
+// animation states (closely tied to the sprites
+// used to represent them, unfortunately).
+#include "d_items.h"
+#include "p_pspr.h"
+
+// In addition, the player is just a special
+// case of the generic moving object/actor.
+#include "p_mobj.h"
+
+// Finally, for odd reasons, the player input
+// is buffered within the player data struct,
+// as commands per game tick.
+#include "d_ticcmd.h"
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+
+
+
+//
+// Player states.
+//
+typedef enum
+{
+    // Playing or camping.
+    PST_LIVE,
+    // Dead on the ground, view follows killer.
+    PST_DEAD,
+    // Ready to restart/respawn???
+    PST_REBORN		
+
+} playerstate_t;
+
+
+//
+// Player internal flags, for cheats and debug.
+//
+typedef enum
+{
+    // No clipping, walk through barriers.
+    CF_NOCLIP		= 1,
+    // No damage, no health loss.
+    CF_GODMODE		= 2,
+    // Not really a cheat, just a debug aid.
+    CF_NOMOMENTUM	= 4
+
+} cheat_t;
+
+
+//
+// Extended player object info: player_t
+//
+typedef struct player_s
+{
+    mobj_t*		mo;
+    playerstate_t	playerstate;
+    ticcmd_t		cmd;
+
+    // Determine POV,
+    //  including viewpoint bobbing during movement.
+    // Focal origin above r.z
+    fixed_t		viewz;
+    // Base height above floor for viewz.
+    fixed_t		viewheight;
+    // Bob/squat speed.
+    fixed_t         	deltaviewheight;
+    // bounded/scaled total momentum.
+    fixed_t         	bob;	
+
+    // This is only used between levels,
+    // mo->health is used during levels.
+    int			health;	
+    int			armorpoints;
+    // Armor type is 0-2.
+    int			armortype;	
+
+    // Power ups. invinc and invis are tic counters.
+    int			powers[NUMPOWERS];
+    boolean		cards[NUMCARDS];
+    boolean		backpack;
+    
+    // Frags, kills of other players.
+    int			frags[MAXPLAYERS];
+    weapontype_t	readyweapon;
+    
+    // Is wp_nochange if not changing.
+    weapontype_t	pendingweapon;
+
+    boolean		weaponowned[NUMWEAPONS];
+    int			ammo[NUMAMMO];
+    int			maxammo[NUMAMMO];
+
+    // True if button down last tic.
+    int			attackdown;
+    int			usedown;
+
+    // Bit flags, for cheats and debug.
+    // See cheat_t, above.
+    int			cheats;		
+
+    // Refired shots are less accurate.
+    int			refire;		
+
+     // For intermission stats.
+    int			killcount;
+    int			itemcount;
+    int			secretcount;
+
+    // Hint messages.
+    char*		message;	
+    
+    // For screen flashing (red or bright).
+    int			damagecount;
+    int			bonuscount;
+
+    // Who did damage (NULL for floors/ceilings).
+    mobj_t*		attacker;
+    
+    // So gun flashes light up areas.
+    int			extralight;
+
+    // Current PLAYPAL, ???
+    //  can be set to REDCOLORMAP for pain, etc.
+    int			fixedcolormap;
+
+    // Player skin colorshift,
+    //  0-3 for which color to draw player.
+    int			colormap;	
+
+    // Overlay view sprites (gun, etc).
+    pspdef_t		psprites[NUMPSPRITES];
+
+    // True if secret level has been done.
+    boolean		didsecret;	
+
+} player_t;
+
+
+//
+// INTERMISSION
+// Structure passed e.g. to WI_Start(wb)
+//
+typedef struct
+{
+    boolean	in;	// whether the player is in game
+    
+    // Player stats, kills, collected items etc.
+    int		skills;
+    int		sitems;
+    int		ssecret;
+    int		stime; 
+    int		frags[4];
+    int		score;	// current score on entry, modified on return
+  
+} wbplayerstruct_t;
+
+typedef struct
+{
+    int		epsd;	// episode # (0-2)
+
+    // if true, splash the secret level
+    boolean	didsecret;
+    
+    // previous and next levels, origin 0
+    int		last;
+    int		next;	
+    
+    int		maxkills;
+    int		maxitems;
+    int		maxsecret;
+    int		maxfrags;
+
+    // the par time
+    int		partime;
+    
+    // index of this player in game
+    int		pnum;	
+
+    wbplayerstruct_t	plyr[MAXPLAYERS];
+
+} wbstartstruct_t;
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:28  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/d_textur.h
@@ -1,0 +1,54 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: d_textur.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//	Typedefs related to to textures etc.,
+//	 isolated here to make it easier separating modules.
+//    
+//-----------------------------------------------------------------------------
+
+
+#ifndef __D_TEXTUR__
+#define __D_TEXTUR__
+
+#include "doomtype.h"
+
+
+
+
+//
+// Flats?
+//
+// a pic is an unmasked block of pixels
+typedef struct
+{
+    byte		width;
+    byte		height;
+    byte		data;
+} pic_t;
+
+
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:00  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/d_think.h
@@ -1,0 +1,82 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: d_think.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//  MapObj data. Map Objects or mobjs are actors, entities,
+//  thinker, take-your-pick... anything that moves, acts, or
+//  suffers state changes of more or less violent nature.
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __D_THINK__
+#define __D_THINK__
+
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+
+
+//
+// Experimental stuff.
+// To compile this as "ANSI C with classes"
+//  we will need to handle the various
+//  action functions cleanly.
+//
+typedef  void (*actionf_v)();
+typedef  void (*actionf_p1)( void* );
+typedef  void (*actionf_p2)( void*, void* );
+
+typedef union
+{
+  actionf_p1	acp1;
+  actionf_v	acv;
+  actionf_p2	acp2;
+
+} actionf_t;
+
+
+
+
+
+// Historically, "think_t" is yet another
+//  function pointer to a routine to handle
+//  an actor.
+typedef actionf_t  think_t;
+
+
+// Doubly linked list of actors.
+typedef struct thinker_s
+{
+    struct thinker_s*	prev;
+    struct thinker_s*	next;
+    think_t		function;
+    
+} thinker_t;
+
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:19:44  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/d_ticcmd.h
@@ -1,0 +1,56 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: d_ticcmd.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//	System specific interface stuff.
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __D_TICCMD__
+#define __D_TICCMD__
+
+#include "doomtype.h"
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+// The data sampled per tick (single player)
+// and transmitted to other peers (multiplayer).
+// Mainly movements/button commands per game tick,
+// plus a checksum for internal state consistency.
+typedef struct
+{
+    char	forwardmove;	// *2048 for move
+    char	sidemove;	// *2048 for move
+    short	angleturn;	// <<16 for angle delta
+    short	consistancy;	// checks for net game
+    byte	chatchar;
+    byte	buttons;
+} ticcmd_t;
+
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:13  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/doomdata.h
@@ -1,0 +1,225 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: doomdata.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//  all external data is defined here
+//  most of the data is loaded into different structures at run time
+//  some internal structures shared by many modules are here
+//
+//-----------------------------------------------------------------------------
+
+#ifndef __DOOMDATA__
+#define __DOOMDATA__
+
+// The most basic types we use, portability.
+#include "doomtype.h"
+
+// Some global defines, that configure the game.
+#include "doomdef.h"
+
+
+
+//
+// Map level types.
+// The following data structures define the persistent format
+// used in the lumps of the WAD files.
+//
+
+// Lump order in a map WAD: each map needs a couple of lumps
+// to provide a complete scene geometry description.
+enum
+{
+  ML_LABEL,		// A separator, name, ExMx or MAPxx
+  ML_THINGS,		// Monsters, items..
+  ML_LINEDEFS,		// LineDefs, from editing
+  ML_SIDEDEFS,		// SideDefs, from editing
+  ML_VERTEXES,		// Vertices, edited and BSP splits generated
+  ML_SEGS,		// LineSegs, from LineDefs split by BSP
+  ML_SSECTORS,		// SubSectors, list of LineSegs
+  ML_NODES,		// BSP nodes
+  ML_SECTORS,		// Sectors, from editing
+  ML_REJECT,		// LUT, sector-sector visibility	
+  ML_BLOCKMAP		// LUT, motion clipping, walls/grid element
+};
+
+
+// A single Vertex.
+typedef struct
+{
+  short		x;
+  short		y;
+} mapvertex_t;
+
+
+// A SideDef, defining the visual appearance of a wall,
+// by setting textures and offsets.
+typedef struct
+{
+  short		textureoffset;
+  short		rowoffset;
+  char		toptexture[8];
+  char		bottomtexture[8];
+  char		midtexture[8];
+  // Front sector, towards viewer.
+  short		sector;
+} mapsidedef_t;
+
+
+
+// A LineDef, as used for editing, and as input
+// to the BSP builder.
+typedef struct
+{
+  short		v1;
+  short		v2;
+  short		flags;
+  short		special;
+  short		tag;
+  // sidenum[1] will be -1 if one sided
+  short		sidenum[2];		
+} maplinedef_t;
+
+
+//
+// LineDef attributes.
+//
+
+// Solid, is an obstacle.
+#define ML_BLOCKING		1
+
+// Blocks monsters only.
+#define ML_BLOCKMONSTERS	2
+
+// Backside will not be present at all
+//  if not two sided.
+#define ML_TWOSIDED		4
+
+// If a texture is pegged, the texture will have
+// the end exposed to air held constant at the
+// top or bottom of the texture (stairs or pulled
+// down things) and will move with a height change
+// of one of the neighbor sectors.
+// Unpegged textures allways have the first row of
+// the texture at the top pixel of the line for both
+// top and bottom textures (use next to windows).
+
+// upper texture unpegged
+#define ML_DONTPEGTOP		8
+
+// lower texture unpegged
+#define ML_DONTPEGBOTTOM	16	
+
+// In AutoMap: don't map as two sided: IT'S A SECRET!
+#define ML_SECRET		32
+
+// Sound rendering: don't let sound cross two of these.
+#define ML_SOUNDBLOCK		64
+
+// Don't draw on the automap at all.
+#define ML_DONTDRAW		128
+
+// Set if already seen, thus drawn in automap.
+#define ML_MAPPED		256
+
+
+
+
+// Sector definition, from editing.
+typedef	struct
+{
+  short		floorheight;
+  short		ceilingheight;
+  char		floorpic[8];
+  char		ceilingpic[8];
+  short		lightlevel;
+  short		special;
+  short		tag;
+} mapsector_t;
+
+// SubSector, as generated by BSP.
+typedef struct
+{
+  short		numsegs;
+  // Index of first one, segs are stored sequentially.
+  short		firstseg;	
+} mapsubsector_t;
+
+
+// LineSeg, generated by splitting LineDefs
+// using partition lines selected by BSP builder.
+typedef struct
+{
+  short		v1;
+  short		v2;
+  short		angle;		
+  short		linedef;
+  short		side;
+  short		offset;
+} mapseg_t;
+
+
+
+// BSP node structure.
+
+// Indicate a leaf.
+#define	NF_SUBSECTOR	0x8000
+
+typedef struct
+{
+  // Partition line from (x,y) to x+dx,y+dy)
+  short		x;
+  short		y;
+  short		dx;
+  short		dy;
+
+  // Bounding box for each child,
+  // clip against view frustum.
+  short		bbox[2][4];
+
+  // If NF_SUBSECTOR its a subsector,
+  // else it's a node of another subtree.
+  unsigned short	children[2];
+
+} mapnode_t;
+
+
+
+
+// Thing definition, position, orientation and type,
+// plus skill/visibility flags and attributes.
+typedef struct
+{
+    short		x;
+    short		y;
+    short		angle;
+    short		type;
+    short		options;
+} mapthing_t;
+
+
+
+
+
+#endif			// __DOOMDATA__
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:00  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
+
--- /dev/null
+++ b/src/doomdef.c
@@ -1,0 +1,41 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: doomdef.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:19:42  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//  DoomDef - basic defines for DOOM, e.g. Version, game mode
+//   and skill level, and display parameters.
+//
+//-----------------------------------------------------------------------------
+
+static const char
+rcsid[] = "$Id: doomdef.c 4 2005-07-23 16:19:41Z fraggle $";
+
+
+#ifdef __GNUG__
+#pragma implementation "doomdef.h"
+#endif
+#include "doomdef.h"
+
+// Location for any defines turned variables.
+
+// None.
+
+
--- /dev/null
+++ b/src/doomdef.h
@@ -1,0 +1,341 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: doomdef.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//  Internally used data structures for virtually everything,
+//   key definitions, lots of other stuff.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef __DOOMDEF__
+#define __DOOMDEF__
+
+#include <stdio.h>
+#include <string.h>
+
+//
+// Global parameters/defines.
+//
+// DOOM version
+enum { VERSION =  110 };
+
+
+// Game mode handling - identify IWAD version
+//  to handle IWAD dependend animations etc.
+typedef enum
+{
+  shareware,	// DOOM 1 shareware, E1, M9
+  registered,	// DOOM 1 registered, E3, M27
+  commercial,	// DOOM 2 retail, E1 M34
+  // DOOM 2 german edition not handled
+  retail,	// DOOM 1 retail, E4, M36
+  indetermined	// Well, no IWAD found.
+  
+} GameMode_t;
+
+
+// Mission packs - might be useful for TC stuff?
+typedef enum
+{
+  doom,		// DOOM 1
+  doom2,	// DOOM 2
+  pack_tnt,	// TNT mission pack
+  pack_plut,	// Plutonia pack
+  none
+
+} GameMission_t;
+
+
+// Identify language to use, software localization.
+typedef enum
+{
+  english,
+  french,
+  german,
+  unknown
+
+} Language_t;
+
+
+// If rangecheck is undefined,
+// most parameter validation debugging code will not be compiled
+#define RANGECHECK
+
+// Do or do not use external soundserver.
+// The sndserver binary to be run separately
+//  has been introduced by Dave Taylor.
+// The integrated sound support is experimental,
+//  and unfinished. Default is synchronous.
+// Experimental asynchronous timer based is
+//  handled by SNDINTR. 
+#define SNDSERV  1
+//#define SNDINTR  1
+
+
+// This one switches between MIT SHM (no proper mouse)
+// and XFree86 DGA (mickey sampling). The original
+// linuxdoom used SHM, which is default.
+//#define X11_DGA		1
+
+
+//
+// For resize of screen, at start of game.
+// It will not work dynamically, see visplanes.
+//
+#define	BASE_WIDTH		320
+
+// It is educational but futile to change this
+//  scaling e.g. to 2. Drawing of status bar,
+//  menues etc. is tied to the scale implied
+//  by the graphics.
+#define	SCREEN_MUL		1
+#define	INV_ASPECT_RATIO	0.625 // 0.75, ideally
+
+// Defines suck. C sucks.
+// C++ might sucks for OOP, but it sure is a better C.
+// So there.
+#define SCREENWIDTH  320
+//SCREEN_MUL*BASE_WIDTH //320
+#define SCREENHEIGHT 200
+//(int)(SCREEN_MUL*BASE_WIDTH*INV_ASPECT_RATIO) //200
+
+
+
+
+// The maximum number of players, multiplayer/networking.
+#define MAXPLAYERS		4
+
+// State updates, number of tics / second.
+#define TICRATE		35
+
+// The current state of the game: whether we are
+// playing, gazing at the intermission screen,
+// the game final animation, or a demo. 
+typedef enum
+{
+    GS_LEVEL,
+    GS_INTERMISSION,
+    GS_FINALE,
+    GS_DEMOSCREEN
+} gamestate_t;
+
+//
+// Difficulty/skill settings/filters.
+//
+
+// Skill flags.
+#define	MTF_EASY		1
+#define	MTF_NORMAL		2
+#define	MTF_HARD		4
+
+// Deaf monsters/do not react to sound.
+#define	MTF_AMBUSH		8
+
+typedef enum
+{
+    sk_baby,
+    sk_easy,
+    sk_medium,
+    sk_hard,
+    sk_nightmare
+} skill_t;
+
+
+
+
+//
+// Key cards.
+//
+typedef enum
+{
+    it_bluecard,
+    it_yellowcard,
+    it_redcard,
+    it_blueskull,
+    it_yellowskull,
+    it_redskull,
+    
+    NUMCARDS
+    
+} card_t;
+
+
+
+// The defined weapons,
+//  including a marker indicating
+//  user has not changed weapon.
+typedef enum
+{
+    wp_fist,
+    wp_pistol,
+    wp_shotgun,
+    wp_chaingun,
+    wp_missile,
+    wp_plasma,
+    wp_bfg,
+    wp_chainsaw,
+    wp_supershotgun,
+
+    NUMWEAPONS,
+    
+    // No pending weapon change.
+    wp_nochange
+
+} weapontype_t;
+
+
+// Ammunition types defined.
+typedef enum
+{
+    am_clip,	// Pistol / chaingun ammo.
+    am_shell,	// Shotgun / double barreled shotgun.
+    am_cell,	// Plasma rifle, BFG.
+    am_misl,	// Missile launcher.
+    NUMAMMO,
+    am_noammo	// Unlimited for chainsaw / fist.	
+
+} ammotype_t;
+
+
+// Power up artifacts.
+typedef enum
+{
+    pw_invulnerability,
+    pw_strength,
+    pw_invisibility,
+    pw_ironfeet,
+    pw_allmap,
+    pw_infrared,
+    NUMPOWERS
+    
+} powertype_t;
+
+
+
+//
+// Power up durations,
+//  how many seconds till expiration,
+//  assuming TICRATE is 35 ticks/second.
+//
+typedef enum
+{
+    INVULNTICS	= (30*TICRATE),
+    INVISTICS	= (60*TICRATE),
+    INFRATICS	= (120*TICRATE),
+    IRONTICS	= (60*TICRATE)
+    
+} powerduration_t;
+
+
+
+
+//
+// DOOM keyboard definition.
+// This is the stuff configured by Setup.Exe.
+// Most key data are simple ascii (uppercased).
+//
+#define KEY_RIGHTARROW	0xae
+#define KEY_LEFTARROW	0xac
+#define KEY_UPARROW	0xad
+#define KEY_DOWNARROW	0xaf
+#define KEY_ESCAPE	27
+#define KEY_ENTER	13
+#define KEY_TAB		9
+#define KEY_F1		(0x80+0x3b)
+#define KEY_F2		(0x80+0x3c)
+#define KEY_F3		(0x80+0x3d)
+#define KEY_F4		(0x80+0x3e)
+#define KEY_F5		(0x80+0x3f)
+#define KEY_F6		(0x80+0x40)
+#define KEY_F7		(0x80+0x41)
+#define KEY_F8		(0x80+0x42)
+#define KEY_F9		(0x80+0x43)
+#define KEY_F10		(0x80+0x44)
+#define KEY_F11		(0x80+0x57)
+#define KEY_F12		(0x80+0x58)
+
+#define KEY_BACKSPACE	127
+#define KEY_PAUSE	0xff
+
+#define KEY_EQUALS	0x3d
+#define KEY_MINUS	0x2d
+
+#define KEY_RSHIFT	(0x80+0x36)
+#define KEY_RCTRL	(0x80+0x1d)
+#define KEY_RALT	(0x80+0x38)
+
+#define KEY_LALT	KEY_RALT
+
+
+
+// DOOM basic types (boolean),
+//  and max/min values.
+//#include "doomtype.h"
+
+// Fixed point.
+//#include "m_fixed.h"
+
+// Endianess handling.
+//#include "m_swap.h"
+
+
+// Binary Angles, sine/cosine/atan lookups.
+//#include "tables.h"
+
+// Event type.
+//#include "d_event.h"
+
+// Game function, skills.
+//#include "g_game.h"
+
+// All external data is defined here.
+//#include "doomdata.h"
+
+// All important printed strings.
+// Language selection (message strings).
+//#include "dstrings.h"
+
+// Player is a special actor.
+//struct player_s;
+
+
+//#include "d_items.h"
+//#include "d_player.h"
+//#include "p_mobj.h"
+//#include "d_net.h"
+
+// PLAY
+//#include "p_tick.h"
+
+
+
+
+// Header, generated by sound utility.
+// The utility was written by Dave Taylor.
+//#include "sounds.h"
+
+
+
+
+#endif          // __DOOMDEF__
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:19:43  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/doomstat.c
@@ -1,0 +1,49 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: doomstat.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:07  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//	Put all global tate variables here.
+//
+//-----------------------------------------------------------------------------
+
+static const char
+rcsid[] = "$Id: doomstat.c 4 2005-07-23 16:19:41Z fraggle $";
+
+
+#ifdef __GNUG__
+#pragma implementation "doomstat.h"
+#endif
+#include "doomstat.h"
+
+
+// Game Mode - identify IWAD as shareware, retail etc.
+GameMode_t gamemode = indetermined;
+GameMission_t	gamemission = doom;
+
+// Language.
+Language_t   language = english;
+
+// Set if homebrew PWAD stuff has been added.
+boolean	modifiedgame;
+
+
+
+
--- /dev/null
+++ b/src/doomstat.h
@@ -1,0 +1,299 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: doomstat.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//   All the global variables that store the internal state.
+//   Theoretically speaking, the internal state of the engine
+//    should be found by looking at the variables collected
+//    here, and every relevant module will have to include
+//    this header file.
+//   In practice, things are a bit messy.
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __D_STATE__
+#define __D_STATE__
+
+// We need globally shared data structures,
+//  for defining the global state variables.
+#include "doomdata.h"
+#include "d_net.h"
+
+// We need the playr data structure as well.
+#include "d_player.h"
+
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+
+
+// ------------------------
+// Command line parameters.
+//
+extern  boolean	nomonsters;	// checkparm of -nomonsters
+extern  boolean	respawnparm;	// checkparm of -respawn
+extern  boolean	fastparm;	// checkparm of -fast
+
+extern  boolean	devparm;	// DEBUG: launched with -devparm
+
+
+
+// -----------------------------------------------------
+// Game Mode - identify IWAD as shareware, retail etc.
+//
+extern GameMode_t	gamemode;
+extern GameMission_t	gamemission;
+
+// Set if homebrew PWAD stuff has been added.
+extern  boolean	modifiedgame;
+
+
+// -------------------------------------------
+// Language.
+extern  Language_t   language;
+
+
+// -------------------------------------------
+// Selected skill type, map etc.
+//
+
+// Defaults for menu, methinks.
+extern  skill_t		startskill;
+extern  int             startepisode;
+extern	int		startmap;
+
+extern  boolean		autostart;
+
+// Selected by user. 
+extern  skill_t         gameskill;
+extern  int		gameepisode;
+extern  int		gamemap;
+
+// Nightmare mode flag, single player.
+extern  boolean         respawnmonsters;
+
+// Netgame? Only true if >1 player.
+extern  boolean	netgame;
+
+// Flag: true only if started as net deathmatch.
+// An enum might handle altdeath/cooperative better.
+extern  boolean	deathmatch;	
+	
+// -------------------------
+// Internal parameters for sound rendering.
+// These have been taken from the DOS version,
+//  but are not (yet) supported with Linux
+//  (e.g. no sound volume adjustment with menu.
+
+// These are not used, but should be (menu).
+// From m_menu.c:
+//  Sound FX volume has default, 0 - 15
+//  Music volume has default, 0 - 15
+// These are multiplied by 8.
+extern int snd_SfxVolume;      // maximum volume for sound
+extern int snd_MusicVolume;    // maximum volume for music
+
+// Current music/sfx card - index useless
+//  w/o a reference LUT in a sound module.
+// Ideally, this would use indices found
+//  in: /usr/include/linux/soundcard.h
+extern int snd_MusicDevice;
+extern int snd_SfxDevice;
+// Config file? Same disclaimer as above.
+extern int snd_DesiredMusicDevice;
+extern int snd_DesiredSfxDevice;
+
+
+// -------------------------
+// Status flags for refresh.
+//
+
+// Depending on view size - no status bar?
+// Note that there is no way to disable the
+//  status bar explicitely.
+extern  boolean statusbaractive;
+
+extern  boolean automapactive;	// In AutoMap mode?
+extern  boolean	menuactive;	// Menu overlayed?
+extern  boolean	paused;		// Game Pause?
+
+
+extern  boolean		viewactive;
+
+extern  boolean		nodrawers;
+extern  boolean		noblit;
+
+extern	int		viewwindowx;
+extern	int		viewwindowy;
+extern	int		viewheight;
+extern	int		viewwidth;
+extern	int		scaledviewwidth;
+
+
+
+
+
+
+// This one is related to the 3-screen display mode.
+// ANG90 = left side, ANG270 = right
+extern  int	viewangleoffset;
+
+// Player taking events, and displaying.
+extern  int	consoleplayer;	
+extern  int	displayplayer;
+
+
+// -------------------------------------
+// Scores, rating.
+// Statistics on a given map, for intermission.
+//
+extern  int	totalkills;
+extern	int	totalitems;
+extern	int	totalsecret;
+
+// Timer, for scores.
+extern  int	levelstarttic;	// gametic at level start
+extern  int	leveltime;	// tics in game play for par
+
+
+
+// --------------------------------------
+// DEMO playback/recording related stuff.
+// No demo, there is a human player in charge?
+// Disable save/end game?
+extern  boolean	usergame;
+
+//?
+extern  boolean	demoplayback;
+extern  boolean	demorecording;
+
+// Quit after playing a demo from cmdline.
+extern  boolean		singledemo;	
+
+
+
+
+//?
+extern  gamestate_t     gamestate;
+
+
+
+
+
+
+//-----------------------------
+// Internal parameters, fixed.
+// These are set by the engine, and not changed
+//  according to user inputs. Partly load from
+//  WAD, partly set at startup time.
+
+
+
+extern	int		gametic;
+
+
+// Bookkeeping on players - state.
+extern	player_t	players[MAXPLAYERS];
+
+// Alive? Disconnected?
+extern  boolean		playeringame[MAXPLAYERS];
+
+
+// Player spawn spots for deathmatch.
+#define MAX_DM_STARTS   10
+extern  mapthing_t      deathmatchstarts[MAX_DM_STARTS];
+extern  mapthing_t*	deathmatch_p;
+
+// Player spawn spots.
+extern  mapthing_t      playerstarts[MAXPLAYERS];
+
+// Intermission stats.
+// Parameters for world map / intermission.
+extern  wbstartstruct_t		wminfo;	
+
+
+// LUT of ammunition limits for each kind.
+// This doubles with BackPack powerup item.
+extern  int		maxammo[NUMAMMO];
+
+
+
+
+
+//-----------------------------------------
+// Internal parameters, used for engine.
+//
+
+// File handling stuff.
+extern	char		basedefault[1024];
+extern  FILE*		debugfile;
+
+// if true, load all graphics at level load
+extern  boolean         precache;
+
+
+// wipegamestate can be set to -1
+//  to force a wipe on the next draw
+extern  gamestate_t     wipegamestate;
+
+extern  int             mouseSensitivity;
+//?
+// debug flag to cancel adaptiveness
+extern  boolean         singletics;	
+
+extern  int             bodyqueslot;
+
+
+
+// Needed to store the number of the dummy sky flat.
+// Used for rendering,
+//  as well as tracking projectiles etc.
+extern int		skyflatnum;
+
+
+
+// Netgame stuff (buffers and pointers, i.e. indices).
+
+// This is ???
+extern  doomcom_t*	doomcom;
+
+// This points inside doomcom.
+extern  doomdata_t*	netbuffer;	
+
+
+extern  ticcmd_t	localcmds[BACKUPTICS];
+extern	int		rndindex;
+
+extern	int		maketic;
+extern  int             nettics[MAXNETNODES];
+
+extern  ticcmd_t        netcmds[MAXPLAYERS][BACKUPTICS];
+extern	int		ticdup;
+
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:09  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/doomtype.h
@@ -1,0 +1,69 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: doomtype.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//	Simple basic typedefs, isolated here to make it easier
+//	 separating modules.
+//    
+//-----------------------------------------------------------------------------
+
+
+#ifndef __DOOMTYPE__
+#define __DOOMTYPE__
+
+
+#ifndef __BYTEBOOL__
+#define __BYTEBOOL__
+// Fixed to use builtin bool type with C++.
+#ifdef __cplusplus
+typedef bool boolean;
+#else
+typedef enum {false, true} boolean;
+#endif
+typedef unsigned char byte;
+#endif
+
+
+// Predefined with some OS.
+#ifdef LINUX
+#include <values.h>
+#else
+#define MAXCHAR		((char)0x7f)
+#define MAXSHORT	((short)0x7fff)
+
+// Max pos 32-bit int.
+#define MAXINT		((int)0x7fffffff)	
+#define MAXLONG		((long)0x7fffffff)
+#define MINCHAR		((char)0x80)
+#define MINSHORT	((short)0x8000)
+
+// Max negative 32-bit integer.
+#define MININT		((int)0x80000000)	
+#define MINLONG		((long)0x80000000)
+#endif
+
+
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:13  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/dstrings.c
@@ -1,0 +1,75 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: dstrings.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:13  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//	Globally defined strings.
+// 
+//-----------------------------------------------------------------------------
+
+static const char
+rcsid[] = "$Id: dstrings.c 4 2005-07-23 16:19:41Z fraggle $";
+
+
+#ifdef __GNUG__
+#pragma implementation "dstrings.h"
+#endif
+#include "dstrings.h"
+
+
+
+char* endmsg[NUM_QUITMESSAGES+1]=
+{
+  // DOOM1
+  QUITMSG,
+  "please don't leave, there's more\ndemons to toast!",
+  "let's beat it -- this is turning\ninto a bloodbath!",
+  "i wouldn't leave if i were you.\ndos is much worse.",
+  "you're trying to say you like dos\nbetter than me, right?",
+  "don't leave yet -- there's a\ndemon around that corner!",
+  "ya know, next time you come in here\ni'm gonna toast ya.",
+  "go ahead and leave. see if i care."
+
+  // QuitDOOM II messages
+  "you want to quit?\nthen, thou hast lost an eighth!",
+  "don't go now, there's a \ndimensional shambler waiting\nat the dos prompt!",
+  "get outta here and go back\nto your boring programs.",
+  "if i were your boss, i'd \n deathmatch ya in a minute!",
+  "look, bud. you leave now\nand you forfeit your body count!",
+  "just leave. when you come\nback, i'll be waiting with a bat.",
+  "you're lucky i don't smack\nyou for thinking about leaving."
+
+  // FinalDOOM?
+  "fuck you, pussy!\nget the fuck out!",
+  "you quit and i'll jizz\nin your cystholes!",
+  "if you leave, i'll make\nthe lord drink my jizz.",
+  "hey, ron! can we say\n'fuck' in the game?",
+  "i'd leave: this is just\nmore monsters and levels.\nwhat a load.",
+  "suck it down, asshole!\nyou're a fucking wimp!",
+  "don't quit now! we're \nstill spending your money!",
+
+  // Internal debug. Different style, too.
+  "THIS IS NO MESSAGE!\nPage intentionally left blank."
+};
+
+
+  
+
+
--- /dev/null
+++ b/src/dstrings.h
@@ -1,0 +1,72 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: dstrings.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:13  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//	DOOM strings, by language.
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __DSTRINGS__
+#define __DSTRINGS__
+
+
+// All important printed strings.
+// Language selection (message strings).
+// Use -DFRENCH etc.
+
+#ifdef FRENCH
+#include "d_french.h"
+#else
+#include "d_englsh.h"
+#endif
+
+// Misc. other strings.
+#define SAVEGAMENAME	"doomsav"
+
+
+//
+// File locations,
+//  relative to current position.
+// Path names are OS-sensitive.
+//
+#define DEVMAPS "devmaps"
+#define DEVDATA "devdata"
+
+
+// Not done in french?
+
+// QuitDOOM messages
+#define NUM_QUITMESSAGES   22
+
+extern char* endmsg[];
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:13  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/f_finale.c
@@ -1,0 +1,741 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: f_finale.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:31  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//	Game completion, final screen animation.
+//
+//-----------------------------------------------------------------------------
+
+
+static const char
+rcsid[] = "$Id: f_finale.c 4 2005-07-23 16:19:41Z fraggle $";
+
+#include <ctype.h>
+
+// Functions.
+#include "i_system.h"
+#include "m_swap.h"
+#include "z_zone.h"
+#include "v_video.h"
+#include "w_wad.h"
+#include "s_sound.h"
+
+// Data.
+#include "dstrings.h"
+#include "sounds.h"
+
+#include "doomstat.h"
+#include "r_state.h"
+
+// ?
+//#include "doomstat.h"
+//#include "r_local.h"
+//#include "f_finale.h"
+
+// Stage of animation:
+//  0 = text, 1 = art screen, 2 = character cast
+int		finalestage;
+
+int		finalecount;
+
+#define	TEXTSPEED	3
+#define	TEXTWAIT	250
+
+char*	e1text = E1TEXT;
+char*	e2text = E2TEXT;
+char*	e3text = E3TEXT;
+char*	e4text = E4TEXT;
+
+char*	c1text = C1TEXT;
+char*	c2text = C2TEXT;
+char*	c3text = C3TEXT;
+char*	c4text = C4TEXT;
+char*	c5text = C5TEXT;
+char*	c6text = C6TEXT;
+
+char*	p1text = P1TEXT;
+char*	p2text = P2TEXT;
+char*	p3text = P3TEXT;
+char*	p4text = P4TEXT;
+char*	p5text = P5TEXT;
+char*	p6text = P6TEXT;
+
+char*	t1text = T1TEXT;
+char*	t2text = T2TEXT;
+char*	t3text = T3TEXT;
+char*	t4text = T4TEXT;
+char*	t5text = T5TEXT;
+char*	t6text = T6TEXT;
+
+char*	finaletext;
+char*	finaleflat;
+
+void	F_StartCast (void);
+void	F_CastTicker (void);
+boolean F_CastResponder (event_t *ev);
+void	F_CastDrawer (void);
+
+//
+// F_StartFinale
+//
+void F_StartFinale (void)
+{
+    gameaction = ga_nothing;
+    gamestate = GS_FINALE;
+    viewactive = false;
+    automapactive = false;
+
+    // Okay - IWAD dependend stuff.
+    // This has been changed severly, and
+    //  some stuff might have changed in the process.
+    switch ( gamemode )
+    {
+
+      // DOOM 1 - E1, E3 or E4, but each nine missions
+      case shareware:
+      case registered:
+      case retail:
+      {
+	S_ChangeMusic(mus_victor, true);
+	
+	switch (gameepisode)
+	{
+	  case 1:
+	    finaleflat = "FLOOR4_8";
+	    finaletext = e1text;
+	    break;
+	  case 2:
+	    finaleflat = "SFLR6_1";
+	    finaletext = e2text;
+	    break;
+	  case 3:
+	    finaleflat = "MFLR8_4";
+	    finaletext = e3text;
+	    break;
+	  case 4:
+	    finaleflat = "MFLR8_3";
+	    finaletext = e4text;
+	    break;
+	  default:
+	    // Ouch.
+	    break;
+	}
+	break;
+      }
+      
+      // DOOM II and missions packs with E1, M34
+      case commercial:
+      {
+	  S_ChangeMusic(mus_read_m, true);
+
+	  switch (gamemap)
+	  {
+	    case 6:
+	      finaleflat = "SLIME16";
+	      finaletext = c1text;
+	      break;
+	    case 11:
+	      finaleflat = "RROCK14";
+	      finaletext = c2text;
+	      break;
+	    case 20:
+	      finaleflat = "RROCK07";
+	      finaletext = c3text;
+	      break;
+	    case 30:
+	      finaleflat = "RROCK17";
+	      finaletext = c4text;
+	      break;
+	    case 15:
+	      finaleflat = "RROCK13";
+	      finaletext = c5text;
+	      break;
+	    case 31:
+	      finaleflat = "RROCK19";
+	      finaletext = c6text;
+	      break;
+	    default:
+	      // Ouch.
+	      break;
+	  }
+	  break;
+      }	
+
+   
+      // Indeterminate.
+      default:
+	S_ChangeMusic(mus_read_m, true);
+	finaleflat = "F_SKY1"; // Not used anywhere else.
+	finaletext = c1text;  // FIXME - other text, music?
+	break;
+    }
+    
+    finalestage = 0;
+    finalecount = 0;
+	
+}
+
+
+
+boolean F_Responder (event_t *event)
+{
+    if (finalestage == 2)
+	return F_CastResponder (event);
+	
+    return false;
+}
+
+
+//
+// F_Ticker
+//
+void F_Ticker (void)
+{
+    int		i;
+    
+    // check for skipping
+    if ( (gamemode == commercial)
+      && ( finalecount > 50) )
+    {
+      // go on to the next level
+      for (i=0 ; i<MAXPLAYERS ; i++)
+	if (players[i].cmd.buttons)
+	  break;
+				
+      if (i < MAXPLAYERS)
+      {	
+	if (gamemap == 30)
+	  F_StartCast ();
+	else
+	  gameaction = ga_worlddone;
+      }
+    }
+    
+    // advance animation
+    finalecount++;
+	
+    if (finalestage == 2)
+    {
+	F_CastTicker ();
+	return;
+    }
+	
+    if ( gamemode == commercial)
+	return;
+		
+    if (!finalestage && finalecount>strlen (finaletext)*TEXTSPEED + TEXTWAIT)
+    {
+	finalecount = 0;
+	finalestage = 1;
+	wipegamestate = -1;		// force a wipe
+	if (gameepisode == 3)
+	    S_StartMusic (mus_bunny);
+    }
+}
+
+
+
+//
+// F_TextWrite
+//
+
+#include "hu_stuff.h"
+extern	patch_t *hu_font[HU_FONTSIZE];
+
+
+void F_TextWrite (void)
+{
+    byte*	src;
+    byte*	dest;
+    
+    int		x,y,w;
+    int		count;
+    char*	ch;
+    int		c;
+    int		cx;
+    int		cy;
+    
+    // erase the entire screen to a tiled background
+    src = W_CacheLumpName ( finaleflat , PU_CACHE);
+    dest = screens[0];
+	
+    for (y=0 ; y<SCREENHEIGHT ; y++)
+    {
+	for (x=0 ; x<SCREENWIDTH/64 ; x++)
+	{
+	    memcpy (dest, src+((y&63)<<6), 64);
+	    dest += 64;
+	}
+	if (SCREENWIDTH&63)
+	{
+	    memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
+	    dest += (SCREENWIDTH&63);
+	}
+    }
+
+    V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
+    
+    // draw some of the text onto the screen
+    cx = 10;
+    cy = 10;
+    ch = finaletext;
+	
+    count = (finalecount - 10)/TEXTSPEED;
+    if (count < 0)
+	count = 0;
+    for ( ; count ; count-- )
+    {
+	c = *ch++;
+	if (!c)
+	    break;
+	if (c == '\n')
+	{
+	    cx = 10;
+	    cy += 11;
+	    continue;
+	}
+		
+	c = toupper(c) - HU_FONTSTART;
+	if (c < 0 || c> HU_FONTSIZE)
+	{
+	    cx += 4;
+	    continue;
+	}
+		
+	w = SHORT (hu_font[c]->width);
+	if (cx+w > SCREENWIDTH)
+	    break;
+	V_DrawPatch(cx, cy, 0, hu_font[c]);
+	cx+=w;
+    }
+	
+}
+
+//
+// Final DOOM 2 animation
+// Casting by id Software.
+//   in order of appearance
+//
+typedef struct
+{
+    char		*name;
+    mobjtype_t	type;
+} castinfo_t;
+
+castinfo_t	castorder[] = {
+    {CC_ZOMBIE, MT_POSSESSED},
+    {CC_SHOTGUN, MT_SHOTGUY},
+    {CC_HEAVY, MT_CHAINGUY},
+    {CC_IMP, MT_TROOP},
+    {CC_DEMON, MT_SERGEANT},
+    {CC_LOST, MT_SKULL},
+    {CC_CACO, MT_HEAD},
+    {CC_HELL, MT_KNIGHT},
+    {CC_BARON, MT_BRUISER},
+    {CC_ARACH, MT_BABY},
+    {CC_PAIN, MT_PAIN},
+    {CC_REVEN, MT_UNDEAD},
+    {CC_MANCU, MT_FATSO},
+    {CC_ARCH, MT_VILE},
+    {CC_SPIDER, MT_SPIDER},
+    {CC_CYBER, MT_CYBORG},
+    {CC_HERO, MT_PLAYER},
+
+    {NULL,0}
+};
+
+int		castnum;
+int		casttics;
+state_t*	caststate;
+boolean		castdeath;
+int		castframes;
+int		castonmelee;
+boolean		castattacking;
+
+
+//
+// F_StartCast
+//
+extern	gamestate_t     wipegamestate;
+
+
+void F_StartCast (void)
+{
+    wipegamestate = -1;		// force a screen wipe
+    castnum = 0;
+    caststate = &states[mobjinfo[castorder[castnum].type].seestate];
+    casttics = caststate->tics;
+    castdeath = false;
+    finalestage = 2;	
+    castframes = 0;
+    castonmelee = 0;
+    castattacking = false;
+    S_ChangeMusic(mus_evil, true);
+}
+
+
+//
+// F_CastTicker
+//
+void F_CastTicker (void)
+{
+    int		st;
+    int		sfx;
+	
+    if (--casttics > 0)
+	return;			// not time to change state yet
+		
+    if (caststate->tics == -1 || caststate->nextstate == S_NULL)
+    {
+	// switch from deathstate to next monster
+	castnum++;
+	castdeath = false;
+	if (castorder[castnum].name == NULL)
+	    castnum = 0;
+	if (mobjinfo[castorder[castnum].type].seesound)
+	    S_StartSound (NULL, mobjinfo[castorder[castnum].type].seesound);
+	caststate = &states[mobjinfo[castorder[castnum].type].seestate];
+	castframes = 0;
+    }
+    else
+    {
+	// just advance to next state in animation
+	if (caststate == &states[S_PLAY_ATK1])
+	    goto stopattack;	// Oh, gross hack!
+	st = caststate->nextstate;
+	caststate = &states[st];
+	castframes++;
+	
+	// sound hacks....
+	switch (st)
+	{
+	  case S_PLAY_ATK1:	sfx = sfx_dshtgn; break;
+	  case S_POSS_ATK2:	sfx = sfx_pistol; break;
+	  case S_SPOS_ATK2:	sfx = sfx_shotgn; break;
+	  case S_VILE_ATK2:	sfx = sfx_vilatk; break;
+	  case S_SKEL_FIST2:	sfx = sfx_skeswg; break;
+	  case S_SKEL_FIST4:	sfx = sfx_skepch; break;
+	  case S_SKEL_MISS2:	sfx = sfx_skeatk; break;
+	  case S_FATT_ATK8:
+	  case S_FATT_ATK5:
+	  case S_FATT_ATK2:	sfx = sfx_firsht; break;
+	  case S_CPOS_ATK2:
+	  case S_CPOS_ATK3:
+	  case S_CPOS_ATK4:	sfx = sfx_shotgn; break;
+	  case S_TROO_ATK3:	sfx = sfx_claw; break;
+	  case S_SARG_ATK2:	sfx = sfx_sgtatk; break;
+	  case S_BOSS_ATK2:
+	  case S_BOS2_ATK2:
+	  case S_HEAD_ATK2:	sfx = sfx_firsht; break;
+	  case S_SKULL_ATK2:	sfx = sfx_sklatk; break;
+	  case S_SPID_ATK2:
+	  case S_SPID_ATK3:	sfx = sfx_shotgn; break;
+	  case S_BSPI_ATK2:	sfx = sfx_plasma; break;
+	  case S_CYBER_ATK2:
+	  case S_CYBER_ATK4:
+	  case S_CYBER_ATK6:	sfx = sfx_rlaunc; break;
+	  case S_PAIN_ATK3:	sfx = sfx_sklatk; break;
+	  default: sfx = 0; break;
+	}
+		
+	if (sfx)
+	    S_StartSound (NULL, sfx);
+    }
+	
+    if (castframes == 12)
+    {
+	// go into attack frame
+	castattacking = true;
+	if (castonmelee)
+	    caststate=&states[mobjinfo[castorder[castnum].type].meleestate];
+	else
+	    caststate=&states[mobjinfo[castorder[castnum].type].missilestate];
+	castonmelee ^= 1;
+	if (caststate == &states[S_NULL])
+	{
+	    if (castonmelee)
+		caststate=
+		    &states[mobjinfo[castorder[castnum].type].meleestate];
+	    else
+		caststate=
+		    &states[mobjinfo[castorder[castnum].type].missilestate];
+	}
+    }
+	
+    if (castattacking)
+    {
+	if (castframes == 24
+	    ||	caststate == &states[mobjinfo[castorder[castnum].type].seestate] )
+	{
+	  stopattack:
+	    castattacking = false;
+	    castframes = 0;
+	    caststate = &states[mobjinfo[castorder[castnum].type].seestate];
+	}
+    }
+	
+    casttics = caststate->tics;
+    if (casttics == -1)
+	casttics = 15;
+}
+
+
+//
+// F_CastResponder
+//
+
+boolean F_CastResponder (event_t* ev)
+{
+    if (ev->type != ev_keydown)
+	return false;
+		
+    if (castdeath)
+	return true;			// already in dying frames
+		
+    // go into death frame
+    castdeath = true;
+    caststate = &states[mobjinfo[castorder[castnum].type].deathstate];
+    casttics = caststate->tics;
+    castframes = 0;
+    castattacking = false;
+    if (mobjinfo[castorder[castnum].type].deathsound)
+	S_StartSound (NULL, mobjinfo[castorder[castnum].type].deathsound);
+	
+    return true;
+}
+
+
+void F_CastPrint (char* text)
+{
+    char*	ch;
+    int		c;
+    int		cx;
+    int		w;
+    int		width;
+    
+    // find width
+    ch = text;
+    width = 0;
+	
+    while (ch)
+    {
+	c = *ch++;
+	if (!c)
+	    break;
+	c = toupper(c) - HU_FONTSTART;
+	if (c < 0 || c> HU_FONTSIZE)
+	{
+	    width += 4;
+	    continue;
+	}
+		
+	w = SHORT (hu_font[c]->width);
+	width += w;
+    }
+    
+    // draw it
+    cx = 160-width/2;
+    ch = text;
+    while (ch)
+    {
+	c = *ch++;
+	if (!c)
+	    break;
+	c = toupper(c) - HU_FONTSTART;
+	if (c < 0 || c> HU_FONTSIZE)
+	{
+	    cx += 4;
+	    continue;
+	}
+		
+	w = SHORT (hu_font[c]->width);
+	V_DrawPatch(cx, 180, 0, hu_font[c]);
+	cx+=w;
+    }
+	
+}
+
+
+//
+// F_CastDrawer
+//
+void V_DrawPatchFlipped (int x, int y, int scrn, patch_t *patch);
+
+void F_CastDrawer (void)
+{
+    spritedef_t*	sprdef;
+    spriteframe_t*	sprframe;
+    int			lump;
+    boolean		flip;
+    patch_t*		patch;
+    
+    // erase the entire screen to a background
+    V_DrawPatch (0,0,0, W_CacheLumpName ("BOSSBACK", PU_CACHE));
+
+    F_CastPrint (castorder[castnum].name);
+    
+    // draw the current frame in the middle of the screen
+    sprdef = &sprites[caststate->sprite];
+    sprframe = &sprdef->spriteframes[ caststate->frame & FF_FRAMEMASK];
+    lump = sprframe->lump[0];
+    flip = (boolean)sprframe->flip[0];
+			
+    patch = W_CacheLumpNum (lump+firstspritelump, PU_CACHE);
+    if (flip)
+	V_DrawPatchFlipped (160,170,0,patch);
+    else
+	V_DrawPatch (160,170,0,patch);
+}
+
+
+//
+// F_DrawPatchCol
+//
+void
+F_DrawPatchCol
+( int		x,
+  patch_t*	patch,
+  int		col )
+{
+    column_t*	column;
+    byte*	source;
+    byte*	dest;
+    byte*	desttop;
+    int		count;
+	
+    column = (column_t *)((byte *)patch + LONG(patch->columnofs[col]));
+    desttop = screens[0]+x;
+
+    // step through the posts in a column
+    while (column->topdelta != 0xff )
+    {
+	source = (byte *)column + 3;
+	dest = desttop + column->topdelta*SCREENWIDTH;
+	count = column->length;
+		
+	while (count--)
+	{
+	    *dest = *source++;
+	    dest += SCREENWIDTH;
+	}
+	column = (column_t *)(  (byte *)column + column->length + 4 );
+    }
+}
+
+
+//
+// F_BunnyScroll
+//
+void F_BunnyScroll (void)
+{
+    int		scrolled;
+    int		x;
+    patch_t*	p1;
+    patch_t*	p2;
+    char	name[10];
+    int		stage;
+    static int	laststage;
+		
+    p1 = W_CacheLumpName ("PFUB2", PU_LEVEL);
+    p2 = W_CacheLumpName ("PFUB1", PU_LEVEL);
+
+    V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
+	
+    scrolled = 320 - (finalecount-230)/2;
+    if (scrolled > 320)
+	scrolled = 320;
+    if (scrolled < 0)
+	scrolled = 0;
+		
+    for ( x=0 ; x<SCREENWIDTH ; x++)
+    {
+	if (x+scrolled < 320)
+	    F_DrawPatchCol (x, p1, x+scrolled);
+	else
+	    F_DrawPatchCol (x, p2, x+scrolled - 320);		
+    }
+	
+    if (finalecount < 1130)
+	return;
+    if (finalecount < 1180)
+    {
+	V_DrawPatch ((SCREENWIDTH-13*8)/2,
+		     (SCREENHEIGHT-8*8)/2,0, W_CacheLumpName ("END0",PU_CACHE));
+	laststage = 0;
+	return;
+    }
+	
+    stage = (finalecount-1180) / 5;
+    if (stage > 6)
+	stage = 6;
+    if (stage > laststage)
+    {
+	S_StartSound (NULL, sfx_pistol);
+	laststage = stage;
+    }
+	
+    sprintf (name,"END%i",stage);
+    V_DrawPatch ((SCREENWIDTH-13*8)/2, (SCREENHEIGHT-8*8)/2,0, W_CacheLumpName (name,PU_CACHE));
+}
+
+
+//
+// F_Drawer
+//
+void F_Drawer (void)
+{
+    if (finalestage == 2)
+    {
+	F_CastDrawer ();
+	return;
+    }
+
+    if (!finalestage)
+	F_TextWrite ();
+    else
+    {
+	switch (gameepisode)
+	{
+	  case 1:
+	    if ( gamemode == retail )
+	      V_DrawPatch (0,0,0,
+			 W_CacheLumpName("CREDIT",PU_CACHE));
+	    else
+	      V_DrawPatch (0,0,0,
+			 W_CacheLumpName("HELP2",PU_CACHE));
+	    break;
+	  case 2:
+	    V_DrawPatch(0,0,0,
+			W_CacheLumpName("VICTORY2",PU_CACHE));
+	    break;
+	  case 3:
+	    F_BunnyScroll ();
+	    break;
+	  case 4:
+	    V_DrawPatch (0,0,0,
+			 W_CacheLumpName("ENDPIC",PU_CACHE));
+	    break;
+	}
+    }
+			
+}
+
+
--- /dev/null
+++ b/src/f_finale.h
@@ -1,0 +1,56 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: f_finale.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//
+//    
+//-----------------------------------------------------------------------------
+
+
+#ifndef __F_FINALE__
+#define __F_FINALE__
+
+
+#include "doomtype.h"
+#include "d_event.h"
+//
+// FINALE
+//
+
+// Called by main loop.
+boolean F_Responder (event_t* ev);
+
+// Called by main loop.
+void F_Ticker (void);
+
+// Called by main loop.
+void F_Drawer (void);
+
+
+void F_StartFinale (void);
+
+
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:32  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/f_wipe.c
@@ -1,0 +1,305 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: f_wipe.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:19:45  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//	Mission begin melt/wipe screen special effect.
+//
+//-----------------------------------------------------------------------------
+
+
+static const char rcsid[] = "$Id: f_wipe.c 4 2005-07-23 16:19:41Z fraggle $";
+
+
+
+#include "z_zone.h"
+#include "i_video.h"
+#include "v_video.h"
+#include "m_random.h"
+
+#include "doomdef.h"
+
+#include "f_wipe.h"
+
+//
+//                       SCREEN WIPE PACKAGE
+//
+
+// when zero, stop the wipe
+static boolean	go = 0;
+
+static byte*	wipe_scr_start;
+static byte*	wipe_scr_end;
+static byte*	wipe_scr;
+
+
+void
+wipe_shittyColMajorXform
+( short*	array,
+  int		width,
+  int		height )
+{
+    int		x;
+    int		y;
+    short*	dest;
+
+    dest = (short*) Z_Malloc(width*height*2, PU_STATIC, 0);
+
+    for(y=0;y<height;y++)
+	for(x=0;x<width;x++)
+	    dest[x*height+y] = array[y*width+x];
+
+    memcpy(array, dest, width*height*2);
+
+    Z_Free(dest);
+
+}
+
+int
+wipe_initColorXForm
+( int	width,
+  int	height,
+  int	ticks )
+{
+    memcpy(wipe_scr, wipe_scr_start, width*height);
+    return 0;
+}
+
+int
+wipe_doColorXForm
+( int	width,
+  int	height,
+  int	ticks )
+{
+    boolean	changed;
+    byte*	w;
+    byte*	e;
+    int		newval;
+
+    changed = false;
+    w = wipe_scr;
+    e = wipe_scr_end;
+    
+    while (w!=wipe_scr+width*height)
+    {
+	if (*w != *e)
+	{
+	    if (*w > *e)
+	    {
+		newval = *w - ticks;
+		if (newval < *e)
+		    *w = *e;
+		else
+		    *w = newval;
+		changed = true;
+	    }
+	    else if (*w < *e)
+	    {
+		newval = *w + ticks;
+		if (newval > *e)
+		    *w = *e;
+		else
+		    *w = newval;
+		changed = true;
+	    }
+	}
+	w++;
+	e++;
+    }
+
+    return !changed;
+
+}
+
+int
+wipe_exitColorXForm
+( int	width,
+  int	height,
+  int	ticks )
+{
+    return 0;
+}
+
+
+static int*	y;
+
+int
+wipe_initMelt
+( int	width,
+  int	height,
+  int	ticks )
+{
+    int i, r;
+    
+    // copy start screen to main screen
+    memcpy(wipe_scr, wipe_scr_start, width*height);
+    
+    // makes this wipe faster (in theory)
+    // to have stuff in column-major format
+    wipe_shittyColMajorXform((short*)wipe_scr_start, width/2, height);
+    wipe_shittyColMajorXform((short*)wipe_scr_end, width/2, height);
+    
+    // setup initial column positions
+    // (y<0 => not ready to scroll yet)
+    y = (int *) Z_Malloc(width*sizeof(int), PU_STATIC, 0);
+    y[0] = -(M_Random()%16);
+    for (i=1;i<width;i++)
+    {
+	r = (M_Random()%3) - 1;
+	y[i] = y[i-1] + r;
+	if (y[i] > 0) y[i] = 0;
+	else if (y[i] == -16) y[i] = -15;
+    }
+
+    return 0;
+}
+
+int
+wipe_doMelt
+( int	width,
+  int	height,
+  int	ticks )
+{
+    int		i;
+    int		j;
+    int		dy;
+    int		idx;
+    
+    short*	s;
+    short*	d;
+    boolean	done = true;
+
+    width/=2;
+
+    while (ticks--)
+    {
+	for (i=0;i<width;i++)
+	{
+	    if (y[i]<0)
+	    {
+		y[i]++; done = false;
+	    }
+	    else if (y[i] < height)
+	    {
+		dy = (y[i] < 16) ? y[i]+1 : 8;
+		if (y[i]+dy >= height) dy = height - y[i];
+		s = &((short *)wipe_scr_end)[i*height+y[i]];
+		d = &((short *)wipe_scr)[y[i]*width+i];
+		idx = 0;
+		for (j=dy;j;j--)
+		{
+		    d[idx] = *(s++);
+		    idx += width;
+		}
+		y[i] += dy;
+		s = &((short *)wipe_scr_start)[i*height];
+		d = &((short *)wipe_scr)[y[i]*width+i];
+		idx = 0;
+		for (j=height-y[i];j;j--)
+		{
+		    d[idx] = *(s++);
+		    idx += width;
+		}
+		done = false;
+	    }
+	}
+    }
+
+    return done;
+
+}
+
+int
+wipe_exitMelt
+( int	width,
+  int	height,
+  int	ticks )
+{
+    Z_Free(y);
+    return 0;
+}
+
+int
+wipe_StartScreen
+( int	x,
+  int	y,
+  int	width,
+  int	height )
+{
+    wipe_scr_start = screens[2];
+    I_ReadScreen(wipe_scr_start);
+    return 0;
+}
+
+int
+wipe_EndScreen
+( int	x,
+  int	y,
+  int	width,
+  int	height )
+{
+    wipe_scr_end = screens[3];
+    I_ReadScreen(wipe_scr_end);
+    V_DrawBlock(x, y, 0, width, height, wipe_scr_start); // restore start scr.
+    return 0;
+}
+
+int
+wipe_ScreenWipe
+( int	wipeno,
+  int	x,
+  int	y,
+  int	width,
+  int	height,
+  int	ticks )
+{
+    int rc;
+    static int (*wipes[])(int, int, int) =
+    {
+	wipe_initColorXForm, wipe_doColorXForm, wipe_exitColorXForm,
+	wipe_initMelt, wipe_doMelt, wipe_exitMelt
+    };
+
+    void V_MarkRect(int, int, int, int);
+
+    // initial stuff
+    if (!go)
+    {
+	go = 1;
+	// wipe_scr = (byte *) Z_Malloc(width*height, PU_STATIC, 0); // DEBUG
+	wipe_scr = screens[0];
+	(*wipes[wipeno*3])(width, height, ticks);
+    }
+
+    // do a piece of wipe-in
+    V_MarkRect(0, 0, width, height);
+    rc = (*wipes[wipeno*3+1])(width, height, ticks);
+    //  V_DrawBlock(x, y, 0, width, height, wipe_scr); // DEBUG
+
+    // final stuff
+    if (rc)
+    {
+	go = 0;
+	(*wipes[wipeno*3+2])(width, height, ticks);
+    }
+
+    return !go;
+
+}
--- /dev/null
+++ b/src/f_wipe.h
@@ -1,0 +1,74 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: f_wipe.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//	Mission start screen wipe/melt, special effects.
+//	
+//-----------------------------------------------------------------------------
+
+
+#ifndef __F_WIPE_H__
+#define __F_WIPE_H__
+
+//
+//                       SCREEN WIPE PACKAGE
+//
+
+enum
+{
+    // simple gradual pixel change for 8-bit only
+    wipe_ColorXForm,
+    
+    // weird screen melt
+    wipe_Melt,	
+
+    wipe_NUMWIPES
+};
+
+int
+wipe_StartScreen
+( int		x,
+  int		y,
+  int		width,
+  int		height );
+
+
+int
+wipe_EndScreen
+( int		x,
+  int		y,
+  int		width,
+  int		height );
+
+
+int
+wipe_ScreenWipe
+( int		wipeno,
+  int		x,
+  int		y,
+  int		width,
+  int		height,
+  int		ticks );
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:19:45  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/g_game.c
@@ -1,0 +1,1693 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: g_game.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:11  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:  none
+//
+//-----------------------------------------------------------------------------
+
+
+static const char
+rcsid[] = "$Id: g_game.c 4 2005-07-23 16:19:41Z fraggle $";
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "doomdef.h" 
+#include "doomstat.h"
+
+#include "z_zone.h"
+#include "f_finale.h"
+#include "m_argv.h"
+#include "m_misc.h"
+#include "m_menu.h"
+#include "m_random.h"
+#include "i_system.h"
+
+#include "p_setup.h"
+#include "p_saveg.h"
+#include "p_tick.h"
+
+#include "d_main.h"
+
+#include "wi_stuff.h"
+#include "hu_stuff.h"
+#include "st_stuff.h"
+#include "am_map.h"
+
+// Needs access to LFB.
+#include "v_video.h"
+
+#include "w_wad.h"
+
+#include "p_local.h" 
+
+#include "s_sound.h"
+
+// Data.
+#include "dstrings.h"
+#include "sounds.h"
+
+// SKY handling - still the wrong place.
+#include "r_data.h"
+#include "r_sky.h"
+
+
+
+#include "g_game.h"
+
+
+#define SAVEGAMESIZE	0x2c000
+#define SAVESTRINGSIZE	24
+
+
+
+boolean	G_CheckDemoStatus (void); 
+void	G_ReadDemoTiccmd (ticcmd_t* cmd); 
+void	G_WriteDemoTiccmd (ticcmd_t* cmd); 
+void	G_PlayerReborn (int player); 
+void	G_InitNew (skill_t skill, int episode, int map); 
+ 
+void	G_DoReborn (int playernum); 
+ 
+void	G_DoLoadLevel (void); 
+void	G_DoNewGame (void); 
+void	G_DoLoadGame (void); 
+void	G_DoPlayDemo (void); 
+void	G_DoCompleted (void); 
+void	G_DoVictory (void); 
+void	G_DoWorldDone (void); 
+void	G_DoSaveGame (void); 
+ 
+ 
+gameaction_t    gameaction; 
+gamestate_t     gamestate; 
+skill_t         gameskill; 
+boolean		respawnmonsters;
+int             gameepisode; 
+int             gamemap; 
+ 
+boolean         paused; 
+boolean         sendpause;             	// send a pause event next tic 
+boolean         sendsave;             	// send a save event next tic 
+boolean         usergame;               // ok to save / end game 
+ 
+boolean         timingdemo;             // if true, exit with report on completion 
+boolean         nodrawers;              // for comparative timing purposes 
+boolean         noblit;                 // for comparative timing purposes 
+int             starttime;          	// for comparative timing purposes  	 
+ 
+boolean         viewactive; 
+ 
+boolean         deathmatch;           	// only if started as net death 
+boolean         netgame;                // only true if packets are broadcast 
+boolean         playeringame[MAXPLAYERS]; 
+player_t        players[MAXPLAYERS]; 
+ 
+int             consoleplayer;          // player taking events and displaying 
+int             displayplayer;          // view being displayed 
+int             gametic; 
+int             levelstarttic;          // gametic at level start 
+int             totalkills, totalitems, totalsecret;    // for intermission 
+ 
+char            demoname[32]; 
+boolean         demorecording; 
+boolean         demoplayback; 
+boolean		netdemo; 
+byte*		demobuffer;
+byte*		demo_p;
+byte*		demoend; 
+boolean         singledemo;            	// quit after playing a demo from cmdline 
+ 
+boolean         precache = true;        // if true, load all graphics at start 
+ 
+wbstartstruct_t wminfo;               	// parms for world map / intermission 
+ 
+short		consistancy[MAXPLAYERS][BACKUPTICS]; 
+ 
+byte*		savebuffer;
+ 
+ 
+// 
+// controls (have defaults) 
+// 
+int             key_right;
+int		key_left;
+
+int		key_up;
+int		key_down; 
+int             key_strafeleft;
+int		key_straferight; 
+int             key_fire;
+int		key_use;
+int		key_strafe;
+int		key_speed; 
+ 
+int             mousebfire; 
+int             mousebstrafe; 
+int             mousebforward; 
+ 
+int             joybfire; 
+int             joybstrafe; 
+int             joybuse; 
+int             joybspeed; 
+ 
+ 
+ 
+#define MAXPLMOVE		(forwardmove[1]) 
+ 
+#define TURBOTHRESHOLD	0x32
+
+fixed_t		forwardmove[2] = {0x19, 0x32}; 
+fixed_t		sidemove[2] = {0x18, 0x28}; 
+fixed_t		angleturn[3] = {640, 1280, 320};	// + slow turn 
+
+#define SLOWTURNTICS	6 
+ 
+#define NUMKEYS		256 
+
+boolean         gamekeydown[NUMKEYS]; 
+int             turnheld;				// for accelerative turning 
+ 
+boolean		mousearray[4]; 
+boolean*	mousebuttons = &mousearray[1];		// allow [-1]
+
+// mouse values are used once 
+int             mousex;
+int		mousey;         
+
+int             dclicktime;
+int		dclickstate;
+int		dclicks; 
+int             dclicktime2;
+int		dclickstate2;
+int		dclicks2;
+
+// joystick values are repeated 
+int             joyxmove;
+int		joyymove;
+boolean         joyarray[5]; 
+boolean*	joybuttons = &joyarray[1];		// allow [-1] 
+ 
+int		savegameslot; 
+char		savedescription[32]; 
+ 
+ 
+#define	BODYQUESIZE	32
+
+mobj_t*		bodyque[BODYQUESIZE]; 
+int		bodyqueslot; 
+ 
+void*		statcopy;				// for statistics driver
+ 
+ 
+ 
+int G_CmdChecksum (ticcmd_t* cmd) 
+{ 
+    int		i;
+    int		sum = 0; 
+	 
+    for (i=0 ; i< sizeof(*cmd)/4 - 1 ; i++) 
+	sum += ((int *)cmd)[i]; 
+		 
+    return sum; 
+} 
+ 
+
+//
+// G_BuildTiccmd
+// Builds a ticcmd from all of the available inputs
+// or reads it from the demo buffer. 
+// If recording a demo, write it out 
+// 
+void G_BuildTiccmd (ticcmd_t* cmd) 
+{ 
+    int		i; 
+    boolean	strafe;
+    boolean	bstrafe; 
+    int		speed;
+    int		tspeed; 
+    int		forward;
+    int		side;
+    
+    ticcmd_t*	base;
+
+    base = I_BaseTiccmd ();		// empty, or external driver
+    memcpy (cmd,base,sizeof(*cmd)); 
+	
+    cmd->consistancy = 
+	consistancy[consoleplayer][maketic%BACKUPTICS]; 
+
+ 
+    strafe = gamekeydown[key_strafe] || mousebuttons[mousebstrafe] 
+	|| joybuttons[joybstrafe]; 
+    speed = gamekeydown[key_speed] || joybuttons[joybspeed];
+ 
+    forward = side = 0;
+    
+    // use two stage accelerative turning
+    // on the keyboard and joystick
+    if (joyxmove < 0
+	|| joyxmove > 0  
+	|| gamekeydown[key_right]
+	|| gamekeydown[key_left]) 
+	turnheld += ticdup; 
+    else 
+	turnheld = 0; 
+
+    if (turnheld < SLOWTURNTICS) 
+	tspeed = 2;             // slow turn 
+    else 
+	tspeed = speed;
+    
+    // let movement keys cancel each other out
+    if (strafe) 
+    { 
+	if (gamekeydown[key_right]) 
+	{
+	    // fprintf(stderr, "strafe right\n");
+	    side += sidemove[speed]; 
+	}
+	if (gamekeydown[key_left]) 
+	{
+	    //	fprintf(stderr, "strafe left\n");
+	    side -= sidemove[speed]; 
+	}
+	if (joyxmove > 0) 
+	    side += sidemove[speed]; 
+	if (joyxmove < 0) 
+	    side -= sidemove[speed]; 
+ 
+    } 
+    else 
+    { 
+	if (gamekeydown[key_right]) 
+	    cmd->angleturn -= angleturn[tspeed]; 
+	if (gamekeydown[key_left]) 
+	    cmd->angleturn += angleturn[tspeed]; 
+	if (joyxmove > 0) 
+	    cmd->angleturn -= angleturn[tspeed]; 
+	if (joyxmove < 0) 
+	    cmd->angleturn += angleturn[tspeed]; 
+    } 
+ 
+    if (gamekeydown[key_up]) 
+    {
+	// fprintf(stderr, "up\n");
+	forward += forwardmove[speed]; 
+    }
+    if (gamekeydown[key_down]) 
+    {
+	// fprintf(stderr, "down\n");
+	forward -= forwardmove[speed]; 
+    }
+    if (joyymove < 0) 
+	forward += forwardmove[speed]; 
+    if (joyymove > 0) 
+	forward -= forwardmove[speed]; 
+    if (gamekeydown[key_straferight]) 
+	side += sidemove[speed]; 
+    if (gamekeydown[key_strafeleft]) 
+	side -= sidemove[speed];
+    
+    // buttons
+    cmd->chatchar = HU_dequeueChatChar(); 
+ 
+    if (gamekeydown[key_fire] || mousebuttons[mousebfire] 
+	|| joybuttons[joybfire]) 
+	cmd->buttons |= BT_ATTACK; 
+ 
+    if (gamekeydown[key_use] || joybuttons[joybuse] ) 
+    { 
+	cmd->buttons |= BT_USE;
+	// clear double clicks if hit use button 
+	dclicks = 0;                   
+    } 
+
+    // chainsaw overrides 
+    for (i=0 ; i<NUMWEAPONS-1 ; i++)        
+	if (gamekeydown['1'+i]) 
+	{ 
+	    cmd->buttons |= BT_CHANGE; 
+	    cmd->buttons |= i<<BT_WEAPONSHIFT; 
+	    break; 
+	}
+    
+    // mouse
+    if (mousebuttons[mousebforward]) 
+	forward += forwardmove[speed];
+    
+    // forward double click
+    if (mousebuttons[mousebforward] != dclickstate && dclicktime > 1 ) 
+    { 
+	dclickstate = mousebuttons[mousebforward]; 
+	if (dclickstate) 
+	    dclicks++; 
+	if (dclicks == 2) 
+	{ 
+	    cmd->buttons |= BT_USE; 
+	    dclicks = 0; 
+	} 
+	else 
+	    dclicktime = 0; 
+    } 
+    else 
+    { 
+	dclicktime += ticdup; 
+	if (dclicktime > 20) 
+	{ 
+	    dclicks = 0; 
+	    dclickstate = 0; 
+	} 
+    }
+    
+    // strafe double click
+    bstrafe =
+	mousebuttons[mousebstrafe] 
+	|| joybuttons[joybstrafe]; 
+    if (bstrafe != dclickstate2 && dclicktime2 > 1 ) 
+    { 
+	dclickstate2 = bstrafe; 
+	if (dclickstate2) 
+	    dclicks2++; 
+	if (dclicks2 == 2) 
+	{ 
+	    cmd->buttons |= BT_USE; 
+	    dclicks2 = 0; 
+	} 
+	else 
+	    dclicktime2 = 0; 
+    } 
+    else 
+    { 
+	dclicktime2 += ticdup; 
+	if (dclicktime2 > 20) 
+	{ 
+	    dclicks2 = 0; 
+	    dclickstate2 = 0; 
+	} 
+    } 
+ 
+    forward += mousey; 
+    if (strafe) 
+	side += mousex*2; 
+    else 
+	cmd->angleturn -= mousex*0x8; 
+
+    mousex = mousey = 0; 
+	 
+    if (forward > MAXPLMOVE) 
+	forward = MAXPLMOVE; 
+    else if (forward < -MAXPLMOVE) 
+	forward = -MAXPLMOVE; 
+    if (side > MAXPLMOVE) 
+	side = MAXPLMOVE; 
+    else if (side < -MAXPLMOVE) 
+	side = -MAXPLMOVE; 
+ 
+    cmd->forwardmove += forward; 
+    cmd->sidemove += side;
+    
+    // special buttons
+    if (sendpause) 
+    { 
+	sendpause = false; 
+	cmd->buttons = BT_SPECIAL | BTS_PAUSE; 
+    } 
+ 
+    if (sendsave) 
+    { 
+	sendsave = false; 
+	cmd->buttons = BT_SPECIAL | BTS_SAVEGAME | (savegameslot<<BTS_SAVESHIFT); 
+    } 
+} 
+ 
+
+//
+// G_DoLoadLevel 
+//
+extern  gamestate_t     wipegamestate; 
+ 
+void G_DoLoadLevel (void) 
+{ 
+    int             i; 
+
+    // Set the sky map.
+    // First thing, we have a dummy sky texture name,
+    //  a flat. The data is in the WAD only because
+    //  we look for an actual index, instead of simply
+    //  setting one.
+    skyflatnum = R_FlatNumForName ( SKYFLATNAME );
+
+    // DOOM determines the sky texture to be used
+    // depending on the current episode, and the game version.
+    if ( (gamemode == commercial)
+	 || ( gamemode == pack_tnt )
+	 || ( gamemode == pack_plut ) )
+    {
+	skytexture = R_TextureNumForName ("SKY3");
+	if (gamemap < 12)
+	    skytexture = R_TextureNumForName ("SKY1");
+	else
+	    if (gamemap < 21)
+		skytexture = R_TextureNumForName ("SKY2");
+    }
+
+    levelstarttic = gametic;        // for time calculation
+    
+    if (wipegamestate == GS_LEVEL) 
+	wipegamestate = -1;             // force a wipe 
+
+    gamestate = GS_LEVEL; 
+
+    for (i=0 ; i<MAXPLAYERS ; i++) 
+    { 
+	if (playeringame[i] && players[i].playerstate == PST_DEAD) 
+	    players[i].playerstate = PST_REBORN; 
+	memset (players[i].frags,0,sizeof(players[i].frags)); 
+    } 
+		 
+    P_SetupLevel (gameepisode, gamemap, 0, gameskill);    
+    displayplayer = consoleplayer;		// view the guy you are playing    
+    starttime = I_GetTime (); 
+    gameaction = ga_nothing; 
+    Z_CheckHeap ();
+    
+    // clear cmd building stuff
+    memset (gamekeydown, 0, sizeof(gamekeydown)); 
+    joyxmove = joyymove = 0; 
+    mousex = mousey = 0; 
+    sendpause = sendsave = paused = false; 
+    memset (mousebuttons, 0, sizeof(mousebuttons)); 
+    memset (joybuttons, 0, sizeof(joybuttons)); 
+} 
+ 
+ 
+//
+// G_Responder  
+// Get info needed to make ticcmd_ts for the players.
+// 
+boolean G_Responder (event_t* ev) 
+{ 
+    // allow spy mode changes even during the demo
+    if (gamestate == GS_LEVEL && ev->type == ev_keydown 
+	&& ev->data1 == KEY_F12 && (singledemo || !deathmatch) )
+    {
+	// spy mode 
+	do 
+	{ 
+	    displayplayer++; 
+	    if (displayplayer == MAXPLAYERS) 
+		displayplayer = 0; 
+	} while (!playeringame[displayplayer] && displayplayer != consoleplayer); 
+	return true; 
+    }
+    
+    // any other key pops up menu if in demos
+    if (gameaction == ga_nothing && !singledemo && 
+	(demoplayback || gamestate == GS_DEMOSCREEN) 
+	) 
+    { 
+	if (ev->type == ev_keydown ||  
+	    (ev->type == ev_mouse && ev->data1) || 
+	    (ev->type == ev_joystick && ev->data1) ) 
+	{ 
+	    M_StartControlPanel (); 
+	    return true; 
+	} 
+	return false; 
+    } 
+ 
+    if (gamestate == GS_LEVEL) 
+    { 
+#if 0 
+	if (devparm && ev->type == ev_keydown && ev->data1 == ';') 
+	{ 
+	    G_DeathMatchSpawnPlayer (0); 
+	    return true; 
+	} 
+#endif 
+	if (HU_Responder (ev)) 
+	    return true;	// chat ate the event 
+	if (ST_Responder (ev)) 
+	    return true;	// status window ate it 
+	if (AM_Responder (ev)) 
+	    return true;	// automap ate it 
+    } 
+	 
+    if (gamestate == GS_FINALE) 
+    { 
+	if (F_Responder (ev)) 
+	    return true;	// finale ate the event 
+    } 
+	 
+    switch (ev->type) 
+    { 
+      case ev_keydown: 
+	if (ev->data1 == KEY_PAUSE) 
+	{ 
+	    sendpause = true; 
+	    return true; 
+	} 
+	if (ev->data1 <NUMKEYS) 
+	    gamekeydown[ev->data1] = true; 
+	return true;    // eat key down events 
+ 
+      case ev_keyup: 
+	if (ev->data1 <NUMKEYS) 
+	    gamekeydown[ev->data1] = false; 
+	return false;   // always let key up events filter down 
+		 
+      case ev_mouse: 
+	mousebuttons[0] = ev->data1 & 1; 
+	mousebuttons[1] = ev->data1 & 2; 
+	mousebuttons[2] = ev->data1 & 4; 
+	mousex = ev->data2*(mouseSensitivity+5)/10; 
+	mousey = ev->data3*(mouseSensitivity+5)/10; 
+	return true;    // eat events 
+ 
+      case ev_joystick: 
+	joybuttons[0] = ev->data1 & 1; 
+	joybuttons[1] = ev->data1 & 2; 
+	joybuttons[2] = ev->data1 & 4; 
+	joybuttons[3] = ev->data1 & 8; 
+	joyxmove = ev->data2; 
+	joyymove = ev->data3; 
+	return true;    // eat events 
+ 
+      default: 
+	break; 
+    } 
+ 
+    return false; 
+} 
+ 
+ 
+ 
+//
+// G_Ticker
+// Make ticcmd_ts for the players.
+//
+void G_Ticker (void) 
+{ 
+    int		i;
+    int		buf; 
+    ticcmd_t*	cmd;
+    
+    // do player reborns if needed
+    for (i=0 ; i<MAXPLAYERS ; i++) 
+	if (playeringame[i] && players[i].playerstate == PST_REBORN) 
+	    G_DoReborn (i);
+    
+    // do things to change the game state
+    while (gameaction != ga_nothing) 
+    { 
+	switch (gameaction) 
+	{ 
+	  case ga_loadlevel: 
+	    G_DoLoadLevel (); 
+	    break; 
+	  case ga_newgame: 
+	    G_DoNewGame (); 
+	    break; 
+	  case ga_loadgame: 
+	    G_DoLoadGame (); 
+	    break; 
+	  case ga_savegame: 
+	    G_DoSaveGame (); 
+	    break; 
+	  case ga_playdemo: 
+	    G_DoPlayDemo (); 
+	    break; 
+	  case ga_completed: 
+	    G_DoCompleted (); 
+	    break; 
+	  case ga_victory: 
+	    F_StartFinale (); 
+	    break; 
+	  case ga_worlddone: 
+	    G_DoWorldDone (); 
+	    break; 
+	  case ga_screenshot: 
+	    M_ScreenShot (); 
+	    gameaction = ga_nothing; 
+	    break; 
+	  case ga_nothing: 
+	    break; 
+	} 
+    }
+    
+    // get commands, check consistancy,
+    // and build new consistancy check
+    buf = (gametic/ticdup)%BACKUPTICS; 
+ 
+    for (i=0 ; i<MAXPLAYERS ; i++)
+    {
+	if (playeringame[i]) 
+	{ 
+	    cmd = &players[i].cmd; 
+ 
+	    memcpy (cmd, &netcmds[i][buf], sizeof(ticcmd_t)); 
+ 
+	    if (demoplayback) 
+		G_ReadDemoTiccmd (cmd); 
+	    if (demorecording) 
+		G_WriteDemoTiccmd (cmd);
+	    
+	    // check for turbo cheats
+	    if (cmd->forwardmove > TURBOTHRESHOLD 
+		&& !(gametic&31) && ((gametic>>5)&3) == i )
+	    {
+		static char turbomessage[80];
+		extern char *player_names[4];
+		sprintf (turbomessage, "%s is turbo!",player_names[i]);
+		players[consoleplayer].message = turbomessage;
+	    }
+			
+	    if (netgame && !netdemo && !(gametic%ticdup) ) 
+	    { 
+		if (gametic > BACKUPTICS 
+		    && consistancy[i][buf] != cmd->consistancy) 
+		{ 
+		    I_Error ("consistency failure (%i should be %i)",
+			     cmd->consistancy, consistancy[i][buf]); 
+		} 
+		if (players[i].mo) 
+		    consistancy[i][buf] = players[i].mo->x; 
+		else 
+		    consistancy[i][buf] = rndindex; 
+	    } 
+	}
+    }
+    
+    // check for special buttons
+    for (i=0 ; i<MAXPLAYERS ; i++)
+    {
+	if (playeringame[i]) 
+	{ 
+	    if (players[i].cmd.buttons & BT_SPECIAL) 
+	    { 
+		switch (players[i].cmd.buttons & BT_SPECIALMASK) 
+		{ 
+		  case BTS_PAUSE: 
+		    paused ^= 1; 
+		    if (paused) 
+			S_PauseSound (); 
+		    else 
+			S_ResumeSound (); 
+		    break; 
+					 
+		  case BTS_SAVEGAME: 
+		    if (!savedescription[0]) 
+			strcpy (savedescription, "NET GAME"); 
+		    savegameslot =  
+			(players[i].cmd.buttons & BTS_SAVEMASK)>>BTS_SAVESHIFT; 
+		    gameaction = ga_savegame; 
+		    break; 
+		} 
+	    } 
+	}
+    }
+    
+    // do main actions
+    switch (gamestate) 
+    { 
+      case GS_LEVEL: 
+	P_Ticker (); 
+	ST_Ticker (); 
+	AM_Ticker (); 
+	HU_Ticker ();            
+	break; 
+	 
+      case GS_INTERMISSION: 
+	WI_Ticker (); 
+	break; 
+			 
+      case GS_FINALE: 
+	F_Ticker (); 
+	break; 
+ 
+      case GS_DEMOSCREEN: 
+	D_PageTicker (); 
+	break; 
+    }        
+} 
+ 
+ 
+//
+// PLAYER STRUCTURE FUNCTIONS
+// also see P_SpawnPlayer in P_Things
+//
+
+//
+// G_InitPlayer 
+// Called at the start.
+// Called by the game initialization functions.
+//
+void G_InitPlayer (int player) 
+{ 
+    player_t*	p; 
+ 
+    // set up the saved info         
+    p = &players[player]; 
+	 
+    // clear everything else to defaults 
+    G_PlayerReborn (player); 
+	 
+} 
+ 
+ 
+
+//
+// G_PlayerFinishLevel
+// Can when a player completes a level.
+//
+void G_PlayerFinishLevel (int player) 
+{ 
+    player_t*	p; 
+	 
+    p = &players[player]; 
+	 
+    memset (p->powers, 0, sizeof (p->powers)); 
+    memset (p->cards, 0, sizeof (p->cards)); 
+    p->mo->flags &= ~MF_SHADOW;		// cancel invisibility 
+    p->extralight = 0;			// cancel gun flashes 
+    p->fixedcolormap = 0;		// cancel ir gogles 
+    p->damagecount = 0;			// no palette changes 
+    p->bonuscount = 0; 
+} 
+ 
+
+//
+// G_PlayerReborn
+// Called after a player dies 
+// almost everything is cleared and initialized 
+//
+void G_PlayerReborn (int player) 
+{ 
+    player_t*	p; 
+    int		i; 
+    int		frags[MAXPLAYERS]; 
+    int		killcount;
+    int		itemcount;
+    int		secretcount; 
+	 
+    memcpy (frags,players[player].frags,sizeof(frags)); 
+    killcount = players[player].killcount; 
+    itemcount = players[player].itemcount; 
+    secretcount = players[player].secretcount; 
+	 
+    p = &players[player]; 
+    memset (p, 0, sizeof(*p)); 
+ 
+    memcpy (players[player].frags, frags, sizeof(players[player].frags)); 
+    players[player].killcount = killcount; 
+    players[player].itemcount = itemcount; 
+    players[player].secretcount = secretcount; 
+ 
+    p->usedown = p->attackdown = true;	// don't do anything immediately 
+    p->playerstate = PST_LIVE;       
+    p->health = MAXHEALTH; 
+    p->readyweapon = p->pendingweapon = wp_pistol; 
+    p->weaponowned[wp_fist] = true; 
+    p->weaponowned[wp_pistol] = true; 
+    p->ammo[am_clip] = 50; 
+	 
+    for (i=0 ; i<NUMAMMO ; i++) 
+	p->maxammo[i] = maxammo[i]; 
+		 
+}
+
+//
+// G_CheckSpot  
+// Returns false if the player cannot be respawned
+// at the given mapthing_t spot  
+// because something is occupying it 
+//
+void P_SpawnPlayer (mapthing_t* mthing); 
+ 
+boolean
+G_CheckSpot
+( int		playernum,
+  mapthing_t*	mthing ) 
+{ 
+    fixed_t		x;
+    fixed_t		y; 
+    subsector_t*	ss; 
+    unsigned		an; 
+    mobj_t*		mo; 
+    int			i;
+	
+    if (!players[playernum].mo)
+    {
+	// first spawn of level, before corpses
+	for (i=0 ; i<playernum ; i++)
+	    if (players[i].mo->x == mthing->x << FRACBITS
+		&& players[i].mo->y == mthing->y << FRACBITS)
+		return false;	
+	return true;
+    }
+		
+    x = mthing->x << FRACBITS; 
+    y = mthing->y << FRACBITS; 
+	 
+    if (!P_CheckPosition (players[playernum].mo, x, y) ) 
+	return false; 
+ 
+    // flush an old corpse if needed 
+    if (bodyqueslot >= BODYQUESIZE) 
+	P_RemoveMobj (bodyque[bodyqueslot%BODYQUESIZE]); 
+    bodyque[bodyqueslot%BODYQUESIZE] = players[playernum].mo; 
+    bodyqueslot++; 
+	
+    // spawn a teleport fog 
+    ss = R_PointInSubsector (x,y); 
+    an = ( ANG45 * (mthing->angle/45) ) >> ANGLETOFINESHIFT; 
+ 
+    mo = P_SpawnMobj (x+20*finecosine[an], y+20*finesine[an] 
+		      , ss->sector->floorheight 
+		      , MT_TFOG); 
+	 
+    if (players[consoleplayer].viewz != 1) 
+	S_StartSound (mo, sfx_telept);	// don't start sound on first frame 
+ 
+    return true; 
+} 
+
+
+//
+// G_DeathMatchSpawnPlayer 
+// Spawns a player at one of the random death match spots 
+// called at level load and each death 
+//
+void G_DeathMatchSpawnPlayer (int playernum) 
+{ 
+    int             i,j; 
+    int				selections; 
+	 
+    selections = deathmatch_p - deathmatchstarts; 
+    if (selections < 4) 
+	I_Error ("Only %i deathmatch spots, 4 required", selections); 
+ 
+    for (j=0 ; j<20 ; j++) 
+    { 
+	i = P_Random() % selections; 
+	if (G_CheckSpot (playernum, &deathmatchstarts[i]) ) 
+	{ 
+	    deathmatchstarts[i].type = playernum+1; 
+	    P_SpawnPlayer (&deathmatchstarts[i]); 
+	    return; 
+	} 
+    } 
+ 
+    // no good spot, so the player will probably get stuck 
+    P_SpawnPlayer (&playerstarts[playernum]); 
+} 
+
+//
+// G_DoReborn 
+// 
+void G_DoReborn (int playernum) 
+{ 
+    int                             i; 
+	 
+    if (!netgame)
+    {
+	// reload the level from scratch
+	gameaction = ga_loadlevel;  
+    }
+    else 
+    {
+	// respawn at the start
+
+	// first dissasociate the corpse 
+	players[playernum].mo->player = NULL;   
+		 
+	// spawn at random spot if in death match 
+	if (deathmatch) 
+	{ 
+	    G_DeathMatchSpawnPlayer (playernum); 
+	    return; 
+	} 
+		 
+	if (G_CheckSpot (playernum, &playerstarts[playernum]) ) 
+	{ 
+	    P_SpawnPlayer (&playerstarts[playernum]); 
+	    return; 
+	}
+	
+	// try to spawn at one of the other players spots 
+	for (i=0 ; i<MAXPLAYERS ; i++)
+	{
+	    if (G_CheckSpot (playernum, &playerstarts[i]) ) 
+	    { 
+		playerstarts[i].type = playernum+1;	// fake as other player 
+		P_SpawnPlayer (&playerstarts[i]); 
+		playerstarts[i].type = i+1;		// restore 
+		return; 
+	    }	    
+	    // he's going to be inside something.  Too bad.
+	}
+	P_SpawnPlayer (&playerstarts[playernum]); 
+    } 
+} 
+ 
+ 
+void G_ScreenShot (void) 
+{ 
+    gameaction = ga_screenshot; 
+} 
+ 
+
+
+// DOOM Par Times
+int pars[4][10] = 
+{ 
+    {0}, 
+    {0,30,75,120,90,165,180,180,30,165}, 
+    {0,90,90,90,120,90,360,240,30,170}, 
+    {0,90,45,90,150,90,90,165,30,135} 
+}; 
+
+// DOOM II Par Times
+int cpars[32] =
+{
+    30,90,120,120,90,150,120,120,270,90,	//  1-10
+    210,150,150,150,210,150,420,150,210,150,	// 11-20
+    240,150,180,150,150,300,330,420,300,180,	// 21-30
+    120,30					// 31-32
+};
+ 
+
+//
+// G_DoCompleted 
+//
+boolean		secretexit; 
+extern char*	pagename; 
+ 
+void G_ExitLevel (void) 
+{ 
+    secretexit = false; 
+    gameaction = ga_completed; 
+} 
+
+// Here's for the german edition.
+void G_SecretExitLevel (void) 
+{ 
+    // IF NO WOLF3D LEVELS, NO SECRET EXIT!
+    if ( (gamemode == commercial)
+      && (W_CheckNumForName("map31")<0))
+	secretexit = false;
+    else
+	secretexit = true; 
+    gameaction = ga_completed; 
+} 
+ 
+void G_DoCompleted (void) 
+{ 
+    int             i; 
+	 
+    gameaction = ga_nothing; 
+ 
+    for (i=0 ; i<MAXPLAYERS ; i++) 
+	if (playeringame[i]) 
+	    G_PlayerFinishLevel (i);        // take away cards and stuff 
+	 
+    if (automapactive) 
+	AM_Stop (); 
+	
+    if ( gamemode != commercial)
+	switch(gamemap)
+	{
+	  case 8:
+	    gameaction = ga_victory;
+	    return;
+	  case 9: 
+	    for (i=0 ; i<MAXPLAYERS ; i++) 
+		players[i].didsecret = true; 
+	    break;
+	}
+		
+//#if 0  Hmmm - why?
+    if ( (gamemap == 8)
+	 && (gamemode != commercial) ) 
+    {
+	// victory 
+	gameaction = ga_victory; 
+	return; 
+    } 
+	 
+    if ( (gamemap == 9)
+	 && (gamemode != commercial) ) 
+    {
+	// exit secret level 
+	for (i=0 ; i<MAXPLAYERS ; i++) 
+	    players[i].didsecret = true; 
+    } 
+//#endif
+    
+	 
+    wminfo.didsecret = players[consoleplayer].didsecret; 
+    wminfo.epsd = gameepisode -1; 
+    wminfo.last = gamemap -1;
+    
+    // wminfo.next is 0 biased, unlike gamemap
+    if ( gamemode == commercial)
+    {
+	if (secretexit)
+	    switch(gamemap)
+	    {
+	      case 15: wminfo.next = 30; break;
+	      case 31: wminfo.next = 31; break;
+	    }
+	else
+	    switch(gamemap)
+	    {
+	      case 31:
+	      case 32: wminfo.next = 15; break;
+	      default: wminfo.next = gamemap;
+	    }
+    }
+    else
+    {
+	if (secretexit) 
+	    wminfo.next = 8; 	// go to secret level 
+	else if (gamemap == 9) 
+	{
+	    // returning from secret level 
+	    switch (gameepisode) 
+	    { 
+	      case 1: 
+		wminfo.next = 3; 
+		break; 
+	      case 2: 
+		wminfo.next = 5; 
+		break; 
+	      case 3: 
+		wminfo.next = 6; 
+		break; 
+	      case 4:
+		wminfo.next = 2;
+		break;
+	    }                
+	} 
+	else 
+	    wminfo.next = gamemap;          // go to next level 
+    }
+		 
+    wminfo.maxkills = totalkills; 
+    wminfo.maxitems = totalitems; 
+    wminfo.maxsecret = totalsecret; 
+    wminfo.maxfrags = 0; 
+    if ( gamemode == commercial )
+	wminfo.partime = 35*cpars[gamemap-1]; 
+    else
+	wminfo.partime = 35*pars[gameepisode][gamemap]; 
+    wminfo.pnum = consoleplayer; 
+ 
+    for (i=0 ; i<MAXPLAYERS ; i++) 
+    { 
+	wminfo.plyr[i].in = playeringame[i]; 
+	wminfo.plyr[i].skills = players[i].killcount; 
+	wminfo.plyr[i].sitems = players[i].itemcount; 
+	wminfo.plyr[i].ssecret = players[i].secretcount; 
+	wminfo.plyr[i].stime = leveltime; 
+	memcpy (wminfo.plyr[i].frags, players[i].frags 
+		, sizeof(wminfo.plyr[i].frags)); 
+    } 
+ 
+    gamestate = GS_INTERMISSION; 
+    viewactive = false; 
+    automapactive = false; 
+ 
+    if (statcopy)
+	memcpy (statcopy, &wminfo, sizeof(wminfo));
+	
+    WI_Start (&wminfo); 
+} 
+
+
+//
+// G_WorldDone 
+//
+void G_WorldDone (void) 
+{ 
+    gameaction = ga_worlddone; 
+
+    if (secretexit) 
+	players[consoleplayer].didsecret = true; 
+
+    if ( gamemode == commercial )
+    {
+	switch (gamemap)
+	{
+	  case 15:
+	  case 31:
+	    if (!secretexit)
+		break;
+	  case 6:
+	  case 11:
+	  case 20:
+	  case 30:
+	    F_StartFinale ();
+	    break;
+	}
+    }
+} 
+ 
+void G_DoWorldDone (void) 
+{        
+    gamestate = GS_LEVEL; 
+    gamemap = wminfo.next+1; 
+    G_DoLoadLevel (); 
+    gameaction = ga_nothing; 
+    viewactive = true; 
+} 
+ 
+
+
+//
+// G_InitFromSavegame
+// Can be called by the startup code or the menu task. 
+//
+extern boolean setsizeneeded;
+void R_ExecuteSetViewSize (void);
+
+char	savename[256];
+
+void G_LoadGame (char* name) 
+{ 
+    strcpy (savename, name); 
+    gameaction = ga_loadgame; 
+} 
+ 
+#define VERSIONSIZE		16 
+
+
+void G_DoLoadGame (void) 
+{ 
+    int		length; 
+    int		i; 
+    int		a,b,c; 
+    char	vcheck[VERSIONSIZE]; 
+	 
+    gameaction = ga_nothing; 
+	 
+    length = M_ReadFile (savename, &savebuffer); 
+    save_p = savebuffer + SAVESTRINGSIZE;
+    
+    // skip the description field 
+    memset (vcheck,0,sizeof(vcheck)); 
+    sprintf (vcheck,"version %i",VERSION); 
+    if (strcmp (save_p, vcheck)) 
+	return;				// bad version 
+    save_p += VERSIONSIZE; 
+			 
+    gameskill = *save_p++; 
+    gameepisode = *save_p++; 
+    gamemap = *save_p++; 
+    for (i=0 ; i<MAXPLAYERS ; i++) 
+	playeringame[i] = *save_p++; 
+
+    // load a base level 
+    G_InitNew (gameskill, gameepisode, gamemap); 
+ 
+    // get the times 
+    a = *save_p++; 
+    b = *save_p++; 
+    c = *save_p++; 
+    leveltime = (a<<16) + (b<<8) + c; 
+	 
+    // dearchive all the modifications
+    P_UnArchivePlayers (); 
+    P_UnArchiveWorld (); 
+    P_UnArchiveThinkers (); 
+    P_UnArchiveSpecials (); 
+ 
+    if (*save_p != 0x1d) 
+	I_Error ("Bad savegame");
+    
+    // done 
+    Z_Free (savebuffer); 
+ 
+    if (setsizeneeded)
+	R_ExecuteSetViewSize ();
+    
+    // draw the pattern into the back screen
+    R_FillBackScreen ();   
+} 
+ 
+
+//
+// G_SaveGame
+// Called by the menu task.
+// Description is a 24 byte text string 
+//
+void
+G_SaveGame
+( int	slot,
+  char*	description ) 
+{ 
+    savegameslot = slot; 
+    strcpy (savedescription, description); 
+    sendsave = true; 
+} 
+ 
+void G_DoSaveGame (void) 
+{ 
+    char	name[100]; 
+    char	name2[VERSIONSIZE]; 
+    char*	description; 
+    int		length; 
+    int		i; 
+	
+    if (M_CheckParm("-cdrom"))
+	sprintf(name,"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",savegameslot);
+    else
+	sprintf (name,SAVEGAMENAME"%d.dsg",savegameslot); 
+    description = savedescription; 
+	 
+    save_p = savebuffer = screens[1]+0x4000; 
+	 
+    memcpy (save_p, description, SAVESTRINGSIZE); 
+    save_p += SAVESTRINGSIZE; 
+    memset (name2,0,sizeof(name2)); 
+    sprintf (name2,"version %i",VERSION); 
+    memcpy (save_p, name2, VERSIONSIZE); 
+    save_p += VERSIONSIZE; 
+	 
+    *save_p++ = gameskill; 
+    *save_p++ = gameepisode; 
+    *save_p++ = gamemap; 
+    for (i=0 ; i<MAXPLAYERS ; i++) 
+	*save_p++ = playeringame[i]; 
+    *save_p++ = leveltime>>16; 
+    *save_p++ = leveltime>>8; 
+    *save_p++ = leveltime; 
+ 
+    P_ArchivePlayers (); 
+    P_ArchiveWorld (); 
+    P_ArchiveThinkers (); 
+    P_ArchiveSpecials (); 
+	 
+    *save_p++ = 0x1d;		// consistancy marker 
+	 
+    length = save_p - savebuffer; 
+    if (length > SAVEGAMESIZE) 
+	I_Error ("Savegame buffer overrun"); 
+    M_WriteFile (name, savebuffer, length); 
+    gameaction = ga_nothing; 
+    savedescription[0] = 0;		 
+	 
+    players[consoleplayer].message = GGSAVED; 
+
+    // draw the pattern into the back screen
+    R_FillBackScreen ();	
+} 
+ 
+
+//
+// G_InitNew
+// Can be called by the startup code or the menu task,
+// consoleplayer, displayplayer, playeringame[] should be set. 
+//
+skill_t	d_skill; 
+int     d_episode; 
+int     d_map; 
+ 
+void
+G_DeferedInitNew
+( skill_t	skill,
+  int		episode,
+  int		map) 
+{ 
+    d_skill = skill; 
+    d_episode = episode; 
+    d_map = map; 
+    gameaction = ga_newgame; 
+} 
+
+
+void G_DoNewGame (void) 
+{
+    demoplayback = false; 
+    netdemo = false;
+    netgame = false;
+    deathmatch = false;
+    playeringame[1] = playeringame[2] = playeringame[3] = 0;
+    respawnparm = false;
+    fastparm = false;
+    nomonsters = false;
+    consoleplayer = 0;
+    G_InitNew (d_skill, d_episode, d_map); 
+    gameaction = ga_nothing; 
+} 
+
+// The sky texture to be used instead of the F_SKY1 dummy.
+extern  int	skytexture; 
+
+
+void
+G_InitNew
+( skill_t	skill,
+  int		episode,
+  int		map ) 
+{ 
+    int             i; 
+	 
+    if (paused) 
+    { 
+	paused = false; 
+	S_ResumeSound (); 
+    } 
+	
+
+    if (skill > sk_nightmare) 
+	skill = sk_nightmare;
+
+
+    // This was quite messy with SPECIAL and commented parts.
+    // Supposedly hacks to make the latest edition work.
+    // It might not work properly.
+    if (episode < 1)
+      episode = 1; 
+
+    if ( gamemode == retail )
+    {
+      if (episode > 4)
+	episode = 4;
+    }
+    else if ( gamemode == shareware )
+    {
+      if (episode > 1) 
+	   episode = 1;	// only start episode 1 on shareware
+    }  
+    else
+    {
+      if (episode > 3)
+	episode = 3;
+    }
+    
+
+  
+    if (map < 1) 
+	map = 1;
+    
+    if ( (map > 9)
+	 && ( gamemode != commercial) )
+      map = 9; 
+		 
+    M_ClearRandom (); 
+	 
+    if (skill == sk_nightmare || respawnparm )
+	respawnmonsters = true;
+    else
+	respawnmonsters = false;
+		
+    if (fastparm || (skill == sk_nightmare && gameskill != sk_nightmare) )
+    { 
+	for (i=S_SARG_RUN1 ; i<=S_SARG_PAIN2 ; i++) 
+	    states[i].tics >>= 1; 
+	mobjinfo[MT_BRUISERSHOT].speed = 20*FRACUNIT; 
+	mobjinfo[MT_HEADSHOT].speed = 20*FRACUNIT; 
+	mobjinfo[MT_TROOPSHOT].speed = 20*FRACUNIT; 
+    } 
+    else if (skill != sk_nightmare && gameskill == sk_nightmare) 
+    { 
+	for (i=S_SARG_RUN1 ; i<=S_SARG_PAIN2 ; i++) 
+	    states[i].tics <<= 1; 
+	mobjinfo[MT_BRUISERSHOT].speed = 15*FRACUNIT; 
+	mobjinfo[MT_HEADSHOT].speed = 10*FRACUNIT; 
+	mobjinfo[MT_TROOPSHOT].speed = 10*FRACUNIT; 
+    } 
+	 
+			 
+    // force players to be initialized upon first level load         
+    for (i=0 ; i<MAXPLAYERS ; i++) 
+	players[i].playerstate = PST_REBORN; 
+ 
+    usergame = true;                // will be set false if a demo 
+    paused = false; 
+    demoplayback = false; 
+    automapactive = false; 
+    viewactive = true; 
+    gameepisode = episode; 
+    gamemap = map; 
+    gameskill = skill; 
+ 
+    viewactive = true;
+    
+    // set the sky map for the episode
+    if ( gamemode == commercial)
+    {
+	skytexture = R_TextureNumForName ("SKY3");
+	if (gamemap < 12)
+	    skytexture = R_TextureNumForName ("SKY1");
+	else
+	    if (gamemap < 21)
+		skytexture = R_TextureNumForName ("SKY2");
+    }
+    else
+	switch (episode) 
+	{ 
+	  case 1: 
+	    skytexture = R_TextureNumForName ("SKY1"); 
+	    break; 
+	  case 2: 
+	    skytexture = R_TextureNumForName ("SKY2"); 
+	    break; 
+	  case 3: 
+	    skytexture = R_TextureNumForName ("SKY3"); 
+	    break; 
+	  case 4:	// Special Edition sky
+	    skytexture = R_TextureNumForName ("SKY4");
+	    break;
+	} 
+ 
+    G_DoLoadLevel (); 
+} 
+ 
+
+//
+// DEMO RECORDING 
+// 
+#define DEMOMARKER		0x80
+
+
+void G_ReadDemoTiccmd (ticcmd_t* cmd) 
+{ 
+    if (*demo_p == DEMOMARKER) 
+    {
+	// end of demo data stream 
+	G_CheckDemoStatus (); 
+	return; 
+    } 
+    cmd->forwardmove = ((signed char)*demo_p++); 
+    cmd->sidemove = ((signed char)*demo_p++); 
+    cmd->angleturn = ((unsigned char)*demo_p++)<<8; 
+    cmd->buttons = (unsigned char)*demo_p++; 
+} 
+
+
+void G_WriteDemoTiccmd (ticcmd_t* cmd) 
+{ 
+    if (gamekeydown['q'])           // press q to end demo recording 
+	G_CheckDemoStatus (); 
+    *demo_p++ = cmd->forwardmove; 
+    *demo_p++ = cmd->sidemove; 
+    *demo_p++ = (cmd->angleturn+128)>>8; 
+    *demo_p++ = cmd->buttons; 
+    demo_p -= 4; 
+    if (demo_p > demoend - 16)
+    {
+	// no more space 
+	G_CheckDemoStatus (); 
+	return; 
+    } 
+	
+    G_ReadDemoTiccmd (cmd);         // make SURE it is exactly the same 
+} 
+ 
+ 
+ 
+//
+// G_RecordDemo 
+// 
+void G_RecordDemo (char* name) 
+{ 
+    int             i; 
+    int				maxsize;
+	
+    usergame = false; 
+    strcpy (demoname, name); 
+    strcat (demoname, ".lmp"); 
+    maxsize = 0x20000;
+    i = M_CheckParm ("-maxdemo");
+    if (i && i<myargc-1)
+	maxsize = atoi(myargv[i+1])*1024;
+    demobuffer = Z_Malloc (maxsize,PU_STATIC,NULL); 
+    demoend = demobuffer + maxsize;
+	
+    demorecording = true; 
+} 
+ 
+ 
+void G_BeginRecording (void) 
+{ 
+    int             i; 
+		
+    demo_p = demobuffer;
+	
+    *demo_p++ = VERSION;
+    *demo_p++ = gameskill; 
+    *demo_p++ = gameepisode; 
+    *demo_p++ = gamemap; 
+    *demo_p++ = deathmatch; 
+    *demo_p++ = respawnparm;
+    *demo_p++ = fastparm;
+    *demo_p++ = nomonsters;
+    *demo_p++ = consoleplayer;
+	 
+    for (i=0 ; i<MAXPLAYERS ; i++) 
+	*demo_p++ = playeringame[i]; 		 
+} 
+ 
+
+//
+// G_PlayDemo 
+//
+
+char*	defdemoname; 
+ 
+void G_DeferedPlayDemo (char* name) 
+{ 
+    defdemoname = name; 
+    gameaction = ga_playdemo; 
+} 
+ 
+void G_DoPlayDemo (void) 
+{ 
+    skill_t skill; 
+    int             i, episode, map; 
+	 
+    gameaction = ga_nothing; 
+    demobuffer = demo_p = W_CacheLumpName (defdemoname, PU_STATIC); 
+    if ( *demo_p++ != VERSION)
+    {
+      fprintf( stderr, "Demo is from a different game version!\n");
+      gameaction = ga_nothing;
+      return;
+    }
+    
+    skill = *demo_p++; 
+    episode = *demo_p++; 
+    map = *demo_p++; 
+    deathmatch = *demo_p++;
+    respawnparm = *demo_p++;
+    fastparm = *demo_p++;
+    nomonsters = *demo_p++;
+    consoleplayer = *demo_p++;
+	
+    for (i=0 ; i<MAXPLAYERS ; i++) 
+	playeringame[i] = *demo_p++; 
+    if (playeringame[1]) 
+    { 
+	netgame = true; 
+	netdemo = true; 
+    }
+
+    // don't spend a lot of time in loadlevel 
+    precache = false;
+    G_InitNew (skill, episode, map); 
+    precache = true; 
+
+    usergame = false; 
+    demoplayback = true; 
+} 
+
+//
+// G_TimeDemo 
+//
+void G_TimeDemo (char* name) 
+{ 	 
+    nodrawers = M_CheckParm ("-nodraw"); 
+    noblit = M_CheckParm ("-noblit"); 
+    timingdemo = true; 
+    singletics = true; 
+
+    defdemoname = name; 
+    gameaction = ga_playdemo; 
+} 
+ 
+ 
+/* 
+=================== 
+= 
+= G_CheckDemoStatus 
+= 
+= Called after a death or level completion to allow demos to be cleaned up 
+= Returns true if a new demo loop action will take place 
+=================== 
+*/ 
+ 
+boolean G_CheckDemoStatus (void) 
+{ 
+    int             endtime; 
+	 
+    if (timingdemo) 
+    { 
+	endtime = I_GetTime (); 
+	I_Error ("timed %i gametics in %i realtics",gametic 
+		 , endtime-starttime); 
+    } 
+	 
+    if (demoplayback) 
+    { 
+	if (singledemo) 
+	    I_Quit (); 
+			 
+	Z_ChangeTag (demobuffer, PU_CACHE); 
+	demoplayback = false; 
+	netdemo = false;
+	netgame = false;
+	deathmatch = false;
+	playeringame[1] = playeringame[2] = playeringame[3] = 0;
+	respawnparm = false;
+	fastparm = false;
+	nomonsters = false;
+	consoleplayer = 0;
+	D_AdvanceDemo (); 
+	return true; 
+    } 
+ 
+    if (demorecording) 
+    { 
+	*demo_p++ = DEMOMARKER; 
+	M_WriteFile (demoname, demobuffer, demo_p - demobuffer); 
+	Z_Free (demobuffer); 
+	demorecording = false; 
+	I_Error ("Demo %s recorded",demoname); 
+    } 
+	 
+    return false; 
+} 
+ 
+ 
+ 
--- /dev/null
+++ b/src/g_game.h
@@ -1,0 +1,82 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: g_game.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//   Duh.
+// 
+//-----------------------------------------------------------------------------
+
+
+#ifndef __G_GAME__
+#define __G_GAME__
+
+#include "doomdef.h"
+#include "d_event.h"
+
+
+
+//
+// GAME
+//
+void G_DeathMatchSpawnPlayer (int playernum);
+
+void G_InitNew (skill_t skill, int episode, int map);
+
+// Can be called by the startup code or M_Responder.
+// A normal game starts at map 1,
+// but a warp test can start elsewhere
+void G_DeferedInitNew (skill_t skill, int episode, int map);
+
+void G_DeferedPlayDemo (char* demo);
+
+// Can be called by the startup code or M_Responder,
+// calls P_SetupLevel or W_EnterWorld.
+void G_LoadGame (char* name);
+
+void G_DoLoadGame (void);
+
+// Called by M_Responder.
+void G_SaveGame (int slot, char* description);
+
+// Only called by startup code.
+void G_RecordDemo (char* name);
+
+void G_BeginRecording (void);
+
+void G_PlayDemo (char* name);
+void G_TimeDemo (char* name);
+boolean G_CheckDemoStatus (void);
+
+void G_ExitLevel (void);
+void G_SecretExitLevel (void);
+
+void G_WorldDone (void);
+
+void G_Ticker (void);
+boolean G_Responder (event_t*	ev);
+
+void G_ScreenShot (void);
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:11  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/hu_lib.c
@@ -1,0 +1,357 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: hu_lib.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:19:55  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:  heads-up text and input code
+//
+//-----------------------------------------------------------------------------
+
+static const char
+rcsid[] = "$Id: hu_lib.c 4 2005-07-23 16:19:41Z fraggle $";
+
+#include <ctype.h>
+
+#include "doomdef.h"
+
+#include "v_video.h"
+#include "m_swap.h"
+
+#include "hu_lib.h"
+#include "r_local.h"
+#include "r_draw.h"
+
+// boolean : whether the screen is always erased
+#define noterased viewwindowx
+
+extern boolean	automapactive;	// in AM_map.c
+
+void HUlib_init(void)
+{
+}
+
+void HUlib_clearTextLine(hu_textline_t* t)
+{
+    t->len = 0;
+    t->l[0] = 0;
+    t->needsupdate = true;
+}
+
+void
+HUlib_initTextLine
+( hu_textline_t*	t,
+  int			x,
+  int			y,
+  patch_t**		f,
+  int			sc )
+{
+    t->x = x;
+    t->y = y;
+    t->f = f;
+    t->sc = sc;
+    HUlib_clearTextLine(t);
+}
+
+boolean
+HUlib_addCharToTextLine
+( hu_textline_t*	t,
+  char			ch )
+{
+
+    if (t->len == HU_MAXLINELENGTH)
+	return false;
+    else
+    {
+	t->l[t->len++] = ch;
+	t->l[t->len] = 0;
+	t->needsupdate = 4;
+	return true;
+    }
+
+}
+
+boolean HUlib_delCharFromTextLine(hu_textline_t* t)
+{
+
+    if (!t->len) return false;
+    else
+    {
+	t->l[--t->len] = 0;
+	t->needsupdate = 4;
+	return true;
+    }
+
+}
+
+void
+HUlib_drawTextLine
+( hu_textline_t*	l,
+  boolean		drawcursor )
+{
+
+    int			i;
+    int			w;
+    int			x;
+    unsigned char	c;
+
+    // draw the new stuff
+    x = l->x;
+    for (i=0;i<l->len;i++)
+    {
+	c = toupper(l->l[i]);
+	if (c != ' '
+	    && c >= l->sc
+	    && c <= '_')
+	{
+	    w = SHORT(l->f[c - l->sc]->width);
+	    if (x+w > SCREENWIDTH)
+		break;
+	    V_DrawPatchDirect(x, l->y, FG, l->f[c - l->sc]);
+	    x += w;
+	}
+	else
+	{
+	    x += 4;
+	    if (x >= SCREENWIDTH)
+		break;
+	}
+    }
+
+    // draw the cursor if requested
+    if (drawcursor
+	&& x + SHORT(l->f['_' - l->sc]->width) <= SCREENWIDTH)
+    {
+	V_DrawPatchDirect(x, l->y, FG, l->f['_' - l->sc]);
+    }
+}
+
+
+// sorta called by HU_Erase and just better darn get things straight
+void HUlib_eraseTextLine(hu_textline_t* l)
+{
+    int			lh;
+    int			y;
+    int			yoffset;
+    static boolean	lastautomapactive = true;
+
+    // Only erases when NOT in automap and the screen is reduced,
+    // and the text must either need updating or refreshing
+    // (because of a recent change back from the automap)
+
+    if (!automapactive &&
+	viewwindowx && l->needsupdate)
+    {
+	lh = SHORT(l->f[0]->height) + 1;
+	for (y=l->y,yoffset=y*SCREENWIDTH ; y<l->y+lh ; y++,yoffset+=SCREENWIDTH)
+	{
+	    if (y < viewwindowy || y >= viewwindowy + viewheight)
+		R_VideoErase(yoffset, SCREENWIDTH); // erase entire line
+	    else
+	    {
+		R_VideoErase(yoffset, viewwindowx); // erase left border
+		R_VideoErase(yoffset + viewwindowx + viewwidth, viewwindowx);
+		// erase right border
+	    }
+	}
+    }
+
+    lastautomapactive = automapactive;
+    if (l->needsupdate) l->needsupdate--;
+
+}
+
+void
+HUlib_initSText
+( hu_stext_t*	s,
+  int		x,
+  int		y,
+  int		h,
+  patch_t**	font,
+  int		startchar,
+  boolean*	on )
+{
+
+    int i;
+
+    s->h = h;
+    s->on = on;
+    s->laston = true;
+    s->cl = 0;
+    for (i=0;i<h;i++)
+	HUlib_initTextLine(&s->l[i],
+			   x, y - i*(SHORT(font[0]->height)+1),
+			   font, startchar);
+
+}
+
+void HUlib_addLineToSText(hu_stext_t* s)
+{
+
+    int i;
+
+    // add a clear line
+    if (++s->cl == s->h)
+	s->cl = 0;
+    HUlib_clearTextLine(&s->l[s->cl]);
+
+    // everything needs updating
+    for (i=0 ; i<s->h ; i++)
+	s->l[i].needsupdate = 4;
+
+}
+
+void
+HUlib_addMessageToSText
+( hu_stext_t*	s,
+  char*		prefix,
+  char*		msg )
+{
+    HUlib_addLineToSText(s);
+    if (prefix)
+	while (*prefix)
+	    HUlib_addCharToTextLine(&s->l[s->cl], *(prefix++));
+
+    while (*msg)
+	HUlib_addCharToTextLine(&s->l[s->cl], *(msg++));
+}
+
+void HUlib_drawSText(hu_stext_t* s)
+{
+    int i, idx;
+    hu_textline_t *l;
+
+    if (!*s->on)
+	return; // if not on, don't draw
+
+    // draw everything
+    for (i=0 ; i<s->h ; i++)
+    {
+	idx = s->cl - i;
+	if (idx < 0)
+	    idx += s->h; // handle queue of lines
+	
+	l = &s->l[idx];
+
+	// need a decision made here on whether to skip the draw
+	HUlib_drawTextLine(l, false); // no cursor, please
+    }
+
+}
+
+void HUlib_eraseSText(hu_stext_t* s)
+{
+
+    int i;
+
+    for (i=0 ; i<s->h ; i++)
+    {
+	if (s->laston && !*s->on)
+	    s->l[i].needsupdate = 4;
+	HUlib_eraseTextLine(&s->l[i]);
+    }
+    s->laston = *s->on;
+
+}
+
+void
+HUlib_initIText
+( hu_itext_t*	it,
+  int		x,
+  int		y,
+  patch_t**	font,
+  int		startchar,
+  boolean*	on )
+{
+    it->lm = 0; // default left margin is start of text
+    it->on = on;
+    it->laston = true;
+    HUlib_initTextLine(&it->l, x, y, font, startchar);
+}
+
+
+// The following deletion routines adhere to the left margin restriction
+void HUlib_delCharFromIText(hu_itext_t* it)
+{
+    if (it->l.len != it->lm)
+	HUlib_delCharFromTextLine(&it->l);
+}
+
+void HUlib_eraseLineFromIText(hu_itext_t* it)
+{
+    while (it->lm != it->l.len)
+	HUlib_delCharFromTextLine(&it->l);
+}
+
+// Resets left margin as well
+void HUlib_resetIText(hu_itext_t* it)
+{
+    it->lm = 0;
+    HUlib_clearTextLine(&it->l);
+}
+
+void
+HUlib_addPrefixToIText
+( hu_itext_t*	it,
+  char*		str )
+{
+    while (*str)
+	HUlib_addCharToTextLine(&it->l, *(str++));
+    it->lm = it->l.len;
+}
+
+// wrapper function for handling general keyed input.
+// returns true if it ate the key
+boolean
+HUlib_keyInIText
+( hu_itext_t*	it,
+  unsigned char ch )
+{
+
+    if (ch >= ' ' && ch <= '_') 
+  	HUlib_addCharToTextLine(&it->l, (char) ch);
+    else 
+	if (ch == KEY_BACKSPACE) 
+	    HUlib_delCharFromIText(it);
+	else 
+	    if (ch != KEY_ENTER) 
+		return false; // did not eat key
+
+    return true; // ate the key
+
+}
+
+void HUlib_drawIText(hu_itext_t* it)
+{
+
+    hu_textline_t *l = &it->l;
+
+    if (!*it->on)
+	return;
+    HUlib_drawTextLine(l, true); // draw the line w/ cursor
+
+}
+
+void HUlib_eraseIText(hu_itext_t* it)
+{
+    if (it->laston && !*it->on)
+	it->l.needsupdate = 4;
+    HUlib_eraseTextLine(&it->l);
+    it->laston = *it->on;
+}
+
--- /dev/null
+++ b/src/hu_lib.h
@@ -1,0 +1,199 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: hu_lib.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:  none
+//
+//-----------------------------------------------------------------------------
+
+#ifndef __HULIB__
+#define __HULIB__
+
+// We are referring to patches.
+#include "r_defs.h"
+
+
+// background and foreground screen numbers
+// different from other modules.
+#define BG			1
+#define FG			0
+
+// font stuff
+#define HU_CHARERASE	KEY_BACKSPACE
+
+#define HU_MAXLINES		4
+#define HU_MAXLINELENGTH	80
+
+//
+// Typedefs of widgets
+//
+
+// Text Line widget
+//  (parent of Scrolling Text and Input Text widgets)
+typedef struct
+{
+    // left-justified position of scrolling text window
+    int		x;
+    int		y;
+    
+    patch_t**	f;			// font
+    int		sc;			// start character
+    char	l[HU_MAXLINELENGTH+1];	// line of text
+    int		len;		      	// current line length
+
+    // whether this line needs to be udpated
+    int		needsupdate;	      
+
+} hu_textline_t;
+
+
+
+// Scrolling Text window widget
+//  (child of Text Line widget)
+typedef struct
+{
+    hu_textline_t	l[HU_MAXLINES];	// text lines to draw
+    int			h;		// height in lines
+    int			cl;		// current line number
+
+    // pointer to boolean stating whether to update window
+    boolean*		on;
+    boolean		laston;		// last value of *->on.
+
+} hu_stext_t;
+
+
+
+// Input Text Line widget
+//  (child of Text Line widget)
+typedef struct
+{
+    hu_textline_t	l;		// text line to input on
+
+     // left margin past which I am not to delete characters
+    int			lm;
+
+    // pointer to boolean stating whether to update window
+    boolean*		on; 
+    boolean		laston; // last value of *->on;
+
+} hu_itext_t;
+
+
+//
+// Widget creation, access, and update routines
+//
+
+// initializes heads-up widget library
+void HUlib_init(void);
+
+//
+// textline code
+//
+
+// clear a line of text
+void	HUlib_clearTextLine(hu_textline_t *t);
+
+void	HUlib_initTextLine(hu_textline_t *t, int x, int y, patch_t **f, int sc);
+
+// returns success
+boolean HUlib_addCharToTextLine(hu_textline_t *t, char ch);
+
+// returns success
+boolean HUlib_delCharFromTextLine(hu_textline_t *t);
+
+// draws tline
+void	HUlib_drawTextLine(hu_textline_t *l, boolean drawcursor);
+
+// erases text line
+void	HUlib_eraseTextLine(hu_textline_t *l); 
+
+
+//
+// Scrolling Text window widget routines
+//
+
+// ?
+void
+HUlib_initSText
+( hu_stext_t*	s,
+  int		x,
+  int		y,
+  int		h,
+  patch_t**	font,
+  int		startchar,
+  boolean*	on );
+
+// add a new line
+void HUlib_addLineToSText(hu_stext_t* s);  
+
+// ?
+void
+HUlib_addMessageToSText
+( hu_stext_t*	s,
+  char*		prefix,
+  char*		msg );
+
+// draws stext
+void HUlib_drawSText(hu_stext_t* s);
+
+// erases all stext lines
+void HUlib_eraseSText(hu_stext_t* s); 
+
+// Input Text Line widget routines
+void
+HUlib_initIText
+( hu_itext_t*	it,
+  int		x,
+  int		y,
+  patch_t**	font,
+  int		startchar,
+  boolean*	on );
+
+// enforces left margin
+void HUlib_delCharFromIText(hu_itext_t* it);
+
+// enforces left margin
+void HUlib_eraseLineFromIText(hu_itext_t* it);
+
+// resets line and left margin
+void HUlib_resetIText(hu_itext_t* it);
+
+// left of left-margin
+void
+HUlib_addPrefixToIText
+( hu_itext_t*	it,
+  char*		str );
+
+// whether eaten
+boolean
+HUlib_keyInIText
+( hu_itext_t*	it,
+  unsigned char ch );
+
+void HUlib_drawIText(hu_itext_t* it);
+
+// erases all itext lines
+void HUlib_eraseIText(hu_itext_t* it); 
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:19:55  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/hu_stuff.c
@@ -1,0 +1,762 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: hu_stuff.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:19:56  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:  Heads-up displays
+//
+//-----------------------------------------------------------------------------
+
+static const char
+rcsid[] = "$Id: hu_stuff.c 4 2005-07-23 16:19:41Z fraggle $";
+
+#include <ctype.h>
+
+#include "doomdef.h"
+
+#include "z_zone.h"
+
+#include "m_swap.h"
+
+#include "hu_stuff.h"
+#include "hu_lib.h"
+#include "w_wad.h"
+
+#include "s_sound.h"
+
+#include "doomstat.h"
+
+// Data.
+#include "dstrings.h"
+#include "sounds.h"
+
+//
+// Locally used constants, shortcuts.
+//
+#define HU_TITLE	(mapnames[(gameepisode-1)*9+gamemap-1])
+#define HU_TITLE2	(mapnames2[gamemap-1])
+#define HU_TITLEP	(mapnamesp[gamemap-1])
+#define HU_TITLET	(mapnamest[gamemap-1])
+#define HU_TITLEHEIGHT	1
+#define HU_TITLEX	0
+#define HU_TITLEY	(167 - SHORT(hu_font[0]->height))
+
+#define HU_INPUTTOGGLE	't'
+#define HU_INPUTX	HU_MSGX
+#define HU_INPUTY	(HU_MSGY + HU_MSGHEIGHT*(SHORT(hu_font[0]->height) +1))
+#define HU_INPUTWIDTH	64
+#define HU_INPUTHEIGHT	1
+
+
+
+char*	chat_macros[] =
+{
+    HUSTR_CHATMACRO0,
+    HUSTR_CHATMACRO1,
+    HUSTR_CHATMACRO2,
+    HUSTR_CHATMACRO3,
+    HUSTR_CHATMACRO4,
+    HUSTR_CHATMACRO5,
+    HUSTR_CHATMACRO6,
+    HUSTR_CHATMACRO7,
+    HUSTR_CHATMACRO8,
+    HUSTR_CHATMACRO9
+};
+
+char*	player_names[] =
+{
+    HUSTR_PLRGREEN,
+    HUSTR_PLRINDIGO,
+    HUSTR_PLRBROWN,
+    HUSTR_PLRRED
+};
+
+
+char			chat_char; // remove later.
+static player_t*	plr;
+patch_t*		hu_font[HU_FONTSIZE];
+static hu_textline_t	w_title;
+boolean			chat_on;
+static hu_itext_t	w_chat;
+static boolean		always_off = false;
+static char		chat_dest[MAXPLAYERS];
+static hu_itext_t w_inputbuffer[MAXPLAYERS];
+
+static boolean		message_on;
+boolean			message_dontfuckwithme;
+static boolean		message_nottobefuckedwith;
+
+static hu_stext_t	w_message;
+static int		message_counter;
+
+extern int		showMessages;
+extern boolean		automapactive;
+
+static boolean		headsupactive = false;
+
+//
+// Builtin map names.
+// The actual names can be found in DStrings.h.
+//
+
+char*	mapnames[] =	// DOOM shareware/registered/retail (Ultimate) names.
+{
+
+    HUSTR_E1M1,
+    HUSTR_E1M2,
+    HUSTR_E1M3,
+    HUSTR_E1M4,
+    HUSTR_E1M5,
+    HUSTR_E1M6,
+    HUSTR_E1M7,
+    HUSTR_E1M8,
+    HUSTR_E1M9,
+
+    HUSTR_E2M1,
+    HUSTR_E2M2,
+    HUSTR_E2M3,
+    HUSTR_E2M4,
+    HUSTR_E2M5,
+    HUSTR_E2M6,
+    HUSTR_E2M7,
+    HUSTR_E2M8,
+    HUSTR_E2M9,
+
+    HUSTR_E3M1,
+    HUSTR_E3M2,
+    HUSTR_E3M3,
+    HUSTR_E3M4,
+    HUSTR_E3M5,
+    HUSTR_E3M6,
+    HUSTR_E3M7,
+    HUSTR_E3M8,
+    HUSTR_E3M9,
+
+    HUSTR_E4M1,
+    HUSTR_E4M2,
+    HUSTR_E4M3,
+    HUSTR_E4M4,
+    HUSTR_E4M5,
+    HUSTR_E4M6,
+    HUSTR_E4M7,
+    HUSTR_E4M8,
+    HUSTR_E4M9,
+
+    "NEWLEVEL",
+    "NEWLEVEL",
+    "NEWLEVEL",
+    "NEWLEVEL",
+    "NEWLEVEL",
+    "NEWLEVEL",
+    "NEWLEVEL",
+    "NEWLEVEL",
+    "NEWLEVEL"
+};
+
+char*	mapnames2[] =	// DOOM 2 map names.
+{
+    HUSTR_1,
+    HUSTR_2,
+    HUSTR_3,
+    HUSTR_4,
+    HUSTR_5,
+    HUSTR_6,
+    HUSTR_7,
+    HUSTR_8,
+    HUSTR_9,
+    HUSTR_10,
+    HUSTR_11,
+	
+    HUSTR_12,
+    HUSTR_13,
+    HUSTR_14,
+    HUSTR_15,
+    HUSTR_16,
+    HUSTR_17,
+    HUSTR_18,
+    HUSTR_19,
+    HUSTR_20,
+	
+    HUSTR_21,
+    HUSTR_22,
+    HUSTR_23,
+    HUSTR_24,
+    HUSTR_25,
+    HUSTR_26,
+    HUSTR_27,
+    HUSTR_28,
+    HUSTR_29,
+    HUSTR_30,
+    HUSTR_31,
+    HUSTR_32
+};
+
+
+char*	mapnamesp[] =	// Plutonia WAD map names.
+{
+    PHUSTR_1,
+    PHUSTR_2,
+    PHUSTR_3,
+    PHUSTR_4,
+    PHUSTR_5,
+    PHUSTR_6,
+    PHUSTR_7,
+    PHUSTR_8,
+    PHUSTR_9,
+    PHUSTR_10,
+    PHUSTR_11,
+	
+    PHUSTR_12,
+    PHUSTR_13,
+    PHUSTR_14,
+    PHUSTR_15,
+    PHUSTR_16,
+    PHUSTR_17,
+    PHUSTR_18,
+    PHUSTR_19,
+    PHUSTR_20,
+	
+    PHUSTR_21,
+    PHUSTR_22,
+    PHUSTR_23,
+    PHUSTR_24,
+    PHUSTR_25,
+    PHUSTR_26,
+    PHUSTR_27,
+    PHUSTR_28,
+    PHUSTR_29,
+    PHUSTR_30,
+    PHUSTR_31,
+    PHUSTR_32
+};
+
+
+char *mapnamest[] =	// TNT WAD map names.
+{
+    THUSTR_1,
+    THUSTR_2,
+    THUSTR_3,
+    THUSTR_4,
+    THUSTR_5,
+    THUSTR_6,
+    THUSTR_7,
+    THUSTR_8,
+    THUSTR_9,
+    THUSTR_10,
+    THUSTR_11,
+	
+    THUSTR_12,
+    THUSTR_13,
+    THUSTR_14,
+    THUSTR_15,
+    THUSTR_16,
+    THUSTR_17,
+    THUSTR_18,
+    THUSTR_19,
+    THUSTR_20,
+	
+    THUSTR_21,
+    THUSTR_22,
+    THUSTR_23,
+    THUSTR_24,
+    THUSTR_25,
+    THUSTR_26,
+    THUSTR_27,
+    THUSTR_28,
+    THUSTR_29,
+    THUSTR_30,
+    THUSTR_31,
+    THUSTR_32
+};
+
+
+const char*	shiftxform;
+
+const char french_shiftxform[] =
+{
+    0,
+    1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+    11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+    21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+    31,
+    ' ', '!', '"', '#', '$', '%', '&',
+    '"', // shift-'
+    '(', ')', '*', '+',
+    '?', // shift-,
+    '_', // shift--
+    '>', // shift-.
+    '?', // shift-/
+    '0', // shift-0
+    '1', // shift-1
+    '2', // shift-2
+    '3', // shift-3
+    '4', // shift-4
+    '5', // shift-5
+    '6', // shift-6
+    '7', // shift-7
+    '8', // shift-8
+    '9', // shift-9
+    '/',
+    '.', // shift-;
+    '<',
+    '+', // shift-=
+    '>', '?', '@',
+    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+    '[', // shift-[
+    '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK
+    ']', // shift-]
+    '"', '_',
+    '\'', // shift-`
+    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+    '{', '|', '}', '~', 127
+
+};
+
+const char english_shiftxform[] =
+{
+
+    0,
+    1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+    11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+    21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+    31,
+    ' ', '!', '"', '#', '$', '%', '&',
+    '"', // shift-'
+    '(', ')', '*', '+',
+    '<', // shift-,
+    '_', // shift--
+    '>', // shift-.
+    '?', // shift-/
+    ')', // shift-0
+    '!', // shift-1
+    '@', // shift-2
+    '#', // shift-3
+    '$', // shift-4
+    '%', // shift-5
+    '^', // shift-6
+    '&', // shift-7
+    '*', // shift-8
+    '(', // shift-9
+    ':',
+    ':', // shift-;
+    '<',
+    '+', // shift-=
+    '>', '?', '@',
+    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+    '[', // shift-[
+    '!', // shift-backslash - OH MY GOD DOES WATCOM SUCK
+    ']', // shift-]
+    '"', '_',
+    '\'', // shift-`
+    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+    'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+    '{', '|', '}', '~', 127
+};
+
+char frenchKeyMap[128]=
+{
+    0,
+    1,2,3,4,5,6,7,8,9,10,
+    11,12,13,14,15,16,17,18,19,20,
+    21,22,23,24,25,26,27,28,29,30,
+    31,
+    ' ','!','"','#','$','%','&','%','(',')','*','+',';','-',':','!',
+    '0','1','2','3','4','5','6','7','8','9',':','M','<','=','>','?',
+    '@','Q','B','C','D','E','F','G','H','I','J','K','L',',','N','O',
+    'P','A','R','S','T','U','V','Z','X','Y','W','^','\\','$','^','_',
+    '@','Q','B','C','D','E','F','G','H','I','J','K','L',',','N','O',
+    'P','A','R','S','T','U','V','Z','X','Y','W','^','\\','$','^',127
+};
+
+char ForeignTranslation(unsigned char ch)
+{
+    return ch < 128 ? frenchKeyMap[ch] : ch;
+}
+
+void HU_Init(void)
+{
+
+    int		i;
+    int		j;
+    char	buffer[9];
+
+    if (french)
+	shiftxform = french_shiftxform;
+    else
+	shiftxform = english_shiftxform;
+
+    // load the heads-up font
+    j = HU_FONTSTART;
+    for (i=0;i<HU_FONTSIZE;i++)
+    {
+	sprintf(buffer, "STCFN%.3d", j++);
+	hu_font[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
+    }
+
+}
+
+void HU_Stop(void)
+{
+    headsupactive = false;
+}
+
+void HU_Start(void)
+{
+
+    int		i;
+    char*	s;
+
+    if (headsupactive)
+	HU_Stop();
+
+    plr = &players[consoleplayer];
+    message_on = false;
+    message_dontfuckwithme = false;
+    message_nottobefuckedwith = false;
+    chat_on = false;
+
+    // create the message widget
+    HUlib_initSText(&w_message,
+		    HU_MSGX, HU_MSGY, HU_MSGHEIGHT,
+		    hu_font,
+		    HU_FONTSTART, &message_on);
+
+    // create the map title widget
+    HUlib_initTextLine(&w_title,
+		       HU_TITLEX, HU_TITLEY,
+		       hu_font,
+		       HU_FONTSTART);
+    
+    switch ( gamemode )
+    {
+      case shareware:
+      case registered:
+      case retail:
+	s = HU_TITLE;
+	break;
+
+/* FIXME
+      case pack_plut:
+	s = HU_TITLEP;
+	break;
+      case pack_tnt:
+	s = HU_TITLET;
+	break;
+*/
+	
+      case commercial:
+      default:
+	 s = HU_TITLE2;
+	 break;
+    }
+    
+    while (*s)
+	HUlib_addCharToTextLine(&w_title, *(s++));
+
+    // create the chat widget
+    HUlib_initIText(&w_chat,
+		    HU_INPUTX, HU_INPUTY,
+		    hu_font,
+		    HU_FONTSTART, &chat_on);
+
+    // create the inputbuffer widgets
+    for (i=0 ; i<MAXPLAYERS ; i++)
+	HUlib_initIText(&w_inputbuffer[i], 0, 0, 0, 0, &always_off);
+
+    headsupactive = true;
+
+}
+
+void HU_Drawer(void)
+{
+
+    HUlib_drawSText(&w_message);
+    HUlib_drawIText(&w_chat);
+    if (automapactive)
+	HUlib_drawTextLine(&w_title, false);
+
+}
+
+void HU_Erase(void)
+{
+
+    HUlib_eraseSText(&w_message);
+    HUlib_eraseIText(&w_chat);
+    HUlib_eraseTextLine(&w_title);
+
+}
+
+void HU_Ticker(void)
+{
+
+    int i, rc;
+    char c;
+
+    // tick down message counter if message is up
+    if (message_counter && !--message_counter)
+    {
+	message_on = false;
+	message_nottobefuckedwith = false;
+    }
+
+    if (showMessages || message_dontfuckwithme)
+    {
+
+	// display message if necessary
+	if ((plr->message && !message_nottobefuckedwith)
+	    || (plr->message && message_dontfuckwithme))
+	{
+	    HUlib_addMessageToSText(&w_message, 0, plr->message);
+	    plr->message = 0;
+	    message_on = true;
+	    message_counter = HU_MSGTIMEOUT;
+	    message_nottobefuckedwith = message_dontfuckwithme;
+	    message_dontfuckwithme = 0;
+	}
+
+    } // else message_on = false;
+
+    // check for incoming chat characters
+    if (netgame)
+    {
+	for (i=0 ; i<MAXPLAYERS; i++)
+	{
+	    if (!playeringame[i])
+		continue;
+	    if (i != consoleplayer
+		&& (c = players[i].cmd.chatchar))
+	    {
+		if (c <= HU_BROADCAST)
+		    chat_dest[i] = c;
+		else
+		{
+		    if (c >= 'a' && c <= 'z')
+			c = (char) shiftxform[(unsigned char) c];
+		    rc = HUlib_keyInIText(&w_inputbuffer[i], c);
+		    if (rc && c == KEY_ENTER)
+		    {
+			if (w_inputbuffer[i].l.len
+			    && (chat_dest[i] == consoleplayer+1
+				|| chat_dest[i] == HU_BROADCAST))
+			{
+			    HUlib_addMessageToSText(&w_message,
+						    player_names[i],
+						    w_inputbuffer[i].l.l);
+			    
+			    message_nottobefuckedwith = true;
+			    message_on = true;
+			    message_counter = HU_MSGTIMEOUT;
+			    if ( gamemode == commercial )
+			      S_StartSound(0, sfx_radio);
+			    else
+			      S_StartSound(0, sfx_tink);
+			}
+			HUlib_resetIText(&w_inputbuffer[i]);
+		    }
+		}
+		players[i].cmd.chatchar = 0;
+	    }
+	}
+    }
+
+}
+
+#define QUEUESIZE		128
+
+static char	chatchars[QUEUESIZE];
+static int	head = 0;
+static int	tail = 0;
+
+
+void HU_queueChatChar(char c)
+{
+    if (((head + 1) & (QUEUESIZE-1)) == tail)
+    {
+	plr->message = HUSTR_MSGU;
+    }
+    else
+    {
+	chatchars[head] = c;
+	head = (head + 1) & (QUEUESIZE-1);
+    }
+}
+
+char HU_dequeueChatChar(void)
+{
+    char c;
+
+    if (head != tail)
+    {
+	c = chatchars[tail];
+	tail = (tail + 1) & (QUEUESIZE-1);
+    }
+    else
+    {
+	c = 0;
+    }
+
+    return c;
+}
+
+boolean HU_Responder(event_t *ev)
+{
+
+    static char		lastmessage[HU_MAXLINELENGTH+1];
+    char*		macromessage;
+    boolean		eatkey = false;
+    static boolean	shiftdown = false;
+    static boolean	altdown = false;
+    unsigned char 	c;
+    int			i;
+    int			numplayers;
+    
+    static char		destination_keys[MAXPLAYERS] =
+    {
+	HUSTR_KEYGREEN,
+	HUSTR_KEYINDIGO,
+	HUSTR_KEYBROWN,
+	HUSTR_KEYRED
+    };
+    
+    static int		num_nobrainers = 0;
+
+    numplayers = 0;
+    for (i=0 ; i<MAXPLAYERS ; i++)
+	numplayers += playeringame[i];
+
+    if (ev->data1 == KEY_RSHIFT)
+    {
+	shiftdown = ev->type == ev_keydown;
+	return false;
+    }
+    else if (ev->data1 == KEY_RALT || ev->data1 == KEY_LALT)
+    {
+	altdown = ev->type == ev_keydown;
+	return false;
+    }
+
+    if (ev->type != ev_keydown)
+	return false;
+
+    if (!chat_on)
+    {
+	if (ev->data1 == HU_MSGREFRESH)
+	{
+	    message_on = true;
+	    message_counter = HU_MSGTIMEOUT;
+	    eatkey = true;
+	}
+	else if (netgame && ev->data1 == HU_INPUTTOGGLE)
+	{
+	    eatkey = chat_on = true;
+	    HUlib_resetIText(&w_chat);
+	    HU_queueChatChar(HU_BROADCAST);
+	}
+	else if (netgame && numplayers > 2)
+	{
+	    for (i=0; i<MAXPLAYERS ; i++)
+	    {
+		if (ev->data1 == destination_keys[i])
+		{
+		    if (playeringame[i] && i!=consoleplayer)
+		    {
+			eatkey = chat_on = true;
+			HUlib_resetIText(&w_chat);
+			HU_queueChatChar(i+1);
+			break;
+		    }
+		    else if (i == consoleplayer)
+		    {
+			num_nobrainers++;
+			if (num_nobrainers < 3)
+			    plr->message = HUSTR_TALKTOSELF1;
+			else if (num_nobrainers < 6)
+			    plr->message = HUSTR_TALKTOSELF2;
+			else if (num_nobrainers < 9)
+			    plr->message = HUSTR_TALKTOSELF3;
+			else if (num_nobrainers < 32)
+			    plr->message = HUSTR_TALKTOSELF4;
+			else
+			    plr->message = HUSTR_TALKTOSELF5;
+		    }
+		}
+	    }
+	}
+    }
+    else
+    {
+	c = ev->data1;
+	// send a macro
+	if (altdown)
+	{
+	    c = c - '0';
+	    if (c > 9)
+		return false;
+	    // fprintf(stderr, "got here\n");
+	    macromessage = chat_macros[c];
+	    
+	    // kill last message with a '\n'
+	    HU_queueChatChar(KEY_ENTER); // DEBUG!!!
+	    
+	    // send the macro message
+	    while (*macromessage)
+		HU_queueChatChar(*macromessage++);
+	    HU_queueChatChar(KEY_ENTER);
+	    
+	    // leave chat mode and notify that it was sent
+	    chat_on = false;
+	    strcpy(lastmessage, chat_macros[c]);
+	    plr->message = lastmessage;
+	    eatkey = true;
+	}
+	else
+	{
+	    if (french)
+		c = ForeignTranslation(c);
+	    if (shiftdown || (c >= 'a' && c <= 'z'))
+		c = shiftxform[c];
+	    eatkey = HUlib_keyInIText(&w_chat, c);
+	    if (eatkey)
+	    {
+		// static unsigned char buf[20]; // DEBUG
+		HU_queueChatChar(c);
+		
+		// sprintf(buf, "KEY: %d => %d", ev->data1, c);
+		//      plr->message = buf;
+	    }
+	    if (c == KEY_ENTER)
+	    {
+		chat_on = false;
+		if (w_chat.l.len)
+		{
+		    strcpy(lastmessage, w_chat.l.l);
+		    plr->message = lastmessage;
+		}
+	    }
+	    else if (c == KEY_ESCAPE)
+		chat_on = false;
+	}
+    }
+
+    return eatkey;
+
+}
--- /dev/null
+++ b/src/hu_stuff.h
@@ -1,0 +1,69 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: hu_stuff.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:  Head up display
+//
+//-----------------------------------------------------------------------------
+
+#ifndef __HU_STUFF_H__
+#define __HU_STUFF_H__
+
+#include "d_event.h"
+
+
+//
+// Globally visible constants.
+//
+#define HU_FONTSTART	'!'	// the first font characters
+#define HU_FONTEND	'_'	// the last font characters
+
+// Calculate # of glyphs in font.
+#define HU_FONTSIZE	(HU_FONTEND - HU_FONTSTART + 1)	
+
+#define HU_BROADCAST	5
+
+#define HU_MSGREFRESH	KEY_ENTER
+#define HU_MSGX		0
+#define HU_MSGY		0
+#define HU_MSGWIDTH	64	// in characters
+#define HU_MSGHEIGHT	1	// in lines
+
+#define HU_MSGTIMEOUT	(4*TICRATE)
+
+//
+// HEADS UP TEXT
+//
+
+void HU_Init(void);
+void HU_Start(void);
+
+boolean HU_Responder(event_t* ev);
+
+void HU_Ticker(void);
+void HU_Drawer(void);
+char HU_dequeueChatChar(void);
+void HU_Erase(void);
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:19:56  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/i_main.c
@@ -1,0 +1,48 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: i_main.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:32  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//	Main program, simply calls D_DoomMain high level loop.
+//
+//-----------------------------------------------------------------------------
+
+static const char
+rcsid[] = "$Id: i_main.c 4 2005-07-23 16:19:41Z fraggle $";
+
+
+
+#include "doomdef.h"
+
+#include "m_argv.h"
+#include "d_main.h"
+
+int
+main
+( int		argc,
+  char**	argv ) 
+{ 
+    myargc = argc; 
+    myargv = argv; 
+ 
+    D_DoomMain (); 
+
+    return 0;
+} 
--- /dev/null
+++ b/src/i_net.c
@@ -1,0 +1,351 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: i_net.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:32  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//
+//-----------------------------------------------------------------------------
+
+static const char
+rcsid[] = "$Id: i_net.c 4 2005-07-23 16:19:41Z fraggle $";
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+
+#include "i_system.h"
+#include "d_event.h"
+#include "d_net.h"
+#include "m_argv.h"
+
+#include "doomstat.h"
+
+#ifdef __GNUG__
+#pragma implementation "i_net.h"
+#endif
+#include "i_net.h"
+
+
+
+
+
+// For some odd reason...
+#define ntohl(x) \
+        ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
+                             (((unsigned long int)(x) & 0x0000ff00U) <<  8) | \
+                             (((unsigned long int)(x) & 0x00ff0000U) >>  8) | \
+                             (((unsigned long int)(x) & 0xff000000U) >> 24)))
+
+#define ntohs(x) \
+        ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
+                              (((unsigned short int)(x) & 0xff00) >> 8))) \
+	  
+#define htonl(x) ntohl(x)
+#define htons(x) ntohs(x)
+
+void	NetSend (void);
+boolean NetListen (void);
+
+
+//
+// NETWORKING
+//
+
+int	DOOMPORT =	(IPPORT_USERRESERVED +0x1d );
+
+int			sendsocket;
+int			insocket;
+
+struct	sockaddr_in	sendaddress[MAXNETNODES];
+
+void	(*netget) (void);
+void	(*netsend) (void);
+
+
+//
+// UDPsocket
+//
+int UDPsocket (void)
+{
+    int	s;
+	
+    // allocate a socket
+    s = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+    if (s<0)
+	I_Error ("can't create socket: %s",strerror(errno));
+		
+    return s;
+}
+
+//
+// BindToLocalPort
+//
+void
+BindToLocalPort
+( int	s,
+  int	port )
+{
+    int			v;
+    struct sockaddr_in	address;
+	
+    memset (&address, 0, sizeof(address));
+    address.sin_family = AF_INET;
+    address.sin_addr.s_addr = INADDR_ANY;
+    address.sin_port = port;
+			
+    v = bind (s, (void *)&address, sizeof(address));
+    if (v == -1)
+	I_Error ("BindToPort: bind: %s", strerror(errno));
+}
+
+
+//
+// PacketSend
+//
+void PacketSend (void)
+{
+    int		c;
+    doomdata_t	sw;
+				
+    // byte swap
+    sw.checksum = htonl(netbuffer->checksum);
+    sw.player = netbuffer->player;
+    sw.retransmitfrom = netbuffer->retransmitfrom;
+    sw.starttic = netbuffer->starttic;
+    sw.numtics = netbuffer->numtics;
+    for (c=0 ; c< netbuffer->numtics ; c++)
+    {
+	sw.cmds[c].forwardmove = netbuffer->cmds[c].forwardmove;
+	sw.cmds[c].sidemove = netbuffer->cmds[c].sidemove;
+	sw.cmds[c].angleturn = htons(netbuffer->cmds[c].angleturn);
+	sw.cmds[c].consistancy = htons(netbuffer->cmds[c].consistancy);
+	sw.cmds[c].chatchar = netbuffer->cmds[c].chatchar;
+	sw.cmds[c].buttons = netbuffer->cmds[c].buttons;
+    }
+		
+    //printf ("sending %i\n",gametic);		
+    c = sendto (sendsocket , &sw, doomcom->datalength
+		,0,(void *)&sendaddress[doomcom->remotenode]
+		,sizeof(sendaddress[doomcom->remotenode]));
+	
+    //	if (c == -1)
+    //		I_Error ("SendPacket error: %s",strerror(errno));
+}
+
+
+//
+// PacketGet
+//
+void PacketGet (void)
+{
+    int			i;
+    int			c;
+    struct sockaddr_in	fromaddress;
+    int			fromlen;
+    doomdata_t		sw;
+				
+    fromlen = sizeof(fromaddress);
+    c = recvfrom (insocket, &sw, sizeof(sw), 0
+		  , (struct sockaddr *)&fromaddress, &fromlen );
+    if (c == -1 )
+    {
+	if (errno != EWOULDBLOCK)
+	    I_Error ("GetPacket: %s",strerror(errno));
+	doomcom->remotenode = -1;		// no packet
+	return;
+    }
+
+    {
+	static int first=1;
+	if (first)
+	    printf("len=%d:p=[0x%x 0x%x] \n", c, *(int*)&sw, *((int*)&sw+1));
+	first = 0;
+    }
+
+    // find remote node number
+    for (i=0 ; i<doomcom->numnodes ; i++)
+	if ( fromaddress.sin_addr.s_addr == sendaddress[i].sin_addr.s_addr )
+	    break;
+
+    if (i == doomcom->numnodes)
+    {
+	// packet is not from one of the players (new game broadcast)
+	doomcom->remotenode = -1;		// no packet
+	return;
+    }
+	
+    doomcom->remotenode = i;			// good packet from a game player
+    doomcom->datalength = c;
+	
+    // byte swap
+    netbuffer->checksum = ntohl(sw.checksum);
+    netbuffer->player = sw.player;
+    netbuffer->retransmitfrom = sw.retransmitfrom;
+    netbuffer->starttic = sw.starttic;
+    netbuffer->numtics = sw.numtics;
+
+    for (c=0 ; c< netbuffer->numtics ; c++)
+    {
+	netbuffer->cmds[c].forwardmove = sw.cmds[c].forwardmove;
+	netbuffer->cmds[c].sidemove = sw.cmds[c].sidemove;
+	netbuffer->cmds[c].angleturn = ntohs(sw.cmds[c].angleturn);
+	netbuffer->cmds[c].consistancy = ntohs(sw.cmds[c].consistancy);
+	netbuffer->cmds[c].chatchar = sw.cmds[c].chatchar;
+	netbuffer->cmds[c].buttons = sw.cmds[c].buttons;
+    }
+}
+
+
+
+int GetLocalAddress (void)
+{
+    char		hostname[1024];
+    struct hostent*	hostentry;	// host information entry
+    int			v;
+
+    // get local address
+    v = gethostname (hostname, sizeof(hostname));
+    if (v == -1)
+	I_Error ("GetLocalAddress : gethostname: errno %d",errno);
+	
+    hostentry = gethostbyname (hostname);
+    if (!hostentry)
+	I_Error ("GetLocalAddress : gethostbyname: couldn't get local host");
+		
+    return *(int *)hostentry->h_addr_list[0];
+}
+
+
+//
+// I_InitNetwork
+//
+void I_InitNetwork (void)
+{
+    boolean		trueval = true;
+    int			i;
+    int			p;
+    struct hostent*	hostentry;	// host information entry
+	
+    doomcom = malloc (sizeof (*doomcom) );
+    memset (doomcom, 0, sizeof(*doomcom) );
+    
+    // set up for network
+    i = M_CheckParm ("-dup");
+    if (i && i< myargc-1)
+    {
+	doomcom->ticdup = myargv[i+1][0]-'0';
+	if (doomcom->ticdup < 1)
+	    doomcom->ticdup = 1;
+	if (doomcom->ticdup > 9)
+	    doomcom->ticdup = 9;
+    }
+    else
+	doomcom-> ticdup = 1;
+	
+    if (M_CheckParm ("-extratic"))
+	doomcom-> extratics = 1;
+    else
+	doomcom-> extratics = 0;
+		
+    p = M_CheckParm ("-port");
+    if (p && p<myargc-1)
+    {
+	DOOMPORT = atoi (myargv[p+1]);
+	printf ("using alternate port %i\n",DOOMPORT);
+    }
+    
+    // parse network game options,
+    //  -net <consoleplayer> <host> <host> ...
+    i = M_CheckParm ("-net");
+    if (!i)
+    {
+	// single player game
+	netgame = false;
+	doomcom->id = DOOMCOM_ID;
+	doomcom->numplayers = doomcom->numnodes = 1;
+	doomcom->deathmatch = false;
+	doomcom->consoleplayer = 0;
+	return;
+    }
+
+    netsend = PacketSend;
+    netget = PacketGet;
+    netgame = true;
+
+    // parse player number and host list
+    doomcom->consoleplayer = myargv[i+1][0]-'1';
+
+    doomcom->numnodes = 1;	// this node for sure
+	
+    i++;
+    while (++i < myargc && myargv[i][0] != '-')
+    {
+	sendaddress[doomcom->numnodes].sin_family = AF_INET;
+	sendaddress[doomcom->numnodes].sin_port = htons(DOOMPORT);
+	if (myargv[i][0] == '.')
+	{
+	    sendaddress[doomcom->numnodes].sin_addr.s_addr 
+		= inet_addr (myargv[i]+1);
+	}
+	else
+	{
+	    hostentry = gethostbyname (myargv[i]);
+	    if (!hostentry)
+		I_Error ("gethostbyname: couldn't find %s", myargv[i]);
+	    sendaddress[doomcom->numnodes].sin_addr.s_addr 
+		= *(int *)hostentry->h_addr_list[0];
+	}
+	doomcom->numnodes++;
+    }
+	
+    doomcom->id = DOOMCOM_ID;
+    doomcom->numplayers = doomcom->numnodes;
+    
+    // build message to receive
+    insocket = UDPsocket ();
+    BindToLocalPort (insocket,htons(DOOMPORT));
+    ioctl (insocket, FIONBIO, &trueval);
+
+    sendsocket = UDPsocket ();
+}
+
+
+void I_NetCmd (void)
+{
+    if (doomcom->command == CMD_SEND)
+    {
+	netsend ();
+    }
+    else if (doomcom->command == CMD_GET)
+    {
+	netget ();
+    }
+    else
+	I_Error ("Bad net cmd: %i\n",doomcom->command);
+}
+
--- /dev/null
+++ b/src/i_net.h
@@ -1,0 +1,48 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: i_net.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//	System specific network interface stuff.
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __I_NET__
+#define __I_NET__
+
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+
+
+// Called by D_DoomMain.
+
+
+void I_InitNetwork (void);
+void I_NetCmd (void);
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:32  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/i_sound.c
@@ -1,0 +1,988 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: i_sound.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:46  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//	System interface for sound.
+//
+//-----------------------------------------------------------------------------
+
+static const char
+rcsid[] = "$Id: i_sound.c 4 2005-07-23 16:19:41Z fraggle $";
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include <math.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+
+#ifndef LINUX
+#include <sys/filio.h>
+#endif
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+// Linux voxware output.
+#include <linux/soundcard.h>
+
+// Timer stuff. Experimental.
+#include <time.h>
+#include <signal.h>
+
+#include "z_zone.h"
+
+#include "i_system.h"
+#include "i_sound.h"
+#include "m_argv.h"
+#include "m_misc.h"
+#include "w_wad.h"
+
+#include "doomdef.h"
+
+// UNIX hack, to be removed.
+#ifdef SNDSERV
+// Separate sound server process.
+FILE*	sndserver=0;
+char*	sndserver_filename = "./sndserver ";
+#elif SNDINTR
+
+// Update all 30 millisecs, approx. 30fps synchronized.
+// Linux resolution is allegedly 10 millisecs,
+//  scale is microseconds.
+#define SOUND_INTERVAL     500
+
+// Get the interrupt. Set duration in millisecs.
+int I_SoundSetTimer( int duration_of_tick );
+void I_SoundDelTimer( void );
+#else
+// None?
+#endif
+
+
+// A quick hack to establish a protocol between
+// synchronous mix buffer updates and asynchronous
+// audio writes. Probably redundant with gametic.
+static int flag = 0;
+
+// The number of internal mixing channels,
+//  the samples calculated for each mixing step,
+//  the size of the 16bit, 2 hardware channel (stereo)
+//  mixing buffer, and the samplerate of the raw data.
+
+
+// Needed for calling the actual sound output.
+#define SAMPLECOUNT		512
+#define NUM_CHANNELS		8
+// It is 2 for 16bit, and 2 for two channels.
+#define BUFMUL                  4
+#define MIXBUFFERSIZE		(SAMPLECOUNT*BUFMUL)
+
+#define SAMPLERATE		11025	// Hz
+#define SAMPLESIZE		2   	// 16bit
+
+// The actual lengths of all sound effects.
+int 		lengths[NUMSFX];
+
+// The actual output device.
+int	audio_fd;
+
+// The global mixing buffer.
+// Basically, samples from all active internal channels
+//  are modifed and added, and stored in the buffer
+//  that is submitted to the audio device.
+signed short	mixbuffer[MIXBUFFERSIZE];
+
+
+// The channel step amount...
+unsigned int	channelstep[NUM_CHANNELS];
+// ... and a 0.16 bit remainder of last step.
+unsigned int	channelstepremainder[NUM_CHANNELS];
+
+
+// The channel data pointers, start and end.
+unsigned char*	channels[NUM_CHANNELS];
+unsigned char*	channelsend[NUM_CHANNELS];
+
+
+// Time/gametic that the channel started playing,
+//  used to determine oldest, which automatically
+//  has lowest priority.
+// In case number of active sounds exceeds
+//  available channels.
+int		channelstart[NUM_CHANNELS];
+
+// The sound in channel handles,
+//  determined on registration,
+//  might be used to unregister/stop/modify,
+//  currently unused.
+int 		channelhandles[NUM_CHANNELS];
+
+// SFX id of the playing sound effect.
+// Used to catch duplicates (like chainsaw).
+int		channelids[NUM_CHANNELS];			
+
+// Pitch to stepping lookup, unused.
+int		steptable[256];
+
+// Volume lookups.
+int		vol_lookup[128*256];
+
+// Hardware left and right channel volume lookup.
+int*		channelleftvol_lookup[NUM_CHANNELS];
+int*		channelrightvol_lookup[NUM_CHANNELS];
+
+
+
+
+//
+// Safe ioctl, convenience.
+//
+void
+myioctl
+( int	fd,
+  int	command,
+  int*	arg )
+{   
+    int		rc;
+    extern int	errno;
+    
+    rc = ioctl(fd, command, arg);  
+    if (rc < 0)
+    {
+	fprintf(stderr, "ioctl(dsp,%d,arg) failed\n", command);
+	fprintf(stderr, "errno=%d\n", errno);
+	exit(-1);
+    }
+}
+
+
+
+
+
+//
+// This function loads the sound data from the WAD lump,
+//  for single sound.
+//
+void*
+getsfx
+( char*         sfxname,
+  int*          len )
+{
+    unsigned char*      sfx;
+    unsigned char*      paddedsfx;
+    int                 i;
+    int                 size;
+    int                 paddedsize;
+    char                name[20];
+    int                 sfxlump;
+
+    
+    // Get the sound data from the WAD, allocate lump
+    //  in zone memory.
+    sprintf(name, "ds%s", sfxname);
+
+    // Now, there is a severe problem with the
+    //  sound handling, in it is not (yet/anymore)
+    //  gamemode aware. That means, sounds from
+    //  DOOM II will be requested even with DOOM
+    //  shareware.
+    // The sound list is wired into sounds.c,
+    //  which sets the external variable.
+    // I do not do runtime patches to that
+    //  variable. Instead, we will use a
+    //  default sound for replacement.
+    if ( W_CheckNumForName(name) == -1 )
+      sfxlump = W_GetNumForName("dspistol");
+    else
+      sfxlump = W_GetNumForName(name);
+    
+    size = W_LumpLength( sfxlump );
+
+    // Debug.
+    // fprintf( stderr, "." );
+    //fprintf( stderr, " -loading  %s (lump %d, %d bytes)\n",
+    //	     sfxname, sfxlump, size );
+    //fflush( stderr );
+    
+    sfx = (unsigned char*)W_CacheLumpNum( sfxlump, PU_STATIC );
+
+    // Pads the sound effect out to the mixing buffer size.
+    // The original realloc would interfere with zone memory.
+    paddedsize = ((size-8 + (SAMPLECOUNT-1)) / SAMPLECOUNT) * SAMPLECOUNT;
+
+    // Allocate from zone memory.
+    paddedsfx = (unsigned char*)Z_Malloc( paddedsize+8, PU_STATIC, 0 );
+    // ddt: (unsigned char *) realloc(sfx, paddedsize+8);
+    // This should interfere with zone memory handling,
+    //  which does not kick in in the soundserver.
+
+    // Now copy and pad.
+    memcpy(  paddedsfx, sfx, size );
+    for (i=size ; i<paddedsize+8 ; i++)
+        paddedsfx[i] = 128;
+
+    // Remove the cached lump.
+    Z_Free( sfx );
+    
+    // Preserve padded length.
+    *len = paddedsize;
+
+    // Return allocated padded data.
+    return (void *) (paddedsfx + 8);
+}
+
+
+
+
+
+//
+// This function adds a sound to the
+//  list of currently active sounds,
+//  which is maintained as a given number
+//  (eight, usually) of internal channels.
+// Returns a handle.
+//
+int
+addsfx
+( int		sfxid,
+  int		volume,
+  int		step,
+  int		seperation )
+{
+    static unsigned short	handlenums = 0;
+ 
+    int		i;
+    int		rc = -1;
+    
+    int		oldest = gametic;
+    int		oldestnum = 0;
+    int		slot;
+
+    int		rightvol;
+    int		leftvol;
+
+    // Chainsaw troubles.
+    // Play these sound effects only one at a time.
+    if ( sfxid == sfx_sawup
+	 || sfxid == sfx_sawidl
+	 || sfxid == sfx_sawful
+	 || sfxid == sfx_sawhit
+	 || sfxid == sfx_stnmov
+	 || sfxid == sfx_pistol	 )
+    {
+	// Loop all channels, check.
+	for (i=0 ; i<NUM_CHANNELS ; i++)
+	{
+	    // Active, and using the same SFX?
+	    if ( (channels[i])
+		 && (channelids[i] == sfxid) )
+	    {
+		// Reset.
+		channels[i] = 0;
+		// We are sure that iff,
+		//  there will only be one.
+		break;
+	    }
+	}
+    }
+
+    // Loop all channels to find oldest SFX.
+    for (i=0; (i<NUM_CHANNELS) && (channels[i]); i++)
+    {
+	if (channelstart[i] < oldest)
+	{
+	    oldestnum = i;
+	    oldest = channelstart[i];
+	}
+    }
+
+    // Tales from the cryptic.
+    // If we found a channel, fine.
+    // If not, we simply overwrite the first one, 0.
+    // Probably only happens at startup.
+    if (i == NUM_CHANNELS)
+	slot = oldestnum;
+    else
+	slot = i;
+
+    // Okay, in the less recent channel,
+    //  we will handle the new SFX.
+    // Set pointer to raw data.
+    channels[slot] = (unsigned char *) S_sfx[sfxid].data;
+    // Set pointer to end of raw data.
+    channelsend[slot] = channels[slot] + lengths[sfxid];
+
+    // Reset current handle number, limited to 0..100.
+    if (!handlenums)
+	handlenums = 100;
+
+    // Assign current handle number.
+    // Preserved so sounds could be stopped (unused).
+    channelhandles[slot] = rc = handlenums++;
+
+    // Set stepping???
+    // Kinda getting the impression this is never used.
+    channelstep[slot] = step;
+    // ???
+    channelstepremainder[slot] = 0;
+    // Should be gametic, I presume.
+    channelstart[slot] = gametic;
+
+    // Separation, that is, orientation/stereo.
+    //  range is: 1 - 256
+    seperation += 1;
+
+    // Per left/right channel.
+    //  x^2 seperation,
+    //  adjust volume properly.
+    leftvol =
+	volume - ((volume*seperation*seperation) >> 16); ///(256*256);
+    seperation = seperation - 257;
+    rightvol =
+	volume - ((volume*seperation*seperation) >> 16);	
+
+    // Sanity check, clamp volume.
+    if (rightvol < 0 || rightvol > 127)
+	I_Error("rightvol out of bounds");
+    
+    if (leftvol < 0 || leftvol > 127)
+	I_Error("leftvol out of bounds");
+    
+    // Get the proper lookup table piece
+    //  for this volume level???
+    channelleftvol_lookup[slot] = &vol_lookup[leftvol*256];
+    channelrightvol_lookup[slot] = &vol_lookup[rightvol*256];
+
+    // Preserve sound SFX id,
+    //  e.g. for avoiding duplicates of chainsaw.
+    channelids[slot] = sfxid;
+
+    // You tell me.
+    return rc;
+}
+
+
+
+
+
+//
+// SFX API
+// Note: this was called by S_Init.
+// However, whatever they did in the
+// old DPMS based DOS version, this
+// were simply dummies in the Linux
+// version.
+// See soundserver initdata().
+//
+void I_SetChannels()
+{
+  // Init internal lookups (raw data, mixing buffer, channels).
+  // This function sets up internal lookups used during
+  //  the mixing process. 
+  int		i;
+  int		j;
+    
+  int*	steptablemid = steptable + 128;
+  
+  // Okay, reset internal mixing channels to zero.
+  /*for (i=0; i<NUM_CHANNELS; i++)
+  {
+    channels[i] = 0;
+  }*/
+
+  // This table provides step widths for pitch parameters.
+  // I fail to see that this is currently used.
+  for (i=-128 ; i<128 ; i++)
+    steptablemid[i] = (int)(pow(2.0, (i/64.0))*65536.0);
+  
+  
+  // Generates volume lookup tables
+  //  which also turn the unsigned samples
+  //  into signed samples.
+  for (i=0 ; i<128 ; i++)
+    for (j=0 ; j<256 ; j++)
+      vol_lookup[i*256+j] = (i*(j-128)*256)/127;
+}	
+
+ 
+void I_SetSfxVolume(int volume)
+{
+  // Identical to DOS.
+  // Basically, this should propagate
+  //  the menu/config file setting
+  //  to the state variable used in
+  //  the mixing.
+  snd_SfxVolume = volume;
+}
+
+// MUSIC API - dummy. Some code from DOS version.
+void I_SetMusicVolume(int volume)
+{
+  // Internal state variable.
+  snd_MusicVolume = volume;
+  // Now set volume on output device.
+  // Whatever( snd_MusciVolume );
+}
+
+
+//
+// Retrieve the raw data lump index
+//  for a given SFX name.
+//
+int I_GetSfxLumpNum(sfxinfo_t* sfx)
+{
+    char namebuf[9];
+    sprintf(namebuf, "ds%s", sfx->name);
+    return W_GetNumForName(namebuf);
+}
+
+//
+// Starting a sound means adding it
+//  to the current list of active sounds
+//  in the internal channels.
+// As the SFX info struct contains
+//  e.g. a pointer to the raw data,
+//  it is ignored.
+// As our sound handling does not handle
+//  priority, it is ignored.
+// Pitching (that is, increased speed of playback)
+//  is set, but currently not used by mixing.
+//
+int
+I_StartSound
+( int		id,
+  int		vol,
+  int		sep,
+  int		pitch,
+  int		priority )
+{
+
+  // UNUSED
+  priority = 0;
+  
+#ifdef SNDSERV 
+    if (sndserver)
+    {
+	fprintf(sndserver, "p%2.2x%2.2x%2.2x%2.2x\n", id, pitch, vol, sep);
+	fflush(sndserver);
+    }
+    // warning: control reaches end of non-void function.
+    return id;
+#else
+    // Debug.
+    //fprintf( stderr, "starting sound %d", id );
+    
+    // Returns a handle (not used).
+    id = addsfx( id, vol, steptable[pitch], sep );
+
+    // fprintf( stderr, "/handle is %d\n", id );
+    
+    return id;
+#endif
+}
+
+
+
+void I_StopSound (int handle)
+{
+  // You need the handle returned by StartSound.
+  // Would be looping all channels,
+  //  tracking down the handle,
+  //  an setting the channel to zero.
+  
+  // UNUSED.
+  handle = 0;
+}
+
+
+int I_SoundIsPlaying(int handle)
+{
+    // Ouch.
+    return gametic < handle;
+}
+
+
+
+
+//
+// This function loops all active (internal) sound
+//  channels, retrieves a given number of samples
+//  from the raw sound data, modifies it according
+//  to the current (internal) channel parameters,
+//  mixes the per channel samples into the global
+//  mixbuffer, clamping it to the allowed range,
+//  and sets up everything for transferring the
+//  contents of the mixbuffer to the (two)
+//  hardware channels (left and right, that is).
+//
+// This function currently supports only 16bit.
+//
+void I_UpdateSound( void )
+{
+#ifdef SNDINTR
+  // Debug. Count buffer misses with interrupt.
+  static int misses = 0;
+#endif
+
+  
+  // Mix current sound data.
+  // Data, from raw sound, for right and left.
+  register unsigned int	sample;
+  register int		dl;
+  register int		dr;
+  
+  // Pointers in global mixbuffer, left, right, end.
+  signed short*		leftout;
+  signed short*		rightout;
+  signed short*		leftend;
+  // Step in mixbuffer, left and right, thus two.
+  int				step;
+
+  // Mixing channel index.
+  int				chan;
+    
+    // Left and right channel
+    //  are in global mixbuffer, alternating.
+    leftout = mixbuffer;
+    rightout = mixbuffer+1;
+    step = 2;
+
+    // Determine end, for left channel only
+    //  (right channel is implicit).
+    leftend = mixbuffer + SAMPLECOUNT*step;
+
+    // Mix sounds into the mixing buffer.
+    // Loop over step*SAMPLECOUNT,
+    //  that is 512 values for two channels.
+    while (leftout != leftend)
+    {
+	// Reset left/right value. 
+	dl = 0;
+	dr = 0;
+
+	// Love thy L2 chache - made this a loop.
+	// Now more channels could be set at compile time
+	//  as well. Thus loop those  channels.
+	for ( chan = 0; chan < NUM_CHANNELS; chan++ )
+	{
+	    // Check channel, if active.
+	    if (channels[ chan ])
+	    {
+		// Get the raw data from the channel. 
+		sample = *channels[ chan ];
+		// Add left and right part
+		//  for this channel (sound)
+		//  to the current data.
+		// Adjust volume accordingly.
+		dl += channelleftvol_lookup[ chan ][sample];
+		dr += channelrightvol_lookup[ chan ][sample];
+		// Increment index ???
+		channelstepremainder[ chan ] += channelstep[ chan ];
+		// MSB is next sample???
+		channels[ chan ] += channelstepremainder[ chan ] >> 16;
+		// Limit to LSB???
+		channelstepremainder[ chan ] &= 65536-1;
+
+		// Check whether we are done.
+		if (channels[ chan ] >= channelsend[ chan ])
+		    channels[ chan ] = 0;
+	    }
+	}
+	
+	// Clamp to range. Left hardware channel.
+	// Has been char instead of short.
+	// if (dl > 127) *leftout = 127;
+	// else if (dl < -128) *leftout = -128;
+	// else *leftout = dl;
+
+	if (dl > 0x7fff)
+	    *leftout = 0x7fff;
+	else if (dl < -0x8000)
+	    *leftout = -0x8000;
+	else
+	    *leftout = dl;
+
+	// Same for right hardware channel.
+	if (dr > 0x7fff)
+	    *rightout = 0x7fff;
+	else if (dr < -0x8000)
+	    *rightout = -0x8000;
+	else
+	    *rightout = dr;
+
+	// Increment current pointers in mixbuffer.
+	leftout += step;
+	rightout += step;
+    }
+
+#ifdef SNDINTR
+    // Debug check.
+    if ( flag )
+    {
+      misses += flag;
+      flag = 0;
+    }
+    
+    if ( misses > 10 )
+    {
+      fprintf( stderr, "I_SoundUpdate: missed 10 buffer writes\n");
+      misses = 0;
+    }
+    
+    // Increment flag for update.
+    flag++;
+#endif
+}
+
+
+// 
+// This would be used to write out the mixbuffer
+//  during each game loop update.
+// Updates sound buffer and audio device at runtime. 
+// It is called during Timer interrupt with SNDINTR.
+// Mixing now done synchronous, and
+//  only output be done asynchronous?
+//
+void
+I_SubmitSound(void)
+{
+  // Write it to DSP device.
+  write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL);
+}
+
+
+
+void
+I_UpdateSoundParams
+( int	handle,
+  int	vol,
+  int	sep,
+  int	pitch)
+{
+  // I fail too see that this is used.
+  // Would be using the handle to identify
+  //  on which channel the sound might be active,
+  //  and resetting the channel parameters.
+
+  // UNUSED.
+  handle = vol = sep = pitch = 0;
+}
+
+
+
+
+void I_ShutdownSound(void)
+{    
+#ifdef SNDSERV
+  if (sndserver)
+  {
+    // Send a "quit" command.
+    fprintf(sndserver, "q\n");
+    fflush(sndserver);
+  }
+#else
+  // Wait till all pending sounds are finished.
+  int done = 0;
+  int i;
+  
+
+  // FIXME (below).
+  fprintf( stderr, "I_ShutdownSound: NOT finishing pending sounds\n");
+  fflush( stderr );
+  
+  while ( !done )
+  {
+    for( i=0 ; i<8 && !channels[i] ; i++);
+    
+    // FIXME. No proper channel output.
+    //if (i==8)
+    done=1;
+  }
+#ifdef SNDINTR
+  I_SoundDelTimer();
+#endif
+  
+  // Cleaning up -releasing the DSP device.
+  close ( audio_fd );
+#endif
+
+  // Done.
+  return;
+}
+
+
+
+
+
+
+void
+I_InitSound()
+{ 
+#ifdef SNDSERV
+  char buffer[256];
+  
+  if (getenv("DOOMWADDIR"))
+    sprintf(buffer, "%s/%s",
+	    getenv("DOOMWADDIR"),
+	    sndserver_filename);
+  else
+    sprintf(buffer, "%s", sndserver_filename);
+  
+  // start sound process
+  if ( !access(buffer, X_OK) )
+  {
+    strcat(buffer, " -quiet");
+    sndserver = popen(buffer, "w");
+  }
+  else
+    fprintf(stderr, "Could not start sound server [%s]\n", buffer);
+#else
+    
+  int i;
+  
+#ifdef SNDINTR
+  fprintf( stderr, "I_SoundSetTimer: %d microsecs\n", SOUND_INTERVAL );
+  I_SoundSetTimer( SOUND_INTERVAL );
+#endif
+    
+  // Secure and configure sound device first.
+  fprintf( stderr, "I_InitSound: ");
+  
+  audio_fd = open("/dev/dsp", O_WRONLY);
+  if (audio_fd<0)
+    fprintf(stderr, "Could not open /dev/dsp\n");
+  
+                     
+  i = 11 | (2<<16);                                           
+  myioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &i);
+  myioctl(audio_fd, SNDCTL_DSP_RESET, 0);
+  
+  i=SAMPLERATE;
+  
+  myioctl(audio_fd, SNDCTL_DSP_SPEED, &i);
+  
+  i=1;
+  myioctl(audio_fd, SNDCTL_DSP_STEREO, &i);
+  
+  myioctl(audio_fd, SNDCTL_DSP_GETFMTS, &i);
+  
+  if (i&=AFMT_S16_LE)    
+    myioctl(audio_fd, SNDCTL_DSP_SETFMT, &i);
+  else
+    fprintf(stderr, "Could not play signed 16 data\n");
+
+  fprintf(stderr, " configured audio device\n" );
+
+    
+  // Initialize external data (all sounds) at start, keep static.
+  fprintf( stderr, "I_InitSound: ");
+  
+  for (i=1 ; i<NUMSFX ; i++)
+  { 
+    // Alias? Example is the chaingun sound linked to pistol.
+    if (!S_sfx[i].link)
+    {
+      // Load data from WAD file.
+      S_sfx[i].data = getsfx( S_sfx[i].name, &lengths[i] );
+    }	
+    else
+    {
+      // Previously loaded already?
+      S_sfx[i].data = S_sfx[i].link->data;
+      lengths[i] = lengths[(S_sfx[i].link - S_sfx)/sizeof(sfxinfo_t)];
+    }
+  }
+
+  fprintf( stderr, " pre-cached all sound data\n");
+  
+  // Now initialize mixbuffer with zero.
+  for ( i = 0; i< MIXBUFFERSIZE; i++ )
+    mixbuffer[i] = 0;
+  
+  // Finished initialization.
+  fprintf(stderr, "I_InitSound: sound module ready\n");
+    
+#endif
+}
+
+
+
+
+//
+// MUSIC API.
+// Still no music done.
+// Remains. Dummies.
+//
+void I_InitMusic(void)		{ }
+void I_ShutdownMusic(void)	{ }
+
+static int	looping=0;
+static int	musicdies=-1;
+
+void I_PlaySong(int handle, int looping)
+{
+  // UNUSED.
+  handle = looping = 0;
+  musicdies = gametic + TICRATE*30;
+}
+
+void I_PauseSong (int handle)
+{
+  // UNUSED.
+  handle = 0;
+}
+
+void I_ResumeSong (int handle)
+{
+  // UNUSED.
+  handle = 0;
+}
+
+void I_StopSong(int handle)
+{
+  // UNUSED.
+  handle = 0;
+  
+  looping = 0;
+  musicdies = 0;
+}
+
+void I_UnRegisterSong(int handle)
+{
+  // UNUSED.
+  handle = 0;
+}
+
+int I_RegisterSong(void* data)
+{
+  // UNUSED.
+  data = NULL;
+  
+  return 1;
+}
+
+// Is the song playing?
+int I_QrySongPlaying(int handle)
+{
+  // UNUSED.
+  handle = 0;
+  return looping || musicdies > gametic;
+}
+
+
+
+//
+// Experimental stuff.
+// A Linux timer interrupt, for asynchronous
+//  sound output.
+// I ripped this out of the Timer class in
+//  our Difference Engine, including a few
+//  SUN remains...
+//  
+#ifdef sun
+    typedef     sigset_t        tSigSet;
+#else    
+    typedef     int             tSigSet;
+#endif
+
+
+// We might use SIGVTALRM and ITIMER_VIRTUAL, if the process
+//  time independend timer happens to get lost due to heavy load.
+// SIGALRM and ITIMER_REAL doesn't really work well.
+// There are issues with profiling as well.
+static int /*__itimer_which*/  itimer = ITIMER_REAL;
+
+static int sig = SIGALRM;
+
+// Interrupt handler.
+void I_HandleSoundTimer( int ignore )
+{
+  // Debug.
+  //fprintf( stderr, "%c", '+' ); fflush( stderr );
+  
+  // Feed sound device if necesary.
+  if ( flag )
+  {
+    // See I_SubmitSound().
+    // Write it to DSP device.
+    write(audio_fd, mixbuffer, SAMPLECOUNT*BUFMUL);
+
+    // Reset flag counter.
+    flag = 0;
+  }
+  else
+    return;
+  
+  // UNUSED, but required.
+  ignore = 0;
+  return;
+}
+
+// Get the interrupt. Set duration in millisecs.
+int I_SoundSetTimer( int duration_of_tick )
+{
+  // Needed for gametick clockwork.
+  struct itimerval    value;
+  struct itimerval    ovalue;
+  struct sigaction    act;
+  struct sigaction    oact;
+
+  int res;
+  
+  // This sets to SA_ONESHOT and SA_NOMASK, thus we can not use it.
+  //     signal( _sig, handle_SIG_TICK );
+  
+  // Now we have to change this attribute for repeated calls.
+  act.sa_handler = I_HandleSoundTimer;
+#ifndef sun    
+  //ac	t.sa_mask = _sig;
+#endif
+  act.sa_flags = SA_RESTART;
+  
+  sigaction( sig, &act, &oact );
+
+  value.it_interval.tv_sec    = 0;
+  value.it_interval.tv_usec   = duration_of_tick;
+  value.it_value.tv_sec       = 0;
+  value.it_value.tv_usec      = duration_of_tick;
+
+  // Error is -1.
+  res = setitimer( itimer, &value, &ovalue );
+
+  // Debug.
+  if ( res == -1 )
+    fprintf( stderr, "I_SoundSetTimer: interrupt n.a.\n");
+  
+  return res;
+}
+
+
+// Remove the interrupt. Set duration to zero.
+void I_SoundDelTimer()
+{
+  // Debug.
+  if ( I_SoundSetTimer( 0 ) == -1)
+    fprintf( stderr, "I_SoundDelTimer: failed to remove interrupt. Doh!\n");
+}
--- /dev/null
+++ b/src/i_sound.h
@@ -1,0 +1,125 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: i_sound.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+//
+// DESCRIPTION:
+//	System interface, sound.
+//
+//-----------------------------------------------------------------------------
+
+#ifndef __I_SOUND__
+#define __I_SOUND__
+
+#include "doomdef.h"
+
+// UNIX hack, to be removed.
+#ifdef SNDSERV
+#include <stdio.h>
+extern FILE* sndserver;
+extern char* sndserver_filename;
+#endif
+
+#include "doomstat.h"
+#include "sounds.h"
+
+
+
+// Init at program start...
+void I_InitSound();
+
+// ... update sound buffer and audio device at runtime...
+void I_UpdateSound(void);
+void I_SubmitSound(void);
+
+// ... shut down and relase at program termination.
+void I_ShutdownSound(void);
+
+
+//
+//  SFX I/O
+//
+
+// Initialize channels?
+void I_SetChannels();
+
+// Get raw data lump index for sound descriptor.
+int I_GetSfxLumpNum (sfxinfo_t* sfxinfo );
+
+
+// Starts a sound in a particular sound channel.
+int
+I_StartSound
+( int		id,
+  int		vol,
+  int		sep,
+  int		pitch,
+  int		priority );
+
+
+// Stops a sound channel.
+void I_StopSound(int handle);
+
+// Called by S_*() functions
+//  to see if a channel is still playing.
+// Returns 0 if no longer playing, 1 if playing.
+int I_SoundIsPlaying(int handle);
+
+// Updates the volume, separation,
+//  and pitch of a sound channel.
+void
+I_UpdateSoundParams
+( int		handle,
+  int		vol,
+  int		sep,
+  int		pitch );
+
+
+//
+//  MUSIC I/O
+//
+void I_InitMusic(void);
+void I_ShutdownMusic(void);
+// Volume.
+void I_SetMusicVolume(int volume);
+// PAUSE game handling.
+void I_PauseSong(int handle);
+void I_ResumeSong(int handle);
+// Registers a song handle to song data.
+int I_RegisterSong(void *data);
+// Called by anything that wishes to start music.
+//  plays a song, and when the song is done,
+//  starts playing it again in an endless loop.
+// Horrible thing to do, considering.
+void
+I_PlaySong
+( int		handle,
+  int		looping );
+// Stops a song over 3 seconds.
+void I_StopSong(int handle);
+// See above (register), then think backwards
+void I_UnRegisterSong(int handle);
+
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:46  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/i_system.c
@@ -1,0 +1,186 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: i_system.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:39  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//
+//-----------------------------------------------------------------------------
+
+static const char
+rcsid[] = "$Id: i_system.c 4 2005-07-23 16:19:41Z fraggle $";
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <stdarg.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "doomdef.h"
+#include "m_misc.h"
+#include "i_video.h"
+#include "i_sound.h"
+
+#include "d_net.h"
+#include "g_game.h"
+
+#ifdef __GNUG__
+#pragma implementation "i_system.h"
+#endif
+#include "i_system.h"
+
+
+
+
+int	mb_used = 6;
+
+
+void
+I_Tactile
+( int	on,
+  int	off,
+  int	total )
+{
+  // UNUSED.
+  on = off = total = 0;
+}
+
+ticcmd_t	emptycmd;
+ticcmd_t*	I_BaseTiccmd(void)
+{
+    return &emptycmd;
+}
+
+
+int  I_GetHeapSize (void)
+{
+    return mb_used*1024*1024;
+}
+
+byte* I_ZoneBase (int*	size)
+{
+    *size = mb_used*1024*1024;
+    return (byte *) malloc (*size);
+}
+
+
+
+//
+// I_GetTime
+// returns time in 1/70th second tics
+//
+int  I_GetTime (void)
+{
+    struct timeval	tp;
+    struct timezone	tzp;
+    int			newtics;
+    static int		basetime=0;
+  
+    gettimeofday(&tp, &tzp);
+    if (!basetime)
+	basetime = tp.tv_sec;
+    newtics = (tp.tv_sec-basetime)*TICRATE + tp.tv_usec*TICRATE/1000000;
+    return newtics;
+}
+
+
+
+//
+// I_Init
+//
+void I_Init (void)
+{
+    I_InitSound();
+    //  I_InitGraphics();
+}
+
+//
+// I_Quit
+//
+void I_Quit (void)
+{
+    D_QuitNetGame ();
+    I_ShutdownSound();
+    I_ShutdownMusic();
+    M_SaveDefaults ();
+    I_ShutdownGraphics();
+    exit(0);
+}
+
+void I_WaitVBL(int count)
+{
+#ifdef SGI
+    sginap(1);                                           
+#else
+#ifdef SUN
+    sleep(0);
+#else
+    usleep (count * (1000000/70) );                                
+#endif
+#endif
+}
+
+void I_BeginRead(void)
+{
+}
+
+void I_EndRead(void)
+{
+}
+
+byte*	I_AllocLow(int length)
+{
+    byte*	mem;
+        
+    mem = (byte *)malloc (length);
+    memset (mem,0,length);
+    return mem;
+}
+
+
+//
+// I_Error
+//
+extern boolean demorecording;
+
+void I_Error (char *error, ...)
+{
+    va_list	argptr;
+
+    // Message first.
+    va_start (argptr,error);
+    fprintf (stderr, "Error: ");
+    vfprintf (stderr,error,argptr);
+    fprintf (stderr, "\n");
+    va_end (argptr);
+
+    fflush( stderr );
+
+    // Shutdown. Here might be other errors.
+    if (demorecording)
+	G_CheckDemoStatus();
+
+    D_QuitNetGame ();
+    I_ShutdownGraphics();
+    
+    exit(-1);
+}
--- /dev/null
+++ b/src/i_system.h
@@ -1,0 +1,100 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: i_system.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//	System specific interface stuff.
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __I_SYSTEM__
+#define __I_SYSTEM__
+
+#include "d_ticcmd.h"
+#include "d_event.h"
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+
+// Called by DoomMain.
+void I_Init (void);
+
+// Called by startup code
+// to get the ammount of memory to malloc
+// for the zone management.
+byte*	I_ZoneBase (int *size);
+
+
+// Called by D_DoomLoop,
+// returns current time in tics.
+int I_GetTime (void);
+
+
+//
+// Called by D_DoomLoop,
+// called before processing any tics in a frame
+// (just after displaying a frame).
+// Time consuming syncronous operations
+// are performed here (joystick reading).
+// Can call D_PostEvent.
+//
+void I_StartFrame (void);
+
+
+//
+// Called by D_DoomLoop,
+// called before processing each tic in a frame.
+// Quick syncronous operations are performed here.
+// Can call D_PostEvent.
+void I_StartTic (void);
+
+// Asynchronous interrupt functions should maintain private queues
+// that are read by the synchronous functions
+// to be converted into events.
+
+// Either returns a null ticcmd,
+// or calls a loadable driver to build it.
+// This ticcmd will then be modified by the gameloop
+// for normal input.
+ticcmd_t* I_BaseTiccmd (void);
+
+
+// Called by M_Responder when quit is selected.
+// Clean exit, displays sell blurb.
+void I_Quit (void);
+
+
+// Allocates from low memory under dos,
+// just mallocs under unix
+byte* I_AllocLow (int length);
+
+void I_Tactile (int on, int off, int total);
+
+
+void I_Error (char *error, ...);
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:39  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/i_video.c
@@ -1,0 +1,1053 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: i_video.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:19:58  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//	DOOM graphics stuff for X11, UNIX.
+//
+//-----------------------------------------------------------------------------
+
+static const char
+rcsid[] = "$Id: i_video.c 4 2005-07-23 16:19:41Z fraggle $";
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+
+#include <X11/extensions/XShm.h>
+// Had to dig up XShm.c for this one.
+// It is in the libXext, but not in the XFree86 headers.
+#ifdef LINUX
+int XShmGetEventBase( Display* dpy ); // problems with g++?
+#endif
+
+#include <stdarg.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <errnos.h>
+#include <signal.h>
+
+#include "doomstat.h"
+#include "i_system.h"
+#include "v_video.h"
+#include "m_argv.h"
+#include "d_main.h"
+
+#include "doomdef.h"
+
+#define POINTER_WARP_COUNTDOWN	1
+
+Display*	X_display=0;
+Window		X_mainWindow;
+Colormap	X_cmap;
+Visual*		X_visual;
+GC		X_gc;
+XEvent		X_event;
+int		X_screen;
+XVisualInfo	X_visualinfo;
+XImage*		image;
+int		X_width;
+int		X_height;
+
+// MIT SHared Memory extension.
+boolean		doShm;
+
+XShmSegmentInfo	X_shminfo;
+int		X_shmeventtype;
+
+// Fake mouse handling.
+// This cannot work properly w/o DGA.
+// Needs an invisible mouse cursor at least.
+boolean		grabMouse;
+int		doPointerWarp = POINTER_WARP_COUNTDOWN;
+
+// Blocky mode,
+// replace each 320x200 pixel with multiply*multiply pixels.
+// According to Dave Taylor, it still is a bonehead thing
+// to use ....
+static int	multiply=1;
+
+
+//
+//  Translates the key currently in X_event
+//
+
+int xlatekey(void)
+{
+
+    int rc;
+
+    switch(rc = XKeycodeToKeysym(X_display, X_event.xkey.keycode, 0))
+    {
+      case XK_Left:	rc = KEY_LEFTARROW;	break;
+      case XK_Right:	rc = KEY_RIGHTARROW;	break;
+      case XK_Down:	rc = KEY_DOWNARROW;	break;
+      case XK_Up:	rc = KEY_UPARROW;	break;
+      case XK_Escape:	rc = KEY_ESCAPE;	break;
+      case XK_Return:	rc = KEY_ENTER;		break;
+      case XK_Tab:	rc = KEY_TAB;		break;
+      case XK_F1:	rc = KEY_F1;		break;
+      case XK_F2:	rc = KEY_F2;		break;
+      case XK_F3:	rc = KEY_F3;		break;
+      case XK_F4:	rc = KEY_F4;		break;
+      case XK_F5:	rc = KEY_F5;		break;
+      case XK_F6:	rc = KEY_F6;		break;
+      case XK_F7:	rc = KEY_F7;		break;
+      case XK_F8:	rc = KEY_F8;		break;
+      case XK_F9:	rc = KEY_F9;		break;
+      case XK_F10:	rc = KEY_F10;		break;
+      case XK_F11:	rc = KEY_F11;		break;
+      case XK_F12:	rc = KEY_F12;		break;
+	
+      case XK_BackSpace:
+      case XK_Delete:	rc = KEY_BACKSPACE;	break;
+
+      case XK_Pause:	rc = KEY_PAUSE;		break;
+
+      case XK_KP_Equal:
+      case XK_equal:	rc = KEY_EQUALS;	break;
+
+      case XK_KP_Subtract:
+      case XK_minus:	rc = KEY_MINUS;		break;
+
+      case XK_Shift_L:
+      case XK_Shift_R:
+	rc = KEY_RSHIFT;
+	break;
+	
+      case XK_Control_L:
+      case XK_Control_R:
+	rc = KEY_RCTRL;
+	break;
+	
+      case XK_Alt_L:
+      case XK_Meta_L:
+      case XK_Alt_R:
+      case XK_Meta_R:
+	rc = KEY_RALT;
+	break;
+	
+      default:
+	if (rc >= XK_space && rc <= XK_asciitilde)
+	    rc = rc - XK_space + ' ';
+	if (rc >= 'A' && rc <= 'Z')
+	    rc = rc - 'A' + 'a';
+	break;
+    }
+
+    return rc;
+
+}
+
+void I_ShutdownGraphics(void)
+{
+  // Detach from X server
+  if (!XShmDetach(X_display, &X_shminfo))
+	    I_Error("XShmDetach() failed in I_ShutdownGraphics()");
+
+  // Release shared memory.
+  shmdt(X_shminfo.shmaddr);
+  shmctl(X_shminfo.shmid, IPC_RMID, 0);
+
+  // Paranoia.
+  image->data = NULL;
+}
+
+
+
+//
+// I_StartFrame
+//
+void I_StartFrame (void)
+{
+    // er?
+
+}
+
+static int	lastmousex = 0;
+static int	lastmousey = 0;
+boolean		mousemoved = false;
+boolean		shmFinished;
+
+void I_GetEvent(void)
+{
+
+    event_t event;
+
+    // put event-grabbing stuff in here
+    XNextEvent(X_display, &X_event);
+    switch (X_event.type)
+    {
+      case KeyPress:
+	event.type = ev_keydown;
+	event.data1 = xlatekey();
+	D_PostEvent(&event);
+	// fprintf(stderr, "k");
+	break;
+      case KeyRelease:
+	event.type = ev_keyup;
+	event.data1 = xlatekey();
+	D_PostEvent(&event);
+	// fprintf(stderr, "ku");
+	break;
+      case ButtonPress:
+	event.type = ev_mouse;
+	event.data1 =
+	    (X_event.xbutton.state & Button1Mask)
+	    | (X_event.xbutton.state & Button2Mask ? 2 : 0)
+	    | (X_event.xbutton.state & Button3Mask ? 4 : 0)
+	    | (X_event.xbutton.button == Button1)
+	    | (X_event.xbutton.button == Button2 ? 2 : 0)
+	    | (X_event.xbutton.button == Button3 ? 4 : 0);
+	event.data2 = event.data3 = 0;
+	D_PostEvent(&event);
+	// fprintf(stderr, "b");
+	break;
+      case ButtonRelease:
+	event.type = ev_mouse;
+	event.data1 =
+	    (X_event.xbutton.state & Button1Mask)
+	    | (X_event.xbutton.state & Button2Mask ? 2 : 0)
+	    | (X_event.xbutton.state & Button3Mask ? 4 : 0);
+	// suggest parentheses around arithmetic in operand of |
+	event.data1 =
+	    event.data1
+	    ^ (X_event.xbutton.button == Button1 ? 1 : 0)
+	    ^ (X_event.xbutton.button == Button2 ? 2 : 0)
+	    ^ (X_event.xbutton.button == Button3 ? 4 : 0);
+	event.data2 = event.data3 = 0;
+	D_PostEvent(&event);
+	// fprintf(stderr, "bu");
+	break;
+      case MotionNotify:
+	event.type = ev_mouse;
+	event.data1 =
+	    (X_event.xmotion.state & Button1Mask)
+	    | (X_event.xmotion.state & Button2Mask ? 2 : 0)
+	    | (X_event.xmotion.state & Button3Mask ? 4 : 0);
+	event.data2 = (X_event.xmotion.x - lastmousex) << 2;
+	event.data3 = (lastmousey - X_event.xmotion.y) << 2;
+
+	if (event.data2 || event.data3)
+	{
+	    lastmousex = X_event.xmotion.x;
+	    lastmousey = X_event.xmotion.y;
+	    if (X_event.xmotion.x != X_width/2 &&
+		X_event.xmotion.y != X_height/2)
+	    {
+		D_PostEvent(&event);
+		// fprintf(stderr, "m");
+		mousemoved = false;
+	    } else
+	    {
+		mousemoved = true;
+	    }
+	}
+	break;
+	
+      case Expose:
+      case ConfigureNotify:
+	break;
+	
+      default:
+	if (doShm && X_event.type == X_shmeventtype) shmFinished = true;
+	break;
+    }
+
+}
+
+Cursor
+createnullcursor
+( Display*	display,
+  Window	root )
+{
+    Pixmap cursormask;
+    XGCValues xgc;
+    GC gc;
+    XColor dummycolour;
+    Cursor cursor;
+
+    cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
+    xgc.function = GXclear;
+    gc =  XCreateGC(display, cursormask, GCFunction, &xgc);
+    XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
+    dummycolour.pixel = 0;
+    dummycolour.red = 0;
+    dummycolour.flags = 04;
+    cursor = XCreatePixmapCursor(display, cursormask, cursormask,
+				 &dummycolour,&dummycolour, 0,0);
+    XFreePixmap(display,cursormask);
+    XFreeGC(display,gc);
+    return cursor;
+}
+
+//
+// I_StartTic
+//
+void I_StartTic (void)
+{
+
+    if (!X_display)
+	return;
+
+    while (XPending(X_display))
+	I_GetEvent();
+
+    // Warp the pointer back to the middle of the window
+    //  or it will wander off - that is, the game will
+    //  loose input focus within X11.
+    if (grabMouse)
+    {
+	if (!--doPointerWarp)
+	{
+	    XWarpPointer( X_display,
+			  None,
+			  X_mainWindow,
+			  0, 0,
+			  0, 0,
+			  X_width/2, X_height/2);
+
+	    doPointerWarp = POINTER_WARP_COUNTDOWN;
+	}
+    }
+
+    mousemoved = false;
+
+}
+
+
+//
+// I_UpdateNoBlit
+//
+void I_UpdateNoBlit (void)
+{
+    // what is this?
+}
+
+//
+// I_FinishUpdate
+//
+void I_FinishUpdate (void)
+{
+
+    static int	lasttic;
+    int		tics;
+    int		i;
+    // UNUSED static unsigned char *bigscreen=0;
+
+    // draws little dots on the bottom of the screen
+    if (devparm)
+    {
+
+	i = I_GetTime();
+	tics = i - lasttic;
+	lasttic = i;
+	if (tics > 20) tics = 20;
+
+	for (i=0 ; i<tics*2 ; i+=2)
+	    screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0xff;
+	for ( ; i<20*2 ; i+=2)
+	    screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0x0;
+    
+    }
+
+    // scales the screen size before blitting it
+    if (multiply == 2)
+    {
+	unsigned int *olineptrs[2];
+	unsigned int *ilineptr;
+	int x, y, i;
+	unsigned int twoopixels;
+	unsigned int twomoreopixels;
+	unsigned int fouripixels;
+
+	ilineptr = (unsigned int *) (screens[0]);
+	for (i=0 ; i<2 ; i++)
+	    olineptrs[i] = (unsigned int *) &image->data[i*X_width];
+
+	y = SCREENHEIGHT;
+	while (y--)
+	{
+	    x = SCREENWIDTH;
+	    do
+	    {
+		fouripixels = *ilineptr++;
+		twoopixels =	(fouripixels & 0xff000000)
+		    |	((fouripixels>>8) & 0xffff00)
+		    |	((fouripixels>>16) & 0xff);
+		twomoreopixels =	((fouripixels<<16) & 0xff000000)
+		    |	((fouripixels<<8) & 0xffff00)
+		    |	(fouripixels & 0xff);
+#ifdef __BIG_ENDIAN__
+		*olineptrs[0]++ = twoopixels;
+		*olineptrs[1]++ = twoopixels;
+		*olineptrs[0]++ = twomoreopixels;
+		*olineptrs[1]++ = twomoreopixels;
+#else
+		*olineptrs[0]++ = twomoreopixels;
+		*olineptrs[1]++ = twomoreopixels;
+		*olineptrs[0]++ = twoopixels;
+		*olineptrs[1]++ = twoopixels;
+#endif
+	    } while (x-=4);
+	    olineptrs[0] += X_width/4;
+	    olineptrs[1] += X_width/4;
+	}
+
+    }
+    else if (multiply == 3)
+    {
+	unsigned int *olineptrs[3];
+	unsigned int *ilineptr;
+	int x, y, i;
+	unsigned int fouropixels[3];
+	unsigned int fouripixels;
+
+	ilineptr = (unsigned int *) (screens[0]);
+	for (i=0 ; i<3 ; i++)
+	    olineptrs[i] = (unsigned int *) &image->data[i*X_width];
+
+	y = SCREENHEIGHT;
+	while (y--)
+	{
+	    x = SCREENWIDTH;
+	    do
+	    {
+		fouripixels = *ilineptr++;
+		fouropixels[0] = (fouripixels & 0xff000000)
+		    |	((fouripixels>>8) & 0xff0000)
+		    |	((fouripixels>>16) & 0xffff);
+		fouropixels[1] = ((fouripixels<<8) & 0xff000000)
+		    |	(fouripixels & 0xffff00)
+		    |	((fouripixels>>8) & 0xff);
+		fouropixels[2] = ((fouripixels<<16) & 0xffff0000)
+		    |	((fouripixels<<8) & 0xff00)
+		    |	(fouripixels & 0xff);
+#ifdef __BIG_ENDIAN__
+		*olineptrs[0]++ = fouropixels[0];
+		*olineptrs[1]++ = fouropixels[0];
+		*olineptrs[2]++ = fouropixels[0];
+		*olineptrs[0]++ = fouropixels[1];
+		*olineptrs[1]++ = fouropixels[1];
+		*olineptrs[2]++ = fouropixels[1];
+		*olineptrs[0]++ = fouropixels[2];
+		*olineptrs[1]++ = fouropixels[2];
+		*olineptrs[2]++ = fouropixels[2];
+#else
+		*olineptrs[0]++ = fouropixels[2];
+		*olineptrs[1]++ = fouropixels[2];
+		*olineptrs[2]++ = fouropixels[2];
+		*olineptrs[0]++ = fouropixels[1];
+		*olineptrs[1]++ = fouropixels[1];
+		*olineptrs[2]++ = fouropixels[1];
+		*olineptrs[0]++ = fouropixels[0];
+		*olineptrs[1]++ = fouropixels[0];
+		*olineptrs[2]++ = fouropixels[0];
+#endif
+	    } while (x-=4);
+	    olineptrs[0] += 2*X_width/4;
+	    olineptrs[1] += 2*X_width/4;
+	    olineptrs[2] += 2*X_width/4;
+	}
+
+    }
+    else if (multiply == 4)
+    {
+	// Broken. Gotta fix this some day.
+	void Expand4(unsigned *, double *);
+  	Expand4 ((unsigned *)(screens[0]), (double *) (image->data));
+    }
+
+    if (doShm)
+    {
+
+	if (!XShmPutImage(	X_display,
+				X_mainWindow,
+				X_gc,
+				image,
+				0, 0,
+				0, 0,
+				X_width, X_height,
+				True ))
+	    I_Error("XShmPutImage() failed\n");
+
+	// wait for it to finish and processes all input events
+	shmFinished = false;
+	do
+	{
+	    I_GetEvent();
+	} while (!shmFinished);
+
+    }
+    else
+    {
+
+	// draw the image
+	XPutImage(	X_display,
+			X_mainWindow,
+			X_gc,
+			image,
+			0, 0,
+			0, 0,
+			X_width, X_height );
+
+	// sync up with server
+	XSync(X_display, False);
+
+    }
+
+}
+
+
+//
+// I_ReadScreen
+//
+void I_ReadScreen (byte* scr)
+{
+    memcpy (scr, screens[0], SCREENWIDTH*SCREENHEIGHT);
+}
+
+
+//
+// Palette stuff.
+//
+static XColor	colors[256];
+
+void UploadNewPalette(Colormap cmap, byte *palette)
+{
+
+    register int	i;
+    register int	c;
+    static boolean	firstcall = true;
+
+#ifdef __cplusplus
+    if (X_visualinfo.c_class == PseudoColor && X_visualinfo.depth == 8)
+#else
+    if (X_visualinfo.class == PseudoColor && X_visualinfo.depth == 8)
+#endif
+	{
+	    // initialize the colormap
+	    if (firstcall)
+	    {
+		firstcall = false;
+		for (i=0 ; i<256 ; i++)
+		{
+		    colors[i].pixel = i;
+		    colors[i].flags = DoRed|DoGreen|DoBlue;
+		}
+	    }
+
+	    // set the X colormap entries
+	    for (i=0 ; i<256 ; i++)
+	    {
+		c = gammatable[usegamma][*palette++];
+		colors[i].red = (c<<8) + c;
+		c = gammatable[usegamma][*palette++];
+		colors[i].green = (c<<8) + c;
+		c = gammatable[usegamma][*palette++];
+		colors[i].blue = (c<<8) + c;
+	    }
+
+	    // store the colors to the current colormap
+	    XStoreColors(X_display, cmap, colors, 256);
+
+	}
+}
+
+//
+// I_SetPalette
+//
+void I_SetPalette (byte* palette)
+{
+    UploadNewPalette(X_cmap, palette);
+}
+
+
+//
+// This function is probably redundant,
+//  if XShmDetach works properly.
+// ddt never detached the XShm memory,
+//  thus there might have been stale
+//  handles accumulating.
+//
+void grabsharedmemory(int size)
+{
+
+  int			key = ('d'<<24) | ('o'<<16) | ('o'<<8) | 'm';
+  struct shmid_ds	shminfo;
+  int			minsize = 320*200;
+  int			id;
+  int			rc;
+  // UNUSED int done=0;
+  int			pollution=5;
+  
+  // try to use what was here before
+  do
+  {
+    id = shmget((key_t) key, minsize, 0777); // just get the id
+    if (id != -1)
+    {
+      rc=shmctl(id, IPC_STAT, &shminfo); // get stats on it
+      if (!rc) 
+      {
+	if (shminfo.shm_nattch)
+	{
+	  fprintf(stderr, "User %d appears to be running "
+		  "DOOM.  Is that wise?\n", shminfo.shm_cpid);
+	  key++;
+	}
+	else
+	{
+	  if (getuid() == shminfo.shm_perm.cuid)
+	  {
+	    rc = shmctl(id, IPC_RMID, 0);
+	    if (!rc)
+	      fprintf(stderr,
+		      "Was able to kill my old shared memory\n");
+	    else
+	      I_Error("Was NOT able to kill my old shared memory");
+	    
+	    id = shmget((key_t)key, size, IPC_CREAT|0777);
+	    if (id==-1)
+	      I_Error("Could not get shared memory");
+	    
+	    rc=shmctl(id, IPC_STAT, &shminfo);
+	    
+	    break;
+	    
+	  }
+	  if (size >= shminfo.shm_segsz)
+	  {
+	    fprintf(stderr,
+		    "will use %d's stale shared memory\n",
+		    shminfo.shm_cpid);
+	    break;
+	  }
+	  else
+	  {
+	    fprintf(stderr,
+		    "warning: can't use stale "
+		    "shared memory belonging to id %d, "
+		    "key=0x%x\n",
+		    shminfo.shm_cpid, key);
+	    key++;
+	  }
+	}
+      }
+      else
+      {
+	I_Error("could not get stats on key=%d", key);
+      }
+    }
+    else
+    {
+      id = shmget((key_t)key, size, IPC_CREAT|0777);
+      if (id==-1)
+      {
+	extern int errno;
+	fprintf(stderr, "errno=%d\n", errno);
+	I_Error("Could not get any shared memory");
+      }
+      break;
+    }
+  } while (--pollution);
+  
+  if (!pollution)
+  {
+    I_Error("Sorry, system too polluted with stale "
+	    "shared memory segments.\n");
+    }	
+  
+  X_shminfo.shmid = id;
+  
+  // attach to the shared memory segment
+  image->data = X_shminfo.shmaddr = shmat(id, 0, 0);
+  
+  fprintf(stderr, "shared memory id=%d, addr=0x%x\n", id,
+	  (int) (image->data));
+}
+
+void I_InitGraphics(void)
+{
+
+    char*		displayname;
+    char*		d;
+    int			n;
+    int			pnum;
+    int			x=0;
+    int			y=0;
+    
+    // warning: char format, different type arg
+    char		xsign=' ';
+    char		ysign=' ';
+    
+    int			oktodraw;
+    unsigned long	attribmask;
+    XSetWindowAttributes attribs;
+    XGCValues		xgcvalues;
+    int			valuemask;
+    static int		firsttime=1;
+
+    if (!firsttime)
+	return;
+    firsttime = 0;
+
+    signal(SIGINT, (void (*)(int)) I_Quit);
+
+    if (M_CheckParm("-2"))
+	multiply = 2;
+
+    if (M_CheckParm("-3"))
+	multiply = 3;
+
+    if (M_CheckParm("-4"))
+	multiply = 4;
+
+    X_width = SCREENWIDTH * multiply;
+    X_height = SCREENHEIGHT * multiply;
+
+    // check for command-line display name
+    if ( (pnum=M_CheckParm("-disp")) ) // suggest parentheses around assignment
+	displayname = myargv[pnum+1];
+    else
+	displayname = 0;
+
+    // check if the user wants to grab the mouse (quite unnice)
+    grabMouse = !!M_CheckParm("-grabmouse");
+
+    // check for command-line geometry
+    if ( (pnum=M_CheckParm("-geom")) ) // suggest parentheses around assignment
+    {
+	// warning: char format, different type arg 3,5
+	n = sscanf(myargv[pnum+1], "%c%d%c%d", &xsign, &x, &ysign, &y);
+	
+	if (n==2)
+	    x = y = 0;
+	else if (n==6)
+	{
+	    if (xsign == '-')
+		x = -x;
+	    if (ysign == '-')
+		y = -y;
+	}
+	else
+	    I_Error("bad -geom parameter");
+    }
+
+    // open the display
+    X_display = XOpenDisplay(displayname);
+    if (!X_display)
+    {
+	if (displayname)
+	    I_Error("Could not open display [%s]", displayname);
+	else
+	    I_Error("Could not open display (DISPLAY=[%s])", getenv("DISPLAY"));
+    }
+
+    // use the default visual 
+    X_screen = DefaultScreen(X_display);
+    if (!XMatchVisualInfo(X_display, X_screen, 8, PseudoColor, &X_visualinfo))
+	I_Error("xdoom currently only supports 256-color PseudoColor screens");
+    X_visual = X_visualinfo.visual;
+
+    // check for the MITSHM extension
+    doShm = XShmQueryExtension(X_display);
+
+    // even if it's available, make sure it's a local connection
+    if (doShm)
+    {
+	if (!displayname) displayname = (char *) getenv("DISPLAY");
+	if (displayname)
+	{
+	    d = displayname;
+	    while (*d && (*d != ':')) d++;
+	    if (*d) *d = 0;
+	    if (!(!strcasecmp(displayname, "unix") || !*displayname)) doShm = false;
+	}
+    }
+
+    fprintf(stderr, "Using MITSHM extension\n");
+
+    // create the colormap
+    X_cmap = XCreateColormap(X_display, RootWindow(X_display,
+						   X_screen), X_visual, AllocAll);
+
+    // setup attributes for main window
+    attribmask = CWEventMask | CWColormap | CWBorderPixel;
+    attribs.event_mask =
+	KeyPressMask
+	| KeyReleaseMask
+	// | PointerMotionMask | ButtonPressMask | ButtonReleaseMask
+	| ExposureMask;
+
+    attribs.colormap = X_cmap;
+    attribs.border_pixel = 0;
+
+    // create the main window
+    X_mainWindow = XCreateWindow(	X_display,
+					RootWindow(X_display, X_screen),
+					x, y,
+					X_width, X_height,
+					0, // borderwidth
+					8, // depth
+					InputOutput,
+					X_visual,
+					attribmask,
+					&attribs );
+
+    XDefineCursor(X_display, X_mainWindow,
+		  createnullcursor( X_display, X_mainWindow ) );
+
+    // create the GC
+    valuemask = GCGraphicsExposures;
+    xgcvalues.graphics_exposures = False;
+    X_gc = XCreateGC(	X_display,
+  			X_mainWindow,
+  			valuemask,
+  			&xgcvalues );
+
+    // map the window
+    XMapWindow(X_display, X_mainWindow);
+
+    // wait until it is OK to draw
+    oktodraw = 0;
+    while (!oktodraw)
+    {
+	XNextEvent(X_display, &X_event);
+	if (X_event.type == Expose
+	    && !X_event.xexpose.count)
+	{
+	    oktodraw = 1;
+	}
+    }
+
+    // grabs the pointer so it is restricted to this window
+    if (grabMouse)
+	XGrabPointer(X_display, X_mainWindow, True,
+		     ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
+		     GrabModeAsync, GrabModeAsync,
+		     X_mainWindow, None, CurrentTime);
+
+    if (doShm)
+    {
+
+	X_shmeventtype = XShmGetEventBase(X_display) + ShmCompletion;
+
+	// create the image
+	image = XShmCreateImage(	X_display,
+					X_visual,
+					8,
+					ZPixmap,
+					0,
+					&X_shminfo,
+					X_width,
+					X_height );
+
+	grabsharedmemory(image->bytes_per_line * image->height);
+
+
+	// UNUSED
+	// create the shared memory segment
+	// X_shminfo.shmid = shmget (IPC_PRIVATE,
+	// image->bytes_per_line * image->height, IPC_CREAT | 0777);
+	// if (X_shminfo.shmid < 0)
+	// {
+	// perror("");
+	// I_Error("shmget() failed in InitGraphics()");
+	// }
+	// fprintf(stderr, "shared memory id=%d\n", X_shminfo.shmid);
+	// attach to the shared memory segment
+	// image->data = X_shminfo.shmaddr = shmat(X_shminfo.shmid, 0, 0);
+	
+
+	if (!image->data)
+	{
+	    perror("");
+	    I_Error("shmat() failed in InitGraphics()");
+	}
+
+	// get the X server to attach to it
+	if (!XShmAttach(X_display, &X_shminfo))
+	    I_Error("XShmAttach() failed in InitGraphics()");
+
+    }
+    else
+    {
+	image = XCreateImage(	X_display,
+    				X_visual,
+    				8,
+    				ZPixmap,
+    				0,
+    				(char*)malloc(X_width * X_height),
+    				X_width, X_height,
+    				8,
+    				X_width );
+
+    }
+
+    if (multiply == 1)
+	screens[0] = (unsigned char *) (image->data);
+    else
+	screens[0] = (unsigned char *) malloc (SCREENWIDTH * SCREENHEIGHT);
+
+}
+
+
+unsigned	exptable[256];
+
+void InitExpand (void)
+{
+    int		i;
+	
+    for (i=0 ; i<256 ; i++)
+	exptable[i] = i | (i<<8) | (i<<16) | (i<<24);
+}
+
+double		exptable2[256*256];
+
+void InitExpand2 (void)
+{
+    int		i;
+    int		j;
+    // UNUSED unsigned	iexp, jexp;
+    double*	exp;
+    union
+    {
+	double 		d;
+	unsigned	u[2];
+    } pixel;
+	
+    printf ("building exptable2...\n");
+    exp = exptable2;
+    for (i=0 ; i<256 ; i++)
+    {
+	pixel.u[0] = i | (i<<8) | (i<<16) | (i<<24);
+	for (j=0 ; j<256 ; j++)
+	{
+	    pixel.u[1] = j | (j<<8) | (j<<16) | (j<<24);
+	    *exp++ = pixel.d;
+	}
+    }
+    printf ("done.\n");
+}
+
+int	inited;
+
+void
+Expand4
+( unsigned*	lineptr,
+  double*	xline )
+{
+    double	dpixel;
+    unsigned	x;
+    unsigned 	y;
+    unsigned	fourpixels;
+    unsigned	step;
+    double*	exp;
+	
+    exp = exptable2;
+    if (!inited)
+    {
+	inited = 1;
+	InitExpand2 ();
+    }
+		
+		
+    step = 3*SCREENWIDTH/2;
+	
+    y = SCREENHEIGHT-1;
+    do
+    {
+	x = SCREENWIDTH;
+
+	do
+	{
+	    fourpixels = lineptr[0];
+			
+	    dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
+	    xline[0] = dpixel;
+	    xline[160] = dpixel;
+	    xline[320] = dpixel;
+	    xline[480] = dpixel;
+			
+	    dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
+	    xline[1] = dpixel;
+	    xline[161] = dpixel;
+	    xline[321] = dpixel;
+	    xline[481] = dpixel;
+
+	    fourpixels = lineptr[1];
+			
+	    dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
+	    xline[2] = dpixel;
+	    xline[162] = dpixel;
+	    xline[322] = dpixel;
+	    xline[482] = dpixel;
+			
+	    dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
+	    xline[3] = dpixel;
+	    xline[163] = dpixel;
+	    xline[323] = dpixel;
+	    xline[483] = dpixel;
+
+	    fourpixels = lineptr[2];
+			
+	    dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
+	    xline[4] = dpixel;
+	    xline[164] = dpixel;
+	    xline[324] = dpixel;
+	    xline[484] = dpixel;
+			
+	    dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
+	    xline[5] = dpixel;
+	    xline[165] = dpixel;
+	    xline[325] = dpixel;
+	    xline[485] = dpixel;
+
+	    fourpixels = lineptr[3];
+			
+	    dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) );
+	    xline[6] = dpixel;
+	    xline[166] = dpixel;
+	    xline[326] = dpixel;
+	    xline[486] = dpixel;
+			
+	    dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) );
+	    xline[7] = dpixel;
+	    xline[167] = dpixel;
+	    xline[327] = dpixel;
+	    xline[487] = dpixel;
+
+	    lineptr+=4;
+	    xline+=8;
+	} while (x-=16);
+	xline += step;
+    } while (y--);
+}
+
+
--- /dev/null
+++ b/src/i_video.h
@@ -1,0 +1,66 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: i_video.h 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// DESCRIPTION:
+//	System specific interface stuff.
+//
+//-----------------------------------------------------------------------------
+
+
+#ifndef __I_VIDEO__
+#define __I_VIDEO__
+
+
+#include "doomtype.h"
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+
+// Called by D_DoomMain,
+// determines the hardware configuration
+// and sets up the video mode
+void I_InitGraphics (void);
+
+
+void I_ShutdownGraphics(void);
+
+// Takes full 8 bit values.
+void I_SetPalette (byte* palette);
+
+void I_UpdateNoBlit (void);
+void I_FinishUpdate (void);
+
+// Wait for vertical retrace or pause a bit.
+void I_WaitVBL(int count);
+
+void I_ReadScreen (byte* scr);
+
+void I_BeginRead (void);
+void I_EndRead (void);
+
+
+
+#endif
+//-----------------------------------------------------------------------------
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:19:58  fraggle
+// Initial revision
+//
+//
+//-----------------------------------------------------------------------------
--- /dev/null
+++ b/src/info.c
@@ -1,0 +1,4673 @@
+// Emacs style mode select   -*- C++ -*- 
+//-----------------------------------------------------------------------------
+//
+// $Id: info.c 4 2005-07-23 16:19:41Z fraggle $
+//
+// Copyright (C) 1993-1996 by id Software, Inc.
+//
+// This source is available for distribution and/or modification
+// only under the terms of the DOOM Source Code License as
+// published by id Software. All rights reserved.
+//
+// The source is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
+// for more details.
+//
+// $Log$
+// Revision 1.1  2005/07/23 16:20:19  fraggle
+// Initial revision
+//
+//
+// DESCRIPTION:
+//	Thing frame/state LUT,
+//	generated by multigen utilitiy.
+//	This one is the original DOOM version, preserved.
+//
+//-----------------------------------------------------------------------------
+
+static const char
+rcsid[] = "$Id: info.c 4 2005-07-23 16:19:41Z fraggle $";
+
+// Data.
+#include "sounds.h"
+#include "m_fixed.h"
+
+#ifdef __GNUG__
+#pragma implementation "info.h"
+#endif
+#include "info.h"
+
+#include "p_mobj.h"
+
+char *sprnames[NUMSPRITES] = {
+    "TROO","SHTG","PUNG","PISG","PISF","SHTF","SHT2","CHGG","CHGF","MISG",
+    "MISF","SAWG","PLSG","PLSF","BFGG","BFGF","BLUD","PUFF","BAL1","BAL2",
+    "PLSS","PLSE","MISL","BFS1","BFE1","BFE2","TFOG","IFOG","PLAY","POSS",
+    "SPOS","VILE","FIRE","FATB","FBXP","SKEL","MANF","FATT","CPOS","SARG",
+    "HEAD","BAL7","BOSS","BOS2","SKUL","SPID","BSPI","APLS","APBX","CYBR",
+    "PAIN","SSWV","KEEN","BBRN","BOSF","ARM1","ARM2","BAR1","BEXP","FCAN",
+    "BON1","BON2","BKEY","RKEY","YKEY","BSKU","RSKU","YSKU","STIM","MEDI",
+    "SOUL","PINV","PSTR","PINS","MEGA","SUIT","PMAP","PVIS","CLIP","AMMO",
+    "ROCK","BROK","CELL","CELP","SHEL","SBOX","BPAK","BFUG","MGUN","CSAW",
+    "LAUN","PLAS","SHOT","SGN2","COLU","SMT2","GOR1","POL2","POL5","POL4",
+    "POL3","POL1","POL6","GOR2","GOR3","GOR4","GOR5","SMIT","COL1","COL2",
+    "COL3","COL4","CAND","CBRA","COL6","TRE1","TRE2","ELEC","CEYE","FSKU",
+    "COL5","TBLU","TGRN","TRED","SMBT","SMGT","SMRT","HDB1","HDB2","HDB3",
+    "HDB4","HDB5","HDB6","POB1","POB2","BRS1","TLMP","TLP2"
+};
+
+
+// Doesn't work with g++, needs actionf_p1
+void  A_Light0();
+void A_WeaponReady();
+void A_Lower();
+void A_Raise();
+void A_Punch();
+void A_ReFire();
+void A_FirePistol();
+void A_Light1();
+void A_FireShotgun();
+void A_Light2();
+void A_FireShotgun2();
+void A_CheckReload();
+void A_OpenShotgun2();
+void A_LoadShotgun2();
+void A_CloseShotgun2();
+void A_FireCGun();
+void A_GunFlash();
+void A_FireMissile();
+void A_Saw();
+void A_FirePlasma();
+void A_BFGsound();
+void A_FireBFG();
+void A_BFGSpray();
+void A_Explode();
+void A_Pain();
+void A_PlayerScream();
+void A_Fall();
+void A_XScream();
+void A_Look();
+void A_Chase();
+void A_FaceTarget();
+void A_PosAttack();
+void A_Scream();
+void A_SPosAttack();
+void A_VileChase();
+void A_VileStart();
+void A_VileTarget();
+void A_VileAttack();
+void A_StartFire();
+void A_Fire();
+void A_FireCrackle();
+void A_Tracer();
+void A_SkelWhoosh();
+void A_SkelFist();
+void A_SkelMissile();
+void A_FatRaise();
+void A_FatAttack1();
+void A_FatAttack2();
+void A_FatAttack3();
+void A_BossDeath();
+void A_CPosAttack();
+void A_CPosRefire();
+void A_TroopAttack();
+void A_SargAttack();
+void A_HeadAttack();
+void A_BruisAttack();
+void A_SkullAttack();
+void A_Metal();
+void A_SpidRefire();
+void A_BabyMetal();
+void A_BspiAttack();
+void A_Hoof();
+void A_CyberAttack();
+void A_PainAttack();
+void A_PainDie();
+void A_KeenDie();
+void A_BrainPain();
+void A_BrainScream();
+void A_BrainDie();
+void A_BrainAwake();
+void A_BrainSpit();
+void A_SpawnSound();
+void A_SpawnFly();
+void A_BrainExplode();
+
+
+state_t	states[NUMSTATES] = {
+    {SPR_TROO,0,-1,{NULL},S_NULL,0,0},	// S_NULL
+    {SPR_SHTG,4,0,{A_Light0},S_NULL,0,0},	// S_LIGHTDONE
+    {SPR_PUNG,0,1,{A_WeaponReady},S_PUNCH,0,0},	// S_PUNCH
+    {SPR_PUNG,0,1,{A_Lower},S_PUNCHDOWN,0,0},	// S_PUNCHDOWN
+    {SPR_PUNG,0,1,{A_Raise},S_PUNCHUP,0,0},	// S_PUNCHUP
+    {SPR_PUNG,1,4,{NULL},S_PUNCH2,0,0},		// S_PUNCH1
+    {SPR_PUNG,2,4,{A_Punch},S_PUNCH3,0,0},	// S_PUNCH2
+    {SPR_PUNG,3,5,{NULL},S_PUNCH4,0,0},		// S_PUNCH3
+    {SPR_PUNG,2,4,{NULL},S_PUNCH5,0,0},		// S_PUNCH4
+    {SPR_PUNG,1,5,{A_ReFire},S_PUNCH,0,0},	// S_PUNCH5
+    {SPR_PISG,0,1,{A_WeaponReady},S_PISTOL,0,0},// S_PISTOL
+    {SPR_PISG,0,1,{A_Lower},S_PISTOLDOWN,0,0},	// S_PISTOLDOWN
+    {SPR_PISG,0,1,{A_Raise},S_PISTOLUP,0,0},	// S_PISTOLUP
+    {SPR_PISG,0,4,{NULL},S_PISTOL2,0,0},	// S_PISTOL1
+    {SPR_PISG,1,6,{A_FirePistol},S_PISTOL3,0,0},// S_PISTOL2
+    {SPR_PISG,2,4,{NULL},S_PISTOL4,0,0},	// S_PISTOL3
+    {SPR_PISG,1,5,{A_ReFire},S_PISTOL,0,0},	// S_PISTOL4
+    {SPR_PISF,32768,7,{A_Light1},S_LIGHTDONE,0,0},	// S_PISTOLFLASH
+    {SPR_SHTG,0,1,{A_WeaponReady},S_SGUN,0,0},	// S_SGUN
+    {SPR_SHTG,0,1,{A_Lower},S_SGUNDOWN,0,0},	// S_SGUNDOWN
+    {SPR_SHTG,0,1,{A_Raise},S_SGUNUP,0,0},	// S_SGUNUP
+    {SPR_SHTG,0,3,{NULL},S_SGUN2,0,0},	// S_SGUN1
+    {SPR_SHTG,0,7,{A_FireShotgun},S_SGUN3,0,0},	// S_SGUN2
+    {SPR_SHTG,1,5,{NULL},S_SGUN4,0,0},	// S_SGUN3
+    {SPR_SHTG,2,5,{NULL},S_SGUN5,0,0},	// S_SGUN4
+    {SPR_SHTG,3,4,{NULL},S_SGUN6,0,0},	// S_SGUN5
+    {SPR_SHTG,2,5,{NULL},S_SGUN7,0,0},	// S_SGUN6
+    {SPR_SHTG,1,5,{NULL},S_SGUN8,0,0},	// S_SGUN7
+    {SPR_SHTG,0,3,{NULL},S_SGUN9,0,0},	// S_SGUN8
+    {SPR_SHTG,0,7,{A_ReFire},S_SGUN,0,0},	// S_SGUN9
+    {SPR_SHTF,32768,4,{A_Light1},S_SGUNFLASH2,0,0},	// S_SGUNFLASH1
+    {SPR_SHTF,32769,3,{A_Light2},S_LIGHTDONE,0,0},	// S_SGUNFLASH2
+    {SPR_SHT2,0,1,{A_WeaponReady},S_DSGUN,0,0},	// S_DSGUN
+    {SPR_SHT2,0,1,{A_Lower},S_DSGUNDOWN,0,0},	// S_DSGUNDOWN
+    {SPR_SHT2,0,1,{A_Raise},S_DSGUNUP,0,0},	// S_DSGUNUP
+    {SPR_SHT2,0,3,{NULL},S_DSGUN2,0,0},	// S_DSGUN1
+    {SPR_SHT2,0,7,{A_FireShotgun2},S_DSGUN3,0,0},	// S_DSGUN2
+    {SPR_SHT2,1,7,{NULL},S_DSGUN4,0,0},	// S_DSGUN3
+    {SPR_SHT2,2,7,{A_CheckReload},S_DSGUN5,0,0},	// S_DSGUN4
+    {SPR_SHT2,3,7,{A_OpenShotgun2},S_DSGUN6,0,0},	// S_DSGUN5
+    {SPR_SHT2,4,7,{NULL},S_DSGUN7,0,0},	// S_DSGUN6
+    {SPR_SHT2,5,7,{A_LoadShotgun2},S_DSGUN8,0,0},	// S_DSGUN7
+    {SPR_SHT2,6,6,{NULL},S_DSGUN9,0,0},	// S_DSGUN8
+    {SPR_SHT2,7,6,{A_CloseShotgun2},S_DSGUN10,0,0},	// S_DSGUN9
+    {SPR_SHT2,0,5,{A_ReFire},S_DSGUN,0,0},	// S_DSGUN10
+    {SPR_SHT2,1,7,{NULL},S_DSNR2,0,0},	// S_DSNR1
+    {SPR_SHT2,0,3,{NULL},S_DSGUNDOWN,0,0},	// S_DSNR2
+    {SPR_SHT2,32776,5,{A_Light1},S_DSGUNFLASH2,0,0},	// S_DSGUNFLASH1
+    {SPR_SHT2,32777,4,{A_Light2},S_LIGHTDONE,0,0},	// S_DSGUNFLASH2
+    {SPR_CHGG,0,1,{A_WeaponReady},S_CHAIN,0,0},	// S_CHAIN
+    {SPR_CHGG,0,1,{A_Lower},S_CHAINDOWN,0,0},	// S_CHAINDOWN
+    {SPR_CHGG,0,1,{A_Raise},S_CHAINUP,0,0},	// S_CHAINUP
+    {SPR_CHGG,0,4,{A_FireCGun},S_CHAIN2,0,0},	// S_CHAIN1
+    {SPR_CHGG,1,4,{A_FireCGun},S_CHAIN3,0,0},	// S_CHAIN2
+    {SPR_CHGG,1,0,{A_ReFire},S_CHAIN,0,0},	// S_CHAIN3
+    {SPR_CHGF,32768,5,{A_Light1},S_LIGHTDONE,0,0},	// S_CHAINFLASH1
+    {SPR_CHGF,32769,5,{A_Light2},S_LIGHTDONE,0,0},	// S_CHAINFLASH2
+    {SPR_MISG,0,1,{A_WeaponReady},S_MISSILE,0,0},	// S_MISSILE
+    {SPR_MISG,0,1,{A_Lower},S_MISSILEDOWN,0,0},	// S_MISSILEDOWN
+    {SPR_MISG,0,1,{A_Raise},S_MISSILEUP,0,0},	// S_MISSILEUP
+    {SPR_MISG,1,8,{A_GunFlash},S_MISSILE2,0,0},	// S_MISSILE1
+    {SPR_MISG,1,12,{A_FireMissile},S_MISSILE3,0,0},	// S_MISSILE2
+    {SPR_MISG,1,0,{A_ReFire},S_MISSILE,0,0},	// S_MISSILE3
+    {SPR_MISF,32768,3,{A_Light1},S_MISSILEFLASH2,0,0},	// S_MISSILEFLASH1
+    {SPR_MISF,32769,4,{NULL},S_MISSILEFLASH3,0,0},	// S_MISSILEFLASH2
+    {SPR_MISF,32770,4,{A_Light2},S_MISSILEFLASH4,0,0},	// S_MISSILEFLASH3
+    {SPR_MISF,32771,4,{A_Light2},S_LIGHTDONE,0,0},	// S_MISSILEFLASH4
+    {SPR_SAWG,2,4,{A_WeaponReady},S_SAWB,0,0},	// S_SAW
+    {SPR_SAWG,3,4,{A_WeaponReady},S_SAW,0,0},	// S_SAWB
+    {SPR_SAWG,2,1,{A_Lower},S_SAWDOWN,0,0},	// S_SAWDOWN
+    {SPR_SAWG,2,1,{A_Raise},S_SAWUP,0,0},	// S_SAWUP
+    {SPR_SAWG,0,4,{A_Saw},S_SAW2,0,0},	// S_SAW1
+    {SPR_SAWG,1,4,{A_Saw},S_SAW3,0,0},	// S_SAW2
+    {SPR_SAWG,1,0,{A_ReFire},S_SAW,0,0},	// S_SAW3
+    {SPR_PLSG,0,1,{A_WeaponReady},S_PLASMA,0,0},	// S_PLASMA
+    {SPR_PLSG,0,1,{A_Lower},S_PLASMADOWN,0,0},	// S_PLASMADOWN
+    {SPR_PLSG,0,1,{A_Raise},S_PLASMAUP,0,0},	// S_PLASMAUP
+    {SPR_PLSG,0,3,{A_FirePlasma},S_PLASMA2,0,0},	// S_PLASMA1
+    {SPR_PLSG,1,20,{A_ReFire},S_PLASMA,0,0},	// S_PLASMA2
+    {SPR_PLSF,32768,4,{A_Light1},S_LIGHTDONE,0,0},	// S_PLASMAFLASH1
+    {SPR_PLSF,32769,4,{A_Light1},S_LIGHTDONE,0,0},	// S_PLASMAFLASH2
+    {SPR_BFGG,0,1,{A_WeaponReady},S_BFG,0,0},	// S_BFG
+    {SPR_BFGG,0,1,{A_Lower},S_BFGDOWN,0,0},	// S_BFGDOWN
+    {SPR_BFGG,0,1,{A_Raise},S_BFGUP,0,0},	// S_BFGUP
+    {SPR_BFGG,0,20,{A_BFGsound},S_BFG2,0,0},	// S_BFG1
+    {SPR_BFGG,1,10,{A_GunFlash},S_BFG3,0,0},	// S_BFG2
+    {SPR_BFGG,1,10,{A_FireBFG},S_BFG4,0,0},	// S_BFG3
+    {SPR_BFGG,1,20,{A_ReFire},S_BFG,0,0},	// S_BFG4
+    {SPR_BFGF,32768,11,{A_Light1},S_BFGFLASH2,0,0},	// S_BFGFLASH1
+    {SPR_BFGF,32769,6,{A_Light2},S_LIGHTDONE,0,0},	// S_BFGFLASH2
+    {SPR_BLUD,2,8,{NULL},S_BLOOD2,0,0},	// S_BLOOD1
+    {SPR_BLUD,1,8,{NULL},S_BLOOD3,0,0},	// S_BLOOD2
+    {SPR_BLUD,0,8,{NULL},S_NULL,0,0},	// S_BLOOD3
+    {SPR_PUFF,32768,4,{NULL},S_PUFF2,0,0},	// S_PUFF1
+    {SPR_PUFF,1,4,{NULL},S_PUFF3,0,0},	// S_PUFF2
+    {SPR_PUFF,2,4,{NULL},S_PUFF4,0,0},	// S_PUFF3
+    {SPR_PUFF,3,4,{NULL},S_NULL,0,0},	// S_PUFF4
+    {SPR_BAL1,32768,4,{NULL},S_TBALL2,0,0},	// S_TBALL1
+    {SPR_BAL1,32769,4,{NULL},S_TBALL1,0,0},	// S_TBALL2
+    {SPR_BAL1,32770,6,{NULL},S_TBALLX2,0,0},	// S_TBALLX1
+    {SPR_BAL1,32771,6,{NULL},S_TBALLX3,0,0},	// S_TBALLX2
+    {SPR_BAL1,32772,6,{NULL},S_NULL,0,0},	// S_TBALLX3
+    {SPR_BAL2,32768,4,{NULL},S_RBALL2,0,0},	// S_RBALL1
+    {SPR_BAL2,32769,4,{NULL},S_RBALL1,0,0},	// S_RBALL2
+    {SPR_BAL2,32770,6,{NULL},S_RBALLX2,0,0},	// S_RBALLX1
+    {SPR_BAL2,32771,6,{NULL},S_RBALLX3,0,0},	// S_RBALLX2
+    {SPR_BAL2,32772,6,{NULL},S_NULL,0,0},	// S_RBALLX3
+    {SPR_PLSS,32768,6,{NULL},S_PLASBALL2,0,0},	// S_PLASBALL
+    {SPR_PLSS,32769,6,{NULL},S_PLASBALL,0,0},	// S_PLASBALL2
+    {SPR_PLSE,32768,4,{NULL},S_PLASEXP2,0,0},	// S_PLASEXP
+    {SPR_PLSE,32769,4,{NULL},S_PLASEXP3,0,0},	// S_PLASEXP2
+    {SPR_PLSE,32770,4,{NULL},S_PLASEXP4,0,0},	// S_PLASEXP3
+    {SPR_PLSE,32771,4,{NULL},S_PLASEXP5,0,0},	// S_PLASEXP4
+    {SPR_PLSE,32772,4,{NULL},S_NULL,0,0},	// S_PLASEXP5
+    {SPR_MISL,32768,1,{NULL},S_ROCKET,0,0},	// S_ROCKET
+    {SPR_BFS1,32768,4,{NULL},S_BFGSHOT2,0,0},	// S_BFGSHOT
+    {SPR_BFS1,32769,4,{NULL},S_BFGSHOT,0,0},	// S_BFGSHOT2
+    {SPR_BFE1,32768,8,{NULL},S_BFGLAND2,0,0},	// S_BFGLAND
+    {SPR_BFE1,32769,8,{NULL},S_BFGLAND3,0,0},	// S_BFGLAND2
+    {SPR_BFE1,32770,8,{A_BFGSpray},S_BFGLAND4,0,0},	// S_BFGLAND3
+    {SPR_BFE1,32771,8,{NULL},S_BFGLAND5,0,0},	// S_BFGLAND4
+    {SPR_BFE1,32772,8,{NULL},S_BFGLAND6,0,0},	// S_BFGLAND5
+    {SPR_BFE1,32773,8,{NULL},S_NULL,0,0},	// S_BFGLAND6
+    {SPR_BFE2,32768,8,{NULL},S_BFGEXP2,0,0},	// S_BFGEXP
+    {SPR_BFE2,32769,8,{NULL},S_BFGEXP3,0,0},	// S_BFGEXP2
+    {SPR_BFE2,32770,8,{NULL},S_BFGEXP4,0,0},	// S_BFGEXP3
+    {SPR_BFE2,32771,8,{NULL},S_NULL,0,0},	// S_BFGEXP4
+    {SPR_MISL,32769,8,{A_Explode},S_EXPLODE2,0,0},	// S_EXPLODE1
+    {SPR_MISL,32770,6,{NULL},S_EXPLODE3,0,0},	// S_EXPLODE2
+    {SPR_MISL,32771,4,{NULL},S_NULL,0,0},	// S_EXPLODE3
+    {SPR_TFOG,32768,6,{NULL},S_TFOG01,0,0},	// S_TFOG
+    {SPR_TFOG,32769,6,{NULL},S_TFOG02,0,0},	// S_TFOG01
+    {SPR_TFOG,32768,6,{NULL},S_TFOG2,0,0},	// S_TFOG02
+    {SPR_TFOG,32769,6,{NULL},S_TFOG3,0,0},	// S_TFOG2
+    {SPR_TFOG,32770,6,{NULL},S_TFOG4,0,0},	// S_TFOG3
+    {SPR_TFOG,32771,6,{NULL},S_TFOG5,0,0},	// S_TFOG4
+    {SPR_TFOG,32772,6,{NULL},S_TFOG6,0,0},	// S_TFOG5
+    {SPR_TFOG,32773,6,{NULL},S_TFOG7,0,0},	// S_TFOG6
+    {SPR_TFOG,32774,6,{NULL},S_TFOG8,0,0},	// S_TFOG7
+    {SPR_TFOG,32775,6,{NULL},S_TFOG9,0,0},	// S_TFOG8
+    {SPR_TFOG,32776,6,{NULL},S_TFOG10,0,0},	// S_TFOG9
+    {SPR_TFOG,32777,6,{NULL},S_NULL,0,0},	// S_TFOG10
+    {SPR_IFOG,32768,6,{NULL},S_IFOG01,0,0},	// S_IFOG
+    {SPR_IFOG,32769,6,{NULL},S_IFOG02,0,0},	// S_IFOG01
+    {SPR_IFOG,32768,6,{NULL},S_IFOG2,0,0},	// S_IFOG02
+    {SPR_IFOG,32769,6,{NULL},S_IFOG3,0,0},	// S_IFOG2
+    {SPR_IFOG,32770,6,{NULL},S_IFOG4,0,0},	// S_IFOG3
+    {SPR_IFOG,32771,6,{NULL},S_IFOG5,0,0},	// S_IFOG4
+    {SPR_IFOG,32772,6,{NULL},S_NULL,0,0},	// S_IFOG5
+    {SPR_PLAY,0,-1,{NULL},S_NULL,0,0},	// S_PLAY
+    {SPR_PLAY,0,4,{NULL},S_PLAY_RUN2,0,0},	// S_PLAY_RUN1
+    {SPR_PLAY,1,4,{NULL},S_PLAY_RUN3,0,0},	// S_PLAY_RUN2
+    {SPR_PLAY,2,4,{NULL},S_PLAY_RUN4,0,0},	// S_PLAY_RUN3
+    {SPR_PLAY,3,4,{NULL},S_PLAY_RUN1,0,0},	// S_PLAY_RUN4
+    {SPR_PLAY,4,12,{NULL},S_PLAY,0,0},	// S_PLAY_ATK1
+    {SPR_PLAY,32773,6,{NULL},S_PLAY_ATK1,0,0},	// S_PLAY_ATK2
+    {SPR_PLAY,6,4,{NULL},S_PLAY_PAIN2,0,0},	// S_PLAY_PAIN
+    {SPR_PLAY,6,4,{A_Pain},S_PLAY,0,0},	// S_PLAY_PAIN2
+    {SPR_PLAY,7,10,{NULL},S_PLAY_DIE2,0,0},	// S_PLAY_DIE1
+    {SPR_PLAY,8,10,{A_PlayerScream},S_PLAY_DIE3,0,0},	// S_PLAY_DIE2
+    {SPR_PLAY,9,10,{A_Fall},S_PLAY_DIE4,0,0},	// S_PLAY_DIE3
+    {SPR_PLAY,10,10,{NULL},S_PLAY_DIE5,0,0},	// S_PLAY_DIE4
+    {SPR_PLAY,11,10,{NULL},S_PLAY_DIE6,0,0},	// S_PLAY_DIE5
+    {SPR_PLAY,12,10,{NULL},S_PLAY_DIE7,0,0},	// S_PLAY_DIE6
+    {SPR_PLAY,13,-1,{NULL},S_NULL,0,0},	// S_PLAY_DIE7
+    {SPR_PLAY,14,5,{NULL},S_PLAY_XDIE2,0,0},	// S_PLAY_XDIE1
+    {SPR_PLAY,15,5,{A_XScream},S_PLAY_XDIE3,0,0},	// S_PLAY_XDIE2
+    {SPR_PLAY,16,5,{A_Fall},S_PLAY_XDIE4,0,0},	// S_PLAY_XDIE3
+    {SPR_PLAY,17,5,{NULL},S_PLAY_XDIE5,0,0},	// S_PLAY_XDIE4
+    {SPR_PLAY,18,5,{NULL},S_PLAY_XDIE6,0,0},	// S_PLAY_XDIE5
+    {SPR_PLAY,19,5,{NULL},S_PLAY_XDIE7,0,0},	// S_PLAY_XDIE6
+    {SPR_PLAY,20,5,{NULL},S_PLAY_XDIE8,0,0},	// S_PLAY_XDIE7
+    {SPR_PLAY,21,5,{NULL},S_PLAY_XDIE9,0,0},	// S_PLAY_XDIE8
+    {SPR_PLAY,22,-1,{NULL},S_NULL,0,0},	// S_PLAY_XDIE9
+    {SPR_POSS,0,10,{A_Look},S_POSS_STND2,0,0},	// S_POSS_STND
+    {SPR_POSS,1,10,{A_Look},S_POSS_STND,0,0},	// S_POSS_STND2
+    {SPR_POSS,0,4,{A_Chase},S_POSS_RUN2,0,0},	// S_POSS_RUN1
+    {SPR_POSS,0,4,{A_Chase},S_POSS_RUN3,0,0},	// S_POSS_RUN2
+    {SPR_POSS,1,4,{A_Chase},S_POSS_RUN4,0,0},	// S_POSS_RUN3
+    {SPR_POSS,1,4,{A_Chase},S_POSS_RUN5,0,0},	// S_POSS_RUN4
+    {SPR_POSS,2,4,{A_Chase},S_POSS_RUN6,0,0},	// S_POSS_RUN5
+    {SPR_POSS,2,4,{A_Chase},S_POSS_RUN7,0,0},	// S_POSS_RUN6
+    {SPR_POSS,3,4,{A_Chase},S_POSS_RUN8,0,0},	// S_POSS_RUN7
+    {SPR_POSS,3,4,{A_Chase},S_POSS_RUN1,0,0},	// S_POSS_RUN8
+    {SPR_POSS,4,10,{A_FaceTarget},S_POSS_ATK2,0,0},	// S_POSS_ATK1
+    {SPR_POSS,5,8,{A_PosAttack},S_POSS_ATK3,0,0},	// S_POSS_ATK2
+    {SPR_POSS,4,8,{NULL},S_POSS_RUN1,0,0},	// S_POSS_ATK3
+    {SPR_POSS,6,3,{NULL},S_POSS_PAIN2,0,0},	// S_POSS_PAIN
+    {SPR_POSS,6,3,{A_Pain},S_POSS_RUN1,0,0},	// S_POSS_PAIN2
+    {SPR_POSS,7,5,{NULL},S_POSS_DIE2,0,0},	// S_POSS_DIE1
+    {SPR_POSS,8,5,{A_Scream},S_POSS_DIE3,0,0},	// S_POSS_DIE2
+    {SPR_POSS,9,5,{A_Fall},S_POSS_DIE4,0,0},	// S_POSS_DIE3
+    {SPR_POSS,10,5,{NULL},S_POSS_DIE5,0,0},	// S_POSS_DIE4
+    {SPR_POSS,11,-1,{NULL},S_NULL,0,0},	// S_POSS_DIE5
+    {SPR_POSS,12,5,{NULL},S_POSS_XDIE2,0,0},	// S_POSS_XDIE1
+    {SPR_POSS,13,5,{A_XScream},S_POSS_XDIE3,0,0},	// S_POSS_XDIE2
+    {SPR_POSS,14,5,{A_Fall},S_POSS_XDIE4,0,0},	// S_POSS_XDIE3
+    {SPR_POSS,15,5,{NULL},S_POSS_XDIE5,0,0},	// S_POSS_XDIE4
+    {SPR_POSS,16,5,{NULL},S_POSS_XDIE6,0,0},	// S_POSS_XDIE5
+    {SPR_POSS,17,5,{NULL},S_POSS_XDIE7,0,0},	// S_POSS_XDIE6
+    {SPR_POSS,18,5,{NULL},S_POSS_XDIE8,0,0},	// S_POSS_XDIE7
+    {SPR_POSS,19,5,{NULL},S_POSS_XDIE9,0,0},	// S_POSS_XDIE8
+    {SPR_POSS,20,-1,{NULL},S_NULL,0,0},	// S_POSS_XDIE9
+    {SPR_POSS,10,5,{NULL},S_POSS_RAISE2,0,0},	// S_POSS_RAISE1
+    {SPR_POSS,9,5,{NULL},S_POSS_RAISE3,0,0},	// S_POSS_RAISE2
+    {SPR_POSS,8,5,{NULL},S_POSS_RAISE4,0,0},	// S_POSS_RAISE3
+    {SPR_POSS,7,5,{NULL},S_POSS_RUN1,0,0},	// S_POSS_RAISE4
+    {SPR_SPOS,0,10,{A_Look},S_SPOS_STND2,0,0},	// S_SPOS_STND
+    {SPR_SPOS,1,10,{A_Look},S_SPOS_STND,0,0},	// S_SPOS_STND2
+    {SPR_SPOS,0,3,{A_Chase},S_SPOS_RUN2,0,0},	// S_SPOS_RUN1
+    {SPR_SPOS,0,3,{A_Chase},S_SPOS_RUN3,0,0},	// S_SPOS_RUN2
+    {SPR_SPOS,1,3,{A_Chase},S_SPOS_RUN4,0,0},	// S_SPOS_RUN3
+    {SPR_SPOS,1,3,{A_Chase},S_SPOS_RUN5,0,0},	// S_SPOS_RUN4
+    {SPR_SPOS,2,3,{A_Chase},S_SPOS_RUN6,0,0},	// S_SPOS_RUN5
+    {SPR_SPOS,2,3,{A_Chase},S_SPOS_RUN7,0,0},	// S_SPOS_RUN6
+    {SPR_SPOS,3,3,{A_Chase},S_SPOS_RUN8,0,0},	// S_SPOS_RUN7
+    {SPR_SPOS,3,3,{A_Chase},S_SPOS_RUN1,0,0},	// S_SPOS_RUN8
+    {SPR_SPOS,4,10,{A_FaceTarget},S_SPOS_ATK2,0,0},	// S_SPOS_ATK1
+    {SPR_SPOS,32773,10,{A_SPosAttack},S_SPOS_ATK3,0,0},	// S_SPOS_ATK2
+    {SPR_SPOS,4,10,{NULL},S_SPOS_RUN1,0,0},	// S_SPOS_ATK3
+    {SPR_SPOS,6,3,{NULL},S_SPOS_PAIN2,0,0},	// S_SPOS_PAIN
+    {SPR_SPOS,6,3,{A_Pain},S_SPOS_RUN1,0,0},	// S_SPOS_PAIN2
+    {SPR_SPOS,7,5,{NULL},S_SPOS_DIE2,0,0},	// S_SPOS_DIE1
+    {SPR_SPOS,8,5,{A_Scream},S_SPOS_DIE3,0,0},	// S_SPOS_DIE2
+    {SPR_SPOS,9,5,{A_Fall},S_SPOS_DIE4,0,0},	// S_SPOS_DIE3
+    {SPR_SPOS,10,5,{NULL},S_SPOS_DIE5,0,0},	// S_SPOS_DIE4
+    {SPR_SPOS,11,-1,{NULL},S_NULL,0,0},	// S_SPOS_DIE5
+    {SPR_SPOS,12,5,{NULL},S_SPOS_XDIE2,0,0},	// S_SPOS_XDIE1
+    {SPR_SPOS,13,5,{A_XScream},S_SPOS_XDIE3,0,0},	// S_SPOS_XDIE2
+    {SPR_SPOS,14,5,{A_Fall},S_SPOS_XDIE4,0,0},	// S_SPOS_XDIE3
+    {SPR_SPOS,15,5,{NULL},S_SPOS_XDIE5,0,0},	// S_SPOS_XDIE4
+    {SPR_SPOS,16,5,{NULL},S_SPOS_XDIE6,0,0},	// S_SPOS_XDIE5
+    {SPR_SPOS,17,5,{NULL},S_SPOS_XDIE7,0,0},	// S_SPOS_XDIE6
+    {SPR_SPOS,18,5,{NULL},S_SPOS_XDIE8,0,0},	// S_SPOS_XDIE7
+    {SPR_SPOS,19,5,{NULL},S_SPOS_XDIE9,0,0},	// S_SPOS_XDIE8
+    {SPR_SPOS,20,-1,{NULL},S_NULL,0,0},	// S_SPOS_XDIE9
+    {SPR_SPOS,11,5,{NULL},S_SPOS_RAISE2,0,0},	// S_SPOS_RAISE1
+    {SPR_SPOS,10,5,{NULL},S_SPOS_RAISE3,0,0},	// S_SPOS_RAISE2
+    {SPR_SPOS,9,5,{NULL},S_SPOS_RAISE4,0,0},	// S_SPOS_RAISE3
+    {SPR_SPOS,8,5,{NULL},S_SPOS_RAISE5,0,0},	// S_SPOS_RAISE4
+    {SPR_SPOS,7,5,{NULL},S_SPOS_RUN1,0,0},	// S_SPOS_RAISE5
+    {SPR_VILE,0,10,{A_Look},S_VILE_STND2,0,0},	// S_VILE_STND
+    {SPR_VILE,1,10,{A_Look},S_VILE_STND,0,0},	// S_VILE_STND2
+    {SPR_VILE,0,2,{A_VileChase},S_VILE_RUN2,0,0},	// S_VILE_RUN1
+    {SPR_VILE,0,2,{A_VileChase},S_VILE_RUN3,0,0},	// S_VILE_RUN2
+    {SPR_VILE,1,2,{A_VileChase},S_VILE_RUN4,0,0},	// S_VILE_RUN3
+    {SPR_VILE,1,2,{A_VileChase},S_VILE_RUN5,0,0},	// S_VILE_RUN4
+    {SPR_VILE,2,2,{A_VileChase},S_VILE_RUN6,0,0},	// S_VILE_RUN5
+    {SPR_VILE,2,2,{A_VileChase},S_VILE_RUN7,0,0},	// S_VILE_RUN6
+    {SPR_VILE,3,2,{A_VileChase},S_VILE_RUN8,0,0},	// S_VILE_RUN7
+    {SPR_VILE,3,2,{A_VileChase},S_VILE_RUN9,0,0},	// S_VILE_RUN8
+    {SPR_VILE,4,2,{A_VileChase},S_VILE_RUN10,0,0},	// S_VILE_RUN9
+    {SPR_VILE,4,2,{A_VileChase},S_VILE_RUN11,0,0},	// S_VILE_RUN10
+    {SPR_VILE,5,2,{A_VileChase},S_VILE_RUN12,0,0},	// S_VILE_RUN11
+    {SPR_VILE,5,2,{A_VileChase},S_VILE_RUN1,0,0},	// S_VILE_RUN12
+    {SPR_VILE,32774,0,{A_VileStart},S_VILE_ATK2,0,0},	// S_VILE_ATK1
+    {SPR_VILE,32774,10,{A_FaceTarget},S_VILE_ATK3,0,0},	// S_VILE_ATK2
+    {SPR_VILE,32775,8,{A_VileTarget},S_VILE_ATK4,0,0},	// S_VILE_ATK3
+    {SPR_VILE,32776,8,{A_FaceTarget},S_VILE_ATK5,0,0},	// S_VILE_ATK4
+    {SPR_VILE,32777,8,{A_FaceTarget},S_VILE_ATK6,0,0},	// S_VILE_ATK5
+    {SPR_VILE,32778,8,{A_FaceTarget},S_VILE_ATK7,0,0},	// S_VILE_ATK6
+    {SPR_VILE,32779,8,{A_FaceTarget},S_VILE_ATK8,0,0},	// S_VILE_ATK7
+    {SPR_VILE,32780,8,{A_FaceTarget},S_VILE_ATK9,0,0},	// S_VILE_ATK8
+    {SPR_VILE,32781,8,{A_FaceTarget},S_VILE_ATK10,0,0},	// S_VILE_ATK9
+    {SPR_VILE,32782,8,{A_VileAttack},S_VILE_ATK11,0,0},	// S_VILE_ATK10
+    {SPR_VILE,32783,20,{NULL},S_VILE_RUN1,0,0},	// S_VILE_ATK11
+    {SPR_VILE,32794,10,{NULL},S_VILE_HEAL2,0,0},	// S_VILE_HEAL1
+    {SPR_VILE,32795,10,{NULL},S_VILE_HEAL3,0,0},	// S_VILE_HEAL2
+    {SPR_VILE,32796,10,{NULL},S_VILE_RUN1,0,0},	// S_VILE_HEAL3
+    {SPR_VILE,16,5,{NULL},S_VILE_PAIN2,0,0},	// S_VILE_PAIN
+    {SPR_VILE,16,5,{A_Pain},S_VILE_RUN1,0,0},	// S_VILE_PAIN2
+    {SPR_VILE,16,7,{NULL},S_VILE_DIE2,0,0},	// S_VILE_DIE1
+    {SPR_VILE,17,7,{A_Scream},S_VILE_DIE3,0,0},	// S_VILE_DIE2
+    {SPR_VILE,18,7,{A_Fall},S_VILE_DIE4,0,0},	// S_VILE_DIE3
+    {SPR_VILE,19,7,{NULL},S_VILE_DIE5,0,0},	// S_VILE_DIE4
+    {SPR_VILE,20,7,{NULL},S_VILE_DIE6,0,0},	// S_VILE_DIE5
+    {SPR_VILE,21,7,{NULL},S_VILE_DIE7,0,0},	// S_VILE_DIE6
+    {SPR_VILE,22,7,{NULL},S_VILE_DIE8,0,0},	// S_VILE_DIE7
+    {SPR_VILE,23,5,{NULL},S_VILE_DIE9,0,0},	// S_VILE_DIE8
+    {SPR_VILE,24,5,{NULL},S_VILE_DIE10,0,0},	// S_VILE_DIE9
+    {SPR_VILE,25,-1,{NULL},S_NULL,0,0},	// S_VILE_DIE10
+    {SPR_FIRE,32768,2,{A_StartFire},S_FIRE2,0,0},	// S_FIRE1
+    {SPR_FIRE,32769,2,{A_Fire},S_FIRE3,0,0},	// S_FIRE2
+    {SPR_FIRE,32768,2,{A_Fire},S_FIRE4,0,0},	// S_FIRE3
+    {SPR_FIRE,32769,2,{A_Fire},S_FIRE5,0,0},	// S_FIRE4
+    {SPR_FIRE,32770,2,{A_FireCrackle},S_FIRE6,0,0},	// S_FIRE5
+    {SPR_FIRE,32769,2,{A_Fire},S_FIRE7,0,0},	// S_FIRE6
+    {SPR_FIRE,32770,2,{A_Fire},S_FIRE8,0,0},	// S_FIRE7
+    {SPR_FIRE,32769,2,{A_Fire},S_FIRE9,0,0},	// S_FIRE8
+    {SPR_FIRE,32770,2,{A_Fire},S_FIRE10,0,0},	// S_FIRE9
+    {SPR_FIRE,32771,2,{A_Fire},S_FIRE11,0,0},	// S_FIRE10
+    {SPR_FIRE,32770,2,{A_Fire},S_FIRE12,0,0},	// S_FIRE11
+    {SPR_FIRE,32771,2,{A_Fire},S_FIRE13,0,0},	// S_FIRE12
+    {SPR_FIRE,32770,2,{A_Fire},S_FIRE14,0,0},	// S_FIRE13
+    {SPR_FIRE,32771,2,{A_Fire},S_FIRE15,0,0},	// S_FIRE14
+    {SPR_FIRE,32772,2,{A_Fire},S_FIRE16,0,0},	// S_FIRE15
+    {SPR_FIRE,32771,2,{A_Fire},S_FIRE17,0,0},	// S_FIRE16
+    {SPR_FIRE,32772,2,{A_Fire},S_FIRE18,0,0},	// S_FIRE17
+    {SPR_FIRE,32771,2,{A_Fire},S_FIRE19,0,0},	// S_FIRE18
+    {SPR_FIRE,32772,2,{A_FireCrackle},S_FIRE20,0,0},	// S_FIRE19
+    {SPR_FIRE,32773,2,{A_Fire},S_FIRE21,0,0},	// S_FIRE20
+    {SPR_FIRE,32772,2,{A_Fire},S_FIRE22,0,0},	// S_FIRE21
+    {SPR_FIRE,32773,2,{A_Fire},S_FIRE23,0,0},	// S_FIRE22
+    {SPR_FIRE,32772,2,{A_Fire},S_FIRE24,0,0},	// S_FIRE23
+    {SPR_FIRE,32773,2,{A_Fire},S_FIRE25,0,0},	// S_FIRE24
+    {SPR_FIRE,32774,2,{A_Fire},S_FIRE26,0,0},	// S_FIRE25
+    {SPR_FIRE,32775,2,{A_Fire},S_FIRE27,0,0},	// S_FIRE26
+    {SPR_FIRE,32774,2,{A_Fire},S_FIRE28,0,0},	// S_FIRE27
+    {SPR_FIRE,32775,2,{A_Fire},S_FIRE29,0,0},	// S_FIRE28
+    {SPR_FIRE,32774,2,{A_Fire},S_FIRE30,0,0},	// S_FIRE29
+    {SPR_FIRE,32775,2,{A_Fire},S_NULL,0,0},	// S_FIRE30
+    {SPR_PUFF,1,4,{NULL},S_SMOKE2,0,0},	// S_SMOKE1
+    {SPR_PUFF,2,4,{NULL},S_SMOKE3,0,0},	// S_SMOKE2
+    {SPR_PUFF,1,4,{NULL},S_SMOKE4,0,0},	// S_SMOKE3
+    {SPR_PUFF,2,4,{NULL},S_SMOKE5,0,0},	// S_SMOKE4
+    {SPR_PUFF,3,4,{NULL},S_NULL,0,0},	// S_SMOKE5
+    {SPR_FATB,32768,2,{A_Tracer},S_TRACER2,0,0},	// S_TRACER
+    {SPR_FATB,32769,2,{A_Tracer},S_TRACER,0,0},	// S_TRACER2
+    {SPR_FBXP,32768,8,{NULL},S_TRACEEXP2,0,0},	// S_TRACEEXP1
+    {SPR_FBXP,32769,6,{NULL},S_TRACEEXP3,0,0},	// S_TRACEEXP2
+    {SPR_FBXP,32770,4,{NULL},S_NULL,0,0},	// S_TRACEEXP3
+    {SPR_SKEL,0,10,{A_Look},S_SKEL_STND2,0,0},	// S_SKEL_STND
+    {SPR_SKEL,1,10,{A_Look},S_SKEL_STND,0,0},	// S_SKEL_STND2
+    {SPR_SKEL,0,2,{A_Chase},S_SKEL_RUN2,0,0},	// S_SKEL_RUN1
+    {SPR_SKEL,0,2,{A_Chase},S_SKEL_RUN3,0,0},	// S_SKEL_RUN2
+    {SPR_SKEL,1,2,{A_Chase},S_SKEL_RUN4,0,0},	// S_SKEL_RUN3
+    {SPR_SKEL,1,2,{A_Chase},S_SKEL_RUN5,0,0},	// S_SKEL_RUN4
+    {SPR_SKEL,2,2,{A_Chase},S_SKEL_RUN6,0,0},	// S_SKEL_RUN5
+    {SPR_SKEL,2,2,{A_Chase},S_SKEL_RUN7,0,0},	// S_SKEL_RUN6
+    {SPR_SKEL,3,2,{A_Chase},S_SKEL_RUN8,0,0},	// S_SKEL_RUN7
+    {SPR_SKEL,3,2,{A_Chase},S_SKEL_RUN9,0,0},	// S_SKEL_RUN8
+    {SPR_SKEL,4,2,{A_Chase},S_SKEL_RUN10,0,0},	// S_SKEL_RUN9
+    {SPR_SKEL,4,2,{A_Chase},S_SKEL_RUN11,0,0},	// S_SKEL_RUN10
+    {SPR_SKEL,5,2,{A_Chase},S_SKEL_RUN12,0,0},	// S_SKEL_RUN11
+    {SPR_SKEL,5,2,{A_Chase},S_SKEL_RUN1,0,0},	// S_SKEL_RUN12
+    {SPR_SKEL,6,0,{A_FaceTarget},S_SKEL_FIST2,0,0},	// S_SKEL_FIST1
+    {SPR_SKEL,6,6,{A_SkelWhoosh},S_SKEL_FIST3,0,0},	// S_SKEL_FIST2
+    {SPR_SKEL,7,6,{A_FaceTarget},S_SKEL_FIST4,0,0},	// S_SKEL_FIST3
+    {SPR_SKEL,8,6,{A_SkelFist},S_SKEL_RUN1,0,0},	// S_SKEL_FIST4
+    {SPR_SKEL,32777,0,{A_FaceTarget},S_SKEL_MISS2,0,0},	// S_SKEL_MISS1
+    {SPR_SKEL,32777,10,{A_FaceTarget},S_SKEL_MISS3,0,0},	// S_SKEL_MISS2
+    {SPR_SKEL,10,10,{A_SkelMissile},S_SKEL_MISS4,0,0},	// S_SKEL_MISS3
+    {SPR_SKEL,10,10,{A_FaceTarget},S_SKEL_RUN1,0,0},	// S_SKEL_MISS4
+    {SPR_SKEL,11,5,{NULL},S_SKEL_PAIN2,0,0},	// S_SKEL_PAIN
+    {SPR_SKEL,11,5,{A_Pain},S_SKEL_RUN1,0,0},	// S_SKEL_PAIN2
+    {SPR_SKEL,11,7,{NULL},S_SKEL_DIE2,0,0},	// S_SKEL_DIE1
+    {SPR_SKEL,12,7,{NULL},S_SKEL_DIE3,0,0},	// S_SKEL_DIE2
+    {SPR_SKEL,13,7,{A_Scream},S_SKEL_DIE4,0,0},	// S_SKEL_DIE3
+    {SPR_SKEL,14,7,{A_Fall},S_SKEL_DIE5,0,0},	// S_SKEL_DIE4
+    {SPR_SKEL,15,7,{NULL},S_SKEL_DIE6,0,0},	// S_SKEL_DIE5
+    {SPR_SKEL,16,-1,{NULL},S_NULL,0,0},	// S_SKEL_DIE6
+    {SPR_SKEL,16,5,{NULL},S_SKEL_RAISE2,0,0},	// S_SKEL_RAISE1
+    {SPR_SKEL,15,5,{NULL},S_SKEL_RAISE3,0,0},	// S_SKEL_RAISE2
+    {SPR_SKEL,14,5,{NULL},S_SKEL_RAISE4,0,0},	// S_SKEL_RAISE3
+    {SPR_SKEL,13,5,{NULL},S_SKEL_RAISE5,0,0},	// S_SKEL_RAISE4
+    {SPR_SKEL,12,5,{NULL},S_SKEL_RAISE6,0,0},	// S_SKEL_RAISE5
+    {SPR_SKEL,11,5,{NULL},S_SKEL_RUN1,0,0},	// S_SKEL_RAISE6
+    {SPR_MANF,32768,4,{NULL},S_FATSHOT2,0,0},	// S_FATSHOT1
+    {SPR_MANF,32769,4,{NULL},S_FATSHOT1,0,0},	// S_FATSHOT2
+    {SPR_MISL,32769,8,{NULL},S_FATSHOTX2,0,0},	// S_FATSHOTX1
+    {SPR_MISL,32770,6,{NULL},S_FATSHOTX3,0,0},	// S_FATSHOTX2
+    {SPR_MISL,32771,4,{NULL},S_NULL,0,0},	// S_FATSHOTX3
+    {SPR_FATT,0,15,{A_Look},S_FATT_STND2,0,0},	// S_FATT_STND
+    {SPR_FATT,1,15,{A_Look},S_FATT_STND,0,0},	// S_FATT_STND2
+    {SPR_FATT,0,4,{A_Chase},S_FATT_RUN2,0,0},	// S_FATT_RUN1
+    {SPR_FATT,0,4,{A_Chase},S_FATT_RUN3,0,0},	// S_FATT_RUN2
+    {SPR_FATT,1,4,{A_Chase},S_FATT_RUN4,0,0},	// S_FATT_RUN3
+    {SPR_FATT,1,4,{A_Chase},S_FATT_RUN5,0,0},	// S_FATT_RUN4
+    {SPR_FATT,2,4,{A_Chase},S_FATT_RUN6,0,0},	// S_FATT_RUN5
+    {SPR_FATT,2,4,{A_Chase},S_FATT_RUN7,0,0},	// S_FATT_RUN6
+    {SPR_FATT,3,4,{A_Chase},S_FATT_RUN8,0,0},	// S_FATT_RUN7
+    {SPR_FATT,3,4,{A_Chase},S_FATT_RUN9,0,0},	// S_FATT_RUN8
+    {SPR_FATT,4,4,{A_Chase},S_FATT_RUN10,0,0},	// S_FATT_RUN9
+    {SPR_FATT,4,4,{A_Chase},S_FATT_RUN11,0,0},	// S_FATT_RUN10
+    {SPR_FATT,5,4,{A_Chase},S_FATT_RUN12,0,0},	// S_FATT_RUN11
+    {SPR_FATT,5,4,{A_Chase},S_FATT_RUN1,0,0},	// S_FATT_RUN12
+    {SPR_FATT,6,20,{A_FatRaise},S_FATT_ATK2,0,0},	// S_FATT_ATK1
+    {SPR_FATT,32775,10,{A_FatAttack1},S_FATT_ATK3,0,0},	// S_FATT_ATK2
+    {SPR_FATT,8,5,{A_FaceTarget},S_FATT_ATK4,0,0},	// S_FATT_ATK3
+    {SPR_FATT,6,5,{A_FaceTarget},S_FATT_ATK5,0,0},	// S_FATT_ATK4
+    {SPR_FATT,32775,10,{A_FatAttack2},S_FATT_ATK6,0,0},	// S_FATT_ATK5
+    {SPR_FATT,8,5,{A_FaceTarget},S_FATT_ATK7,0,0},	// S_FATT_ATK6
+    {SPR_FATT,6,5,{A_FaceTarget},S_FATT_ATK8,0,0},	// S_FATT_ATK7
+    {SPR_FATT,32775,10,{A_FatAttack3},S_FATT_ATK9,0,0},	// S_FATT_ATK8
+    {SPR_FATT,8,5,{A_FaceTarget},S_FATT_ATK10,0,0},	// S_FATT_ATK9
+    {SPR_FATT,6,5,{A_FaceTarget},S_FATT_RUN1,0,0},	// S_FATT_ATK10
+    {SPR_FATT,9,3,{NULL},S_FATT_PAIN2,0,0},	// S_FATT_PAIN
+    {SPR_FATT,9,3,{A_Pain},S_FATT_RUN1,0,0},	// S_FATT_PAIN2
+    {SPR_FATT,10,6,{NULL},S_FATT_DIE2,0,0},	// S_FATT_DIE1
+    {SPR_FATT,11,6,{A_Scream},S_FATT_DIE3,0,0},	// S_FATT_DIE2
+    {SPR_FATT,12,6,{A_Fall},S_FATT_DIE4,0,0},	// S_FATT_DIE3
+    {SPR_FATT,13,6,{NULL},S_FATT_DIE5,0,0},	// S_FATT_DIE4
+    {SPR_FATT,14,6,{NULL},S_FATT_DIE6,0,0},	// S_FATT_DIE5
+    {SPR_FATT,15,6,{NULL},S_FATT_DIE7,0,0},	// S_FATT_DIE6
+    {SPR_FATT,16,6,{NULL},S_FATT_DIE8,0,0},	// S_FATT_DIE7
+    {SPR_FATT,17,6,{NULL},S_FATT_DIE9,0,0},	// S_FATT_DIE8
+    {SPR_FATT,18,6,{NULL},S_FATT_DIE10,0,0},	// S_FATT_DIE9
+    {SPR_FATT,19,-1,{A_BossDeath},S_NULL,0,0},	// S_FATT_DIE10
+    {SPR_FATT,17,5,{NULL},S_FATT_RAISE2,0,0},	// S_FATT_RAISE1
+    {SPR_FATT,16,5,{NULL},S_FATT_RAISE3,0,0},	// S_FATT_RAISE2
+    {SPR_FATT,15,5,{NULL},S_FATT_RAISE4,0,0},	// S_FATT_RAISE3
+    {SPR_FATT,14,5,{NULL},S_FATT_RAISE5,0,0},	// S_FATT_RAISE4
+    {SPR_FATT,13,5,{NULL},S_FATT_RAISE6,0,0},	// S_FATT_RAISE5
+    {SPR_FATT,12,5,{NULL},S_FATT_RAISE7,0,0},	// S_FATT_RAISE6
+    {SPR_FATT,11,5,{NULL},S_FATT_RAISE8,0,0},	// S_FATT_RAISE7
+    {SPR_FATT,10,5,{NULL},S_FATT_RUN1,0,0},	// S_FATT_RAISE8
+    {SPR_CPOS,0,10,{A_Look},S_CPOS_STND2,0,0},	// S_CPOS_STND
+    {SPR_CPOS,1,10,{A_Look},S_CPOS_STND,0,0},	// S_CPOS_STND2
+    {SPR_CPOS,0,3,{A_Chase},S_CPOS_RUN2,0,0},	// S_CPOS_RUN1
+    {SPR_CPOS,0,3,{A_Chase},S_CPOS_RUN3,0,0},	// S_CPOS_RUN2
+    {SPR_CPOS,1,3,{A_Chase},S_CPOS_RUN4,0,0},	// S_CPOS_RUN3
+    {SPR_CPOS,1,3,{A_Chase},S_CPOS_RUN5,0,0},	// S_CPOS_RUN4
+    {SPR_CPOS,2,3,{A_Chase},S_CPOS_RUN6,0,0},	// S_CPOS_RUN5
+    {SPR_CPOS,2,3,{A_Chase},S_CPOS_RUN7,0,0},	// S_CPOS_RUN6
+    {SPR_CPOS,3,3,{A_Chase},S_CPOS_RUN8,0,0},	// S_CPOS_RUN7
+    {SPR_CPOS,3,3,{A_Chase},S_CPOS_RUN1,0,0},	// S_CPOS_RUN8
+    {SPR_CPOS,4,10,{A_FaceTarget},S_CPOS_ATK2,0,0},	// S_CPOS_ATK1
+    {SPR_CPOS,32773,4,{A_CPosAttack},S_CPOS_ATK3,0,0},	// S_CPOS_ATK2
+    {SPR_CPOS,32772,4,{A_CPosAttack},S_CPOS_ATK4,0,0},	// S_CPOS_ATK3
+    {SPR_CPOS,5,1,{A_CPosRefire},S_CPOS_ATK2,0,0},	// S_CPOS_ATK4
+    {SPR_CPOS,6,3,{NULL},S_CPOS_PAIN2,0,0},	// S_CPOS_PAIN
+    {SPR_CPOS,6,3,{A_Pain},S_CPOS_RUN1,0,0},	// S_CPOS_PAIN2
+    {SPR_CPOS,7,5,{NULL},S_CPOS_DIE2,0,0},	// S_CPOS_DIE1
+    {SPR_CPOS,8,5,{A_Scream},S_CPOS_DIE3,0,0},	// S_CPOS_DIE2
+    {SPR_CPOS,9,5,{A_Fall},S_CPOS_DIE4,0,0},	// S_CPOS_DIE3
+    {SPR_CPOS,10,5,{NULL},S_CPOS_DIE5,0,0},	// S_CPOS_DIE4
+    {SPR_CPOS,11,5,{NULL},S_CPOS_DIE6,0,0},	// S_CPOS_DIE5
+    {SPR_CPOS,12,5,{NULL},S_CPOS_DIE7,0,0},	// S_CPOS_DIE6
+    {SPR_CPOS,13,-1,{NULL},S_NULL,0,0},	// S_CPOS_DIE7
+    {SPR_CPOS,14,5,{NULL},S_CPOS_XDIE2,0,0},	// S_CPOS_XDIE1
+    {SPR_CPOS,15,5,{A_XScream},S_CPOS_XDIE3,0,0},	// S_CPOS_XDIE2
+    {SPR_CPOS,16,5,{A_Fall},S_CPOS_XDIE4,0,0},	// S_CPOS_XDIE3
+    {SPR_CPOS,17,5,{NULL},S_CPOS_XDIE5,0,0},	// S_CPOS_XDIE4
+    {SPR_CPOS,18,5,{NULL},S_CPOS_XDIE6,0,0},	// S_CPOS_XDIE5
+    {SPR_CPOS,19,-1,{NULL},S_NULL,0,0},	// S_CPOS_XDIE6
+    {SPR_CPOS,13,5,{NULL},S_CPOS_RAISE2,0,0},	// S_CPOS_RAISE1
+    {SPR_CPOS,12,5,{NULL},S_CPOS_RAISE3,0,0},	// S_CPOS_RAISE2
+    {SPR_CPOS,11,5,{NULL},S_CPOS_RAISE4,0,0},	// S_CPOS_RAISE3
+    {SPR_CPOS,10,5,{NULL},S_CPOS_RAISE5,0,0},	// S_CPOS_RAISE4
+    {SPR_CPOS,9,5,{NULL},S_CPOS_RAISE6,0,0},	// S_CPOS_RAISE5
+    {SPR_CPOS,8,5,{NULL},S_CPOS_RAISE7,0,0},	// S_CPOS_RAISE6
+    {SPR_CPOS,7,5,{NULL},S_CPOS_RUN1,0,0},	// S_CPOS_RAISE7
+    {SPR_TROO,0,10,{A_Look},S_TROO_STND2,0,0},	// S_TROO_STND
+    {SPR_TROO,1,10,{A_Look},S_TROO_STND,0,0},	// S_TROO_STND2
+    {SPR_TROO,0,3,{A_Chase},S_TROO_RUN2,0,0},	// S_TROO_RUN1
+    {SPR_TROO,0,3,{A_Chase},S_TROO_RUN3,0,0},	// S_TROO_RUN2
+    {SPR_TROO,1,3,{A_Chase},S_TROO_RUN4,0,0},	// S_TROO_RUN3
+    {SPR_TROO,1,3,{A_Chase},S_TROO_RUN5,0,0},	// S_TROO_RUN4
+    {SPR_TROO,2,3,{A_Chase},S_TROO_RUN6,0,0},	// S_TROO_RUN5
+    {SPR_TROO,2,3,{A_Chase},S_TROO_RUN7,0,0},	// S_TROO_RUN6
+    {SPR_TROO,3,3,{A_Chase},S_TROO_RUN8,0,0},	// S_TROO_RUN7
+    {SPR_TROO,3,3,{A_Chase},S_TROO_RUN1,0,0},	// S_TROO_RUN8
+    {SPR_TROO,4,8,{A_FaceTarget},S_TROO_ATK2,0,0},	// S_TROO_ATK1
+    {SPR_TROO,5,8,{A_FaceTarget},S_TROO_ATK3,0,0},	// S_TROO_ATK2
+    {SPR_TROO,6,6,{A_TroopAttack},S_TROO_RUN1,0,0},	// S_TROO_ATK3
+    {SPR_TROO,7,2,{NULL},S_TROO_PAIN2,0,0},	// S_TROO_PAIN
+    {SPR_TROO,7,2,{A_Pain},S_TROO_RUN1,0,0},	// S_TROO_PAIN2
+    {SPR_TROO,8,8,{NULL},S_TROO_DIE2,0,0},	// S_TROO_DIE1
+    {SPR_TROO,9,8,{A_Scream},S_TROO_DIE3,0,0},	// S_TROO_DIE2
+    {SPR_TROO,10,6,{NULL},S_TROO_DIE4,0,0},	// S_TROO_DIE3
+    {SPR_TROO,11,6,{A_Fall},S_TROO_DIE5,0,0},	// S_TROO_DIE4
+    {SPR_TROO,12,-1,{NULL},S_NULL,0,0},	// S_TROO_DIE5
+    {SPR_TROO,13,5,{NULL},S_TROO_XDIE2,0,0},	// S_TROO_XDIE1
+    {SPR_TROO,14,5,{A_XScream},S_TROO_XDIE3,0,0},	// S_TROO_XDIE2
+    {SPR_TROO,15,5,{NULL},S_TROO_XDIE4,0,0},	// S_TROO_XDIE3
+    {SPR_TROO,16,5,{A_Fall},S_TROO_XDIE5,0,0},	// S_TROO_XDIE4
+    {SPR_TROO,17,5,{NULL},S_TROO_XDIE6,0,0},	// S_TROO_XDIE5
+    {SPR_TROO,18,5,{NULL},S_TROO_XDIE7,0,0},	// S_TROO_XDIE6
+    {SPR_TROO,19,5,{NULL},S_TROO_XDIE8,0,0},	// S_TROO_XDIE7
+    {SPR_TROO,20,-1,{NULL},S_NULL,0,0},	// S_TROO_XDIE8
+    {SPR_TROO,12,8,{NULL},S_TROO_RAISE2,0,0},	// S_TROO_RAISE1
+    {SPR_TROO,11,8,{NULL},S_TROO_RAISE3,0,0},	// S_TROO_RAISE2
+    {SPR_TROO,10,6,{NULL},S_TROO_RAISE4,0,0},	// S_TROO_RAISE3
+    {SPR_TROO,9,6,{NULL},S_TROO_RAISE5,0,0},	// S_TROO_RAISE4
+    {SPR_TROO,8,6,{NULL},S_TROO_RUN1,0,0},	// S_TROO_RAISE5
+    {SPR_SARG,0,10,{A_Look},S_SARG_STND2,0,0},	// S_SARG_STND
+    {SPR_SARG,1,10,{A_Look},S_SARG_STND,0,0},	// S_SARG_STND2
+    {SPR_SARG,0,2,{A_Chase},S_SARG_RUN2,0,0},	// S_SARG_RUN1
+    {SPR_SARG,0,2,{A_Chase},S_SARG_RUN3,0,0},	// S_SARG_RUN2
+    {SPR_SARG,1,2,{A_Chase},S_SARG_RUN4,0,0},	// S_SARG_RUN3
+    {SPR_SARG,1,2,{A_Chase},S_SARG_RUN5,0,0},	// S_SARG_RUN4
+    {SPR_SARG,2,2,{A_Chase},S_SARG_RUN6,0,0},	// S_SARG_RUN5
+    {SPR_SARG,2,2,{A_Chase},S_SARG_RUN7,0,0},	// S_SARG_RUN6
+    {SPR_SARG,3,2,{A_Chase},S_SARG_RUN8,0,0},	// S_SARG_RUN7
+    {SPR_SARG,3,2,{A_Chase},S_SARG_RUN1,0,0},	// S_SARG_RUN8
+    {SPR_SARG,4,8,{A_FaceTarget},S_SARG_ATK2,0,0},	// S_SARG_ATK1
+    {SPR_SARG,5,8,{A_FaceTarget},S_SARG_ATK3,0,0},	// S_SARG_ATK2
+    {SPR_SARG,6,8,{A_SargAttack},S_SARG_RUN1,0,0},	// S_SARG_ATK3
+    {SPR_SARG,7,2,{NULL},S_SARG_PAIN2,0,0},	// S_SARG_PAIN
+    {SPR_SARG,7,2,{A_Pain},S_SARG_RUN1,0,0},	// S_SARG_PAIN2
+    {SPR_SARG,8,8,{NULL},S_SARG_DIE2,0,0},	// S_SARG_DIE1
+    {SPR_SARG,9,8,{A_Scream},S_SARG_DIE3,0,0},	// S_SARG_DIE2
+    {SPR_SARG,10,4,{NULL},S_SARG_DIE4,0,0},	// S_SARG_DIE3
+    {SPR_SARG,11,4,{A_Fall},S_SARG_DIE5,0,0},	// S_SARG_DIE4
+    {SPR_SARG,12,4,{NULL},S_SARG_DIE6,0,0},	// S_SARG_DIE5
+    {SPR_SARG,13,-1,{NULL},S_NULL,0,0},	// S_SARG_DIE6
+    {SPR_SARG,13,5,{NULL},S_SARG_RAISE2,0,0},	// S_SARG_RAISE1
+    {SPR_SARG,12,5,{NULL},S_SARG_RAISE3,0,0},	// S_SARG_RAISE2
+    {SPR_SARG,11,5,{NULL},S_SARG_RAISE4,0,0},	// S_SARG_RAISE3
+    {SPR_SARG,10,5,{NULL},S_SARG_RAISE5,0,0},	// S_SARG_RAISE4
+    {SPR_SARG,9,5,{NULL},S_SARG_RAISE6,0,0},	// S_SARG_RAISE5
+    {SPR_SARG,8,5,{NULL},S_SARG_RUN1,0,0},	// S_SARG_RAISE6
+    {SPR_HEAD,0,10,{A_Look},S_HEAD_STND,0,0},	// S_HEAD_STND
+    {SPR_HEAD,0,3,{A_Chase},S_HEAD_RUN1,0,0},	// S_HEAD_RUN1
+    {SPR_HEAD,1,5,{A_FaceTarget},S_HEAD_ATK2,0,0},	// S_HEAD_ATK1
+    {SPR_HEAD,2,5,{A_FaceTarget},S_HEAD_ATK3,0,0},	// S_HEAD_ATK2
+    {SPR_HEAD,32771,5,{A_HeadAttack},S_HEAD_RUN1,0,0},	// S_HEAD_ATK3
+    {SPR_HEAD,4,3,{NULL},S_HEAD_PAIN2,0,0},	// S_HEAD_PAIN
+    {SPR_HEAD,4,3,{A_Pain},S_HEAD_PAIN3,0,0},	// S_HEAD_PAIN2
+    {SPR_HEAD,5,6,{NULL},S_HEAD_RUN1,0,0},	// S_HEAD_PAIN3
+    {SPR_HEAD,6,8,{NULL},S_HEAD_DIE2,0,0},	// S_HEAD_DIE1
+    {SPR_HEAD,7,8,{A_Scream},S_HEAD_DIE3,0,0},	// S_HEAD_DIE2
+    {SPR_HEAD,8,8,{NULL},S_HEAD_DIE4,0,0},	// S_HEAD_DIE3
+    {SPR_HEAD,9,8,{NULL},S_HEAD_DIE5,0,0},	// S_HEAD_DIE4
+    {SPR_HEAD,10,8,{A_Fall},S_HEAD_DIE6,0,0},	// S_HEAD_DIE5
+    {SPR_HEAD,11,-1,{NULL},S_NULL,0,0},	// S_HEAD_DIE6
+    {SPR_HEAD,11,8,{NULL},S_HEAD_RAISE2,0,0},	// S_HEAD_RAISE1
+    {SPR_HEAD,10,8,{NULL},S_HEAD_RAISE3,0,0},	// S_HEAD_RAISE2
+    {SPR_HEAD,9,8,{NULL},S_HEAD_RAISE4,0,0},	// S_HEAD_RAISE3
+    {SPR_HEAD,8,8,{NULL},S_HEAD_RAISE5,0,0},	// S_HEAD_RAISE4
+    {SPR_HEAD,7,8,{NULL},S_HEAD_RAISE6,0,0},	// S_HEAD_RAISE5
+    {SPR_HEAD,6,8,{NULL},S_HEAD_RUN1,0,0},	// S_HEAD_RAISE6
+    {SPR_BAL7,32768,4,{NULL},S_BRBALL2,0,0},	// S_BRBALL1
+    {SPR_BAL7,32769,4,{NULL},S_BRBALL1,0,0},	// S_BRBALL2
+    {SPR_BAL7,32770,6,{NULL},S_BRBALLX2,0,0},	// S_BRBALLX1
+    {SPR_BAL7,32771,6,{NULL},S_BRBALLX3,0,0},	// S_BRBALLX2
+    {SPR_BAL7,32772,6,{NULL},S_NULL,0,0},	// S_BRBALLX3
+    {SPR_BOSS,0,10,{A_Look},S_BOSS_STND2,0,0},	// S_BOSS_STND
+    {SPR_BOSS,1,10,{A_Look},S_BOSS_STND,0,0},	// S_BOSS_STND2
+    {SPR_BOSS,0,3,{A_Chase},S_BOSS_RUN2,0,0},	// S_BOSS_RUN1
+    {SPR_BOSS,0,3,{A_Chase},S_BOSS_RUN3,0,0},	// S_BOSS_RUN2
+    {SPR_BOSS,1,3,{A_Chase},S_BOSS_RUN4,0,0},	// S_BOSS_RUN3
+    {SPR_BOSS,1,3,{A_Chase},S_BOSS_RUN5,0,0},	// S_BOSS_RUN4
+    {SPR_BOSS,2,3,{A_Chase},S_BOSS_RUN6,0,0},	// S_BOSS_RUN5
+    {SPR_BOSS,2,3,{A_Chase},S_BOSS_RUN7,0,0},	// S_BOSS_RUN6
+    {SPR_BOSS,3,3,{A_Chase},S_BOSS_RUN8,0,0},	// S_BOSS_RUN7
+    {SPR_BOSS,3,3,{A_Chase},S_BOSS_RUN1,0,0},	// S_BOSS_RUN8
+    {SPR_BOSS,4,8,{A_FaceTarget},S_BOSS_ATK2,0,0},	// S_BOSS_ATK1
+    {SPR_BOSS,5,8,{A_FaceTarget},S_BOSS_ATK3,0,0},	// S_BOSS_ATK2
+    {SPR_BOSS,6,8,{A_BruisAttack},S_BOSS_RUN1,0,0},	// S_BOSS_ATK3
+    {SPR_BOSS,7,2,{NULL},S_BOSS_PAIN2,0,0},	// S_BOSS_PAIN
+    {SPR_BOSS,7,2,{A_Pain},S_BOSS_RUN1,0,0},	// S_BOSS_PAIN2
+    {SPR_BOSS,8,8,{NULL},S_BOSS_DIE2,0,0},	// S_BOSS_DIE1
+    {SPR_BOSS,9,8,{A_Scream},S_BOSS_DIE3,0,0},	// S_BOSS_DIE2
+    {SPR_BOSS,10,8,{NULL},S_BOSS_DIE4,0,0},	// S_BOSS_DIE3
+    {SPR_BOSS,11,8,{A_Fall},S_BOSS_DIE5,0,0},	// S_BOSS_DIE4
+    {SPR_BOSS,12,8,{NULL},S_BOSS_DIE6,0,0},	// S_BOSS_DIE5
+    {SPR_BOSS,13,8,{NULL},S_BOSS_DIE7,0,0},	// S_BOSS_DIE6
+    {SPR_BOSS,14,-1,{A_BossDeath},S_NULL,0,0},	// S_BOSS_DIE7
+    {SPR_BOSS,14,8,{NULL},S_BOSS_RAISE2,0,0},	// S_BOSS_RAISE1
+    {SPR_BOSS,13,8,{NULL},S_BOSS_RAISE3,0,0},	// S_BOSS_RAISE2
+    {SPR_BOSS,12,8,{NULL},S_BOSS_RAISE4,0,0},	// S_BOSS_RAISE3
+    {SPR_BOSS,11,8,{NULL},S_BOSS_RAISE5,0,0},	// S_BOSS_RAISE4
+    {SPR_BOSS,10,8,{NULL},S_BOSS_RAISE6,0,0},	// S_BOSS_RAISE5
+    {SPR_BOSS,9,8,{NULL},S_BOSS_RAISE7,0,0},	// S_BOSS_RAISE6
+    {SPR_BOSS,8,8,{NULL},S_BOSS_RUN1,0,0},	// S_BOSS_RAISE7
+    {SPR_BOS2,0,10,{A_Look},S_BOS2_STND2,0,0},	// S_BOS2_STND
+    {SPR_BOS2,1,10,{A_Look},S_BOS2_STND,0,0},	// S_BOS2_STND2
+    {SPR_BOS2,0,3,{A_Chase},S_BOS2_RUN2,0,0},	// S_BOS2_RUN1
+    {SPR_BOS2,0,3,{A_Chase},S_BOS2_RUN3,0,0},	// S_BOS2_RUN2
+    {SPR_BOS2,1,3,{A_Chase},S_BOS2_RUN4,0,0},	// S_BOS2_RUN3
+    {SPR_BOS2,1,3,{A_Chase},S_BOS2_RUN5,0,0},	// S_BOS2_RUN4
+    {SPR_BOS2,2,3,{A_Chase},S_BOS2_RUN6,0,0},	// S_BOS2_RUN5
+    {SPR_BOS2,2,3,{A_Chase},S_BOS2_RUN7,0,0},	// S_BOS2_RUN6
+    {SPR_BOS2,3,3,{A_Chase},S_BOS2_RUN8,0,0},	// S_BOS2_RUN7
+    {SPR_BOS2,3,3,{A_Chase},S_BOS2_RUN1,0,0},	// S_BOS2_RUN8
+    {SPR_BOS2,4,8,{A_FaceTarget},S_BOS2_ATK2,0,0},	// S_BOS2_ATK1
+    {SPR_BOS2,5,8,{A_FaceTarget},S_BOS2_ATK3,0,0},	// S_BOS2_ATK2
+    {SPR_BOS2,6,8,{A_BruisAttack},S_BOS2_RUN1,0,0},	// S_BOS2_ATK3
+    {SPR_BOS2,7,2,{NULL},S_BOS2_PAIN2,0,0},	// S_BOS2_PAIN
+    {SPR_BOS2,7,2,{A_Pain},S_BOS2_RUN1,0,0},	// S_BOS2_PAIN2
+    {SPR_BOS2,8,8,{NULL},S_BOS2_DIE2,0,0},	// S_BOS2_DIE1
+    {SPR_BOS2,9,8,{A_Scream},S_BOS2_DIE3,0,0},	// S_BOS2_DIE2
+    {SPR_BOS2,10,8,{NULL},S_BOS2_DIE4,0,0},	// S_BOS2_DIE3
+    {SPR_BOS2,11,8,{A_Fall},S_BOS2_DIE5,0,0},	// S_BOS2_DIE4
+    {SPR_BOS2,12,8,{NULL},S_BOS2_DIE6,0,0},	// S_BOS2_DIE5
+    {SPR_BOS2,13,8,{NULL},S_BOS2_DIE7,0,0},	// S_BOS2_DIE6
+    {SPR_BOS2,14,-1,{NULL},S_NULL,0,0},	// S_BOS2_DIE7
+    {SPR_BOS2,14,8,{NULL},S_BOS2_RAISE2,0,0},	// S_BOS2_RAISE1
+    {SPR_BOS2,13,8,{NULL},S_BOS2_RAISE3,0,0},	// S_BOS2_RAISE2
+    {SPR_BOS2,12,8,{NULL},S_BOS2_RAISE4,0,0},	// S_BOS2_RAISE3
+    {SPR_BOS2,11,8,{NULL},S_BOS2_RAISE5,0,0},	// S_BOS2_RAISE4
+    {SPR_BOS2,10,8,{NULL},S_BOS2_RAISE6,0,0},	// S_BOS2_RAISE5
+    {SPR_BOS2,9,8,{NULL},S_BOS2_RAISE7,0,0},	// S_BOS2_RAISE6
+    {SPR_BOS2,8,8,{NULL},S_BOS2_RUN1,0,0},	// S_BOS2_RAISE7
+    {SPR_SKUL,32768,10,{A_Look},S_SKULL_STND2,0,0},	// S_SKULL_STND
+    {SPR_SKUL,32769,10,{A_Look},S_SKULL_STND,0,0},	// S_SKULL_STND2
+    {SPR_SKUL,32768,6,{A_Chase},S_SKULL_RUN2,0,0},	// S_SKULL_RUN1
+    {SPR_SKUL,32769,6,{A_Chase},S_SKULL_RUN1,0,0},	// S_SKULL_RUN2
+    {SPR_SKUL,32770,10,{A_FaceTarget},S_SKULL_ATK2,0,0},	// S_SKULL_ATK1
+    {SPR_SKUL,32771,4,{A_SkullAttack},S_SKULL_ATK3,0,0},	// S_SKULL_ATK2
+    {SPR_SKUL,32770,4,{NULL},S_SKULL_ATK4,0,0},	// S_SKULL_ATK3
+    {SPR_SKUL,32771,4,{NULL},S_SKULL_ATK3,0,0},	// S_SKULL_ATK4
+    {SPR_SKUL,32772,3,{NULL},S_SKULL_PAIN2,0,0},	// S_SKULL_PAIN
+    {SPR_SKUL,32772,3,{A_Pain},S_SKULL_RUN1,0,0},	// S_SKULL_PAIN2
+    {SPR_SKUL,32773,6,{NULL},S_SKULL_DIE2,0,0},	// S_SKULL_DIE1
+    {SPR_SKUL,32774,6,{A_Scream},S_SKULL_DIE3,0,0},	// S_SKULL_DIE2
+    {SPR_SKUL,32775,6,{NULL},S_SKULL_DIE4,0,0},	// S_SKULL_DIE3
+    {SPR_SKUL,32776,6,{A_Fall},S_SKULL_DIE5,0,0},	// S_SKULL_DIE4
+    {SPR_SKUL,9,6,{NULL},S_SKULL_DIE6,0,0},	// S_SKULL_DIE5
+    {SPR_SKUL,10,6,{NULL},S_NULL,0,0},	// S_SKULL_DIE6
+    {SPR_SPID,0,10,{A_Look},S_SPID_STND2,0,0},	// S_SPID_STND
+    {SPR_SPID,1,10,{A_Look},S_SPID_STND,0,0},	// S_SPID_STND2
+    {SPR_SPID,0,3,{A_Metal},S_SPID_RUN2,0,0},	// S_SPID_RUN1
+    {SPR_SPID,0,3,{A_Chase},S_SPID_RUN3,0,0},	// S_SPID_RUN2
+    {SPR_SPID,1,3,{A_Chase},S_SPID_RUN4,0,0},	// S_SPID_RUN3
+    {SPR_SPID,1,3,{A_Chase},S_SPID_RUN5,0,0},	// S_SPID_RUN4
+    {SPR_SPID,2,3,{A_Metal},S_SPID_RUN6,0,0},	// S_SPID_RUN5
+    {SPR_SPID,2,3,{A_Chase},S_SPID_RUN7,0,0},	// S_SPID_RUN6
+    {SPR_SPID,3,3,{A_Chase},S_SPID_RUN8,0,0},	// S_SPID_RUN7
+    {SPR_SPID,3,3,{A_Chase},S_SPID_RUN9,0,0},	// S_SPID_RUN8
+    {SPR_SPID,4,3,{A_Metal},S_SPID_RUN10,0,0},	// S_SPID_RUN9
+    {SPR_SPID,4,3,{A_Chase},S_SPID_RUN11,0,0},	// S_SPID_RUN10
+    {SPR_SPID,5,3,{A_Chase},S_SPID_RUN12,0,0},	// S_SPID_RUN11
+    {SPR_SPID,5,3,{A_Chase},S_SPID_RUN1,0,0},	// S_SPID_RUN12
+    {SPR_SPID,32768,20,{A_FaceTarget},S_SPID_ATK2,0,0},	// S_SPID_ATK1
+    {SPR_SPID,32774,4,{A_SPosAttack},S_SPID_ATK3,0,0},	// S_SPID_ATK2
+    {SPR_SPID,32775,4,{A_SPosAttack},S_SPID_ATK4,0,0},	// S_SPID_ATK3
+    {SPR_SPID,32775,1,{A_SpidRefire},S_SPID_ATK2,0,0},	// S_SPID_ATK4
+    {SPR_SPID,8,3,{NULL},S_SPID_PAIN2,0,0},	// S_SPID_PAIN
+    {SPR_SPID,8,3,{A_Pain},S_SPID_RUN1,0,0},	// S_SPID_PAIN2
+    {SPR_SPID,9,20,{A_Scream},S_SPID_DIE2,0,0},	// S_SPID_DIE1
+    {SPR_SPID,10,10,{A_Fall},S_SPID_DIE3,0,0},	// S_SPID_DIE2
+    {SPR_SPID,11,10,{NULL},S_SPID_DIE4,0,0},	// S_SPID_DIE3
+    {SPR_SPID,12,10,{NULL},S_SPID_DIE5,0,0},	// S_SPID_DIE4
+    {SPR_SPID,13,10,{NULL},S_SPID_DIE6,0,0},	// S_SPID_DIE5
+    {SPR_SPID,14,10,{NULL},S_SPID_DIE7,0,0},	// S_SPID_DIE6
+    {SPR_SPID,15,10,{NULL},S_SPID_DIE8,0,0},	// S_SPID_DIE7
+    {SPR_SPID,16,10,{NULL},S_SPID_DIE9,0,0},	// S_SPID_DIE8
+    {SPR_SPID,17,10,{NULL},S_SPID_DIE10,0,0},	// S_SPID_DIE9
+    {SPR_SPID,18,30,{NULL},S_SPID_DIE11,0,0},	// S_SPID_DIE10
+    {SPR_SPID,18,-1,{A_BossDeath},S_NULL,0,0},	// S_SPID_DIE11
+    {SPR_BSPI,0,10,{A_Look},S_BSPI_STND2,0,0},	// S_BSPI_STND
+    {SPR_BSPI,1,10,{A_Look},S_BSPI_STND,0,0},	// S_BSPI_STND2
+    {SPR_BSPI,0,20,{NULL},S_BSPI_RUN1,0,0},	// S_BSPI_SIGHT
+    {SPR_BSPI,0,3,{A_BabyMetal},S_BSPI_RUN2,0,0},	// S_BSPI_RUN1
+    {SPR_BSPI,0,3,{A_Chase},S_BSPI_RUN3,0,0},	// S_BSPI_RUN2
+    {SPR_BSPI,1,3,{A_Chase},S_BSPI_RUN4,0,0},	// S_BSPI_RUN3
+    {SPR_BSPI,1,3,{A_Chase},S_BSPI_RUN5,0,0},	// S_BSPI_RUN4
+    {SPR_BSPI,2,3,{A_Chase},S_BSPI_RUN6,0,0},	// S_BSPI_RUN5
+    {SPR_BSPI,2,3,{A_Chase},S_BSPI_RUN7,0,0},	// S_BSPI_RUN6
+    {SPR_BSPI,3,3,{A_BabyMetal},S_BSPI_RUN8,0,0},	// S_BSPI_RUN7
+    {SPR_BSPI,3,3,{A_Chase},S_BSPI_RUN9,0,0},	// S_BSPI_RUN8
+    {SPR_BSPI,4,3,{A_Chase},S_BSPI_RUN10,0,0},	// S_BSPI_RUN9
+    {SPR_BSPI,4,3,{A_Chase},S_BSPI_RUN11,0,0},	// S_BSPI_RUN10
+    {SPR_BSPI,5,3,{A_Chase},S_BSPI_RUN12,0,0},	// S_BSPI_RUN11
+    {SPR_BSPI,5,3,{A_Chase},S_BSPI_RUN1,0,0},	// S_BSPI_RUN12
+    {SPR_BSPI,32768,20,{A_FaceTarget},S_BSPI_ATK2,0,0},	// S_BSPI_ATK1
+    {SPR_BSPI,32774,4,{A_BspiAttack},S_BSPI_ATK3,0,0},	// S_BSPI_ATK2
+    {SPR_BSPI,32775,4,{NULL},S_BSPI_ATK4,0,0},	// S_BSPI_ATK3
+    {SPR_BSPI,32775,1,{A_SpidRefire},S_BSPI_ATK2,0,0},	// S_BSPI_ATK4
+    {SPR_BSPI,8,3,{NULL},S_BSPI_PAIN2,0,0},	// S_BSPI_PAIN
+    {SPR_BSPI,8,3,{A_Pain},S_BSPI_RUN1,0,0},	// S_BSPI_PAIN2
+    {SPR_BSPI,9,20,{A_Scream},S_BSPI_DIE2,0,0},	// S_BSPI_DIE1
+    {SPR_BSPI,10,7,{A_Fall},S_BSPI_DIE3,0,0},	// S_BSPI_DIE2
+    {SPR_BSPI,11,7,{NULL},S_BSPI_DIE4,0,0},	// S_BSPI_DIE3
+    {SPR_BSPI,12,7,{NULL},S_BSPI_DIE5,0,0},	// S_BSPI_DIE4
+    {SPR_BSPI,13,7,{NULL},S_BSPI_DIE6,0,0},	// S_BSPI_DIE5
+    {SPR_BSPI,14,7,{NULL},S_BSPI_DIE7,0,0},	// S_BSPI_DIE6
+    {SPR_BSPI,15,-1,{A_BossDeath},S_NULL,0,0},	// S_BSPI_DIE7
+    {SPR_BSPI,15,5,{NULL},S_BSPI_RAISE2,0,0},	// S_BSPI_RAISE1
+    {SPR_BSPI,14,5,{NULL},S_BSPI_RAISE3,0,0},	// S_BSPI_RAISE2
+    {SPR_BSPI,13,5,{NULL},S_BSPI_RAISE4,0,0},	// S_BSPI_RAISE3
+    {SPR_BSPI,12,5,{NULL},S_BSPI_RAISE5,0,0},	// S_BSPI_RAISE4
+    {SPR_BSPI,11,5,{NULL},S_BSPI_RAISE6,0,0},	// S_BSPI_RAISE5
+    {SPR_BSPI,10,5,{NULL},S_BSPI_RAISE7,0,0},	// S_BSPI_RAISE6
+    {SPR_BSPI,9,5,{NULL},S_BSPI_RUN1,0,0},	// S_BSPI_RAISE7
+    {SPR_APLS,32768,5,{NULL},S_ARACH_PLAZ2,0,0},	// S_ARACH_PLAZ
+    {SPR_APLS,32769,5,{NULL},S_ARACH_PLAZ,0,0},	// S_ARACH_PLAZ2
+    {SPR_APBX,32768,5,{NULL},S_ARACH_PLEX2,0,0},	// S_ARACH_PLEX
+    {SPR_APBX,32769,5,{NULL},S_ARACH_PLEX3,0,0},	// S_ARACH_PLEX2
+    {SPR_APBX,32770,5,{NULL},S_ARACH_PLEX4,0,0},	// S_ARACH_PLEX3
+    {SPR_APBX,32771,5,{NULL},S_ARACH_PLEX5,0,0},	// S_ARACH_PLEX4
+    {SPR_APBX,32772,5,{NULL},S_NULL,0,0},	// S_ARACH_PLEX5
+    {SPR_CYBR,0,10,{A_Look},S_CYBER_STND2,0,0},	// S_CYBER_STND
+    {SPR_CYBR,1,10,{A_Look},S_CYBER_STND,0,0},	// S_CYBER_STND2
+    {SPR_CYBR,0,3,{A_Hoof},S_CYBER_RUN2,0,0},	// S_CYBER_RUN1
+    {SPR_CYBR,0,3,{A_Chase},S_CYBER_RUN3,0,0},	// S_CYBER_RUN2
+    {SPR_CYBR,1,3,{A_Chase},S_CYBER_RUN4,0,0},	// S_CYBER_RUN3
+    {SPR_CYBR,1,3,{A_Chase},S_CYBER_RUN5,0,0},	// S_CYBER_RUN4
+    {SPR_CYBR,2,3,{A_Chase},S_CYBER_RUN6,0,0},	// S_CYBER_RUN5
+    {SPR_CYBR,2,3,{A_Chase},S_CYBER_RUN7,0,0},	// S_CYBER_RUN6
+    {SPR_CYBR,3,3,{A_Metal},S_CYBER_RUN8,0,0},	// S_CYBER_RUN7
+    {SPR_CYBR,3,3,{A_Chase},S_CYBER_RUN1,0,0},	// S_CYBER_RUN8
+    {SPR_CYBR,4,6,{A_FaceTarget},S_CYBER_ATK2,0,0},	// S_CYBER_ATK1
+    {SPR_CYBR,5,12,{A_CyberAttack},S_CYBER_ATK3,0,0},	// S_CYBER_ATK2
+    {SPR_CYBR,4,12,{A_FaceTarget},S_CYBER_ATK4,0,0},	// S_CYBER_ATK3
+    {SPR_CYBR,5,12,{A_CyberAttack},S_CYBER_ATK5,0,0},	// S_CYBER_ATK4
+    {SPR_CYBR,4,12,{A_FaceTarget},S_CYBER_ATK6,0,0},	// S_CYBER_ATK5
+    {SPR_CYBR,5,12,{A_CyberAttack},S_CYBER_RUN1,0,0},	// S_CYBER_ATK6
+    {SPR_CYBR,6,10,{A_Pain},S_CYBER_RUN1,0,0},	// S_CYBER_PAIN
+    {SPR_CYBR,7,10,{NULL},S_CYBER_DIE2,0,0},	// S_CYBER_DIE1
+    {SPR_CYBR,8,10,{A_Scream},S_CYBER_DIE3,0,0},	// S_CYBER_DIE2
+    {SPR_CYBR,9,10,{NULL},S_CYBER_DIE4,0,0},	// S_CYBER_DIE3
+    {SPR_CYBR,10,10,{NULL},S_CYBER_DIE5,0,0},	// S_CYBER_DIE4
+    {SPR_CYBR,11,10,{NULL},S_CYBER_DIE6,0,0},	// S_CYBER_DIE5
+    {SPR_CYBR,12,10,{A_Fall},S_CYBER_DIE7,0,0},	// S_CYBER_DIE6
+    {SPR_CYBR,13,10,{NULL},S_CYBER_DIE8,0,0},	// S_CYBER_DIE7
+    {SPR_CYBR,14,10,{NULL},S_CYBER_DIE9,0,0},	// S_CYBER_DIE8
+    {SPR_CYBR,15,30,{NULL},S_CYBER_DIE10,0,0},	// S_CYBER_DIE9
+    {SPR_CYBR,15,-1,{A_BossDeath},S_NULL,0,0},	// S_CYBER_DIE10
+    {SPR_PAIN,0,10,{A_Look},S_PAIN_STND,0,0},	// S_PAIN_STND
+    {SPR_PAIN,0,3,{A_Chase},S_PAIN_RUN2,0,0},	// S_PAIN_RUN1
+    {SPR_PAIN,0,3,{A_Chase},S_PAIN_RUN3,0,0},	// S_PAIN_RUN2
+    {SPR_PAIN,1,3,{A_Chase},S_PAIN_RUN4,0,0},	// S_PAIN_RUN3
+    {SPR_PAIN,1,3,{A_Chase},S_PAIN_RUN5,0,0},	// S_PAIN_RUN4
+    {SPR_PAIN,2,3,{A_Chase},S_PAIN_RUN6,0,0},	// S_PAIN_RUN5
+    {SPR_PAIN,2,3,{A_Chase},S_PAIN_RUN1,0,0},	// S_PAIN_RUN6
+    {SPR_PAIN,3,5,{A_FaceTarget},S_PAIN_ATK2,0,0},	// S_PAIN_ATK1
+    {SPR_PAIN,4,5,{A_FaceTarget},S_PAIN_ATK3,0,0},	// S_PAIN_ATK2
+    {SPR_PAIN,32773,5,{A_FaceTarget},S_PAIN_ATK4,0,0},	// S_PAIN_ATK3
+    {SPR_PAIN,32773,0,{A_PainAttack},S_PAIN_RUN1,0,0},	// S_PAIN_ATK4
+    {SPR_PAIN,6,6,{NULL},S_PAIN_PAIN2,0,0},	// S_PAIN_PAIN
+    {SPR_PAIN,6,6,{A_Pain},S_PAIN_RUN1,0,0},	// S_PAIN_PAIN2
+    {SPR_PAIN,32775,8,{NULL},S_PAIN_DIE2,0,0},	// S_PAIN_DIE1
+    {SPR_PAIN,32776,8,{A_Scream},S_PAIN_DIE3,0,0},	// S_PAIN_DIE2
+    {SPR_PAIN,32777,8,{NULL},S_PAIN_DIE4,0,0},	// S_PAIN_DIE3
+    {SPR_PAIN,32778,8,{NULL},S_PAIN_DIE5,0,0},	// S_PAIN_DIE4
+    {SPR_PAIN,32779,8,{A_PainDie},S_PAIN_DIE6,0,0},	// S_PAIN_DIE5
+    {SPR_PAIN,32780,8,{NULL},S_NULL,0,0},	// S_PAIN_DIE6
+    {SPR_PAIN,12,8,{NULL},S_PAIN_RAISE2,0,0},	// S_PAIN_RAISE1
+    {SPR_PAIN,11,8,{NULL},S_PAIN_RAISE3,0,0},	// S_PAIN_RAISE2
+    {SPR_PAIN,10,8,{NULL},S_PAIN_RAISE4,0,0},	// S_PAIN_RAISE3
+    {SPR_PAIN,9,8,{NULL},S_PAIN_RAISE5,0,0},	// S_PAIN_RAISE4
+    {SPR_PAIN,8,8,{NULL},S_PAIN_RAISE6,0,0},	// S_PAIN_RAISE5
+    {SPR_PAIN,7,8,{NULL},S_PAIN_RUN1,0,0},	// S_PAIN_RAISE6
+    {SPR_SSWV,0,10,{A_Look},S_SSWV_STND2,0,0},	// S_SSWV_STND
+    {SPR_SSWV,1,10,{A_Look},S_SSWV_STND,0,0},	// S_SSWV_STND2
+    {SPR_SSWV,0,3,{A_Chase},S_SSWV_RUN2,0,0},	// S_SSWV_RUN1
+    {SPR_SSWV,0,3,{A_Chase},S_SSWV_RUN3,0,0},	// S_SSWV_RUN2
+    {SPR_SSWV,1,3,{A_Chase},S_SSWV_RUN4,0,0},	// S_SSWV_RUN3
+    {SPR_SSWV,1,3,{A_Chase},S_SSWV_RUN5,0,0},	// S_SSWV_RUN4
+    {SPR_SSWV,2,3,{A_Chase},S_SSWV_RUN6,0,0},	// S_SSWV_RUN5
+    {SPR_SSWV,2,3,{A_Chase},S_SSWV_RUN7,0,0},	// S_SSWV_RUN6
+    {SPR_SSWV,3,3,{A_Chase},S_SSWV_RUN8,0,0},	// S_SSWV_RUN7
+    {SPR_SSWV,3,3,{A_Chase},S_SSWV_RUN1,0,0},	// S_SSWV_RUN8
+    {SPR_SSWV,4,10,{A_FaceTarget},S_SSWV_ATK2,0,0},	// S_SSWV_ATK1
+    {SPR_SSWV,5,10,{A_FaceTarget},S_SSWV_ATK3,0,0},	// S_SSWV_ATK2
+    {SPR_SSWV,32774,4,{A_CPosAttack},S_SSWV_ATK4,0,0},	// S_SSWV_ATK3
+    {SPR_SSWV,5,6,{A_FaceTarget},S_SSWV_ATK5,0,0},	// S_SSWV_ATK4
+    {SPR_SSWV,32774,4,{A_CPosAttack},S_SSWV_ATK6,0,0},	// S_SSWV_ATK5
+    {SPR_SSWV,5,1,{A_CPosRefire},S_SSWV_ATK2,0,0},	// S_SSWV_ATK6
+    {SPR_SSWV,7,3,{NULL},S_SSWV_PAIN2,0,0},	// S_SSWV_PAIN
+    {SPR_SSWV,7,3,{A_Pain},S_SSWV_RUN1,0,0},	// S_SSWV_PAIN2
+    {SPR_SSWV,8,5,{NULL},S_SSWV_DIE2,0,0},	// S_SSWV_DIE1
+    {SPR_SSWV,9,5,{A_Scream},S_SSWV_DIE3,0,0},	// S_SSWV_DIE2
+    {SPR_SSWV,10,5,{A_Fall},S_SSWV_DIE4,0,0},	// S_SSWV_DIE3
+    {SPR_SSWV,11,5,{NULL},S_SSWV_DIE5,0,0},	// S_SSWV_DIE4
+    {SPR_SSWV,12,-1,{NULL},S_NULL,0,0},	// S_SSWV_DIE5
+    {SPR_SSWV,13,5,{NULL},S_SSWV_XDIE2,0,0},	// S_SSWV_XDIE1
+    {SPR_SSWV,14,5,{A_XScream},S_SSWV_XDIE3,0,0},	// S_SSWV_XDIE2
+    {SPR_SSWV,15,5,{A_Fall},S_SSWV_XDIE4,0,0},	// S_SSWV_XDIE3
+    {SPR_SSWV,16,5,{NULL},S_SSWV_XDIE5,0,0},	// S_SSWV_XDIE4
+    {SPR_SSWV,17,5,{NULL},S_SSWV_XDIE6,0,0},	// S_SSWV_XDIE5
+    {SPR_SSWV,18,5,{NULL},S_SSWV_XDIE7,0,0},	// S_SSWV_XDIE6
+    {SPR_SSWV,19,5,{NULL},S_SSWV_XDIE8,0,0},	// S_SSWV_XDIE7
+    {SPR_SSWV,20,5,{NULL},S_SSWV_XDIE9,0,0},	// S_SSWV_XDIE8
+    {SPR_SSWV,21,-1,{NULL},S_NULL,0,0},	// S_SSWV_XDIE9
+    {SPR_SSWV,12,5,{NULL},S_SSWV_RAISE2,0,0},	// S_SSWV_RAISE1
+    {SPR_SSWV,11,5,{NULL},S_SSWV_RAISE3,0,0},	// S_SSWV_RAISE2
+    {SPR_SSWV,10,5,{NULL},S_SSWV_RAISE4,0,0},	// S_SSWV_RAISE3
+    {SPR_SSWV,9,5,{NULL},S_SSWV_RAISE5,0,0},	// S_SSWV_RAISE4
+    {SPR_SSWV,8,5,{NULL},S_SSWV_RUN1,0,0},	// S_SSWV_RAISE5
+    {SPR_KEEN,0,-1,{NULL},S_KEENSTND,0,0},	// S_KEENSTND
+    {SPR_KEEN,0,6,{NULL},S_COMMKEEN2,0,0},	// S_COMMKEEN
+    {SPR_KEEN,1,6,{NULL},S_COMMKEEN3,0,0},	// S_COMMKEEN2
+    {SPR_KEEN,2,6,{A_Scream},S_COMMKEEN4,0,0},	// S_COMMKEEN3
+    {SPR_KEEN,3,6,{NULL},S_COMMKEEN5,0,0},	// S_COMMKEEN4
+    {SPR_KEEN,4,6,{NULL},S_COMMKEEN6,0,0},	// S_COMMKEEN5
+    {SPR_KEEN,5,6,{NULL},S_COMMKEEN7,0,0},	// S_COMMKEEN6
+    {SPR_KEEN,6,6,{NULL},S_COMMKEEN8,0,0},	// S_COMMKEEN7
+    {SPR_KEEN,7,6,{NULL},S_COMMKEEN9,0,0},	// S_COMMKEEN8
+    {SPR_KEEN,8,6,{NULL},S_COMMKEEN10,0,0},	// S_COMMKEEN9
+    {SPR_KEEN,9,6,{NULL},S_COMMKEEN11,0,0},	// S_COMMKEEN10
+    {SPR_KEEN,10,6,{A_KeenDie},S_COMMKEEN12,0,0},// S_COMMKEEN11
+    {SPR_KEEN,11,-1,{NULL},S_NULL,0,0},		// S_COMMKEEN12
+    {SPR_KEEN,12,4,{NULL},S_KEENPAIN2,0,0},	// S_KEENPAIN
+    {SPR_KEEN,12,8,{A_Pain},S_KEENSTND,0,0},	// S_KEENPAIN2
+    {SPR_BBRN,0,-1,{NULL},S_NULL,0,0},		// S_BRAIN
+    {SPR_BBRN,1,36,{A_BrainPain},S_BRAIN,0,0},	// S_BRAIN_PAIN
+    {SPR_BBRN,0,100,{A_BrainScream},S_BRAIN_DIE2,0,0},	// S_BRAIN_DIE1
+    {SPR_BBRN,0,10,{NULL},S_BRAIN_DIE3,0,0},	// S_BRAIN_DIE2
+    {SPR_BBRN,0,10,{NULL},S_BRAIN_DIE4,0,0},	// S_BRAIN_DIE3
+    {SPR_BBRN,0,-1,{A_BrainDie},S_NULL,0,0},	// S_BRAIN_DIE4
+    {SPR_SSWV,0,10,{A_Look},S_BRAINEYE,0,0},	// S_BRAINEYE
+    {SPR_SSWV,0,181,{A_BrainAwake},S_BRAINEYE1,0,0},	// S_BRAINEYESEE
+    {SPR_SSWV,0,150,{A_BrainSpit},S_BRAINEYE1,0,0},	// S_BRAINEYE1
+    {SPR_BOSF,32768,3,{A_SpawnSound},S_SPAWN2,0,0},	// S_SPAWN1
+    {SPR_BOSF,32769,3,{A_SpawnFly},S_SPAWN3,0,0},	// S_SPAWN2
+    {SPR_BOSF,32770,3,{A_SpawnFly},S_SPAWN4,0,0},	// S_SPAWN3
+    {SPR_BOSF,32771,3,{A_SpawnFly},S_SPAWN1,0,0},	// S_SPAWN4
+    {SPR_FIRE,32768,4,{A_Fire},S_SPAWNFIRE2,0,0},	// S_SPAWNFIRE1
+    {SPR_FIRE,32769,4,{A_Fire},S_SPAWNFIRE3,0,0},	// S_SPAWNFIRE2
+    {SPR_FIRE,32770,4,{A_Fire},S_SPAWNFIRE4,0,0},	// S_SPAWNFIRE3
+    {SPR_FIRE,32771,4,{A_Fire},S_SPAWNFIRE5,0,0},	// S_SPAWNFIRE4
+    {SPR_FIRE,32772,4,{A_Fire},S_SPAWNFIRE6,0,0},	// S_SPAWNFIRE5
+    {SPR_FIRE,32773,4,{A_Fire},S_SPAWNFIRE7,0,0},	// S_SPAWNFIRE6
+    {SPR_FIRE,32774,4,{A_Fire},S_SPAWNFIRE8,0,0},	// S_SPAWNFIRE7
+    {SPR_FIRE,32775,4,{A_Fire},S_NULL,0,0},		// S_SPAWNFIRE8
+    {SPR_MISL,32769,10,{NULL},S_BRAINEXPLODE2,0,0},	// S_BRAINEXPLODE1
+    {SPR_MISL,32770,10,{NULL},S_BRAINEXPLODE3,0,0},	// S_BRAINEXPLODE2
+    {SPR_MISL,32771,10,{A_BrainExplode},S_NULL,0,0},	// S_BRAINEXPLODE3
+    {SPR_ARM1,0,6,{NULL},S_ARM1A,0,0},	// S_ARM1
+    {SPR_ARM1,32769,7,{NULL},S_ARM1,0,0},	// S_ARM1A
+    {SPR_ARM2,0,6,{NULL},S_ARM2A,0,0},	// S_ARM2
+    {SPR_ARM2,32769,6,{NULL},S_ARM2,0,0},	// S_ARM2A
+    {SPR_BAR1,0,6,{NULL},S_BAR2,0,0},	// S_BAR1
+    {SPR_BAR1,1,6,{NULL},S_BAR1,0,0},	// S_BAR2
+    {SPR_BEXP,32768,5,{NULL},S_BEXP2,0,0},	// S_BEXP
+    {SPR_BEXP,32769,5,{A_Scream},S_BEXP3,0,0},	// S_BEXP2
+    {SPR_BEXP,32770,5,{NULL},S_BEXP4,0,0},	// S_BEXP3
+    {SPR_BEXP,32771,10,{A_Explode},S_BEXP5,0,0},	// S_BEXP4
+    {SPR_BEXP,32772,10,{NULL},S_NULL,0,0},	// S_BEXP5
+    {SPR_FCAN,32768,4,{NULL},S_BBAR2,0,0},	// S_BBAR1
+    {SPR_FCAN,32769,4,{NULL},S_BBAR3,0,0},	// S_BBAR2
+    {SPR_FCAN,32770,4,{NULL},S_BBAR1,0,0},	// S_BBAR3
+    {SPR_BON1,0,6,{NULL},S_BON1A,0,0},	// S_BON1
+    {SPR_BON1,1,6,{NULL},S_BON1B,0,0},	// S_BON1A
+    {SPR_BON1,2,6,{NULL},S_BON1C,0,0},	// S_BON1B
+    {SPR_BON1,3,6,{NULL},S_BON1D,0,0},	// S_BON1C
+    {SPR_BON1,2,6,{NULL},S_BON1E,0,0},	// S_BON1D
+    {SPR_BON1,1,6,{NULL},S_BON1,0,0},	// S_BON1E
+    {SPR_BON2,0,6,{NULL},S_BON2A,0,0},	// S_BON2
+    {SPR_BON2,1,6,{NULL},S_BON2B,0,0},	// S_BON2A
+    {SPR_BON2,2,6,{NULL},S_BON2C,0,0},	// S_BON2B
+    {SPR_BON2,3,6,{NULL},S_BON2D,0,0},	// S_BON2C
+    {SPR_BON2,2,6,{NULL},S_BON2E,0,0},	// S_BON2D
+    {SPR_BON2,1,6,{NULL},S_BON2,0,0},	// S_BON2E
+    {SPR_BKEY,0,10,{NULL},S_BKEY2,0,0},	// S_BKEY
+    {SPR_BKEY,32769,10,{NULL},S_BKEY,0,0},	// S_BKEY2
+    {SPR_RKEY,0,10,{NULL},S_RKEY2,0,0},	// S_RKEY
+    {SPR_RKEY,32769,10,{NULL},S_RKEY,0,0},	// S_RKEY2
+    {SPR_YKEY,0,10,{NULL},S_YKEY2,0,0},	// S_YKEY
+    {SPR_YKEY,32769,10,{NULL},S_YKEY,0,0},	// S_YKEY2
+    {SPR_BSKU,0,10,{NULL},S_BSKULL2,0,0},	// S_BSKULL
+    {SPR_BSKU,32769,10,{NULL},S_BSKULL,0,0},	// S_BSKULL2
+    {SPR_RSKU,0,10,{NULL},S_RSKULL2,0,0},	// S_RSKULL
+    {SPR_RSKU,32769,10,{NULL},S_RSKULL,0,0},	// S_RSKULL2
+    {SPR_YSKU,0,10,{NULL},S_YSKULL2,0,0},	// S_YSKULL
+    {SPR_YSKU,32769,10,{NULL},S_YSKULL,0,0},	// S_YSKULL2
+    {SPR_STIM,0,-1,{NULL},S_NULL,0,0},	// S_STIM
+    {SPR_MEDI,0,-1,{NULL},S_NULL,0,0},	// S_MEDI
+    {SPR_SOUL,32768,6,{NULL},S_SOUL2,0,0},	// S_SOUL
+    {SPR_SOUL,32769,6,{NULL},S_SOUL3,0,0},	// S_SOUL2
+    {SPR_SOUL,32770,6,{NULL},S_SOUL4,0,0},	// S_SOUL3
+    {SPR_SOUL,32771,6,{NULL},S_SOUL5,0,0},	// S_SOUL4
+    {SPR_SOUL,32770,6,{NULL},S_SOUL6,0,0},	// S_SOUL5
+    {SPR_SOUL,32769,6,{NULL},S_SOUL,0,0},	// S_SOUL6
+    {SPR_PINV,32768,6,{NULL},S_PINV2,0,0},	// S_PINV
+    {SPR_PINV,32769,6,{NULL},S_PINV3,0,0},	// S_PINV2
+    {SPR_PINV,32770,6,{NULL},S_PINV4,0,0},	// S_PINV3
+    {SPR_PINV,32771,6,{NULL},S_PINV,0,0},	// S_PINV4
+    {SPR_PSTR,32768,-1,{NULL},S_NULL,0,0},	// S_PSTR
+    {SPR_PINS,32768,6,{NULL},S_PINS2,0,0},	// S_PINS
+    {SPR_PINS,32769,6,{NULL},S_PINS3,0,0},	// S_PINS2
+    {SPR_PINS,32770,6,{NULL},S_PINS4,0,0},	// S_PINS3
+    {SPR_PINS,32771,6,{NULL},S_PINS,0,0},	// S_PINS4
+    {SPR_MEGA,32768,6,{NULL},S_MEGA2,0,0},	// S_MEGA
+    {SPR_MEGA,32769,6,{NULL},S_MEGA3,0,0},	// S_MEGA2
+    {SPR_MEGA,32770,6,{NULL},S_MEGA4,0,0},	// S_MEGA3
+    {SPR_MEGA,32771,6,{NULL},S_MEGA,0,0},	// S_MEGA4
+    {SPR_SUIT,32768,-1,{NULL},S_NULL,0,0},	// S_SUIT
+    {SPR_PMAP,32768,6,{NULL},S_PMAP2,0,0},	// S_PMAP
+    {SPR_PMAP,32769,6,{NULL},S_PMAP3,0,0},	// S_PMAP2
+    {SPR_PMAP,32770,6,{NULL},S_PMAP4,0,0},	// S_PMAP3
+    {SPR_PMAP,32771,6,{NULL},S_PMAP5,0,0},	// S_PMAP4
+    {SPR_PMAP,32770,6,{NULL},S_PMAP6,0,0},	// S_PMAP5
+    {SPR_PMAP,32769,6,{NULL},S_PMAP,0,0},	// S_PMAP6
+    {SPR_PVIS,32768,6,{NULL},S_PVIS2,0,0},	// S_PVIS
+    {SPR_PVIS,1,6,{NULL},S_PVIS,0,0},	// S_PVIS2
+    {SPR_CLIP,0,-1,{NULL},S_NULL,0,0},	// S_CLIP
+    {SPR_AMMO,0,-1,{NULL},S_NULL,0,0},	// S_AMMO
+    {SPR_ROCK,0,-1,{NULL},S_NULL,0,0},	// S_ROCK
+    {SPR_BROK,0,-1,{NULL},S_NULL,0,0},	// S_BROK
+    {SPR_CELL,0,-1,{NULL},S_NULL,0,0},	// S_CELL
+    {SPR_CELP,0,-1,{NULL},S_NULL,0,0},	// S_CELP
+    {SPR_SHEL,0,-1,{NULL},S_NULL,0,0},	// S_SHEL
+    {SPR_SBOX,0,-1,{NULL},S_NULL,0,0},	// S_SBOX
+    {SPR_BPAK,0,-1,{NULL},S_NULL,0,0},	// S_BPAK
+    {SPR_BFUG,0,-1,{NULL},S_NULL,0,0},	// S_BFUG
+    {SPR_MGUN,0,-1,{NULL},S_NULL,0,0},	// S_MGUN
+    {SPR_CSAW,0,-1,{NULL},S_NULL,0,0},	// S_CSAW
+    {SPR_LAUN,0,-1,{NULL},S_NULL,0,0},	// S_LAUN
+    {SPR_PLAS,0,-1,{NULL},S_NULL,0,0},	// S_PLAS
+    {SPR_SHOT,0,-1,{NULL},S_NULL,0,0},	// S_SHOT
+    {SPR_SGN2,0,-1,{NULL},S_NULL,0,0},	// S_SHOT2
+    {SPR_COLU,32768,-1,{NULL},S_NULL,0,0},	// S_COLU
+    {SPR_SMT2,0,-1,{NULL},S_NULL,0,0},	// S_STALAG
+    {SPR_GOR1,0,10,{NULL},S_BLOODYTWITCH2,0,0},	// S_BLOODYTWITCH
+    {SPR_GOR1,1,15,{NULL},S_BLOODYTWITCH3,0,0},	// S_BLOODYTWITCH2
+    {SPR_GOR1,2,8,{NULL},S_BLOODYTWITCH4,0,0},	// S_BLOODYTWITCH3
+    {SPR_GOR1,1,6,{NULL},S_BLOODYTWITCH,0,0},	// S_BLOODYTWITCH4
+    {SPR_PLAY,13,-1,{NULL},S_NULL,0,0},	// S_DEADTORSO
+    {SPR_PLAY,18,-1,{NULL},S_NULL,0,0},	// S_DEADBOTTOM
+    {SPR_POL2,0,-1,{NULL},S_NULL,0,0},	// S_HEADSONSTICK
+    {SPR_POL5,0,-1,{NULL},S_NULL,0,0},	// S_GIBS
+    {SPR_POL4,0,-1,{NULL},S_NULL,0,0},	// S_HEADONASTICK
+    {SPR_POL3,32768,6,{NULL},S_HEADCANDLES2,0,0},	// S_HEADCANDLES
+    {SPR_POL3,32769,6,{NULL},S_HEADCANDLES,0,0},	// S_HEADCANDLES2
+    {SPR_POL1,0,-1,{NULL},S_NULL,0,0},	// S_DEADSTICK
+    {SPR_POL6,0,6,{NULL},S_LIVESTICK2,0,0},	// S_LIVESTICK
+    {SPR_POL6,1,8,{NULL},S_LIVESTICK,0,0},	// S_LIVESTICK2
+    {SPR_GOR2,0,-1,{NULL},S_NULL,0,0},	// S_MEAT2
+    {SPR_GOR3,0,-1,{NULL},S_NULL,0,0},	// S_MEAT3
+    {SPR_GOR4,0,-1,{NULL},S_NULL,0,0},	// S_MEAT4
+    {SPR_GOR5,0,-1,{NULL},S_NULL,0,0},	// S_MEAT5
+    {SPR_SMIT,0,-1,{NULL},S_NULL,0,0},	// S_STALAGTITE
+    {SPR_COL1,0,-1,{NULL},S_NULL,0,0},	// S_TALLGRNCOL
+    {SPR_COL2,0,-1,{NULL},S_NULL,0,0},	// S_SHRTGRNCOL
+    {SPR_COL3,0,-1,{NULL},S_NULL,0,0},	// S_TALLREDCOL
+    {SPR_COL4,0,-1,{NULL},S_NULL,0,0},	// S_SHRTREDCOL
+    {SPR_CAND,32768,-1,{NULL},S_NULL,0,0},	// S_CANDLESTIK
+    {SPR_CBRA,32768,-1,{NULL},S_NULL,0,0},	// S_CANDELABRA
+    {SPR_COL6,0,-1,{NULL},S_NULL,0,0},	// S_SKULLCOL
+    {SPR_TRE1,0,-1,{NULL},S_NULL,0,0},	// S_TORCHTREE
+    {SPR_TRE2,0,-1,{NULL},S_NULL,0,0},	// S_BIGTREE
+    {SPR_ELEC,0,-1,{NULL},S_NULL,0,0},	// S_TECHPILLAR
+    {SPR_CEYE,32768,6,{NULL},S_EVILEYE2,0,0},	// S_EVILEYE
+    {SPR_CEYE,32769,6,{NULL},S_EVILEYE3,0,0},	// S_EVILEYE2
+    {SPR_CEYE,32770,6,{NULL},S_EVILEYE4,0,0},	// S_EVILEYE3
+    {SPR_CEYE,32769,6,{NULL},S_EVILEYE,0,0},	// S_EVILEYE4
+    {SPR_FSKU,32768,6,{NULL},S_FLOATSKULL2,0,0},	// S_FLOATSKULL
+    {SPR_FSKU,32769,6,{NULL},S_FLOATSKULL3,0,0},	// S_FLOATSKULL2
+    {SPR_FSKU,32770,6,{NULL},S_FLOATSKULL,0,0},	// S_FLOATSKULL3
+    {SPR_COL5,0,14,{NULL},S_HEARTCOL2,0,0},	// S_HEARTCOL
+    {SPR_COL5,1,14,{NULL},S_HEARTCOL,0,0},	// S_HEARTCOL2
+    {SPR_TBLU,32768,4,{NULL},S_BLUETORCH2,0,0},	// S_BLUETORCH
+    {SPR_TBLU,32769,4,{NULL},S_BLUETORCH3,0,0},	// S_BLUETORCH2
+    {SPR_TBLU,32770,4,{NULL},S_BLUETORCH4,0,0},	// S_BLUETORCH3
+    {SPR_TBLU,32771,4,{NULL},S_BLUETORCH,0,0},	// S_BLUETORCH4
+    {SPR_TGRN,32768,4,{NULL},S_GREENTORCH2,0,0},	// S_GREENTORCH
+    {SPR_TGRN,32769,4,{NULL},S_GREENTORCH3,0,0},	// S_GREENTORCH2
+    {SPR_TGRN,32770,4,{NULL},S_GREENTORCH4,0,0},	// S_GREENTORCH3
+    {SPR_TGRN,32771,4,{NULL},S_GREENTORCH,0,0},	// S_GREENTORCH4
+    {SPR_TRED,32768,4,{NULL},S_REDTORCH2,0,0},	// S_REDTORCH
+    {SPR_TRED,32769,4,{NULL},S_REDTORCH3,0,0},	// S_REDTORCH2
+    {SPR_TRED,32770,4,{NULL},S_REDTORCH4,0,0},	// S_REDTORCH3
+    {SPR_TRED,32771,4,{NULL},S_REDTORCH,0,0},	// S_REDTORCH4
+    {SPR_SMBT,32768,4,{NULL},S_BTORCHSHRT2,0,0},	// S_BTORCHSHRT
+    {SPR_SMBT,32769,4,{NULL},S_BTORCHSHRT3,0,0},	// S_BTORCHSHRT2
+    {SPR_SMBT,32770,4,{NULL},S_BTORCHSHRT4,0,0},	// S_BTORCHSHRT3
+    {SPR_SMBT,32771,4,{NULL},S_BTORCHSHRT,0,0},	// S_BTORCHSHRT4
+    {SPR_SMGT,32768,4,{NULL},S_GTORCHSHRT2,0,0},	// S_GTORCHSHRT
+    {SPR_SMGT,32769,4,{NULL},S_GTORCHSHRT3,0,0},	// S_GTORCHSHRT2
+    {SPR_SMGT,32770,4,{NULL},S_GTORCHSHRT4,0,0},	// S_GTORCHSHRT3
+    {SPR_SMGT,32771,4,{NULL},S_GTORCHSHRT,0,0},	// S_GTORCHSHRT4
+    {SPR_SMRT,32768,4,{NULL},S_RTORCHSHRT2,0,0},	// S_RTORCHSHRT
+    {SPR_SMRT,32769,4,{NULL},S_RTORCHSHRT3,0,0},	// S_RTORCHSHRT2
+    {SPR_SMRT,32770,4,{NULL},S_RTORCHSHRT4,0,0},	// S_RTORCHSHRT3
+    {SPR_SMRT,32771,4,{NULL},S_RTORCHSHRT,0,0},	// S_RTORCHSHRT4
+    {SPR_HDB1,0,-1,{NULL},S_NULL,0,0},	// S_HANGNOGUTS
+    {SPR_HDB2,0,-1,{NULL},S_NULL,0,0},	// S_HANGBNOBRAIN
+    {SPR_HDB3,0,-1,{NULL},S_NULL,0,0},	// S_HANGTLOOKDN
+    {SPR_HDB4,0,-1,{NULL},S_NULL,0,0},	// S_HANGTSKULL
+    {SPR_HDB5,0,-1,{NULL},S_NULL,0,0},	// S_HANGTLOOKUP
+    {SPR_HDB6,0,-1,{NULL},S_NULL,0,0},	// S_HANGTNOBRAIN
+    {SPR_POB1,0,-1,{NULL},S_NULL,0,0},	// S_COLONGIBS
+    {SPR_POB2,0,-1,{NULL},S_NULL,0,0},	// S_SMALLPOOL
+    {SPR_BRS1,0,-1,{NULL},S_NULL,0,0},		// S_BRAINSTEM
+    {SPR_TLMP,32768,4,{NULL},S_TECHLAMP2,0,0},	// S_TECHLAMP
+    {SPR_TLMP,32769,4,{NULL},S_TECHLAMP3,0,0},	// S_TECHLAMP2
+    {SPR_TLMP,32770,4,{NULL},S_TECHLAMP4,0,0},	// S_TECHLAMP3
+    {SPR_TLMP,32771,4,{NULL},S_TECHLAMP,0,0},	// S_TECHLAMP4
+    {SPR_TLP2,32768,4,{NULL},S_TECH2LAMP2,0,0},	// S_TECH2LAMP
+    {SPR_TLP2,32769,4,{NULL},S_TECH2LAMP3,0,0},	// S_TECH2LAMP2
+    {SPR_TLP2,32770,4,{NULL},S_TECH2LAMP4,0,0},	// S_TECH2LAMP3
+    {SPR_TLP2,32771,4,{NULL},S_TECH2LAMP,0,0}	// S_TECH2LAMP4
+};
+
+
+mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
+
+    {		// MT_PLAYER
+	-1,		// doomednum
+	S_PLAY,		// spawnstate
+	100,		// spawnhealth
+	S_PLAY_RUN1,		// seestate
+	sfx_None,		// seesound
+	0,		// reactiontime
+	sfx_None,		// attacksound
+	S_PLAY_PAIN,		// painstate
+	255,		// painchance
+	sfx_plpain,		// painsound
+	S_NULL,		// meleestate
+	S_PLAY_ATK1,		// missilestate
+	S_PLAY_DIE1,		// deathstate
+	S_PLAY_XDIE1,		// xdeathstate
+	sfx_pldeth,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	56*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_POSSESSED
+	3004,		// doomednum
+	S_POSS_STND,		// spawnstate
+	20,		// spawnhealth
+	S_POSS_RUN1,		// seestate
+	sfx_posit1,		// seesound
+	8,		// reactiontime
+	sfx_pistol,		// attacksound
+	S_POSS_PAIN,		// painstate
+	200,		// painchance
+	sfx_popain,		// painsound
+	0,		// meleestate
+	S_POSS_ATK1,		// missilestate
+	S_POSS_DIE1,		// deathstate
+	S_POSS_XDIE1,		// xdeathstate
+	sfx_podth1,		// deathsound
+	8,		// speed
+	20*FRACUNIT,		// radius
+	56*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_posact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_POSS_RAISE1		// raisestate
+    },
+
+    {		// MT_SHOTGUY
+	9,		// doomednum
+	S_SPOS_STND,		// spawnstate
+	30,		// spawnhealth
+	S_SPOS_RUN1,		// seestate
+	sfx_posit2,		// seesound
+	8,		// reactiontime
+	0,		// attacksound
+	S_SPOS_PAIN,		// painstate
+	170,		// painchance
+	sfx_popain,		// painsound
+	0,		// meleestate
+	S_SPOS_ATK1,		// missilestate
+	S_SPOS_DIE1,		// deathstate
+	S_SPOS_XDIE1,		// xdeathstate
+	sfx_podth2,		// deathsound
+	8,		// speed
+	20*FRACUNIT,		// radius
+	56*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_posact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_SPOS_RAISE1		// raisestate
+    },
+
+    {		// MT_VILE
+	64,		// doomednum
+	S_VILE_STND,		// spawnstate
+	700,		// spawnhealth
+	S_VILE_RUN1,		// seestate
+	sfx_vilsit,		// seesound
+	8,		// reactiontime
+	0,		// attacksound
+	S_VILE_PAIN,		// painstate
+	10,		// painchance
+	sfx_vipain,		// painsound
+	0,		// meleestate
+	S_VILE_ATK1,		// missilestate
+	S_VILE_DIE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_vildth,		// deathsound
+	15,		// speed
+	20*FRACUNIT,		// radius
+	56*FRACUNIT,		// height
+	500,		// mass
+	0,		// damage
+	sfx_vilact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_FIRE
+	-1,		// doomednum
+	S_FIRE1,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_UNDEAD
+	66,		// doomednum
+	S_SKEL_STND,		// spawnstate
+	300,		// spawnhealth
+	S_SKEL_RUN1,		// seestate
+	sfx_skesit,		// seesound
+	8,		// reactiontime
+	0,		// attacksound
+	S_SKEL_PAIN,		// painstate
+	100,		// painchance
+	sfx_popain,		// painsound
+	S_SKEL_FIST1,		// meleestate
+	S_SKEL_MISS1,		// missilestate
+	S_SKEL_DIE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_skedth,		// deathsound
+	10,		// speed
+	20*FRACUNIT,		// radius
+	56*FRACUNIT,		// height
+	500,		// mass
+	0,		// damage
+	sfx_skeact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_SKEL_RAISE1		// raisestate
+    },
+
+    {		// MT_TRACER
+	-1,		// doomednum
+	S_TRACER,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_skeatk,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_TRACEEXP1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_barexp,		// deathsound
+	10*FRACUNIT,		// speed
+	11*FRACUNIT,		// radius
+	8*FRACUNIT,		// height
+	100,		// mass
+	10,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_SMOKE
+	-1,		// doomednum
+	S_SMOKE1,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_FATSO
+	67,		// doomednum
+	S_FATT_STND,		// spawnstate
+	600,		// spawnhealth
+	S_FATT_RUN1,		// seestate
+	sfx_mansit,		// seesound
+	8,		// reactiontime
+	0,		// attacksound
+	S_FATT_PAIN,		// painstate
+	80,		// painchance
+	sfx_mnpain,		// painsound
+	0,		// meleestate
+	S_FATT_ATK1,		// missilestate
+	S_FATT_DIE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_mandth,		// deathsound
+	8,		// speed
+	48*FRACUNIT,		// radius
+	64*FRACUNIT,		// height
+	1000,		// mass
+	0,		// damage
+	sfx_posact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_FATT_RAISE1		// raisestate
+    },
+
+    {		// MT_FATSHOT
+	-1,		// doomednum
+	S_FATSHOT1,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_firsht,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_FATSHOTX1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_firxpl,		// deathsound
+	20*FRACUNIT,		// speed
+	6*FRACUNIT,		// radius
+	8*FRACUNIT,		// height
+	100,		// mass
+	8,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_CHAINGUY
+	65,		// doomednum
+	S_CPOS_STND,		// spawnstate
+	70,		// spawnhealth
+	S_CPOS_RUN1,		// seestate
+	sfx_posit2,		// seesound
+	8,		// reactiontime
+	0,		// attacksound
+	S_CPOS_PAIN,		// painstate
+	170,		// painchance
+	sfx_popain,		// painsound
+	0,		// meleestate
+	S_CPOS_ATK1,		// missilestate
+	S_CPOS_DIE1,		// deathstate
+	S_CPOS_XDIE1,		// xdeathstate
+	sfx_podth2,		// deathsound
+	8,		// speed
+	20*FRACUNIT,		// radius
+	56*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_posact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_CPOS_RAISE1		// raisestate
+    },
+
+    {		// MT_TROOP
+	3001,		// doomednum
+	S_TROO_STND,		// spawnstate
+	60,		// spawnhealth
+	S_TROO_RUN1,		// seestate
+	sfx_bgsit1,		// seesound
+	8,		// reactiontime
+	0,		// attacksound
+	S_TROO_PAIN,		// painstate
+	200,		// painchance
+	sfx_popain,		// painsound
+	S_TROO_ATK1,		// meleestate
+	S_TROO_ATK1,		// missilestate
+	S_TROO_DIE1,		// deathstate
+	S_TROO_XDIE1,		// xdeathstate
+	sfx_bgdth1,		// deathsound
+	8,		// speed
+	20*FRACUNIT,		// radius
+	56*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_bgact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_TROO_RAISE1		// raisestate
+    },
+
+    {		// MT_SERGEANT
+	3002,		// doomednum
+	S_SARG_STND,		// spawnstate
+	150,		// spawnhealth
+	S_SARG_RUN1,		// seestate
+	sfx_sgtsit,		// seesound
+	8,		// reactiontime
+	sfx_sgtatk,		// attacksound
+	S_SARG_PAIN,		// painstate
+	180,		// painchance
+	sfx_dmpain,		// painsound
+	S_SARG_ATK1,		// meleestate
+	0,		// missilestate
+	S_SARG_DIE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_sgtdth,		// deathsound
+	10,		// speed
+	30*FRACUNIT,		// radius
+	56*FRACUNIT,		// height
+	400,		// mass
+	0,		// damage
+	sfx_dmact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_SARG_RAISE1		// raisestate
+    },
+
+    {		// MT_SHADOWS
+	58,		// doomednum
+	S_SARG_STND,		// spawnstate
+	150,		// spawnhealth
+	S_SARG_RUN1,		// seestate
+	sfx_sgtsit,		// seesound
+	8,		// reactiontime
+	sfx_sgtatk,		// attacksound
+	S_SARG_PAIN,		// painstate
+	180,		// painchance
+	sfx_dmpain,		// painsound
+	S_SARG_ATK1,		// meleestate
+	0,		// missilestate
+	S_SARG_DIE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_sgtdth,		// deathsound
+	10,		// speed
+	30*FRACUNIT,		// radius
+	56*FRACUNIT,		// height
+	400,		// mass
+	0,		// damage
+	sfx_dmact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_SHADOW|MF_COUNTKILL,		// flags
+	S_SARG_RAISE1		// raisestate
+    },
+
+    {		// MT_HEAD
+	3005,		// doomednum
+	S_HEAD_STND,		// spawnstate
+	400,		// spawnhealth
+	S_HEAD_RUN1,		// seestate
+	sfx_cacsit,		// seesound
+	8,		// reactiontime
+	0,		// attacksound
+	S_HEAD_PAIN,		// painstate
+	128,		// painchance
+	sfx_dmpain,		// painsound
+	0,		// meleestate
+	S_HEAD_ATK1,		// missilestate
+	S_HEAD_DIE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_cacdth,		// deathsound
+	8,		// speed
+	31*FRACUNIT,		// radius
+	56*FRACUNIT,		// height
+	400,		// mass
+	0,		// damage
+	sfx_dmact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_FLOAT|MF_NOGRAVITY|MF_COUNTKILL,		// flags
+	S_HEAD_RAISE1		// raisestate
+    },
+
+    {		// MT_BRUISER
+	3003,		// doomednum
+	S_BOSS_STND,		// spawnstate
+	1000,		// spawnhealth
+	S_BOSS_RUN1,		// seestate
+	sfx_brssit,		// seesound
+	8,		// reactiontime
+	0,		// attacksound
+	S_BOSS_PAIN,		// painstate
+	50,		// painchance
+	sfx_dmpain,		// painsound
+	S_BOSS_ATK1,		// meleestate
+	S_BOSS_ATK1,		// missilestate
+	S_BOSS_DIE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_brsdth,		// deathsound
+	8,		// speed
+	24*FRACUNIT,		// radius
+	64*FRACUNIT,		// height
+	1000,		// mass
+	0,		// damage
+	sfx_dmact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_BOSS_RAISE1		// raisestate
+    },
+
+    {		// MT_BRUISERSHOT
+	-1,		// doomednum
+	S_BRBALL1,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_firsht,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_BRBALLX1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_firxpl,		// deathsound
+	15*FRACUNIT,		// speed
+	6*FRACUNIT,		// radius
+	8*FRACUNIT,		// height
+	100,		// mass
+	8,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_KNIGHT
+	69,		// doomednum
+	S_BOS2_STND,		// spawnstate
+	500,		// spawnhealth
+	S_BOS2_RUN1,		// seestate
+	sfx_kntsit,		// seesound
+	8,		// reactiontime
+	0,		// attacksound
+	S_BOS2_PAIN,		// painstate
+	50,		// painchance
+	sfx_dmpain,		// painsound
+	S_BOS2_ATK1,		// meleestate
+	S_BOS2_ATK1,		// missilestate
+	S_BOS2_DIE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_kntdth,		// deathsound
+	8,		// speed
+	24*FRACUNIT,		// radius
+	64*FRACUNIT,		// height
+	1000,		// mass
+	0,		// damage
+	sfx_dmact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_BOS2_RAISE1		// raisestate
+    },
+
+    {		// MT_SKULL
+	3006,		// doomednum
+	S_SKULL_STND,		// spawnstate
+	100,		// spawnhealth
+	S_SKULL_RUN1,		// seestate
+	0,		// seesound
+	8,		// reactiontime
+	sfx_sklatk,		// attacksound
+	S_SKULL_PAIN,		// painstate
+	256,		// painchance
+	sfx_dmpain,		// painsound
+	0,		// meleestate
+	S_SKULL_ATK1,		// missilestate
+	S_SKULL_DIE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_firxpl,		// deathsound
+	8,		// speed
+	16*FRACUNIT,		// radius
+	56*FRACUNIT,		// height
+	50,		// mass
+	3,		// damage
+	sfx_dmact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_FLOAT|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_SPIDER
+	7,		// doomednum
+	S_SPID_STND,		// spawnstate
+	3000,		// spawnhealth
+	S_SPID_RUN1,		// seestate
+	sfx_spisit,		// seesound
+	8,		// reactiontime
+	sfx_shotgn,		// attacksound
+	S_SPID_PAIN,		// painstate
+	40,		// painchance
+	sfx_dmpain,		// painsound
+	0,		// meleestate
+	S_SPID_ATK1,		// missilestate
+	S_SPID_DIE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_spidth,		// deathsound
+	12,		// speed
+	128*FRACUNIT,		// radius
+	100*FRACUNIT,		// height
+	1000,		// mass
+	0,		// damage
+	sfx_dmact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_BABY
+	68,		// doomednum
+	S_BSPI_STND,		// spawnstate
+	500,		// spawnhealth
+	S_BSPI_SIGHT,		// seestate
+	sfx_bspsit,		// seesound
+	8,		// reactiontime
+	0,		// attacksound
+	S_BSPI_PAIN,		// painstate
+	128,		// painchance
+	sfx_dmpain,		// painsound
+	0,		// meleestate
+	S_BSPI_ATK1,		// missilestate
+	S_BSPI_DIE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_bspdth,		// deathsound
+	12,		// speed
+	64*FRACUNIT,		// radius
+	64*FRACUNIT,		// height
+	600,		// mass
+	0,		// damage
+	sfx_bspact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_BSPI_RAISE1		// raisestate
+    },
+
+    {		// MT_CYBORG
+	16,		// doomednum
+	S_CYBER_STND,		// spawnstate
+	4000,		// spawnhealth
+	S_CYBER_RUN1,		// seestate
+	sfx_cybsit,		// seesound
+	8,		// reactiontime
+	0,		// attacksound
+	S_CYBER_PAIN,		// painstate
+	20,		// painchance
+	sfx_dmpain,		// painsound
+	0,		// meleestate
+	S_CYBER_ATK1,		// missilestate
+	S_CYBER_DIE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_cybdth,		// deathsound
+	16,		// speed
+	40*FRACUNIT,		// radius
+	110*FRACUNIT,		// height
+	1000,		// mass
+	0,		// damage
+	sfx_dmact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_PAIN
+	71,		// doomednum
+	S_PAIN_STND,		// spawnstate
+	400,		// spawnhealth
+	S_PAIN_RUN1,		// seestate
+	sfx_pesit,		// seesound
+	8,		// reactiontime
+	0,		// attacksound
+	S_PAIN_PAIN,		// painstate
+	128,		// painchance
+	sfx_pepain,		// painsound
+	0,		// meleestate
+	S_PAIN_ATK1,		// missilestate
+	S_PAIN_DIE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_pedth,		// deathsound
+	8,		// speed
+	31*FRACUNIT,		// radius
+	56*FRACUNIT,		// height
+	400,		// mass
+	0,		// damage
+	sfx_dmact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_FLOAT|MF_NOGRAVITY|MF_COUNTKILL,		// flags
+	S_PAIN_RAISE1		// raisestate
+    },
+
+    {		// MT_WOLFSS
+	84,		// doomednum
+	S_SSWV_STND,		// spawnstate
+	50,		// spawnhealth
+	S_SSWV_RUN1,		// seestate
+	sfx_sssit,		// seesound
+	8,		// reactiontime
+	0,		// attacksound
+	S_SSWV_PAIN,		// painstate
+	170,		// painchance
+	sfx_popain,		// painsound
+	0,		// meleestate
+	S_SSWV_ATK1,		// missilestate
+	S_SSWV_DIE1,		// deathstate
+	S_SSWV_XDIE1,		// xdeathstate
+	sfx_ssdth,		// deathsound
+	8,		// speed
+	20*FRACUNIT,		// radius
+	56*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_posact,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_SSWV_RAISE1		// raisestate
+    },
+
+    {		// MT_KEEN
+	72,		// doomednum
+	S_KEENSTND,		// spawnstate
+	100,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_KEENPAIN,		// painstate
+	256,		// painchance
+	sfx_keenpn,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_COMMKEEN,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_keendt,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	72*FRACUNIT,		// height
+	10000000,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY|MF_SHOOTABLE|MF_COUNTKILL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_BOSSBRAIN
+	88,		// doomednum
+	S_BRAIN,		// spawnstate
+	250,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_BRAIN_PAIN,		// painstate
+	255,		// painchance
+	sfx_bospn,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_BRAIN_DIE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_bosdth,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	10000000,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID|MF_SHOOTABLE,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_BOSSSPIT
+	89,		// doomednum
+	S_BRAINEYE,		// spawnstate
+	1000,		// spawnhealth
+	S_BRAINEYESEE,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	32*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_NOSECTOR,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_BOSSTARGET
+	87,		// doomednum
+	S_NULL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	32*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_NOSECTOR,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_SPAWNSHOT
+	-1,		// doomednum
+	S_SPAWN1,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_bospit,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_firxpl,		// deathsound
+	10*FRACUNIT,		// speed
+	6*FRACUNIT,		// radius
+	32*FRACUNIT,		// height
+	100,		// mass
+	3,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY|MF_NOCLIP,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_SPAWNFIRE
+	-1,		// doomednum
+	S_SPAWNFIRE1,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_BARREL
+	2035,		// doomednum
+	S_BAR1,		// spawnstate
+	20,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_BEXP,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_barexp,		// deathsound
+	0,		// speed
+	10*FRACUNIT,		// radius
+	42*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID|MF_SHOOTABLE|MF_NOBLOOD,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_TROOPSHOT
+	-1,		// doomednum
+	S_TBALL1,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_firsht,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_TBALLX1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_firxpl,		// deathsound
+	10*FRACUNIT,		// speed
+	6*FRACUNIT,		// radius
+	8*FRACUNIT,		// height
+	100,		// mass
+	3,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_HEADSHOT
+	-1,		// doomednum
+	S_RBALL1,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_firsht,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_RBALLX1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_firxpl,		// deathsound
+	10*FRACUNIT,		// speed
+	6*FRACUNIT,		// radius
+	8*FRACUNIT,		// height
+	100,		// mass
+	5,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_ROCKET
+	-1,		// doomednum
+	S_ROCKET,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_rlaunc,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_EXPLODE1,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_barexp,		// deathsound
+	20*FRACUNIT,		// speed
+	11*FRACUNIT,		// radius
+	8*FRACUNIT,		// height
+	100,		// mass
+	20,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_PLASMA
+	-1,		// doomednum
+	S_PLASBALL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_plasma,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_PLASEXP,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_firxpl,		// deathsound
+	25*FRACUNIT,		// speed
+	13*FRACUNIT,		// radius
+	8*FRACUNIT,		// height
+	100,		// mass
+	5,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_BFG
+	-1,		// doomednum
+	S_BFGSHOT,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	0,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_BFGLAND,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_rxplod,		// deathsound
+	25*FRACUNIT,		// speed
+	13*FRACUNIT,		// radius
+	8*FRACUNIT,		// height
+	100,		// mass
+	100,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_ARACHPLAZ
+	-1,		// doomednum
+	S_ARACH_PLAZ,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_plasma,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_ARACH_PLEX,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_firxpl,		// deathsound
+	25*FRACUNIT,		// speed
+	13*FRACUNIT,		// radius
+	8*FRACUNIT,		// height
+	100,		// mass
+	5,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_MISSILE|MF_DROPOFF|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_PUFF
+	-1,		// doomednum
+	S_PUFF1,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_BLOOD
+	-1,		// doomednum
+	S_BLOOD1,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_TFOG
+	-1,		// doomednum
+	S_TFOG,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_IFOG
+	-1,		// doomednum
+	S_IFOG,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_TELEPORTMAN
+	14,		// doomednum
+	S_NULL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_NOSECTOR,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_EXTRABFG
+	-1,		// doomednum
+	S_BFGEXP,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_NOBLOCKMAP|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC0
+	2018,		// doomednum
+	S_ARM1,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC1
+	2019,		// doomednum
+	S_ARM2,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC2
+	2014,		// doomednum
+	S_BON1,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_COUNTITEM,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC3
+	2015,		// doomednum
+	S_BON2,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_COUNTITEM,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC4
+	5,		// doomednum
+	S_BKEY,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_NOTDMATCH,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC5
+	13,		// doomednum
+	S_RKEY,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_NOTDMATCH,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC6
+	6,		// doomednum
+	S_YKEY,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_NOTDMATCH,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC7
+	39,		// doomednum
+	S_YSKULL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_NOTDMATCH,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC8
+	38,		// doomednum
+	S_RSKULL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_NOTDMATCH,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC9
+	40,		// doomednum
+	S_BSKULL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_NOTDMATCH,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC10
+	2011,		// doomednum
+	S_STIM,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC11
+	2012,		// doomednum
+	S_MEDI,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC12
+	2013,		// doomednum
+	S_SOUL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_COUNTITEM,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_INV
+	2022,		// doomednum
+	S_PINV,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_COUNTITEM,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC13
+	2023,		// doomednum
+	S_PSTR,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_COUNTITEM,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_INS
+	2024,		// doomednum
+	S_PINS,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_COUNTITEM,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC14
+	2025,		// doomednum
+	S_SUIT,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC15
+	2026,		// doomednum
+	S_PMAP,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_COUNTITEM,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC16
+	2045,		// doomednum
+	S_PVIS,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_COUNTITEM,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MEGA
+	83,		// doomednum
+	S_MEGA,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL|MF_COUNTITEM,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_CLIP
+	2007,		// doomednum
+	S_CLIP,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC17
+	2048,		// doomednum
+	S_AMMO,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC18
+	2010,		// doomednum
+	S_ROCK,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC19
+	2046,		// doomednum
+	S_BROK,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC20
+	2047,		// doomednum
+	S_CELL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC21
+	17,		// doomednum
+	S_CELP,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC22
+	2008,		// doomednum
+	S_SHEL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC23
+	2049,		// doomednum
+	S_SBOX,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC24
+	8,		// doomednum
+	S_BPAK,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC25
+	2006,		// doomednum
+	S_BFUG,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_CHAINGUN
+	2002,		// doomednum
+	S_MGUN,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC26
+	2005,		// doomednum
+	S_CSAW,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC27
+	2003,		// doomednum
+	S_LAUN,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC28
+	2004,		// doomednum
+	S_PLAS,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_SHOTGUN
+	2001,		// doomednum
+	S_SHOT,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_SUPERSHOTGUN
+	82,		// doomednum
+	S_SHOT2,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPECIAL,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC29
+	85,		// doomednum
+	S_TECHLAMP,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC30
+	86,		// doomednum
+	S_TECH2LAMP,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC31
+	2028,		// doomednum
+	S_COLU,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC32
+	30,		// doomednum
+	S_TALLGRNCOL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC33
+	31,		// doomednum
+	S_SHRTGRNCOL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC34
+	32,		// doomednum
+	S_TALLREDCOL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC35
+	33,		// doomednum
+	S_SHRTREDCOL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC36
+	37,		// doomednum
+	S_SKULLCOL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC37
+	36,		// doomednum
+	S_HEARTCOL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC38
+	41,		// doomednum
+	S_EVILEYE,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC39
+	42,		// doomednum
+	S_FLOATSKULL,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC40
+	43,		// doomednum
+	S_TORCHTREE,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC41
+	44,		// doomednum
+	S_BLUETORCH,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC42
+	45,		// doomednum
+	S_GREENTORCH,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC43
+	46,		// doomednum
+	S_REDTORCH,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC44
+	55,		// doomednum
+	S_BTORCHSHRT,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC45
+	56,		// doomednum
+	S_GTORCHSHRT,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC46
+	57,		// doomednum
+	S_RTORCHSHRT,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC47
+	47,		// doomednum
+	S_STALAGTITE,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC48
+	48,		// doomednum
+	S_TECHPILLAR,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC49
+	34,		// doomednum
+	S_CANDLESTIK,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	0,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC50
+	35,		// doomednum
+	S_CANDELABRA,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	16*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC51
+	49,		// doomednum
+	S_BLOODYTWITCH,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	68*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC52
+	50,		// doomednum
+	S_MEAT2,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	84*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC53
+	51,		// doomednum
+	S_MEAT3,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	84*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC54
+	52,		// doomednum
+	S_MEAT4,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	68*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC55
+	53,		// doomednum
+	S_MEAT5,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	16*FRACUNIT,		// radius
+	52*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SOLID|MF_SPAWNCEILING|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC56
+	59,		// doomednum
+	S_MEAT2,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	84*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPAWNCEILING|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC57
+	60,		// doomednum
+	S_MEAT4,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	68*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPAWNCEILING|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC58
+	61,		// doomednum
+	S_MEAT3,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	52*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPAWNCEILING|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC59
+	62,		// doomednum
+	S_MEAT5,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	52*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPAWNCEILING|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC60
+	63,		// doomednum
+	S_BLOODYTWITCH,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_NULL,		// meleestate
+	S_NULL,		// missilestate
+	S_NULL,		// deathstate
+	S_NULL,		// xdeathstate
+	sfx_None,		// deathsound
+	0,		// speed
+	20*FRACUNIT,		// radius
+	68*FRACUNIT,		// height
+	100,		// mass
+	0,		// damage
+	sfx_None,		// activesound
+	MF_SPAWNCEILING|MF_NOGRAVITY,		// flags
+	S_NULL		// raisestate
+    },
+
+    {		// MT_MISC61
+	22,		// doomednum
+	S_HEAD_DIE6,		// spawnstate
+	1000,		// spawnhealth
+	S_NULL,		// seestate
+	sfx_None,		// seesound
+	8,		// reactiontime
+	sfx_None,		// attacksound
+	S_NULL,		// painstate
+	0,		// painchance
+	sfx_None,		// painsound
+	S_N