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