Source release for DOOM Classic for iOS version 2.1

This commit is contained in:
Travis Bradshaw
2012-01-31 16:40:40 -06:00
parent 0cdbbdf96e
commit 3bf2af22f3
371 changed files with 167116 additions and 776 deletions

View File

@@ -0,0 +1,72 @@
#
# automake Makefile.am for the PrBoom source directory
#
#
# Process this file with automake to produce Makefile.in
#
#
SUBDIRS = SDL POSIX MAC
gamesdir=$(prefix)/games
games_PROGRAMS = prboom prboom-game-server
CFLAGS = @CFLAGS@ @SDL_CFLAGS@
prboom_game_server_SOURCES = d_server.c protocol.h
prboom_game_server_LDADD = POSIX/libposixdoom.a SDL/i_network.o @NET_LIBS@ @SDL_LIBS@
COMMON_SRC = \
am_map.c g_game.c p_maputl.h r_plane.h \
am_map.h g_game.h p_mobj.c r_demo.c r_segs.c \
hu_lib.c lprintf.c p_mobj.h r_demo.h r_segs.h \
hu_lib.h lprintf.h p_plats.c r_sky.c \
d_deh.c hu_stuff.c m_argv.c p_pspr.c r_sky.h \
d_deh.h hu_stuff.h m_argv.h p_pspr.h r_state.h \
d_englsh.h i_joy.h m_bbox.c p_saveg.c r_things.c \
d_event.h m_bbox.h p_saveg.h r_things.h \
d_items.c i_network.h m_cheat.c p_setup.c s_sound.c \
d_items.h i_sound.h m_cheat.h p_setup.h s_sound.h \
d_main.c i_system.h m_fixed.h p_sight.c sounds.c \
d_main.h i_video.h m_menu.c p_spec.c sounds.h \
info.c m_menu.h p_spec.h st_lib.c \
d_net.h info.h m_misc.c p_switch.c st_lib.h \
d_player.h m_misc.h p_telept.c st_stuff.c \
m_random.c p_tick.c st_stuff.h i_main.h \
d_think.h m_random.h p_tick.h tables.c \
d_ticcmd.h m_swap.h p_user.c tables.h \
doomdata.h p_ceilng.c p_user.h v_video.c \
doomdef.c p_doors.c protocol.h v_video.h \
doomdef.h p_enemy.c r_bsp.c version.c \
doomstat.c p_enemy.h r_bsp.h version.h \
doomstat.h p_floor.c r_data.c w_wad.c \
doomtype.h p_genlin.c r_data.h w_wad.h \
dstrings.c p_inter.c r_defs.h wi_stuff.c \
dstrings.h p_inter.h r_draw.c wi_stuff.h \
f_finale.c p_lights.c r_draw.h z_bmalloc.c \
f_finale.h p_map.c r_main.c z_bmalloc.h \
f_wipe.c p_map.h r_main.h z_zone.c \
f_wipe.h p_maputl.c r_plane.c z_zone.h \
md5.c md5.h p_checksum.h p_checksum.c \
r_patch.c r_patch.h r_fps.c r_fps.h \
r_filter.c r_filter.h
NET_CLIENT_SRC = d_client.c
if BUILD_GL
USE_GL_SRC = gl_intern.h gl_main.c gl_struct.h gl_texture.c
else
USE_GL_SRC =
endif
if WAD_MMAP
WAD_SRC = w_mmap.c
else
WAD_SRC = w_memcache.c
endif
prboom_SOURCES = mmus2mid.c mmus2mid.h $(COMMON_SRC) $(NET_CLIENT_SRC) $(USE_GL_SRC) $(WAD_SRC)
prboom_LDADD = SDL/libsdldoom.a @MIXER_LIBS@ @NET_LIBS@ @SDL_LIBS@ @GL_LIBS@ @MATH_LIB@
EXTRA_DIST = \
r_drawcolumn.inl r_drawflush.inl r_drawspan.inl r_drawcolpipeline.inl

View File

@@ -0,0 +1,211 @@
/*
* SDL_opengl.h
* doom
*
* Created by John Carmack on 4/13/09.
* Copyright 2009 idSoftware. All rights reserved.
*
* iPhone glue to get the prBoom code compiling
* Replaces SDL_opengl.h
*/
#ifndef __SDL_OPENGL_H__
#define __SDL_OPENGL_H__
#include <OpenGLES/ES1/gl.h>
#include <OpenGLES/ES1/glext.h>
#define GLAPIENTRY
// this needs to be added before each projection matrix
int iphoneRotateForLandscape();
// no colorTable in ES
typedef void (* PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
static GLubyte *gluErrorString( int err ) { return (GLubyte *)"GLU error"; }
static void *SDL_GL_GetProcAddress( const char *proc ) { return 0; }
static void SDL_GL_SwapBuffers() {}
// we need to emulate immediate mode gl for ES
void glBegin( GLenum prim );
void glVertex3f( GLfloat x, GLfloat y, GLfloat z );
void glVertex3fv( GLfloat *xyz );
void glVertex2f( GLfloat x, GLfloat y );
void glVertex2i( GLint x, GLint y );
void glTexCoord2i( GLint s, GLint t );
void glTexCoord2f( GLfloat s, GLfloat t );
void glTexCoord2fv( GLfloat *st );
void glEnd();
// Doom just uses state color for all draw calls, setting it once
// before a glBegin, rather than setting it each vertex, so we
// don't need to emulate the color functions.
//#defne VERTEX_COLOR
#ifdef VERTEX_COLOR
void glColor4ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a );
void glColor4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a );
void glColor4fv( GLfloat *rgba );
void glColor3f( GLfloat r, GLfloat g, GLfloat b );
#endif
// GLES only defines glColor4ub and glColor4f, so define the others in terms of that
#define glColor4fv(x) glColor4f(x[0],x[1],x[2],x[3])
#define glColor4ubv(x) glColor4ub(x[0],x[1],x[2],x[3])
#define glColor3f(r,g,b) glColor4f(r,g,b,1)
// The width and height need to be flipped for iPhone landscape mode,
// so redefine these functions to something that can do the work behind
// the scenes.
void landscapeViewport( GLint x, GLint y, GLsizei width, GLsizei height );
void landscapeScissor( GLint x, GLint y, GLsizei width, GLsizei height );
#define glViewport landscapeViewport
#define glScissor landscapeScissor
// ES made matching fixed and floating versions of some functions
#define glClearDepth glClearDepthf
#define glOrtho glOrthof
#define glFogi glFogx
// no GLdouble in ES, but needed for glu tesselator
typedef double GLdouble;
// ES doesn't have the messy clamp-to-half-border mode
#define GL_CLAMP GL_CLAMP_TO_EDGE
// this is the internal format used by the prBoom gl code
// ES doesn't allow format conversions between external and internal,
// so we need to manually convert to 5551 before doing glTexSubImage
#define GL_RGB5_A1 GL_RGBA
#define GL_RGBA8 GL_RGBA
#define GL_RGBA4 GL_RGBA
#define GL_RGBA2 GL_RGBA
// not available in ES, so prBoom's skies must be implemeted differently
static void glTexGenfv( int a, int b, void *c ) { };
static void glTexGenf( int a, int b, int c ) { };
// texGen enums not present in ES
#define GL_S 0x2000
#define GL_T 0x2001
#define GL_R 0x2002
#define GL_Q 0x2003
#define GL_OBJECT_LINEAR 0x2401
#define GL_OBJECT_PLANE 0x2501
#define GL_EYE_LINEAR 0x2400
#define GL_EYE_PLANE 0x2502
#define GL_TEXTURE_GEN_MODE 0x2500
#define GL_TEXTURE_GEN_S 0x0C60
#define GL_TEXTURE_GEN_T 0x0C61
#define GL_TEXTURE_GEN_R 0x0C62
#define GL_TEXTURE_GEN_Q 0x0C63
// other extensions not present in ES
// Whlle the iPhone exports the extension for paletted
// textures, it isn't actually supported in hardware, so
// they are expanded internally on glTexImage2D, making their
// use completely counterproductive.
#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB
#define GL_COLOR_INDEX 0x1900
#define GL_COLOR_INDEX8_EXT 0x80E5
//===========================
// all this for the glu tesselator, used by prBoom to make drawable sector geometry
//===========================
#include "../libtess/tess.h"
/* TessCallback */
#define GLU_TESS_BEGIN 100100
#define GLU_BEGIN 100100
#define GLU_TESS_VERTEX 100101
#define GLU_VERTEX 100101
#define GLU_TESS_END 100102
#define GLU_END 100102
#define GLU_TESS_ERROR 100103
#define GLU_TESS_EDGE_FLAG 100104
#define GLU_EDGE_FLAG 100104
#define GLU_TESS_COMBINE 100105
#define GLU_TESS_BEGIN_DATA 100106
#define GLU_TESS_VERTEX_DATA 100107
#define GLU_TESS_END_DATA 100108
#define GLU_TESS_ERROR_DATA 100109
#define GLU_TESS_EDGE_FLAG_DATA 100110
#define GLU_TESS_COMBINE_DATA 100111
/* TessContour */
#define GLU_CW 100120
#define GLU_CCW 100121
#define GLU_INTERIOR 100122
#define GLU_EXTERIOR 100123
#define GLU_UNKNOWN 100124
/* TessProperty */
#define GLU_TESS_WINDING_RULE 100140
#define GLU_TESS_BOUNDARY_ONLY 100141
#define GLU_TESS_TOLERANCE 100142
/* TessError */
#define GLU_TESS_ERROR1 100151
#define GLU_TESS_ERROR2 100152
#define GLU_TESS_ERROR3 100153
#define GLU_TESS_ERROR4 100154
#define GLU_TESS_ERROR5 100155
#define GLU_TESS_ERROR6 100156
#define GLU_TESS_ERROR7 100157
#define GLU_TESS_ERROR8 100158
#define GLU_TESS_MISSING_BEGIN_POLYGON 100151
#define GLU_TESS_MISSING_BEGIN_CONTOUR 100152
#define GLU_TESS_MISSING_END_POLYGON 100153
#define GLU_TESS_MISSING_END_CONTOUR 100154
#define GLU_TESS_COORD_TOO_LARGE 100155
#define GLU_TESS_NEED_COMBINE_CALLBACK 100156
/* TessWinding */
#define GLU_TESS_WINDING_ODD 100130
#define GLU_TESS_WINDING_NONZERO 100131
#define GLU_TESS_WINDING_POSITIVE 100132
#define GLU_TESS_WINDING_NEGATIVE 100133
#define GLU_TESS_WINDING_ABS_GEQ_TWO 100134
/* ErrorCode */
#define GLU_INVALID_ENUM 100900
#define GLU_INVALID_VALUE 100901
#define GLU_OUT_OF_MEMORY 100902
#define GLU_INCOMPATIBLE_GL_VERSION 100903
#define GLU_INVALID_OPERATION 100904
#define GLAPI
#define GLAPIENTRYP
typedef struct GLUtesselator GLUtesselator;
typedef GLUtesselator GLUtesselatorObj;
typedef GLUtesselator GLUtriangulatorObj;
#define GLU_TESS_MAX_COORD 1.0e150
/* Internal convenience typedefs */
typedef void (GLAPIENTRYP _GLUfuncptr)();
GLAPI void GLAPIENTRY gluTessBeginContour (GLUtesselator* tess);
GLAPI void GLAPIENTRY gluTessBeginPolygon (GLUtesselator* tess, GLvoid* data);
GLAPI void GLAPIENTRY gluTessCallback (GLUtesselator* tess, GLenum which, _GLUfuncptr CallBackFunc);
GLAPI void GLAPIENTRY gluTessEndContour (GLUtesselator* tess);
GLAPI void GLAPIENTRY gluTessEndPolygon (GLUtesselator* tess);
GLAPI void GLAPIENTRY gluTessNormal (GLUtesselator* tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ);
GLAPI void GLAPIENTRY gluTessProperty (GLUtesselator* tess, GLenum which, GLdouble data);
GLAPI void GLAPIENTRY gluTessVertex (GLUtesselator* tess, GLdouble *location, GLvoid* data);
GLUtesselator * GLAPIENTRY gluNewTess( void );
void GLAPIENTRY gluDeleteTess( GLUtesselator *tess );
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,111 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* AutoMap module.
*
*-----------------------------------------------------------------------------*/
#ifndef __AMMAP_H__
#define __AMMAP_H__
#include "d_event.h"
#define MAPBITS 12
#define FRACTOMAPBITS (FRACBITS-MAPBITS)
// 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);
// killough 2/22/98: for saving automap information in savegame:
extern void AM_Start(void);
//jff 4/16/98 make externally available
extern void AM_clearMarks(void);
typedef struct
{
fixed_t x,y;
} mpoint_t;
extern mpoint_t *markpoints;
extern int markpointnum, markpointnum_max;
// end changes -- killough 2/22/98
// killough 5/2/98: moved from m_misc.c
//jff 1/7/98 automap colors added
extern int mapcolor_back; // map background
extern int mapcolor_grid; // grid lines color
extern int mapcolor_wall; // normal 1s wall color
extern int mapcolor_fchg; // line at floor height change color
extern int mapcolor_cchg; // line at ceiling height change color
extern int mapcolor_clsd; // line at sector with floor=ceiling color
extern int mapcolor_rkey; // red key color
extern int mapcolor_bkey; // blue key color
extern int mapcolor_ykey; // yellow key color
extern int mapcolor_rdor; // red door color (diff from keys to allow option)
extern int mapcolor_bdor; // blue door color (of enabling one not other)
extern int mapcolor_ydor; // yellow door color
extern int mapcolor_tele; // teleporter line color
extern int mapcolor_secr; // secret sector boundary color
//jff 4/23/98
extern int mapcolor_exit; // exit line
extern int mapcolor_unsn; // computer map unseen line color
extern int mapcolor_flat; // line with no floor/ceiling changes
extern int mapcolor_sprt; // general sprite color
extern int mapcolor_item; // item sprite color
extern int mapcolor_enemy; // enemy sprite color
extern int mapcolor_frnd; // friendly sprite color
extern int mapcolor_hair; // crosshair color
extern int mapcolor_sngl; // single player arrow color
extern int mapcolor_plyr[4]; // colors for players in multiplayer
extern int mapcolor_me; // consoleplayer's chosen colour
//jff 3/9/98
extern int map_secret_after; // secrets do not appear til after bagged
#endif

View File

@@ -0,0 +1,112 @@
/**/
#define PACKAGE "prboom"
#define VERSION "2.5.0"
#ifdef DEBUG
/* Define to enable internal range checking */
#define RANGECHECK 1
/* Define this to see real-time memory allocation
* statistics, and enable extra debugging features
*/
#define INSTRUMENTED 1
/* Uncomment this to exhaustively run memory checks
* while the game is running (this is EXTREMELY slow).
* Only useful if INSTRUMENTED is also defined.
*/
#define CHECKHEAP 1
/* Uncomment this to cause heap dumps to be generated.
* Only useful if INSTRUMENTED is also defined.
*/
#define HEAPDUMP 1
/* Uncomment this to perform id checks on zone blocks,
* to detect corrupted and illegally freed blocks
*/
#define ZONEIDCHECK 1
/* CPhipps - some debugging macros for the new wad lump handling code */
/* Defining this causes quick checks which only impose an overhead if a
* posible error is detected. */
#define SIMPLECHECKS 1
/* Defining this causes time stamps to be created each time a lump is locked, and
* lumps locked for long periods of time are reported */
#define TIMEDIAG 1
#endif // DEBUG
#define DOGS 1
#define MONITOR_VISIBILITY 1
/*#define DISABLE_LUMP_CACHING*/
/**/
#define USE_SDL 1
/*#define HAVE_MIXER 1*/
#define HAVE_NET 1
#define USE_SDL_NET 1
/**/
#define HIGHRES 1
#define GL_DOOM 1
#define USE_GLU_TESS 1
#define USE_GLU_IMAGESCALE 1
#define USE_GLU_MIPMAP 1
#define DISABLE_DOUBLEBUFFER
/**/
#define STDC_HEADERS 1
#define stricmp strcasecmp
#define strnicmp strncasecmp
#define HAVE_INET_ATON 1
#define HAVE_INET_NTOP 1
#define HAVE_INET_PTON 1
#define HAVE_SETSOCKOPT 1
#define HAVE_SNPRINTF 1
#define HAVE_VSNPRINTF 1
#define HAVE_MKSTEMPS 1
#define HAVE_IPv6 1
#define HAVE_UNISTD_H
#define HAVE_SYS_WAIT_H
#define HAVE_GETOPT
/* causes a duplicate define warning
#define HAVE_NETINET_IN_H
*/
#define SYS_SIGLIST_DECLARED
/**/
#ifdef __BIG_ENDIAN__
#define WORDS_BIGENDIAN
#endif
#ifdef __i386__
#define I386_ASM 1
#endif
#define PACKEDATTR __attribute__((packed))
#define MACOSX
#define HAVE_LIBKERN_OSBYTEORDER_H
#define HAVE_OWN_MUSIC
#define UPDATE_MUSIC
#define SCREENSHOT_DIR I_DoomExeDir()
#define HEAPDUMP_DIR I_DoomExeDir()
//------ JDC config changes for iPhone ------------
#undef I386_ASM
#undef USE_SDL
#undef USE_SDL_NET
#undef HAVE_NET
#undef DOGS // not sure why this needs to be removed, info.c complains
#undef USE_GLU_IMAGESCALE
#undef USE_GLU_MIPMAP

View File

@@ -0,0 +1,539 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Network client. Passes information to/from server, staying
* synchronised.
* Contains the main wait loop, waiting for network input or
* time before doing the next tic.
* Rewritten for LxDoom, but based around bits of the old code.
*
*-----------------------------------------------------------------------------
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifdef USE_SDL_NET
#include "SDL.h"
#endif
#include "doomtype.h"
#include "doomstat.h"
#include "d_net.h"
#include "z_zone.h"
#include "d_main.h"
#include "g_game.h"
#include "m_menu.h"
#include "p_checksum.h"
#include "protocol.h"
#include "i_network.h"
#include "i_system.h"
#include "i_main.h"
#include "i_video.h"
#include "m_argv.h"
#include "r_fps.h"
#include "lprintf.h"
static boolean server;
static int remotetic; // Tic expected from the remote
static int remotesend; // Tic expected by the remote
ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS];
static ticcmd_t* localcmds;
static unsigned numqueuedpackets;
static packet_header_t** queuedpacket;
int maketic;
int ticdup = 1;
static int xtratics = 0;
int wanted_player_number;
static boolean isExtraDDisplay = false;
static void D_QuitNetGame (void);
#ifndef HAVE_NET
doomcom_t* doomcom;
#endif
#ifdef HAVE_NET
void D_InitNetGame (void)
{
int i;
int numplayers = 1;
i = M_CheckParm("-net");
if (i && i < myargc-1) i++;
if (!(netgame = server = !!i)) {
playeringame[consoleplayer = 0] = true;
// e6y
// for play, recording or playback using "single-player coop" mode.
// Equivalent to using prboom_server with -N 1
netgame = M_CheckParm("-solo-net") || M_CheckParm("-net1");
} else {
// Get game info from server
packet_header_t *packet = Z_Malloc(1000, PU_STATIC, NULL);
struct setup_packet_s *sinfo = (void*)(packet+1);
struct { packet_header_t head; short pn; } PACKEDATTR initpacket;
I_InitNetwork();
udp_socket = I_Socket(0);
I_ConnectToServer(myargv[i]);
do
{
do {
// Send init packet
initpacket.pn = doom_htons(wanted_player_number);
packet_set(&initpacket.head, PKT_INIT, 0);
I_SendPacket(&initpacket.head, sizeof(initpacket));
I_WaitForPacket(5000);
} while (!I_GetPacket(packet, 1000));
if (packet->type == PKT_DOWN) I_Error("Server aborted the game");
} while (packet->type != PKT_SETUP);
// Once we have been accepted by the server, we should tell it when we leave
atexit(D_QuitNetGame);
// Get info from the setup packet
consoleplayer = sinfo->yourplayer;
compatibility_level = sinfo->complevel;
G_Compatibility();
startskill = sinfo->skill;
deathmatch = sinfo->deathmatch;
startmap = sinfo->level;
startepisode = sinfo->episode;
ticdup = sinfo->ticdup;
xtratics = sinfo->extratic;
G_ReadOptions(sinfo->game_options);
lprintf(LO_INFO, "\tjoined game as player %d/%d; %d WADs specified\n",
consoleplayer+1, numplayers = sinfo->players, sinfo->numwads);
{
char *p = sinfo->wadnames;
int i = sinfo->numwads;
while (i--) {
D_AddFile(p, source_net);
p += strlen(p) + 1;
}
}
Z_Free(packet);
}
localcmds = netcmds[displayplayer = consoleplayer];
for (i=0; i<numplayers; i++)
playeringame[i] = true;
for (; i<MAXPLAYERS; i++)
playeringame[i] = false;
if (!playeringame[consoleplayer]) I_Error("D_InitNetGame: consoleplayer not in game");
}
#else
void D_InitNetGame (void)
{
int i;
doomcom = Z_Malloc(sizeof *doomcom, PU_STATIC, NULL);
doomcom->consoleplayer = 0;
doomcom->numnodes = 0; doomcom->numplayers = 1;
localcmds = netcmds[consoleplayer];
netgame = (M_CheckParm("-solo-net") != 0) || (M_CheckParm("-net1") != 0);
for (i=0; i<doomcom->numplayers; i++)
playeringame[i] = true;
for (; i<MAXPLAYERS; i++)
playeringame[i] = false;
consoleplayer = displayplayer = doomcom->consoleplayer;
}
#endif // HAVE_NET
#ifdef HAVE_NET
void D_CheckNetGame(void)
{
packet_header_t *packet = Z_Malloc(sizeof(packet_header_t)+1, PU_STATIC, NULL);
if (server) {
lprintf(LO_INFO, "D_CheckNetGame: waiting for server to signal game start\n");
do {
while (!I_GetPacket(packet, sizeof(packet_header_t)+1)) {
packet_set(packet, PKT_GO, 0);
*(byte*)(packet+1) = consoleplayer;
I_SendPacket(packet, sizeof(packet_header_t)+1);
I_uSleep(100000);
}
} while (packet->type != PKT_GO);
}
Z_Free(packet);
}
boolean D_NetGetWad(const char* name)
{
#if defined(HAVE_WAIT_H)
size_t psize = sizeof(packet_header_t) + strlen(name) + 500;
packet_header_t *packet;
boolean done = false;
if (!server || strchr(name, '/')) return false; // If it contains path info, reject
do {
// Send WAD request to remote
packet = Z_Malloc(psize, PU_STATIC, NULL);
packet_set(packet, PKT_WAD, 0);
*(byte*)(packet+1) = consoleplayer;
strcpy(1+(byte*)(packet+1), name);
I_SendPacket(packet, sizeof(packet_header_t) + strlen(name) + 2);
I_uSleep(10000);
} while (!I_GetPacket(packet, psize) || (packet->type != PKT_WAD));
Z_Free(packet);
if (!strcasecmp((void*)(packet+1), name)) {
pid_t pid;
int rv;
byte *p = (byte*)(packet+1) + strlen(name) + 1;
/* Automatic wad file retrieval using wget (supports http and ftp, using URLs)
* Unix systems have all these commands handy, this kind of thing is easy
* Any windo$e port will have some awkward work replacing these.
*/
/* cph - caution here. This is data from an untrusted source.
* Don't pass it via a shell. */
if ((pid = fork()) == -1)
perror("fork");
else if (!pid) {
/* Child chains to wget, does the download */
execlp("wget", "wget", p, NULL);
}
/* This is the parent, i.e. main LxDoom process */
wait(&rv);
if (!(done = !access(name, R_OK))) {
if (!strcmp(p+strlen(p)-4, ".zip")) {
p = strrchr(p, '/')+1;
if ((pid = fork()) == -1)
perror("fork");
else if (!pid) {
/* Child executes decompressor */
execlp("unzip", "unzip", p, name, NULL);
}
/* Parent waits for the file */
wait(&rv);
done = !!access(name, R_OK);
}
/* Add more decompression protocols here as desired */
}
Z_Free(buffer);
}
return done;
#else /* HAVE_WAIT_H */
return false;
#endif
}
void NetUpdate(void)
{
static int lastmadetic;
if (isExtraDDisplay)
return;
if (server) { // Receive network packets
size_t recvlen;
packet_header_t *packet = Z_Malloc(10000, PU_STATIC, NULL);
while ((recvlen = I_GetPacket(packet, 10000))) {
switch(packet->type) {
case PKT_TICS:
{
byte *p = (void*)(packet+1);
int tics = *p++;
unsigned long ptic = doom_ntohl(packet->tic);
if (ptic > (unsigned)remotetic) { // Missed some
packet_set(packet, PKT_RETRANS, remotetic);
*(byte*)(packet+1) = consoleplayer;
I_SendPacket(packet, sizeof(*packet)+1);
} else {
if (ptic + tics <= (unsigned)remotetic) break; // Will not improve things
remotetic = ptic;
while (tics--) {
int players = *p++;
while (players--) {
int n = *p++;
RawToTic(&netcmds[n][remotetic%BACKUPTICS], p);
p += sizeof(ticcmd_t);
}
remotetic++;
}
}
}
break;
case PKT_RETRANS: // Resend request
remotesend = doom_ntohl(packet->tic);
break;
case PKT_DOWN: // Server downed
{
int j;
for (j=0; j<MAXPLAYERS; j++)
if (j != consoleplayer) playeringame[j] = false;
server = false;
doom_printf("Server is down\nAll other players are no longer in the game\n");
}
break;
case PKT_EXTRA: // Misc stuff
case PKT_QUIT: // Player quit
// Queue packet to be processed when its tic time is reached
queuedpacket = Z_Realloc(queuedpacket, ++numqueuedpackets * sizeof *queuedpacket,
PU_STATIC, NULL);
queuedpacket[numqueuedpackets-1] = Z_Malloc(recvlen, PU_STATIC, NULL);
memcpy(queuedpacket[numqueuedpackets-1], packet, recvlen);
break;
case PKT_BACKOFF:
/* cph 2003-09-18 -
* The server sends this when we have got ahead of the other clients. We should
* stall the input side on this client, to allow other clients to catch up.
*/
lastmadetic++;
break;
default: // Other packet, unrecognised or redundant
break;
}
}
Z_Free(packet);
}
{ // Build new ticcmds
int newtics = I_GetTime() - lastmadetic;
newtics = (newtics > 0 ? newtics : 0);
lastmadetic += newtics;
if (ffmap) newtics++;
while (newtics--) {
I_StartTic();
if (maketic - gametic > BACKUPTICS/2) break;
G_BuildTiccmd(&localcmds[maketic%BACKUPTICS]);
maketic++;
}
if (server && maketic > remotesend) { // Send the tics to the server
int sendtics;
remotesend -= xtratics;
if (remotesend < 0) remotesend = 0;
sendtics = maketic - remotesend;
{
size_t pkt_size = sizeof(packet_header_t) + 2 + sendtics * sizeof(ticcmd_t);
packet_header_t *packet = Z_Malloc(pkt_size, PU_STATIC, NULL);
packet_set(packet, PKT_TICC, maketic - sendtics);
*(byte*)(packet+1) = sendtics;
*(((byte*)(packet+1))+1) = consoleplayer;
{
void *tic = ((byte*)(packet+1)) +2;
while (sendtics--) {
TicToRaw(tic, &localcmds[remotesend++%BACKUPTICS]);
tic = (byte *)tic + sizeof(ticcmd_t);
}
}
I_SendPacket(packet, pkt_size);
Z_Free(packet);
}
}
}
}
#else
void D_BuildNewTiccmds(void)
{
static int lastmadetic;
int newtics = I_GetTime() - lastmadetic;
lastmadetic += newtics;
while (newtics--)
{
I_StartTic();
if (maketic - gametic > BACKUPTICS/2) break;
G_BuildTiccmd(&localcmds[maketic%BACKUPTICS]);
maketic++;
}
}
#endif
#ifdef HAVE_NET
/* cph - data passed to this must be in the Doom (little-) endian */
void D_NetSendMisc(netmisctype_t type, size_t len, void* data)
{
if (server) {
size_t size = sizeof(packet_header_t) + 3*sizeof(int) + len;
packet_header_t *packet = Z_Malloc(size, PU_STATIC, NULL);
int *p = (void*)(packet+1);
packet_set(packet, PKT_EXTRA, gametic);
*p++ = LONG(type); *p++ = LONG(consoleplayer); *p++ = LONG(len);
memcpy(p, data, len);
I_SendPacket(packet, size);
Z_Free(packet);
}
}
static void CheckQueuedPackets(void)
{
int i;
for (i=0; (unsigned)i<numqueuedpackets; i++)
if (doom_ntohl(queuedpacket[i]->tic) <= gametic)
switch (queuedpacket[i]->type) {
case PKT_QUIT: // Player quit the game
{
int pn = *(byte*)(queuedpacket[i]+1);
playeringame[pn] = false;
doom_printf("Player %d left the game\n", pn);
}
break;
case PKT_EXTRA:
{
int *p = (int*)(queuedpacket[i]+1);
size_t len = LONG(*(p+2));
switch (LONG(*p)) {
case nm_plcolour:
G_ChangedPlayerColour(LONG(*(p+1)), LONG(*(p+3)));
break;
case nm_savegamename:
if (len < SAVEDESCLEN) {
memcpy(savedescription, p+3, len);
// Force terminating 0 in case
savedescription[len] = 0;
}
break;
}
}
break;
default: // Should not be queued
break;
}
{ // Requeue remaining packets
int newnum = 0;
packet_header_t **newqueue = NULL;
for (i=0; (unsigned)i<numqueuedpackets; i++)
if (doom_ntohl(queuedpacket[i]->tic) > gametic) {
newqueue = Z_Realloc(newqueue, ++newnum * sizeof *newqueue,
PU_STATIC, NULL);
newqueue[newnum-1] = queuedpacket[i];
} else Z_Free(queuedpacket[i]);
Z_Free(queuedpacket);
numqueuedpackets = newnum; queuedpacket = newqueue;
}
}
#endif // HAVE_NET
void TryRunTics (void)
{
int runtics;
int entertime = I_GetTime();
// Wait for tics to run
while (1) {
#ifdef HAVE_NET
NetUpdate();
#else
D_BuildNewTiccmds();
#endif
runtics = (server ? remotetic : maketic) - gametic;
if (!runtics) {
if (!movement_smooth) {
#ifdef HAVE_NET
if (server)
I_WaitForPacket(ms_to_next_tick);
else
#endif
I_uSleep(ms_to_next_tick*1000);
}
if (I_GetTime() - entertime > 10) {
#ifdef HAVE_NET
if (server) {
char buf[sizeof(packet_header_t)+1];
remotesend--;
packet_set((packet_header_t *)buf, PKT_RETRANS, remotetic);
buf[sizeof(buf)-1] = consoleplayer;
I_SendPacket((packet_header_t *)buf, sizeof buf);
}
#endif
M_Ticker(); return;
}
//if ((displaytime) < (tic_vars.next-SDL_GetTicks()))
{
WasRenderedInTryRunTics = true;
if (V_GetMode() == VID_MODEGL ?
movement_smooth :
movement_smooth && gamestate==wipegamestate)
{
isExtraDDisplay = true;
D_Display();
isExtraDDisplay = false;
}
}
} else break;
}
while (runtics--) {
#ifdef HAVE_NET
if (server) CheckQueuedPackets();
#endif
if (advancedemo)
D_DoAdvanceDemo ();
M_Ticker ();
I_GetTime_SaveMS();
G_Ticker ();
P_Checksum(gametic);
gametic++;
#ifdef HAVE_NET
NetUpdate(); // Keep sending our tics to avoid stalling remote nodes
#endif
}
}
#ifdef HAVE_NET
static void D_QuitNetGame (void)
{
byte buf[1 + sizeof(packet_header_t)];
packet_header_t *packet = (void*)buf;
int i;
if (!server) return;
buf[sizeof(packet_header_t)] = consoleplayer;
packet_set(packet, PKT_QUIT, gametic);
for (i=0; i<4; i++) {
I_SendPacket(packet, 1 + sizeof(packet_header_t));
I_uSleep(10000);
}
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,707 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Printed strings for translation.
* English language support (default).
* See dstrings.h for suggestions about foreign language BEX support
*
*-----------------------------------------------------------------------------*/
#ifndef __D_ENGLSH__
#define __D_ENGLSH__
/* 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 RESTARTLEVEL "restart the level?\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 shotgun shells." // JDC: removed number 4 so baby mode isn't incorrect
#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"
/* jff 02/05/98 Create messages specific to card and skull keys */
#define PD_BLUEC "You need a blue card to open this door"
#define PD_REDC "You need a red card to open this door"
#define PD_YELLOWC "You need a yellow card to open this door"
#define PD_BLUES "You need a blue skull to open this door"
#define PD_REDS "You need a red skull to open this door"
#define PD_YELLOWS "You need a yellow skull to open this door"
#define PD_ANY "Any key will open this door"
#define PD_ALL3 "You need all three keys to open this door"
#define PD_ALL6 "You need all six keys 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 "Player 1: "
#define HUSTR_PLRINDIGO "Player 2: "
#define HUSTR_PLRBROWN "Player 3: "
#define HUSTR_PLRRED "Player 4: "
#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"
#define AMSTR_ROTATEON "Rotate Mode ON"
#define AMSTR_ROTATEOFF "Rotate Mode OFF"
#define AMSTR_OVERLAYON "Overlay Mode ON"
#define AMSTR_OVERLAYOFF "Overlay Mode OFF"
/* 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..."
#define STSTR_COMPON "Compatibility Mode On" /* phares */
#define STSTR_COMPOFF "Compatibility Mode Off" /* phares */
/* 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"
/*** Plutonia ***/
/* 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."
/*** TNT: Evilution ***/
#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

View File

@@ -0,0 +1,125 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Event information structures.
*
*-----------------------------------------------------------------------------*/
#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,
} 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 4 bits hold weapon num.
BT_CHANGE = 4,
// The 4bit weapon mask and shift, convenience.
//BT_WEAPONMASK = (8+16+32),
BT_WEAPONMASK = (8+16+32+64), // extended to pick up SSG // phares
BT_WEAPONSHIFT = 3,
// Special events
BTS_LOADGAME = 0, // Loads a game
// Pause the game.
BTS_PAUSE = 1,
// Save the game at each console.
BTS_SAVEGAME = 2,
BTS_RESTARTLEVEL= 3, // Restarts the current level
// Savegame slot numbers occupy the second byte of buttons.
BTS_SAVEMASK = (4+8+16),
BTS_SAVESHIFT = 2,
} buttoncode_t;
//
// GLOBAL VARIABLES
//
extern gameaction_t gameaction;
#endif

View File

@@ -0,0 +1,291 @@
#include <stdio.h>
#include <stdlib.h>
#include <netipx/ipx.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "protocol.h"
#define BACKUPTICS 12
#define NCMD_EXIT 0x80000000
#define NCMD_RETRANSMIT 0x40000000
#define NCMD_SETUP 0x20000000
#define NCMD_KILL 0x10000000 // kill game
#define NCMD_CHECKSUM 0x0fffffff
typedef struct
{
short gameid; // so multiple games can setup at once
short drone;
short nodesfound;
short nodeswanted;
} setupdata_t;
typedef struct
a
{
// 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
{
signed int tic;
union altu {
setupdata_t s;
unsigned char data[100];
doomdata_t d;
} u;
} ipxpacket_t;
int nodes;
unsigned short port = 0x869b;
int ipx_socket(void) {
int s = socket(PF_IPX,SOCK_DGRAM,0);
struct sockaddr_ipx sa;
if (s == -1) {
fprintf(stderr,"socket(PF_PIPX): %s\n",strerror(errno));
exit(-1);
}
memset(&sa,0,sizeof(sa));
memset(sa.sipx_node,0xff,sizeof(sa.sipx_node));
sa.sipx_port = htons(port);
if (bind(s,(struct sockaddr*)&sa,sizeof(sa)) == -1) {
fprintf(stderr,"bind(%d): %s\n",port,strerror(errno));
exit(-1);
}
return s;
}
int udp_socket(const char* ip) {
struct sockaddr_in sa;
int s = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
if (s == -1) {
fprintf(stderr,"socket(PF_INET): %s\n", strerror(errno));
exit(-1);
}
sa.sin_family=PF_INET;
inet_aton(ip,&sa.sin_addr);
sa.sin_port = htons(5030);
if (connect(s,(struct sockaddr*)&sa,sizeof sa) == -1) {
fprintf(stderr,"connect(%s:%d): %s\n", ip, 5030, strerror(errno));
exit(-1);
}
return s;
}
static byte ChecksumPacket(const packet_header_t* buffer, size_t len)
{
const byte* p = (void*)buffer;
byte sum = 0;
if (len==0)
return 0;
while (p++, --len)
sum += *p;
return sum;
}
//
// Checksum
//
unsigned NetbufferChecksum (void* p, size_t l)
{
unsigned c;
c = 0x1234567;
l = l/4;
for (int i=0 ; i<l ; i++)
c += ((unsigned *)p)[i] * (i+1);
return c & NCMD_CHECKSUM;
}
int ipxs, udps;
int consoleplayer;
int basetic;
int ExpandTics (int low, int maketic)
{
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;
fprintf(stderr,"ExpandTics strange value %i at maketic %i\n",low,maketic);
exit(-2);
}
void send_udp_packet(enum packet_type_e type, unsigned tic, void* data, size_t len) {
packet_header_t* p = calloc(sizeof(packet_header_t)+len+1,1);
p->tic = doom_htonl(basetic = tic); p->type = type;
if (!data) {
data = (void*)&consoleplayer; len = 1;
}
memcpy(((char*)p)+sizeof(*p),data,len);
p->checksum = ChecksumPacket(p,sizeof(packet_header_t)+len);
write(udps,p,sizeof(packet_header_t)+len+1);
}
int connected;
int ipxcounter;
void ipx_receive(int s) {
ipxpacket_t buf;
int rc;
struct sockaddr from;
size_t sl = sizeof(from);
rc = recvfrom(s,&buf,sizeof buf,0,&from,&sl);
if (rc == -1) {
fprintf(stderr,"read(ipx): %s\n", strerror(errno));
exit(-2);
}
if (rc > 0) {
if (buf.tic == -1) {
// Setup packet
if (!connected++) {
connect(s,&from,sl);
send_udp_packet(PKT_INIT,0,NULL,0);
}
} else {
if (buf.u.d.checksum & NCMD_SETUP) {
printf("setup packet, dropped\n");
} else if (buf.u.d.checksum & NCMD_EXIT) {
send_udp_packet(PKT_QUIT,buf.u.d.starttic,NULL,0);
exit(0);
} else if ((buf.u.d.checksum & NCMD_CHECKSUM) == buf.u.d.checksum) {
// No flags, normal game packet
char outbuf[100];
int tics;
outbuf[0] = tics = buf.u.d.numtics;
outbuf[1] = buf.u.d.player;
for (int i=0; i< tics; i++)
TicToRaw(outbuf+2+i*sizeof(ticcmd_t),&buf.u.d.cmds[i]);
send_udp_packet(PKT_TICC, ExpandTics(buf.u.d.starttic, basetic), outbuf, 2+tics*sizeof(ticcmd_t));
}
}
}
}
void udp_receive(int s) {
size_t len = 1024;
packet_header_t *p = malloc(len);
int rc;
rc = read(s,p,len);
if (rc < 0) {
fprintf(stderr,"read(udp): %s\n", strerror(errno));
exit(-2);
}
if (rc > 0) {
switch (p->type) {
case PKT_SETUP:
{
struct setup_packet_s *sinfo = (void*)(p+1);
consoleplayer = sinfo->yourplayer;
send_udp_packet(PKT_GO,0,NULL,0);
write(ipxs,"\xff\xff\xff\xff\x00\x00\x00\x00\x02\x00\x02\x00\x00\x00\x00\x00",16);
}
break;
case PKT_GO:
{
ipxpacket_t pkt;
memset(&pkt,0,sizeof(pkt));
pkt.tic = ipxcounter++;
pkt.u.d.player = consoleplayer^1;
pkt.u.d.starttic = 0;
pkt.u.d.numtics = 0;
pkt.u.d.retransmitfrom = 0;
pkt.u.d.checksum = NetbufferChecksum(&pkt.u.d.retransmitfrom, 4);
write(ipxs,&pkt,16);
}
break;
case PKT_TICS:
{
ipxpacket_t pkt;
int tic = doom_ntohl(p->tic);
byte *pp = (void*)(p+1);
int tics = *pp++;
memset(&pkt,0,sizeof(pkt));
size_t len;
pkt.tic = ipxcounter++;
pkt.u.d.starttic = tic;
pkt.u.d.player = (consoleplayer == 0 ? 1 : 0);
pkt.u.d.numtics = tics;
for (int t=0; t<tics; t++) {
int players = *pp++;
for (int i=0; i<players; i++) {
if (*pp++ == pkt.u.d.player)
RawToTic(&pkt.u.d.cmds[t],pp);
pp += sizeof(ticcmd_t);
}
}
pkt.u.d.retransmitfrom = 0;
len = 12+tics*sizeof(ticcmd_t);
len = (len+7)&0xff8; // round up to next 16
pkt.u.d.checksum = NetbufferChecksum(&pkt.u.d.retransmitfrom, len-8);
write(ipxs,&pkt,len);
}
}
}
}
void loop(int ipxs, int udps) {
for (;;) {
struct timeval wt = {60,0};
fd_set fds;
int rc;
FD_ZERO(&fds);
FD_SET(ipxs,&fds);
FD_SET(udps,&fds);
rc = select(ipxs+udps,&fds,NULL,NULL,&wt);
if (rc < 0) {
fprintf(stderr,"select: %s\n", strerror(errno));
exit(-2);
}
if (rc>0) {
if (FD_ISSET(ipxs,&fds))
ipx_receive(ipxs);
if (FD_ISSET(udps,&fds))
udp_receive(udps);
}
}
}
int main(int argc, char**argv) {
ipxs = ipx_socket();
udps = udp_socket(argv[1]);
loop(ipxs,udps);
return 0;
}

View File

@@ -0,0 +1,140 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Something to do with weapon sprite frames. Don't ask me.
*
*-----------------------------------------------------------------------------
*/
// We are referring to sprite numbers.
#include "doomtype.h"
#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
},
};

View File

@@ -0,0 +1,59 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* 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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,80 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Main startup and splash screenstuff.
*
*-----------------------------------------------------------------------------*/
#ifndef __D_MAIN__
#define __D_MAIN__
#include "d_event.h"
#include "w_wad.h"
#ifdef __GNUG__
#pragma interface
#endif
/* CPhipps - removed wadfiles[] stuff to w_wad.h */
extern char basesavegame[]; // killough 2/16/98: savegame path
//jff 1/24/98 make command line copies of play modes available
extern boolean clnomonsters; // checkparm of -nomonsters
extern boolean clrespawnparm; // checkparm of -respawn
extern boolean clfastparm; // checkparm of -fast
//jff end of external declaration of command line playmode
extern boolean nosfxparm;
extern boolean nomusicparm;
extern int ffmap;
// Called by IO functions when input is detected.
void D_PostEvent(event_t* ev);
// Demo stuff
extern boolean advancedemo;
void D_AdvanceDemo(void);
void D_DoAdvanceDemo (void);
//
// BASE LEVEL
//
void D_Display(void);
void D_PageTicker(void);
void D_StartTitle(void);
void D_DoomMain(void);
void D_AddFile (const char *file, wad_source_t source);
/* cph - MBF-like wad/deh/bex autoload code */
#define MAXLOADFILES 2
extern const char *wad_files[MAXLOADFILES], *deh_files[MAXLOADFILES];
#endif

View File

@@ -0,0 +1,214 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* 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
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;
//
// Startup packet difference
// SG: 4/12/98
// Added so we can send more startup data to synch things like
// bobbing, recoil, etc.
// this is just mapped over the ticcmd_t array when setup packet is sent
//
// Note: the original code takes care of startskill, deathmatch, nomonsters
// respawn, startepisode, startmap
// Note: for phase 1 we need to add monsters_remember, variable_friction,
// weapon_recoil, allow_pushers, over_under, player_bobbing,
// fastparm, demo_insurance, and the rngseed
//Stick all options into bytes so we don't need to mess with bitfields
//WARNING: make sure this doesn't exceed the size of the ticcmds area!
//sizeof(ticcmd_t)*BACKUPTICS
//This is the current length of our extra stuff
//
//killough 5/2/98: this should all be replaced by calls to G_WriteOptions()
//and G_ReadOptions(), which were specifically designed to set up packets.
//By creating a separate struct and functions to read/write the options,
//you now have two functions and data to maintain instead of just one.
//If the array in g_game.c which G_WriteOptions()/G_ReadOptions() operates
//on, is too large (more than sizeof(ticcmd_t)*BACKUPTICS), it can
//either be shortened, or the net code needs to divide it up
//automatically into packets. The STARTUPLEN below is non-portable.
//There's a portable way to do it without having to know the sizes.
#define STARTUPLEN 12
typedef struct
{
byte monsters_remember;
byte variable_friction;
byte weapon_recoil;
byte allow_pushers;
byte over_under;
byte player_bobbing;
byte fastparm;
byte demo_insurance;
unsigned long rngseed;
char filler[sizeof(ticcmd_t)*BACKUPTICS-STARTUPLEN];
} startup_t;
typedef enum {
// Leave space, so low values corresponding to normal netgame setup packets can be ignored
nm_plcolour = 3,
nm_savegamename = 4,
} netmisctype_t;
typedef struct
{
netmisctype_t type;
size_t len;
byte value[sizeof(ticcmd_t)*BACKUPTICS - sizeof(netmisctype_t) - sizeof(size_t)];
} netmisc_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.
#ifdef HAVE_NET
void NetUpdate (void);
#else
void D_BuildNewTiccmds(void);
#endif
//? how many ticks to run?
void TryRunTics (void);
// CPhipps - move to header file
void D_InitNetGame (void); // This does the setup
void D_CheckNetGame(void); // This waits for game start
// CPhipps - misc info broadcast
void D_NetSendMisc(netmisctype_t type, size_t len, void* data);
// CPhipps - ask server for a wad file we need
boolean D_NetGetWad(const char* name);
// Netgame stuff (buffers and pointers, i.e. indices).
extern doomcom_t *doomcom;
extern doomdata_t *netbuffer; // This points inside doomcom.
#endif

View File

@@ -0,0 +1,234 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Player state structure.
*
*-----------------------------------------------------------------------------*/
#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;
/* killough 10/98: used for realistic bobbing (i.e. not simply overall speed)
* mo->momx and mo->momy represent true momenta experienced by player.
* This only represents the thrust that the player applies himself.
* This avoids anomolies with such things as Boom ice and conveyors.
*/
fixed_t momx, momy; // killough 10/98
// 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. // CPhipps - const
const 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];
// CPhipps - total game time for completed levels so far
int totaltimes;
} wbstartstruct_t;
#endif

View File

@@ -0,0 +1,754 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2004 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Network game server code
* New for LxDoom, but drawing ideas and code fragments from the
* earlier net code
*-----------------------------------------------------------------------------
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <limits.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdarg.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/types.h>
#ifdef USE_SDL_NET
#include "SDL.h"
#endif
#include "doomtype.h"
#include "protocol.h"
#include "i_network.h"
#ifndef PRBOOM_SERVER
#include "m_fixed.h"
#endif
#include "i_system.h"
#include "m_swap.h"
#ifndef HAVE_NET
int main(void)
{
fprintf(stderr,
PACKAGE "-server: You must compile with networking enabled!\n");
exit(1);
return 1;
}
#else
#ifndef HAVE_GETOPT
/* The following code for getopt is from the libc-source of FreeBSD,
* it might be changed a little bit.
* Florian Schulze (florian.schulze@gmx.net)
*/
/*
* Copyright (c) 1987, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
#endif
static const char rcsid[] = "$FreeBSD$";
#endif /* LIBC_SCCS and not lint */
int opterr = 1, /* if error message should be printed */
optind = 1, /* index into parent argv vector */
optopt, /* character checked for validity */
optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#define BADCH (int)'?'
#define BADARG (int)':'
#define EMSG ""
char *__progname="prboom_server";
/*
* getopt --
* Parse argc/argv argument vector.
*/
int
getopt(nargc, nargv, ostr)
int nargc;
char * const *nargv;
const char *ostr;
{
extern char *__progname;
static char *place = EMSG; /* option letter processing */
char *oli; /* option letter list index */
int ret;
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc || *(place = nargv[optind]) != '-') {
place = EMSG;
return (-1);
}
if (place[1] && *++place == '-') { /* found "--" */
++optind;
place = EMSG;
return (-1);
}
} /* option letter okay? */
if ((optopt = (int)*place++) == (int)':' ||
!(oli = strchr(ostr, optopt))) {
/*
* if the user didn't specify '-' as an option,
* assume it means -1.
*/
if (optopt == (int)'-')
return (-1);
if (!*place)
++optind;
if (opterr && *ostr != ':')
(void)fprintf(stderr,
"%s: illegal option -- %c\n", __progname, optopt);
return (BADCH);
}
if (*++oli != ':') { /* don't need argument */
optarg = NULL;
if (!*place)
++optind;
}
else { /* need an argument */
if (*place) /* no white space */
optarg = place;
else if (nargc <= ++optind) { /* no arg */
place = EMSG;
if (*ostr == ':')
ret = BADARG;
else
ret = BADCH;
if (opterr)
(void)fprintf(stderr,
"%s: option requires an argument -- %c\n",
__progname, optopt);
return (ret);
}
else /* white space */
optarg = nargv[optind];
place = EMSG;
++optind;
}
return (optopt); /* dump back option letter */
}
#else
#include <unistd.h>
#endif
#define MAXPLAYERS 4
#define BACKUPTICS 12
// Dummies to forfill l_udp.c unused client stuff
int M_CheckParm(const char* p) { p = NULL; return 1; }
int myargc;
char** myargv;
void NORETURN I_Error(const char *error, ...) // killough 3/20/98: add const
{
va_list argptr;
va_start(argptr,error);
vfprintf(stderr,error,argptr);
va_end(argptr);
exit(-1);
}
int playerjoingame[MAXPLAYERS], playerleftgame[MAXPLAYERS];
UDP_CHANNEL remoteaddr[MAXPLAYERS];
enum { pc_unused, pc_connected, pc_ready, pc_confirmedready, pc_playing, pc_quit } playerstate[MAXPLAYERS];
int displaycounter;
boolean n_players_in_state(int n, int ps) {
int i,j;
for (i=j=0;i<MAXPLAYERS;i++)
if (playerstate[i] == ps) j++;
return (j == n);
}
void BroadcastPacket(packet_header_t *packet, size_t len)
{
int i;
for (i=0; i<MAXPLAYERS; i++)
if (playerstate[i] != pc_unused && playerstate[i] != pc_quit)
I_SendPacketTo(packet, len, &remoteaddr[i]);
}
byte def_game_options[GAME_OPTIONS_SIZE] = \
{ // cf g_game.c:G_WriteOptions()
1, // monsters remember
1, // friction
0, // weapon recoil
1, // pushers
0, // reserved/unused
1, // player bobbing
0, 0, 0, // respawn, fast, nomonsters
1, // demo insurance
0, 0, 0, 0, // 4 bytes of random number seed
1, 0, 0, 0,
0, 128, /* distfriend */
0, 1, 1, 1, 1, 0,
/* Zeroes for all compatibility stuff */
};
#define nosuch "NOSUCHCONFIGITEM"
const char* gameopt_config_names[] = {
"monsters_remember",nosuch,"weapon_recoil",nosuch,nosuch,"player_bobbing",nosuch,nosuch,nosuch,"demo_insurance",
nosuch,nosuch,nosuch,nosuch, // RNG seed
"monster_infighting","player_helpers",nosuch,nosuch,
nosuch,nosuch, // distfriend
"monster_backing","monster_avoid_hazards","monster_friction","help_friends","dog_jumping","monkeys",
"comp_telefrag","comp_dropoff","comp_vile","comp_pain","comp_skull","comp_blazing","comp_doorlight","comp_model","comp_god","comp_falloff","comp_floors","comp_skymap","comp_pursuit","comp_doorstuck","comp_staylift","comp_zombie","comp_stairs","comp_infcheat","comp_zerotags","comp_moveblock","comp_respawn","comp_sound" };
const int num_gameopts = sizeof gameopt_config_names / sizeof gameopt_config_names[0];
int verbose;
void NORETURN sig_handler(int signum)
{
char buf[80];
I_SigString(buf,80,signum);
printf("Received signal: %s\n", buf);
// Any signal is fatal
exit(1);
}
void doexit(void)
{
packet_header_t packet;
// Send "downed" packet
packet_set(&packet, PKT_DOWN, 0);
BroadcastPacket(&packet, sizeof packet);
}
#ifndef USE_SDL_NET
static void I_InitSockets(int v4port)
{
v4socket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
I_SetupSocket(v4socket, v4port, AF_INET);
}
#else
static void I_InitSockets(Uint16 port)
{
I_InitNetwork();
udp_socket = I_Socket(port);
if (!udp_socket) I_Error("I_InitSockets: failed to open UDP port %d\n",port);
}
#endif
long int ptic(packet_header_t* p)
{
return doom_ntohl(p->tic);
}
void read_config_file(FILE* fp, struct setup_packet_s* sp)
{
byte* gameopt = sp->game_options;
while (!feof(fp)) {
char def[80];
char strparm[100];
if (fscanf (fp, "%79s %99[^\n]\n", def, strparm) == 2) {
int v = atoi(strparm);
if (!strcmp(def,"default_skill")) {
if (verbose) printf("config file sets default_skill to %d\n",v);
sp->skill = v-1;
} else if (!strcmp(def,"default_compatibility_level")) {
if (verbose) printf("config file sets compatibility_level to %d\n",v);
if (v == -1) v = MAX_COMPATIBILITY_LEVEL-1; //e6y: -1 => maxcompat
sp->complevel = v;
} else {
int i;
for (i=0; i<num_gameopts; i++) {
if (!!strcmp(gameopt_config_names[i],def)) continue;
if (verbose) printf("config file sets %s to %d\n",def,v);
gameopt[i] = v;
}
}
}
}
}
static int badplayer(int n) { return (n < 0 || n >= MAXPLAYERS); }
int main(int argc, char** argv)
{
#ifndef USE_SDL_NET
int localport = 5030;
#else
Uint16 localport = 5030;
#endif
int numplayers = 2, xtratics = 0, ticdup = 1;
int exectics = 0; // gametics completed
struct setup_packet_s setupinfo = { 2, 0, 1, 1, 1, 0, best_compatibility, 0, 0};
char**wadname = NULL;
char**wadget = NULL;
int numwads = 0;
{
int opt;
byte *gameopt = setupinfo.game_options;
memcpy(gameopt, &def_game_options, sizeof (setupinfo.game_options));
while ((opt = getopt(argc, argv, "c:t:x:p:e:l:adrfns:N:vw:")) != EOF)
switch (opt) {
case 'c':
{
FILE *cf = fopen(optarg,"r");
if (!cf) { perror("fopen"); return -1; }
read_config_file(cf,&setupinfo);
fclose(cf);
}
break;
case 't':
if (optarg) ticdup = atoi(optarg);
break;
case 'x':
if (optarg) xtratics = atoi(optarg);
break;
case 'p':
if (optarg) localport = atoi(optarg);
break;
case 'e':
if (optarg) setupinfo.episode = atoi(optarg);
break;
case 'l':
if (optarg) setupinfo.level = atoi(optarg);
break;
case 'a':
setupinfo.deathmatch = 2;
break;
case 'd':
setupinfo.deathmatch = 1;
break;
case 'r':
setupinfo.game_options[6] = 1;
break;
case 'f':
setupinfo.game_options[7] = 1;
break;
case 'n':
setupinfo.game_options[8] = 1;
break;
case 's':
if (optarg) setupinfo.skill = atoi(optarg)-1;
break;
case 'N':
if (optarg) setupinfo.players = numplayers = atoi(optarg);
break;
case 'v':
verbose++;
break;
case 'w':
if (optarg) {
char *p;
wadname = realloc(wadname, ++numwads * sizeof *wadname);
wadget = realloc(wadget , numwads * sizeof *wadget );
wadname[numwads-1] = strdup(optarg);
if ((p = strchr(wadname[numwads-1], ','))) {
*p++ = 0; wadget[numwads-1] = p;
} else wadget[numwads-1] = NULL;
}
break;
}
}
setupinfo.ticdup = ticdup; setupinfo.extratic = xtratics;
{ /* Random number seed
* Mirrors the corresponding code in G_ReadOptions */
int rngseed = (int)time(NULL);
setupinfo.game_options[13] = rngseed & 0xff;
rngseed >>= 8;
setupinfo.game_options[12] = rngseed & 0xff;
rngseed >>= 8;
setupinfo.game_options[11] = rngseed & 0xff;
rngseed >>= 8;
setupinfo.game_options[10] = rngseed & 0xff;
}
I_InitSockets(localport);
printf("Listening on port %d, waiting for %d players\n", localport, numplayers);
{ // no players initially
int i;
for (i=0; i<MAXPLAYERS; i++) {
playerjoingame[i] = INT_MAX;
playerleftgame[i] = 0;
playerstate[i] = pc_unused;
}
// Print wads
for (i=0; i<numwads; i++)
printf("Wad %s (%s)\n", wadname[i], wadget[i] ? wadget[i] : "");
}
// Exit and signal handling
atexit(doexit); // heh
signal(SIGTERM, sig_handler);
signal(SIGINT , sig_handler);
#ifndef USE_SDL_NET
signal(SIGQUIT, sig_handler);
signal(SIGKILL, sig_handler);
signal(SIGHUP , sig_handler);
#endif
{
int remoteticfrom[MAXPLAYERS] = { 0, 0, 0, 0 };
int remoteticto[MAXPLAYERS] = { 0, 0, 0, 0 };
int backoffcounter[MAXPLAYERS] = { 0, 0, 0, 0 };
int curplayers = 0;
int confirming = 0;
boolean ingame = false;
ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS];
while (1) {
packet_header_t *packet = malloc(10000);
size_t len;
I_WaitForPacket(120*1000);
while ((len = I_GetPacket(packet, 10000))) {
if (verbose>2) printf("Received packet:");
switch (packet->type) {
case PKT_INIT:
if (!ingame) {
{
int n;
struct setup_packet_s *sinfo = (void*)(packet+1);
/* Find player number and add to the game */
n = *(short*)(packet+1);
if (badplayer(n) || playerstate[n] != pc_unused)
for (n=0; n<numplayers; n++)
if (playerstate[n] == pc_unused) break;
if (n == numplayers) break; // Full game
playerstate[n] = pc_connected;
#ifndef USE_SDL_NET
remoteaddr[n] = sentfrom;
#else
if (sentfrom==-1)
remoteaddr[n]=I_RegisterPlayer(&sentfrom_addr);
#endif
printf("Join by ");
I_PrintAddress(stdout, &remoteaddr[n]);
#ifdef USE_SDL_NET
printf(" (channel %d)",remoteaddr[n]);
#endif
printf(" as player %d\n",n);
{
int i;
size_t extrabytes = 0;
// Send setup packet
packet_set(packet, PKT_SETUP, 0);
memcpy(sinfo, &setupinfo, sizeof setupinfo);
sinfo->yourplayer = n;
sinfo->numwads = numwads;
for (i=0; i<numwads; i++) {
strcpy(sinfo->wadnames + extrabytes, wadname[i]);
extrabytes += strlen(wadname[i]) + 1;
}
I_SendPacketTo(packet, sizeof *packet + sizeof setupinfo + extrabytes,
remoteaddr+n);
I_uSleep(10000);
I_SendPacketTo(packet, sizeof *packet + sizeof setupinfo + extrabytes,
remoteaddr+n);
}
}
}
break;
case PKT_GO:
if (!ingame) {
int from = *(byte*)(packet+1);
if (badplayer(from) || playerstate[from] == pc_unused) break;
if (confirming) {
if (playerstate[from] != pc_confirmedready) curplayers++;
playerstate[from] = pc_confirmedready;
} else
playerstate[from] = pc_ready;
}
break;
case PKT_TICC:
{
byte tics = *(byte*)(packet+1);
int from = *(((byte*)(packet+1))+1);
if (badplayer(from)) break;
if (verbose>2)
printf("tics %ld - %ld from %d\n", ptic(packet), ptic(packet) + tics - 1, from);
if (ptic(packet) > remoteticfrom[from]) {
// Missed tics, so request a resend
packet_set(packet, PKT_RETRANS, remoteticfrom[from]);
I_SendPacketTo(packet, sizeof *packet, remoteaddr+from);
} else {
ticcmd_t *newtic = (void*)(((byte*)(packet+1))+2);
if (ptic(packet) + tics < remoteticfrom[from]) break; // Won't help
remoteticfrom[from] = ptic(packet);
while (tics--)
netcmds[from][remoteticfrom[from]++%BACKUPTICS] = *newtic++;
}
}
break;
case PKT_RETRANS:
{
int from = *(byte*)(packet+1);
if (badplayer(from)) break;
if (verbose>2) printf("%d requests resend from %d\n", from, ptic(packet));
remoteticto[from] = ptic(packet);
}
break;
case PKT_QUIT:
{
int from = *(byte*)(packet+1);
if (badplayer(from)) break;
if (!ingame && playerstate[from] != pc_unused) {
// If we already got a PKT_GO, we have to remove this player frmo the count of ready players. And we then flag this player slot as vacant.
printf("player %d pulls out\n", from);
if (playerstate[from] == pc_confirmedready) curplayers--;
playerstate[from] = pc_unused;
} else
if (playerleftgame[from] == INT_MAX) { // In the game
playerleftgame[from] = ptic(packet);
--curplayers;
if (verbose) printf("%d quits at %d (%d left)\n", from, ptic(packet),curplayers);
if (ingame && !curplayers) exit(0); // All players have exited
}
}
// Fall through and broadcast it
case PKT_EXTRA:
BroadcastPacket(packet, len);
if (packet->type == PKT_EXTRA) {
if (verbose>2) printf("misc from %d\n", *(((byte*)(packet+1))+1));
}
break;
case PKT_WAD:
{
int i;
int from = *(byte*)(packet+1);
char *name = 1 + (char*)(packet+1);
size_t size = sizeof(packet_header_t);
packet_header_t *reply;
if (badplayer(from) || playerstate[from] != pc_unused) break;
if (verbose) printf("Request for %s ", name);
for (i=0; i<numwads; i++)
if (!strcasecmp(name, wadname[i]))
break;
if ((i==numwads) || !wadget[i]) {
if (verbose) printf("n/a\n");
*(char*)(packet+1) = 0;
I_SendPacketTo(packet, size+1, remoteaddr + from);
} else {
size += strlen(wadname[i]) + strlen(wadget[i]) + 2;
reply = malloc(size);
packet_set(reply, PKT_WAD, 0);
strcpy((char*)(reply+1), wadname[i]);
strcpy((char*)(reply+1) + strlen(wadname[i]) + 1, wadget[i]);
printf("sending %s\n", wadget[i]);
I_SendPacketTo(reply, size, remoteaddr + from);
free(reply);
}
}
break;
default:
printf("Unrecognised packet type %d\n", packet->type);
break;
}
}
free(packet);
if (!ingame && n_players_in_state(numplayers,pc_confirmedready)) {
int i;
packet_header_t gopacket;
packet = &gopacket;
ingame=true;
printf("All players joined, beginning game.\n");
for (i=0; i<MAXPLAYERS; i++) {
if (playerstate[i] == pc_confirmedready) {
playerjoingame[i] = 0;
playerleftgame[i] = INT_MAX;
playerstate[i] = pc_playing;
}
}
packet_set(packet, PKT_GO, 0);
BroadcastPacket(packet, sizeof *packet);
I_uSleep(10000);
BroadcastPacket(packet, sizeof *packet);
I_uSleep(10000);
}
if (confirming && !--confirming && !ingame) {
int i;
curplayers = 0;
for (i=0; i<MAXPLAYERS; i++) {
if (playerstate[i] == pc_ready) {
playerstate[i] = pc_unused;
printf("Player %d dropped, no PKT_GO received in confirmation\n", i);
}
if (playerstate[i] == pc_confirmedready) playerstate[i] = pc_ready;
}
}
if (!ingame && n_players_in_state(numplayers,pc_ready)) {
printf("All players ready, now confirming.\n");
confirming = 100;
}
if (ingame) { // Run some tics
int lowtic = INT_MAX;
int i;
for (i=0; i<MAXPLAYERS; i++)
if (playerstate[i] == pc_playing || playerstate[i] == pc_quit) {
if (remoteticfrom[i] < playerleftgame[i]-1 && remoteticfrom[i]<lowtic)
lowtic = remoteticfrom[i];
}
if (verbose>1) printf("%d new tics can be run\n", lowtic - exectics);
if (lowtic > exectics)
exectics = lowtic; // count exec'ed tics
// Now send all tics up to lowtic
for (i=0; i<MAXPLAYERS; i++)
if (playerstate[i] == pc_playing) {
int tics;
if (lowtic <= remoteticto[i]) continue;
if ((remoteticto[i] -= xtratics) < 0) remoteticto[i] = 0;
tics = lowtic - remoteticto[i];
{
byte *p;
packet = malloc(sizeof(packet_header_t) + 1 +
tics * (1 + numplayers * (1 + sizeof(ticcmd_t))));
p = (void*)(packet+1);
packet_set(packet, PKT_TICS, remoteticto[i]);
*p++ = tics;
if (verbose>1) printf("sending %d tics to %d\n", tics, i);
while (tics--) {
int j, playersthistic = 0;
byte *q = p++;
for (j=0; j<MAXPLAYERS; j++)
if ((playerjoingame[j] <= remoteticto[i]) &&
(playerleftgame[j] > remoteticto[i])) {
*p++ = j;
memcpy(p, &netcmds[j][remoteticto[i]%BACKUPTICS], sizeof(ticcmd_t));
p += sizeof(ticcmd_t);
playersthistic++;
}
*q = playersthistic;
remoteticto[i]++;
}
I_SendPacketTo(packet, p - ((byte*)packet), remoteaddr+i);
free(packet);
}
{
if (remoteticfrom[i] == remoteticto[i]) {
backoffcounter[i] = 0;
} else if (remoteticfrom[i] > remoteticto[i]+1) {
if ((backoffcounter[i] += remoteticfrom[i] - remoteticto[i] - 1) > 35) {
packet_header_t *packet = malloc(sizeof(packet_header_t));
packet_set(packet, PKT_BACKOFF, remoteticto[i]);
I_SendPacketTo(packet,sizeof *packet,remoteaddr+i);
backoffcounter[i] = 0;
if (verbose) printf("telling client %d to back off\n",i);
free(packet);
}
}
}
}
}
if (!((ingame ? 0xff : 0xf) & displaycounter++)) {
int i;
fprintf(stderr,"Player states: [");
for (i=0;i<MAXPLAYERS;i++) {
switch (playerstate[i]) {
case pc_unused: fputc(' ',stderr); break;
case pc_connected: fputc('c',stderr); break;
case pc_ready: fputc('r',stderr); break;
case pc_confirmedready: fputc('g',stderr); break;
case pc_playing: fputc('p',stderr); break;
case pc_quit: fputc('x',stderr); break;
}
}
fprintf(stderr,"]\n");
}
}
}
}
#endif // HAVE_NET

View File

@@ -0,0 +1,94 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* 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.
*/
// killough 11/98: convert back to C instead of C++
typedef void (*actionf_t)();
//typedef void (*actionf_v)();
//typedef void (*actionf_p1)( void* );
//typedef void (*actionf_p2)( void*, void* );
/* Note: In d_deh.c you will find references to these
* wherever code pointers and function handlers exist
*/
/*
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;
/* killough 8/29/98: we maintain thinkers in several equivalence classes,
* according to various criteria, so as to allow quicker searches.
*/
struct thinker_s *cnext, *cprev; /* Next, previous thinkers in same class */
/* killough 11/98: count of how many other objects reference
* this one using pointers. Used for garbage collection.
*/
unsigned references;
} thinker_t;
#endif

View File

@@ -0,0 +1,59 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* 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.
* CPhipps - explicitely signed the elements, since they have to be signed to work right
*/
typedef struct
{
signed char forwardmove; /* *2048 for move */
signed char sidemove; /* *2048 for move */
signed short angleturn; /* <<16 for angle delta */
short consistancy; /* checks for net game */
byte chatchar;
byte buttons;
} ticcmd_t;
#endif

View File

@@ -0,0 +1,204 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* 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 "config.h"
#include "doomtype.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
};
#ifdef _MSC_VER // proff: This is the same as __attribute__ ((packed)) in GNUC
#pragma pack(push)
#pragma pack(1)
#endif //_MSC_VER
// A single Vertex.
typedef struct {
short x,y;
} PACKEDATTR 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];
short sector; // Front sector, towards viewer.
} PACKEDATTR mapsidedef_t;
// A LineDef, as used for editing, and as input to the BSP builder.
typedef struct {
unsigned short v1;
unsigned short v2;
unsigned short flags;
short special;
short tag;
// proff 07/23/2006 - support more than 32768 sidedefs
// use the unsigned value and special case the -1
// sidenum[1] will be -1 (NO_INDEX) if one sided
unsigned short sidenum[2];
} PACKEDATTR maplinedef_t;
#define NO_INDEX ((unsigned short)-1)
//
// LineDef attributes.
//
// Solid, is an obstacle.
#define ML_BLOCKING 1
// Blocks monsters only.
#define ML_BLOCKMONSTERS 2
// Backside will not be drawn 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 always 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
//jff 3/21/98 Set if line absorbs use by player
//allow multiple push/switch triggers to be used on one push
#define ML_PASSUSE 512
// Sector definition, from editing.
typedef struct {
short floorheight;
short ceilingheight;
char floorpic[8];
char ceilingpic[8];
short lightlevel;
short special;
short tag;
} PACKEDATTR mapsector_t;
// SubSector, as generated by BSP.
typedef struct {
unsigned short numsegs;
unsigned short firstseg; // Index of first one; segs are stored sequentially.
} PACKEDATTR mapsubsector_t;
// LineSeg, generated by splitting LineDefs
// using partition lines selected by BSP builder.
typedef struct {
unsigned short v1;
unsigned short v2;
short angle;
unsigned short linedef;
short side;
short offset;
} PACKEDATTR mapseg_t;
// BSP node structure.
// Indicate a leaf.
#define NF_SUBSECTOR 0x8000
typedef struct {
short x; // Partition line from (x,y) to x+dx,y+dy)
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];
} PACKEDATTR 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;
} PACKEDATTR mapthing_t;
#ifdef _MSC_VER
#pragma pack(pop)
#endif //_MSC_VER
#endif // __DOOMDATA__

View File

@@ -0,0 +1,48 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* DoomDef - basic defines for DOOM, e.g. Version, game mode
* and skill level, and display parameters.
*
*-----------------------------------------------------------------------------
*/
#ifdef __GNUG__
#pragma implementation "doomdef.h"
#endif
#include "doomdef.h"
// Location for any defines turned variables.
// None.
// proff 08/17/98: Changed for high-res
int SCREENWIDTH=320;
int SCREENHEIGHT=200;
int SCREENPITCH=320;

View File

@@ -0,0 +1,335 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Internally used data structures for virtually everything,
* key definitions, lots of other stuff.
*
*-----------------------------------------------------------------------------*/
#ifndef __DOOMDEF__
#define __DOOMDEF__
/* use config.h if autoconf made one -- josh */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
// killough 4/25/98: Make gcc extensions mean nothing on other compilers
#ifndef __GNUC__
#define __attribute__(x)
#endif
// This must come first, since it redefines malloc(), free(), etc. -- killough:
#include "z_zone.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
// this should go here, not in makefile/configure.ac -- josh
#ifndef O_BINARY
#define O_BINARY 0
#endif
#include "m_swap.h"
#include "version.h"
// 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;
//
// For resize of screen, at start of game.
//
#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 INV_ASPECT_RATIO 0.625 /* 0.75, ideally */
// killough 2/8/98: MAX versions for maximum screen sizes
// allows us to avoid the overhead of dynamic allocation
// when multiple screen sizes are supported
// proff 08/17/98: Changed for high-res
#ifdef IPHONE // JDC
#define MAX_SCREENWIDTH 480
#define MAX_SCREENHEIGHT 320
#else
#define MAX_SCREENWIDTH 2048
#define MAX_SCREENHEIGHT 1536
#endif
// SCREENWIDTH and SCREENHEIGHT define the visible size
extern int SCREENWIDTH;
extern int SCREENHEIGHT;
// SCREENPITCH is the size of one line in the buffer and
// can be bigger than the SCREENWIDTH depending on the size
// of one pixel (8, 16 or 32 bit) and the padding at the
// end of the line caused by hardware considerations
extern int SCREENPITCH;
// The maximum number of players, multiplayer/networking.
#define MAXPLAYERS 4
// phares 5/14/98:
// DOOM Editor Numbers (aka doomednum in mobj_t)
#define DEN_PLAYER5 4001
#define DEN_PLAYER6 4002
#define DEN_PLAYER7 4003
#define DEN_PLAYER8 4004
// 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.
//
// These are Thing flags
// 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
/* killough 11/98 */
#define MTF_NOTSINGLE 16
#define MTF_NOTDM 32
#define MTF_NOTCOOP 64
#define MTF_FRIEND 128
#define MTF_RESERVED 256
typedef enum {
sk_none=-1, //jff 3/24/98 create unpicked skill setting
sk_baby=0,
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,
wp_nochange // No pending weapon change.
} 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).
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 KEYD_RIGHTARROW 0xae
#define KEYD_LEFTARROW 0xac
#define KEYD_UPARROW 0xad
#define KEYD_DOWNARROW 0xaf
#define KEYD_ESCAPE 27
#define KEYD_ENTER 13
#define KEYD_TAB 9
#define KEYD_F1 (0x80+0x3b)
#define KEYD_F2 (0x80+0x3c)
#define KEYD_F3 (0x80+0x3d)
#define KEYD_F4 (0x80+0x3e)
#define KEYD_F5 (0x80+0x3f)
#define KEYD_F6 (0x80+0x40)
#define KEYD_F7 (0x80+0x41)
#define KEYD_F8 (0x80+0x42)
#define KEYD_F9 (0x80+0x43)
#define KEYD_F10 (0x80+0x44)
#define KEYD_F11 (0x80+0x57)
#define KEYD_F12 (0x80+0x58)
#define KEYD_BACKSPACE 127
#define KEYD_PAUSE 0xff
#define KEYD_EQUALS 0x3d
#define KEYD_MINUS 0x2d
#define KEYD_RSHIFT (0x80+0x36)
#define KEYD_RCTRL (0x80+0x1d)
#define KEYD_RALT (0x80+0x38)
#define KEYD_LALT KEYD_RALT
#define KEYD_CAPSLOCK 0xba // phares
// phares 3/2/98:
#define KEYD_INSERT 0xd2
#define KEYD_HOME 0xc7
#define KEYD_PAGEUP 0xc9
#define KEYD_PAGEDOWN 0xd1
#define KEYD_DEL 0xc8
#define KEYD_END 0xcf
#define KEYD_SCROLLLOCK 0xc6
#define KEYD_SPACEBAR 0x20
// phares 3/2/98
#define KEYD_NUMLOCK 0xC5 // killough 3/6/98
// cph - Add the numeric keypad keys, as suggested by krose 4/22/99:
// The way numbers are assigned to keys is a mess, but it's too late to
// change that easily. At least these additions are don neatly.
// Codes 0x100-0x200 are reserved for number pad
#define KEYD_KEYPAD0 (0x100 + '0')
#define KEYD_KEYPAD1 (0x100 + '1')
#define KEYD_KEYPAD2 (0x100 + '2')
#define KEYD_KEYPAD3 (0x100 + '3')
#define KEYD_KEYPAD4 (0x100 + '4')
#define KEYD_KEYPAD5 (0x100 + '5')
#define KEYD_KEYPAD6 (0x100 + '6')
#define KEYD_KEYPAD7 (0x100 + '7')
#define KEYD_KEYPAD8 (0x100 + '8')
#define KEYD_KEYPAD9 (0x100 + '9')
#define KEYD_KEYPADENTER (0x100 + KEYD_ENTER)
#define KEYD_KEYPADDIVIDE (0x100 + '/')
#define KEYD_KEYPADMULTIPLY (0x100 + '*')
#define KEYD_KEYPADMINUS (0x100 + '-')
#define KEYD_KEYPADPLUS (0x100 + '+')
#define KEYD_KEYPADPERIOD (0x100 + '.')
// phares 4/19/98:
// Defines Setup Screen groups that config variables appear in.
// Used when resetting the defaults for every item in a Setup group.
typedef enum {
ss_none,
ss_keys,
ss_weap,
ss_stat,
ss_auto,
ss_enem,
ss_mess,
ss_chat,
ss_gen, /* killough 10/98 */
ss_comp, /* killough 10/98 */
ss_max
} ss_types;
// phares 3/20/98:
//
// Player friction is variable, based on controlling
// linedefs. More friction can create mud, sludge,
// magnetized floors, etc. Less friction can create ice.
#define MORE_FRICTION_MOMENTUM 15000 // mud factor based on momentum
#define ORIG_FRICTION 0xE800 // original value
#define ORIG_FRICTION_FACTOR 2048 // original value
#endif // __DOOMDEF__

View File

@@ -0,0 +1,108 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Put all global state variables here.
*
*-----------------------------------------------------------------------------
*/
#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;
//-----------------------------------------------------------------------------
// CPhipps - compatibility vars
complevel_t compatibility_level, default_compatibility_level;
int comp[COMP_TOTAL], default_comp[COMP_TOTAL]; // killough 10/98
// v1.1-like pitched sounds
int pitched_sounds; // killough
int default_translucency; // config file says // phares
boolean general_translucency; // true if translucency is ok // phares
int demo_insurance, default_demo_insurance; // killough 1/16/98
int allow_pushers = 1; // MT_PUSH Things // phares 3/10/98
int default_allow_pushers; // killough 3/1/98: make local to each game
int variable_friction = 1; // ice & mud // phares 3/10/98
int default_variable_friction; // killough 3/1/98: make local to each game
int weapon_recoil; // weapon recoil // phares
int default_weapon_recoil; // killough 3/1/98: make local to each game
int player_bobbing; // whether player bobs or not // phares 2/25/98
int default_player_bobbing; // killough 3/1/98: make local to each game
int monsters_remember; // killough 3/1/98
int default_monsters_remember;
int monster_infighting=1; // killough 7/19/98: monster<=>monster attacks
int default_monster_infighting=1;
int monster_friction=1; // killough 10/98: monsters affected by friction
int default_monster_friction=1;
#ifdef DOGS
int dogs, default_dogs; // killough 7/19/98: Marine's best friend :)
int dog_jumping, default_dog_jumping; // killough 10/98
#endif
// killough 8/8/98: distance friends tend to move towards players
int distfriend = 128, default_distfriend = 128;
// killough 9/8/98: whether monsters are allowed to strafe or retreat
int monster_backing, default_monster_backing;
// killough 9/9/98: whether monsters are able to avoid hazards (e.g. crushers)
int monster_avoid_hazards, default_monster_avoid_hazards;
// killough 9/9/98: whether monsters help friends
int help_friends, default_help_friends;
int flashing_hom; // killough 10/98
int doom_weapon_toggles; // killough 10/98
int monkeys, default_monkeys;

View File

@@ -0,0 +1,336 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2006 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* 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 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;
// CPhipps - new compatibility handling
extern complevel_t compatibility_level, default_compatibility_level;
// CPhipps - old compatibility testing flags aliased to new handling
#define compatibility (compatibility_level<=boom_compatibility_compatibility)
#define demo_compatibility (compatibility_level < boom_compatibility_compatibility)
#define mbf_features (compatibility_level>=mbf_compatibility)
// v1.1-like pitched sounds
extern int pitched_sounds; // killough
extern int default_translucency; // config file says // phares
extern boolean general_translucency; // true if translucency is ok // phares
extern int demo_insurance, default_demo_insurance; // killough 4/5/98
// -------------------------------------------
// killough 10/98: compatibility vector
enum {
comp_telefrag,
comp_dropoff,
comp_vile,
comp_pain,
comp_skull,
comp_blazing,
comp_doorlight,
comp_model,
comp_god,
comp_falloff,
comp_floors,
comp_skymap,
comp_pursuit,
comp_doorstuck,
comp_staylift,
comp_zombie,
comp_stairs,
comp_infcheat,
comp_zerotags,
comp_moveblock,
comp_respawn, /* cph - this is the inverse of comp_respawnfix from eternity */
comp_sound,
comp_666,
comp_soul,
comp_maskedanim,
COMP_NUM, /* cph - should be last in sequence */
COMP_TOTAL=32 // Some extra room for additional variables
};
extern int comp[COMP_TOTAL], default_comp[COMP_TOTAL];
// -------------------------------------------
// 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
// CPhipps - screen parameters
extern unsigned int desired_screenwidth, desired_screenheight;
// -------------------------
// Status flags for refresh.
//
enum automapmode_e {
am_active = 1, // currently shown
am_overlay= 2, // covers the screen, i.e. not overlay mode
am_rotate = 4, // rotates to the player facing direction
am_follow = 8, // keep the player centred
am_grid =16, // show grid
};
extern enum automapmode_e automapmode; // Mode that the automap is in
extern boolean menuactive; // Menu overlayed?
extern boolean paused; // Game Pause?
extern boolean nodrawers;
extern boolean noblit;
// 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, totallive;
extern int totalitems;
extern int totalsecret;
// Timer, for scores.
extern int basetic; /* killough 9/29/98: levelstarttic, adjusted */
extern int leveltime; // tics in game play for par
// --------------------------------------
// DEMO playback/recording related stuff.
extern boolean usergame;
extern boolean demoplayback;
extern boolean demorecording;
extern int demover;
// Quit after playing a demo from cmdline.
extern boolean singledemo;
// Print timing information after quitting. killough
extern boolean timingdemo;
// Run tick clock at fastest speed possible while playing demo. killough
extern boolean fastdemo;
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];
extern boolean realplayeringame[MAXPLAYERS];
extern mapthing_t *deathmatchstarts; // killough
extern size_t num_deathmatchstarts; // killough
extern mapthing_t *deathmatch_p;
// Player spawn spots.
extern mapthing_t playerstarts[];
// Intermission stats.
// Parameters for world map / intermission.
extern wbstartstruct_t wminfo;
//-----------------------------------------
// Internal parameters, used for engine.
//
// File handling stuff.
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_horiz; // killough
extern int mouseSensitivity_vert;
// 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;
extern int maketic;
// Networking and tick handling related.
#ifdef IPHONE
#define BACKUPTICS 16 // JDC: changed from 12 to 16 to allow and masking instead of mod
#define BACKUPTICMASK (BACKUPTICS-1) // JDC
#else
#define BACKUPTICS 12
#endif
extern ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS]; // JDC: added MAXPLAYERS
extern int ticdup;
//-----------------------------------------------------------------------------
extern int allow_pushers; // MT_PUSH Things // phares 3/10/98
extern int default_allow_pushers;
extern int variable_friction; // ice & mud // phares 3/10/98
extern int default_variable_friction;
extern int monsters_remember; // killough 3/1/98
extern int default_monsters_remember;
extern int weapon_recoil; // weapon recoil // phares
extern int default_weapon_recoil;
extern int player_bobbing; // whether player bobs or not // phares 2/25/98
extern int default_player_bobbing; // killough 3/1/98: make local to each game
#ifdef DOGS
extern int dogs, default_dogs; // killough 7/19/98: Marine's best friend :)
extern int dog_jumping, default_dog_jumping; // killough 10/98
#endif
/* killough 8/8/98: distance friendly monsters tend to stay from player */
extern int distfriend, default_distfriend;
/* killough 9/8/98: whether monsters are allowed to strafe or retreat */
extern int monster_backing, default_monster_backing;
/* killough 9/9/98: whether monsters intelligently avoid hazards */
extern int monster_avoid_hazards, default_monster_avoid_hazards;
/* killough 10/98: whether monsters are affected by friction */
extern int monster_friction, default_monster_friction;
/* killough 9/9/98: whether monsters help friends */
extern int help_friends, default_help_friends;
extern int flashing_hom; // killough 10/98
extern int doom_weapon_toggles; // killough 10/98
/* killough 7/19/98: whether monsters should fight against each other */
extern int monster_infighting, default_monster_infighting;
extern int monkeys, default_monkeys;
extern int HelperThing; // type of thing to use for helper
#endif

View File

@@ -0,0 +1,128 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2006 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Simple basic typedefs, isolated here to make it easier
* separating modules.
*
*-----------------------------------------------------------------------------*/
#ifndef __DOOMTYPE__
#define __DOOMTYPE__
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#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
//e6y
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
/* cph - Wrapper for the long long type, as Win32 used a different name.
* Except I don't know what to test as it's compiler specific
* Proff - I fixed it */
#ifndef _MSC_VER
typedef signed long long int_64_t;
typedef unsigned long long uint_64_t;
// define compiled-specific long-long contstant notation here
#define LONGLONG(num) (uint_64_t)num ## ll
#else
typedef __int64 int_64_t;
typedef unsigned __int64 uint_64_t;
// define compiled-specific long-long contstant notation here
#define LONGLONG(num) (uint_64_t)num
#undef PATH_MAX
#define PATH_MAX 1024
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define S_ISDIR(x) (((sbuf.st_mode & S_IFDIR)==S_IFDIR)?1:0)
#endif
#ifdef __GNUC__
#define CONSTFUNC __attribute__((const))
#define PUREFUNC __attribute__((pure))
#define NORETURN __attribute__ ((noreturn))
#else
#define CONSTFUNC
#define PUREFUNC
#define NORETURN
#endif
/* CPhipps - use limits.h instead of depreciated values.h */
#include <limits.h>
/* cph - move compatibility levels here so we can use them in d_server.c */
typedef enum {
doom_12_compatibility, /* Doom v1.2 */
doom_1666_compatibility, /* Doom v1.666 */
doom2_19_compatibility, /* Doom & Doom 2 v1.9 */
ultdoom_compatibility, /* Doom 2 v1.9 */
finaldoom_compatibility, /* Final & Ultimate Doom v1.9, and Doom95 */
dosdoom_compatibility, /* Early dosdoom & tasdoom */
tasdoom_compatibility, /* Early dosdoom & tasdoom */
boom_compatibility_compatibility, /* Boom's compatibility mode */
boom_201_compatibility, /* Compatible with Boom v2.01 */
boom_202_compatibility, /* Compatible with Boom v2.01 */
lxdoom_1_compatibility, /* LxDoom v1.3.2+ */
mbf_compatibility, /* MBF */
prboom_1_compatibility, /* PrBoom 2.03beta? */
prboom_2_compatibility, /* PrBoom 2.1.0-2.1.1 */
prboom_3_compatibility, /* PrBoom 2.2.x */
prboom_4_compatibility, /* PrBoom 2.3.x */
prboom_5_compatibility, /* PrBoom 2.4.0 */
prboom_6_compatibility, /* Latest PrBoom */
MAX_COMPATIBILITY_LEVEL, /* Must be last entry */
/* Aliases follow */
boom_compatibility = boom_201_compatibility, /* Alias used by G_Compatibility */
best_compatibility = prboom_6_compatibility,
} complevel_t;
/* cph - from v_video.h, needed by gl_struct.h */
enum patch_translation_e {
VPT_NONE = 0, // Normal
VPT_FLIP = 1, // Flip image horizontally
VPT_TRANS = 2, // Translate image via a translation table
VPT_STRETCH = 4, // Stretch to compensate for high-res
};
#endif

View File

@@ -0,0 +1,85 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Globally defined strings.
*
*-----------------------------------------------------------------------------
*/
#ifdef __GNUG__
#pragma implementation "dstrings.h"
#endif
#include "dstrings.h"
// killough 1/18/98: remove hardcoded limit, add const:
const char *const endmsg[]=
{
// 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.", // 1/15/98 killough
// 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.", // 1/15/98 killough
// FinalDOOM?
// Note that these ending "bad taste" strings were commented out
// in the original id code as the #else case of an #if 1
// Obviously they were internal playthings before the release of
// DOOM2 and were not intended for public use.
//
// Following messages commented out for now. Bad taste. // phares
// "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.", // 1/15/98 killough
};
// killough 1/18/98: remove hardcoded limit and replace with var (silly hack):
const size_t NUM_QUITMESSAGES = sizeof(endmsg)/sizeof(*endmsg) - 1;

View File

@@ -0,0 +1,80 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* DOOM strings, by language.
* Note: In BOOM, some new strings hav ebeen defined that are
* not found in the French version. A better approach is
* to create a BEX text-replacement file for other
* languages since any language can be supported that way
* without recompiling the program.
*
*-----------------------------------------------------------------------------*/
#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
/* Note this is not externally modifiable through DEH/BEX
* Misc. other strings.
* #define SAVEGAMENAME "boomsav" * killough 3/22/98 *
* Ty 05/04/98 - replaced with a modifiable string, see d_deh.c
*/
/*
* File locations,
* relative to current position.
* Path names are OS-sensitive.
*/
#define DEVMAPS "devmaps"
#define DEVDATA "devdata"
/* Not done in french?
* QuitDOOM messages *
* killough 1/18/98:
* replace hardcoded limit with extern var (silly hack, I know)
*/
#include <stddef.h>
extern const size_t NUM_QUITMESSAGES; /* Calculated in dstrings.c */
extern const char* const endmsg[]; /* killough 1/18/98 const added */
#endif

View File

@@ -0,0 +1,668 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Game completion, final screen animation.
*
*-----------------------------------------------------------------------------
*/
#include "doomstat.h"
#include "d_event.h"
#include "v_video.h"
#include "w_wad.h"
#include "s_sound.h"
#include "sounds.h"
#include "d_deh.h" // Ty 03/22/98 - externalizations
#include "f_finale.h" // CPhipps - hmm...
// Stage of animation:
// 0 = text, 1 = art screen, 2 = character cast
static int finalestage; // cph -
static int finalecount; // made static
static const char* finaletext; // cph -
static const char* finaleflat; // made static const
// defines for the end mission display text // phares
#define TEXTSPEED 3 // original value // phares
#define TEXTWAIT 250 // original value // phares
#define NEWTEXTSPEED 0.01f // new value // phares
#define NEWTEXTWAIT 1000 // new value // phares
// CPhipps - removed the old finale screen text message strings;
// they were commented out for ages already
// Ty 03/22/98 - ... the new s_WHATEVER extern variables are used
// in the code below instead.
void F_StartCast (void);
void F_CastTicker (void);
boolean F_CastResponder (event_t *ev);
void F_CastDrawer (void);
void WI_checkForAccelerate(void); // killough 3/28/98: used to
extern int acceleratestage; // accelerate intermission screens
static int midstage; // whether we're in "mid-stage"
//
// F_StartFinale
//
void F_StartFinale (void)
{
gameaction = ga_nothing;
gamestate = GS_FINALE;
automapmode &= ~am_active;
// killough 3/28/98: clear accelerative text flags
acceleratestage = midstage = 0;
// 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 = bgflatE1; // Ty 03/30/98 - new externalized bg flats
finaletext = s_E1TEXT; // Ty 03/23/98 - Was e1text variable.
break;
case 2:
finaleflat = bgflatE2;
finaletext = s_E2TEXT; // Ty 03/23/98 - Same stuff for each
break;
case 3:
finaleflat = bgflatE3;
finaletext = s_E3TEXT;
break;
case 4:
finaleflat = bgflatE4;
finaletext = s_E4TEXT;
break;
default:
// Ouch.
break;
}
break;
}
// DOOM II and missions packs with E1, M34
case commercial:
{
S_ChangeMusic(mus_read_m, true);
// Ty 08/27/98 - added the gamemission logic
switch (gamemap)
{
case 6:
finaleflat = bgflat06;
finaletext = (gamemission==pack_tnt) ? s_T1TEXT :
(gamemission==pack_plut) ? s_P1TEXT : s_C1TEXT;
break;
case 11:
finaleflat = bgflat11;
finaletext = (gamemission==pack_tnt) ? s_T2TEXT :
(gamemission==pack_plut) ? s_P2TEXT : s_C2TEXT;
break;
case 20:
finaleflat = bgflat20;
finaletext = (gamemission==pack_tnt) ? s_T3TEXT :
(gamemission==pack_plut) ? s_P3TEXT : s_C3TEXT;
break;
case 30:
finaleflat = bgflat30;
finaletext = (gamemission==pack_tnt) ? s_T4TEXT :
(gamemission==pack_plut) ? s_P4TEXT : s_C4TEXT;
break;
case 15:
finaleflat = bgflat15;
finaletext = (gamemission==pack_tnt) ? s_T5TEXT :
(gamemission==pack_plut) ? s_P5TEXT : s_C5TEXT;
break;
case 31:
finaleflat = bgflat31;
finaletext = (gamemission==pack_tnt) ? s_T6TEXT :
(gamemission==pack_plut) ? s_P6TEXT : s_C6TEXT;
break;
default:
// Ouch.
break;
}
break;
// Ty 08/27/98 - end gamemission logic
}
// Indeterminate.
default: // Ty 03/30/98 - not externalized
S_ChangeMusic(mus_read_m, true);
finaleflat = "F_SKY1"; // Not used anywhere else.
finaletext = s_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;
}
// Get_TextSpeed() returns the value of the text display speed // phares
// Rewritten to allow user-directed acceleration -- killough 3/28/98
static float Get_TextSpeed(void)
{
return midstage ? NEWTEXTSPEED : (midstage=acceleratestage) ?
acceleratestage=0, NEWTEXTSPEED : TEXTSPEED;
}
//
// F_Ticker
//
// killough 3/28/98: almost totally rewritten, to use
// player-directed acceleration instead of constant delays.
// Now the player can accelerate the text display by using
// the fire/use keys while it is being printed. The delay
// automatically responds to the user, and gives enough
// time to read.
//
// killough 5/10/98: add back v1.9 demo compatibility
//
void F_Ticker(void)
{
int i;
if (!demo_compatibility)
WI_checkForAccelerate(); // killough 3/28/98: check for acceleration
else
if (gamemode == commercial && finalecount > 50) // check for skipping
for (i=0; i<MAXPLAYERS; i++)
if (players[i].cmd.buttons)
goto next_level; // go on to the next level
// advance animation
finalecount++;
if (finalestage == 2)
F_CastTicker();
if (!finalestage)
{
float speed = demo_compatibility ? TEXTSPEED : Get_TextSpeed();
/* killough 2/28/98: changed to allow acceleration */
if (finalecount > strlen(finaletext)*speed +
(midstage ? NEWTEXTWAIT : TEXTWAIT) ||
(midstage && acceleratestage)) {
if (gamemode != commercial) // Doom 1 / Ultimate Doom episode end
{ // with enough time, it's automatic
finalecount = 0;
finalestage = 1;
wipegamestate = -1; // force a wipe
if (gameepisode == 3)
S_StartMusic(mus_bunny);
}
else // you must press a button to continue in Doom 2
if (!demo_compatibility && midstage)
{
next_level:
if (gamemap == 30)
F_StartCast(); // cast of Doom 2 characters
else
gameaction = ga_worlddone; // next level, e.g. MAP07
}
}
}
}
//
// F_TextWrite
//
// This program displays the background and text at end-mission // phares
// text time. It draws both repeatedly so that other displays, // |
// like the main menu, can be drawn over it dynamically and // V
// erased dynamically. The TEXTSPEED constant is changed into
// the Get_TextSpeed function so that the speed of writing the // ^
// text can be increased, and there's still time to read what's // |
// written. // phares
// CPhipps - reformatted
#include "hu_stuff.h"
extern patchnum_t hu_font[HU_FONTSIZE];
static void F_TextWrite (void)
{
V_DrawBackground(finaleflat, 0);
{ // draw some of the text onto the screen
int cx = 10;
int cy = 10;
const char* ch = finaletext; // CPhipps - const
int count = (int)((float)(finalecount - 10)/Get_TextSpeed()); // phares
int w;
if (count < 0)
count = 0;
for ( ; count ; count-- ) {
int 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 = hu_font[c].width;
if (cx+w > SCREENWIDTH)
break;
// CPhipps - patch drawing updated
V_DrawNumPatch(cx, cy, 0, hu_font[c].lumpnum, CR_DEFAULT, VPT_STRETCH);
cx+=w;
}
}
}
//
// Final DOOM 2 animation
// Casting by id Software.
// in order of appearance
//
typedef struct
{
const char **name; // CPhipps - const**
mobjtype_t type;
} castinfo_t;
#define MAX_CASTORDER 18 /* Ty - hard coded for now */
static const castinfo_t castorder[] = { // CPhipps - static const, initialised here
{ &s_CC_ZOMBIE, MT_POSSESSED },
{ &s_CC_SHOTGUN, MT_SHOTGUY },
{ &s_CC_HEAVY, MT_CHAINGUY },
{ &s_CC_IMP, MT_TROOP },
{ &s_CC_DEMON, MT_SERGEANT },
{ &s_CC_LOST, MT_SKULL },
{ &s_CC_CACO, MT_HEAD },
{ &s_CC_HELL, MT_KNIGHT },
{ &s_CC_BARON, MT_BRUISER },
{ &s_CC_ARACH, MT_BABY },
{ &s_CC_PAIN, MT_PAIN },
{ &s_CC_REVEN, MT_UNDEAD },
{ &s_CC_MANCU, MT_FATSO },
{ &s_CC_ARCH, MT_VILE },
{ &s_CC_SPIDER, MT_SPIDER },
{ &s_CC_CYBER, MT_CYBORG },
{ &s_CC_HERO, MT_PLAYER },
{ NULL, 0}
};
int castnum;
int casttics;
state_t* caststate;
boolean castdeath;
int castframes;
int castonmelee;
boolean castattacking;
//
// F_StartCast
//
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;
}
static void F_CastPrint (const char* text) // CPhipps - static, const char*
{
const char* ch; // CPhipps - const
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 = 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 = hu_font[c].width;
// CPhipps - patch drawing updated
V_DrawNumPatch(cx, 180, 0, hu_font[c].lumpnum, CR_DEFAULT, VPT_STRETCH);
cx+=w;
}
}
//
// F_CastDrawer
//
void F_CastDrawer (void)
{
spritedef_t* sprdef;
spriteframe_t* sprframe;
int lump;
boolean flip;
// erase the entire screen to a background
// CPhipps - patch drawing updated
V_DrawNamePatch(0,0,0, bgcastcall, CR_DEFAULT, VPT_STRETCH); // Ty 03/30/98 bg texture extern
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];
// CPhipps - patch drawing updated
V_DrawNumPatch(160, 170, 0, lump+firstspritelump, CR_DEFAULT,
VPT_STRETCH | (flip ? VPT_FLIP : 0));
}
//
// F_BunnyScroll
//
static const char pfub2[] = { "PFUB2" };
static const char pfub1[] = { "PFUB1" };
static void F_BunnyScroll (void)
{
char name[10];
int stage;
static int laststage;
{
int scrolled = 320 - (finalecount-230)/2;
if (scrolled <= 0) {
V_DrawNamePatch(0, 0, 0, pfub2, CR_DEFAULT, VPT_STRETCH);
} else if (scrolled >= 320) {
V_DrawNamePatch(0, 0, 0, pfub1, CR_DEFAULT, VPT_STRETCH);
} else {
V_DrawNamePatch(320-scrolled, 0, 0, pfub1, CR_DEFAULT, VPT_STRETCH);
V_DrawNamePatch(-scrolled, 0, 0, pfub2, CR_DEFAULT, VPT_STRETCH);
}
}
if (finalecount < 1130)
return;
if (finalecount < 1180)
{
// CPhipps - patch drawing updated
V_DrawNamePatch((320-13*8)/2, (200-8*8)/2,0, "END0", CR_DEFAULT, VPT_STRETCH);
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);
// CPhipps - patch drawing updated
V_DrawNamePatch((320-13*8)/2, (200-8*8)/2, 0, name, CR_DEFAULT, VPT_STRETCH);
}
//
// F_Drawer
//
void F_Drawer (void)
{
if (finalestage == 2)
{
F_CastDrawer ();
return;
}
if (!finalestage)
F_TextWrite ();
else
{
switch (gameepisode)
{
// CPhipps - patch drawing updated
case 1:
if ( gamemode == retail )
V_DrawNamePatch(0, 0, 0, "CREDIT", CR_DEFAULT, VPT_STRETCH);
else
V_DrawNamePatch(0, 0, 0, "HELP2", CR_DEFAULT, VPT_STRETCH);
break;
case 2:
V_DrawNamePatch(0, 0, 0, "VICTORY2", CR_DEFAULT, VPT_STRETCH);
break;
case 3:
F_BunnyScroll ();
break;
case 4:
V_DrawNamePatch(0, 0, 0, "ENDPIC", CR_DEFAULT, VPT_STRETCH);
break;
}
}
}

View File

@@ -0,0 +1,56 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Related to f_finale.c, which is called at the end of a level
*
*-----------------------------------------------------------------------------*/
#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

View File

@@ -0,0 +1,202 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Mission begin melt/wipe screen special effect.
*
*-----------------------------------------------------------------------------
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "z_zone.h"
#include "doomdef.h"
#include "i_video.h"
#include "v_video.h"
#include "m_random.h"
#include "f_wipe.h"
//
// SCREEN WIPE PACKAGE
//
// Parts re-written to support true-color video modes. Column-major
// formatting removed. - POPE
// CPhipps - macros for the source and destination screens
#define SRC_SCR 2
#define DEST_SCR 3
static screeninfo_t wipe_scr_start;
static screeninfo_t wipe_scr_end;
static screeninfo_t wipe_scr;
static int y_lookup[MAX_SCREENWIDTH];
static int wipe_initMelt(int ticks)
{
int i;
// copy start screen to main screen
for(i=0;i<SCREENHEIGHT;i++)
memcpy(wipe_scr.data+i*wipe_scr.byte_pitch,
wipe_scr_start.data+i*wipe_scr.byte_pitch,
SCREENWIDTH*V_GetPixelDepth());
// setup initial column positions (y<0 => not ready to scroll yet)
y_lookup[0] = -(M_Random()%16);
for (i=1;i<SCREENWIDTH;i++)
{
int r = (M_Random()%3) - 1;
y_lookup[i] = y_lookup[i-1] + r;
if (y_lookup[i] > 0)
y_lookup[i] = 0;
else
if (y_lookup[i] == -16)
y_lookup[i] = -15;
}
return 0;
}
static int wipe_doMelt(int ticks)
{
boolean done = true;
int i;
const int depth = V_GetPixelDepth();
while (ticks--) {
for (i=0;i<(SCREENWIDTH);i++) {
if (y_lookup[i]<0) {
y_lookup[i]++;
done = false;
continue;
}
if (y_lookup[i] < SCREENHEIGHT) {
byte *s, *d;
int j, k, dy;
/* cph 2001/07/29 -
* The original melt rate was 8 pixels/sec, i.e. 25 frames to melt
* the whole screen, so make the melt rate depend on SCREENHEIGHT
* so it takes no longer in high res
*/
dy = (y_lookup[i] < 16) ? y_lookup[i]+1 : SCREENHEIGHT/25;
if (y_lookup[i]+dy >= SCREENHEIGHT)
dy = SCREENHEIGHT - y_lookup[i];
s = wipe_scr_end.data + (y_lookup[i]*wipe_scr_end.byte_pitch+(i*depth));
d = wipe_scr.data + (y_lookup[i]*wipe_scr.byte_pitch+(i*depth));
for (j=dy;j;j--) {
for (k=0; k<depth; k++)
d[k] = s[k];
d += wipe_scr.byte_pitch;
s += wipe_scr_end.byte_pitch;
}
y_lookup[i] += dy;
s = wipe_scr_start.data + (i*depth);
d = wipe_scr.data + (y_lookup[i]*wipe_scr.byte_pitch+(i*depth));
for (j=SCREENHEIGHT-y_lookup[i];j;j--) {
for (k=0; k<depth; k++)
d[k] = s[k];
d += wipe_scr.byte_pitch;
s += wipe_scr_end.byte_pitch;
}
done = false;
}
}
}
return done;
}
// CPhipps - modified to allocate and deallocate screens[2 to 3] as needed, saving memory
static int wipe_exitMelt(int ticks)
{
V_FreeScreen(&wipe_scr_start);
wipe_scr_start.width = 0;
wipe_scr_start.height = 0;
V_FreeScreen(&wipe_scr_end);
wipe_scr_end.width = 0;
wipe_scr_end.height = 0;
// Paranoia
screens[SRC_SCR] = wipe_scr_start;
screens[DEST_SCR] = wipe_scr_end;
return 0;
}
int wipe_StartScreen(void)
{
wipe_scr_start.width = SCREENWIDTH;
wipe_scr_start.height = SCREENHEIGHT;
wipe_scr_start.byte_pitch = screens[0].byte_pitch;
wipe_scr_start.short_pitch = screens[0].short_pitch;
wipe_scr_start.int_pitch = screens[0].int_pitch;
wipe_scr_start.not_on_heap = false;
V_AllocScreen(&wipe_scr_start);
screens[SRC_SCR] = wipe_scr_start;
V_CopyRect(0, 0, 0, SCREENWIDTH, SCREENHEIGHT, 0, 0, SRC_SCR, VPT_NONE ); // Copy start screen to buffer
return 0;
}
int wipe_EndScreen(void)
{
wipe_scr_end.width = SCREENWIDTH;
wipe_scr_end.height = SCREENHEIGHT;
wipe_scr_end.byte_pitch = screens[0].byte_pitch;
wipe_scr_end.short_pitch = screens[0].short_pitch;
wipe_scr_end.int_pitch = screens[0].int_pitch;
wipe_scr_end.not_on_heap = false;
V_AllocScreen(&wipe_scr_end);
screens[DEST_SCR] = wipe_scr_end;
V_CopyRect(0, 0, 0, SCREENWIDTH, SCREENHEIGHT, 0, 0, DEST_SCR, VPT_NONE); // Copy end screen to buffer
V_CopyRect(0, 0, SRC_SCR, SCREENWIDTH, SCREENHEIGHT, 0, 0, 0 , VPT_NONE); // restore start screen
return 0;
}
// killough 3/5/98: reformatted and cleaned up
int wipe_ScreenWipe(int ticks)
{
static boolean go; // when zero, stop the wipe
if (!go) // initial stuff
{
go = 1;
wipe_scr = screens[0];
wipe_initMelt(ticks);
}
// do a piece of wipe-in
if (wipe_doMelt(ticks)) // final stuff
{
wipe_exitMelt(ticks);
go = 0;
}
return !go;
}

View File

@@ -0,0 +1,45 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Mission start screen wipe/melt, special effects.
*
*-----------------------------------------------------------------------------*/
#ifndef __F_WIPE_H__
#define __F_WIPE_H__
/*
* SCREEN WIPE PACKAGE
*/
int wipe_ScreenWipe (int ticks);
int wipe_StartScreen(void);
int wipe_EndScreen (void);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,178 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION: Main game control interface.
*-----------------------------------------------------------------------------*/
#ifndef __G_GAME__
#define __G_GAME__
#include "doomdef.h"
#include "d_event.h"
#include "d_ticcmd.h"
//
// GAME
//
// killough 5/2/98: number of bytes reserved for saving options
#define GAME_OPTION_SIZE 64
boolean G_Responder(event_t *ev);
boolean G_CheckDemoStatus(void);
void G_DeathMatchSpawnPlayer(int playernum);
void G_InitNew(skill_t skill, int episode, int map);
void G_DeferedInitNew(skill_t skill, int episode, int map);
void G_DeferedPlayDemo(const char *demo); // CPhipps - const
void G_LoadGame(int slot, boolean is_command); // killough 5/15/98
void G_ForcedLoadGame(void); // killough 5/15/98: forced loadgames
void G_DoLoadGame(void);
void G_SaveGame(int slot, char *description); // Called by M_Responder.
void G_BeginRecording(void);
// CPhipps - const on these string params
void G_RecordDemo(const char *name); // Only called by startup code.
void G_ExitLevel(void);
void G_SecretExitLevel(void);
void G_WorldDone(void);
void G_EndGame(void); /* cph - make m_menu.c call a G_* function for this */
void G_Ticker(void);
void G_ReloadDefaults(void); // killough 3/1/98: loads game defaults
void G_SaveGameName(char *, size_t, int, boolean); /* killough 3/22/98: sets savegame filename */
void G_SetFastParms(int); // killough 4/10/98: sets -fast parameters
void G_DoNewGame(void);
void G_DoReborn(int playernum);
void G_DoPlayDemo(void);
void G_DoCompleted(void);
void G_ReadDemoTiccmd(ticcmd_t *cmd);
void G_WriteDemoTiccmd(ticcmd_t *cmd);
void G_DoWorldDone(void);
void G_Compatibility(void);
const byte *G_ReadOptions(const byte *demo_p); /* killough 3/1/98 - cph: const byte* */
byte *G_WriteOptions(byte *demo_p); // killough 3/1/98
void G_PlayerReborn(int player);
void G_RestartLevel(void); // CPhipps - menu involked level restart
void G_DoVictory(void);
void G_BuildTiccmd (ticcmd_t* cmd); // CPhipps - move decl to header
void G_ChangedPlayerColour(int pn, int cl); // CPhipps - On-the-fly player colour changing
void G_MakeSpecialEvent(buttoncode_t bc, ...); /* cph - new event stuff */
// killough 1/18/98: Doom-style printf; killough 4/25/98: add gcc attributes
// CPhipps - renames to doom_printf to avoid name collision with glibc
void doom_printf(const char *, ...) __attribute__((format(printf,1,2)));
// killough 5/2/98: moved from m_misc.c:
extern int key_right;
extern int key_left;
extern int key_up;
extern int key_down;
extern int key_menu_right; // phares 3/7/98
extern int key_menu_left; // |
extern int key_menu_up; // V
extern int key_menu_down;
extern int key_menu_backspace; // ^
extern int key_menu_escape; // |
extern int key_menu_enter; // phares 3/7/98
extern int key_strafeleft;
extern int key_straferight;
extern int key_fire;
extern int key_use;
extern int key_strafe;
extern int key_speed;
extern int key_escape; // phares
extern int key_savegame; // |
extern int key_loadgame; // V
extern int key_autorun;
extern int key_reverse;
extern int key_zoomin;
extern int key_zoomout;
extern int key_chat;
extern int key_backspace;
extern int key_enter;
extern int key_help;
extern int key_soundvolume;
extern int key_hud;
extern int key_quicksave;
extern int key_endgame;
extern int key_messages;
extern int key_quickload;
extern int key_quit;
extern int key_gamma;
extern int key_spy;
extern int key_pause;
extern int key_setup;
extern int key_forward;
extern int key_leftturn;
extern int key_rightturn;
extern int key_backward;
extern int key_weapontoggle;
extern int key_weapon1;
extern int key_weapon2;
extern int key_weapon3;
extern int key_weapon4;
extern int key_weapon5;
extern int key_weapon6;
extern int key_weapon7;
extern int key_weapon8;
extern int key_weapon9;
extern int destination_keys[MAXPLAYERS];
extern int key_map_right;
extern int key_map_left;
extern int key_map_up;
extern int key_map_down;
extern int key_map_zoomin;
extern int key_map_zoomout;
extern int key_map;
extern int key_map_gobig;
extern int key_map_follow;
extern int key_map_mark; // ^
extern int key_map_clear; // |
extern int key_map_grid; // phares
extern int key_map_rotate; // cph - map rotation
extern int key_map_overlay;// cph - map overlay
extern int key_screenshot; // killough 2/22/98 -- add key for screenshot
extern int autorun; // always running? // phares
extern int defaultskill; //jff 3/24/98 default skill
extern boolean haswolflevels; //jff 4/18/98 wolf levels present
extern int bodyquesize; // killough 2/8/98: adustable corpse limit
// killough 5/2/98: moved from d_deh.c:
// Par times (new item with BOOM) - from g_game.c
extern int pars[4][10]; // hardcoded array size
extern int cpars[32]; // hardcoded array size
// CPhipps - Make savedesciption visible in wider scope
#define SAVEDESCLEN 32
extern char savedescription[SAVEDESCLEN]; // Description to save in savegame
/* cph - compatibility level strings */
extern const char * comp_lev_str[];
#endif

View File

@@ -0,0 +1,228 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
*
*---------------------------------------------------------------------
*/
#ifndef _GL_INTERN_H
#define _GL_INTERN_H
typedef enum
{
GLDT_UNREGISTERED,
GLDT_BROKEN,
GLDT_PATCH,
GLDT_TEXTURE,
GLDT_FLAT
} GLTexType;
typedef struct
{
int index;
int width,height;
int leftoffset,topoffset;
int tex_width,tex_height;
int realtexwidth, realtexheight;
int buffer_width,buffer_height;
int buffer_size;
int glTexID[CR_LIMIT+MAXPLAYERS];
GLTexType textype;
boolean mipmap;
} GLTexture;
// JDC: moved these to header ---------------------------
#define MAP_COEFF 128.0f
#define MAP_SCALE (MAP_COEFF*(float)FRACUNIT)
typedef struct
{
float x1,x2;
float z1,z2;
} GLSeg;
#define GLDWF_TOP 1
#define GLDWF_M1S 2
#define GLDWF_M2S 3
#define GLDWF_BOT 4
#define GLDWF_SKY 5
#define GLDWF_SKYFLIP 6
typedef struct
{
GLSeg *glseg;
float ytop,ybottom;
float ul,ur,vt,vb;
float light;
float alpha;
float skyymid;
float skyyaw;
GLTexture *gltexture;
byte flag;
#ifdef IPHONE
side_t *side;
#endif
} GLWall;
typedef struct
{
int sectornum;
float light; // the lightlevel of the flat
float uoffs,voffs; // the texture coordinates
float z; // the z position of the flat (height)
GLTexture *gltexture;
boolean ceiling;
} GLFlat;
typedef struct
{
int cm;
float x,y,z;
float vt,vb;
float ul,ur;
float x1,y1;
float x2,y2;
float light;
fixed_t scale;
GLTexture *gltexture;
boolean shadow;
boolean trans;
} GLSprite;
typedef enum
{
GLDIT_NONE,
GLDIT_WALL,
GLDIT_FLAT,
GLDIT_SPRITE
} GLDrawItemType;
typedef struct
{
GLDrawItemType itemtype;
int itemcount;
int firstitemindex;
byte rendermarker;
} GLDrawItem;
typedef struct
{
GLWall *walls;
int num_walls;
int max_walls;
GLFlat *flats;
int num_flats;
int max_flats;
GLSprite *sprites;
int num_sprites;
int max_sprites;
GLDrawItem *drawitems;
int num_drawitems;
int max_drawitems;
} GLDrawInfo;
extern GLDrawInfo gld_drawinfo;
typedef struct
{
GLfloat x;
GLfloat y;
GLfloat z;
} GLVertex;
typedef struct
{
GLfloat u;
GLfloat v;
} GLTexcoord;
/* GLLoopDef is the struct for one loop. A loop is a list of vertexes
* for triangles, which is calculated by the gluTesselator in gld_PrecalculateSector
* and in gld_PreprocessCarvedFlat
*/
typedef struct
{
GLenum mode; // GL_TRIANGLES, GL_TRIANGLE_STRIP or GL_TRIANGLE_FAN
int vertexcount; // number of vertexes in this loop
int vertexindex; // index into vertex list
} GLLoopDef;
// GLSector is the struct for a sector with a list of loops.
typedef struct
{
int loopcount; // number of loops for this sector
GLLoopDef *loops; // the loops itself
} GLSector;
extern GLSector *sectorloops;
typedef struct drawVert_s { // JDC
float xyz[3]; // TODO: adjust MAP_SCALE, make shorts
float st[2]; // TODO: set texture matrix, make shorts
unsigned char rgba[4];
} drawVert_t;
#define MAX_DRAW_VERTS 0x10000
extern drawVert_t drawVerts[MAX_DRAW_VERTS];
extern int numDrawVerts;
//--------------------------------------
extern int gld_max_texturesize;
extern char *gl_tex_format_string;
extern int gl_tex_format;
extern int gl_tex_filter;
extern int gl_mipmap_filter;
extern int gl_texture_filter_anisotropic;
extern int gl_paletted_texture;
extern int gl_shared_texture_palette;
extern boolean use_mipmapping;
extern int transparent_pal_index;
extern unsigned char gld_palmap[256];
extern GLTexture *last_gltexture;
extern int last_cm;
//e6y: in some cases textures with a zero index (NO_TEXTURE) should be registered
GLTexture *gld_RegisterTexture(int texture_num, boolean mipmap, boolean force);
void gld_BindTexture(GLTexture *gltexture);
GLTexture *gld_RegisterPatch(int lump, int cm);
void gld_BindPatch(GLTexture *gltexture, int cm);
GLTexture *gld_RegisterFlat(int lump, boolean mipmap);
void gld_BindFlat(GLTexture *gltexture);
void gld_InitPalettedTextures(void);
int gld_GetTexDimension(int value);
void gld_SetTexturePalette(GLenum target);
void gld_Precache(void);
PFNGLCOLORTABLEEXTPROC gld_ColorTableEXT;
#endif // _GL_INTERN_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,67 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
*
*---------------------------------------------------------------------
*/
#ifndef _GL_STRUCT_H
#define _GL_STRUCT_H
extern int nodesVersion;
extern byte *staticPlaypal; // JDC: added to avoid the continuous lookup of PLAYPAL
void gld_Init(int width, int height);
void gld_InitCommandLine();
void gld_DrawNumPatch(int x, int y, int lump, int cm, enum patch_translation_e flags);
void gld_DrawBackground(const char* name);
void gld_DrawLine(int x0, int y0, int x1, int y1, int BaseColor);
void gld_DrawWeapon(int weaponlump, vissprite_t *vis, int lightlevel);
void gld_FillBlock(int x, int y, int width, int height, int col);
void gld_SetPalette(int palette);
unsigned char *gld_ReadScreen (void);
void gld_CleanMemory(void);
void gld_PreprocessLevel(void);
void gld_Set2DMode();
void gld_InitDrawScene(void);
void gld_StartDrawScene(void);
void gld_AddPlane(int subsectornum, visplane_t *floor, visplane_t *ceiling);
void gld_AddWall(seg_t *seg);
void gld_AddSprite(vissprite_t *vspr);
void gld_DrawScene(player_t *player);
void gld_EndDrawScene(void);
void gld_Finish();
#endif // _GL_STRUCT_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,767 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION: heads-up text and input code
*
*-----------------------------------------------------------------------------
*/
#include "doomdef.h"
#include "doomstat.h"
#include "v_video.h"
#include "m_swap.h"
#include "hu_lib.h"
#include "hu_stuff.h"
#include "r_main.h"
#include "r_draw.h"
// boolean : whether the screen is always erased
#define noterased viewwindowx
extern int key_backspace; // phares
extern int key_enter; // phares
//
// not used currently
// code to initialize HUlib would go here if needed
//
static void HUlib_init(void)
{
}
////////////////////////////////////////////////////////
//
// Basic text line widget
//
////////////////////////////////////////////////////////
//
// HUlib_clearTextLine()
//
// Blank the internal text line in a hu_textline_t widget
//
// Passed a hu_textline_t, returns nothing
//
void HUlib_clearTextLine(hu_textline_t* t)
{
t->linelen = // killough 1/23 98: support multiple lines
t->len = 0;
t->l[0] = 0;
t->needsupdate = true;
}
//
// HUlib_initTextLine()
//
// Initialize a hu_textline_t widget. Set the position, font, start char
// of the font, and color range to be used.
//
// Passed a hu_textline_t, and the values used to initialize
// Returns nothing
//
void HUlib_initTextLine(hu_textline_t* t, int x, int y,
const patchnum_t* f, int sc, int cm )
//jff 2/16/98 add color range parameter
{
t->x = x;
t->y = y;
t->f = f;
t->sc = sc;
t->cm = cm;
HUlib_clearTextLine(t);
}
//
// HUlib_addCharToTextLine()
//
// Adds a character at the end of the text line in a hu_textline_t widget
//
// Passed the hu_textline_t and the char to add
// Returns false if already at length limit, true if the character added
//
boolean HUlib_addCharToTextLine
( hu_textline_t* t,
char ch )
{
// killough 1/23/98 -- support multiple lines
if (t->linelen == HU_MAXLINELENGTH)
return false;
else
{
t->linelen++;
if (ch == '\n')
t->linelen=0;
t->l[t->len++] = ch;
t->l[t->len] = 0;
t->needsupdate = 4;
return true;
}
}
//
// HUlib_delCharFromTextLine()
//
// Deletes a character at the end of the text line in a hu_textline_t widget
//
// Passed the hu_textline_t
// Returns false if already empty, true if the character deleted
//
static boolean HUlib_delCharFromTextLine(hu_textline_t* t)
{
if (!t->len) return false;
else
{
t->l[--t->len] = 0;
t->needsupdate = 4;
return true;
}
}
//
// HUlib_drawTextLine()
//
// Draws a hu_textline_t widget
//
// Passed the hu_textline_t and flag whether to draw a cursor
// Returns nothing
//
void HUlib_drawTextLine
( hu_textline_t* l,
boolean drawcursor )
{
int i;
int w;
int x;
unsigned char c;
int oc = l->cm; //jff 2/17/98 remember default color
int y = l->y; // killough 1/18/98 -- support multiple lines
// draw the new stuff
x = l->x;
for (i=0;i<l->len;i++)
{
c = toupper(l->l[i]); //jff insure were not getting a cheap toupper conv.
if (c=='\n') // killough 1/18/98 -- support multiple lines
x=0,y+=8;
else if (c=='\t') // killough 1/23/98 -- support tab stops
x=x-x%80+80;
else if (c=='\x1b') //jff 2/17/98 escape code for color change
{ //jff 3/26/98 changed to actual escape char
if (++i<l->len)
if (l->l[i]>='0' && l->l[i]<='9')
l->cm = l->l[i]-'0';
}
else if (c != ' ' && c >= l->sc && c <= 127)
{
w = l->f[c - l->sc].width;
if (x+w > BASE_WIDTH)
break;
// killough 1/18/98 -- support multiple lines:
// CPhipps - patch drawing updated
V_DrawNumPatch(x, y, FG, l->f[c - l->sc].lumpnum, l->cm, VPT_TRANS | VPT_STRETCH);
x += w;
}
else
{
x += 4;
if (x >= BASE_WIDTH)
break;
}
}
l->cm = oc; //jff 2/17/98 restore original color
// draw the cursor if requested
if (drawcursor && x + l->f['_' - l->sc].width <= BASE_WIDTH)
{
// killough 1/18/98 -- support multiple lines
// CPhipps - patch drawing updated
V_DrawNumPatch(x, y, FG, l->f['_' - l->sc].lumpnum, CR_DEFAULT, VPT_NONE | VPT_STRETCH);
}
}
//
// HUlib_eraseTextLine()
//
// Erases a hu_textline_t widget when screen border is behind text
// Sorta called by HU_Erase and just better darn get things straight
//
// Passed the hu_textline_t
// Returns nothing
//
void HUlib_eraseTextLine(hu_textline_t* l)
{
int lh;
int y;
// 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 (!(automapmode & am_active) && viewwindowx && l->needsupdate)
{
lh = l->f[0].height + 1;
for (y=l->y; y<l->y+lh ; y++)
{
if (y < viewwindowy || y >= viewwindowy + viewheight)
R_VideoErase(0, y, SCREENWIDTH); // erase entire line
else
{
// erase left border
R_VideoErase(0, y, viewwindowx);
// erase right border
R_VideoErase(viewwindowx + viewwidth, y, viewwindowx);
}
}
}
if (l->needsupdate) l->needsupdate--;
}
////////////////////////////////////////////////////////
//
// Player message widget (up to 4 lines of text)
//
////////////////////////////////////////////////////////
//
// HUlib_initSText()
//
// Initialize a hu_stext_t widget. Set the position, number of lines, font,
// start char of the font, and color range to be used, and whether enabled.
//
// Passed a hu_stext_t, and the values used to initialize
// Returns nothing
//
void HUlib_initSText
( hu_stext_t* s,
int x,
int y,
int h,
const patchnum_t* font,
int startchar,
int cm, //jff 2/16/98 add color range parameter
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*(font[0].height+1),
font,
startchar,
cm
);
}
//
// HUlib_addLineToSText()
//
// Adds a blank line to a hu_stext_t widget
//
// Passed a hu_stext_t
// Returns nothing
//
static 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;
}
//
// HUlib_addMessageToSText()
//
// Adds a message line with prefix to a hu_stext_t widget
//
// Passed a hu_stext_t, the prefix string, and a message string
// Returns nothing
//
void HUlib_addMessageToSText(hu_stext_t* s, const char* prefix, const 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++));
}
//
// HUlib_drawSText()
//
// Displays a hu_stext_t widget
//
// Passed a hu_stext_t
// Returns nothing
//
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
}
}
//
// HUlib_eraseSText()
//
// Erases a hu_stext_t widget, when the screen is not fullsize
//
// Passed a hu_stext_t
// Returns nothing
//
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;
}
////////////////////////////////////////////////////////
//
// Scrolling message review widget
//
// jff added 2/26/98
//
////////////////////////////////////////////////////////
//
// HUlib_initMText()
//
// Initialize a hu_mtext_t widget. Set the position, width, number of lines,
// font, start char of the font, color range, background font, and whether
// enabled.
//
// Passed a hu_mtext_t, and the values used to initialize
// Returns nothing
//
void HUlib_initMText(hu_mtext_t *m, int x, int y, int w, int h,
const patchnum_t* font, int startchar, int cm,
const patchnum_t* bgfont, boolean *on)
{
int i;
m->nl = 0;
m->nr = 0;
m->cl = -1; //jff 4/28/98 prepare for pre-increment
m->x = x;
m->y = y;
m->w = w;
m->h = h;
m->bg = bgfont;
m->on = on;
for (i=0;i<HU_MAXMESSAGES;i++)
{
HUlib_initTextLine
(
&m->l[i],
x,
y + (hud_list_bgon? i+1 : i)*HU_REFRESHSPACING,
font,
startchar,
cm
);
}
}
//
// HUlib_addLineToMText()
//
// Adds a blank line to a hu_mtext_t widget
//
// Passed a hu_mtext_t
// Returns nothing
//
static void HUlib_addLineToMText(hu_mtext_t* m)
{
// add a clear line
if (++m->cl == hud_msg_lines)
m->cl = 0;
HUlib_clearTextLine(&m->l[m->cl]);
if (m->nl<hud_msg_lines)
m->nl++;
// needs updating
m->l[m->cl].needsupdate = 4;
}
//
// HUlib_addMessageToMText()
//
// Adds a message line with prefix to a hu_mtext_t widget
//
// Passed a hu_mtext_t, the prefix string, and a message string
// Returns nothing
//
void HUlib_addMessageToMText(hu_mtext_t* m, const char* prefix, const char* msg)
{
HUlib_addLineToMText(m);
if (prefix)
while (*prefix)
HUlib_addCharToTextLine(&m->l[m->cl], *(prefix++));
while (*msg)
HUlib_addCharToTextLine(&m->l[m->cl], *(msg++));
}
//
// HUlib_drawMBg()
//
// Draws a background box which the message display review widget can
// display over
//
// Passed position, width, height, and the background patches
// Returns nothing
//
void HUlib_drawMBg
( int x,
int y,
int w,
int h,
const patchnum_t* bgp
)
{
int xs = bgp[0].width;
int ys = bgp[0].height;
int i,j;
// CPhipps - patch drawing updated
// top rows
V_DrawNumPatch(x, y, FG, bgp[0].lumpnum, CR_DEFAULT, VPT_STRETCH); // ul
for (j=x+xs;j<x+w-xs;j+=xs) // uc
V_DrawNumPatch(j, y, FG, bgp[1].lumpnum, CR_DEFAULT, VPT_STRETCH);
V_DrawNumPatch(j, y, FG, bgp[2].lumpnum, CR_DEFAULT, VPT_STRETCH); // ur
// middle rows
for (i=y+ys;i<y+h-ys;i+=ys)
{
V_DrawNumPatch(x, i, FG, bgp[3].lumpnum, CR_DEFAULT, VPT_STRETCH); // cl
for (j=x+xs;j<x+w-xs;j+=xs) // cc
V_DrawNumPatch(j, i, FG, bgp[4].lumpnum, CR_DEFAULT, VPT_STRETCH);
V_DrawNumPatch(j, i, FG, bgp[5].lumpnum, CR_DEFAULT, VPT_STRETCH); // cr
}
// bottom row
V_DrawNumPatch(x, i, FG, bgp[6].lumpnum, CR_DEFAULT, VPT_STRETCH); // ll
for (j=x+xs;j<x+w-xs;j+=xs) // lc
V_DrawNumPatch(j, i, FG, bgp[7].lumpnum, CR_DEFAULT, VPT_STRETCH);
V_DrawNumPatch(j, i, FG, bgp[8].lumpnum, CR_DEFAULT, VPT_STRETCH); // lr
}
//
// HUlib_drawMText()
//
// Displays a hu_mtext_t widget
//
// Passed a hu_mtext_t
// Returns nothing
//
void HUlib_drawMText(hu_mtext_t* m)
{
int i, idx, y;
hu_textline_t *l;
if (!*m->on)
return; // if not on, don't draw
// draw everything
if (hud_list_bgon)
HUlib_drawMBg(m->x,m->y,m->w,m->h,m->bg);
y = m->y + HU_REFRESHSPACING;
for (i=0 ; i<m->nl ; i++)
{
idx = m->cl - i;
if (idx < 0)
idx += m->nl; // handle queue of lines
l = &m->l[idx];
if (hud_list_bgon)
{
l->x = m->x + 4;
l->y = m->y + (i+1)*HU_REFRESHSPACING;
}
else
{
l->x = m->x;
l->y = m->y + i*HU_REFRESHSPACING;
}
// need a decision made here on whether to skip the draw
HUlib_drawTextLine(l, false); // no cursor, please
}
}
//
// HUlib_eraseMBg()
//
// Erases background behind hu_mtext_t widget, when the screen is not fullsize
//
// Passed a hu_mtext_t
// Returns nothing
//
static void HUlib_eraseMBg(hu_mtext_t* m)
{
int lh;
int y;
// 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 (!(automapmode & am_active) && viewwindowx)
{
lh = m->l[0].f[0].height + 1;
for (y=m->y; y<m->y+lh*(hud_msg_lines+2) ; y++)
{
if (y < viewwindowy || y >= viewwindowy + viewheight)
R_VideoErase(0, y, SCREENWIDTH); // erase entire line
else
{
// erase left border
R_VideoErase(0, y, viewwindowx);
// erase right border
R_VideoErase(viewwindowx + viewwidth, y, viewwindowx);
}
}
}
}
//
// HUlib_eraseMText()
//
// Erases a hu_mtext_t widget, when the screen is not fullsize
//
// Passed a hu_mtext_t
// Returns nothing
//
void HUlib_eraseMText(hu_mtext_t* m)
{
int i;
if (hud_list_bgon)
HUlib_eraseMBg(m);
for (i=0 ; i< m->nl ; i++)
{
m->l[i].needsupdate = 4;
HUlib_eraseTextLine(&m->l[i]);
}
}
////////////////////////////////////////////////////////
//
// Interactive text entry widget
//
////////////////////////////////////////////////////////
//
// HUlib_initIText()
//
// Initialize a hu_itext_t widget. Set the position, font,
// start char of the font, color range, and whether enabled.
//
// Passed a hu_itext_t, and the values used to initialize
// Returns nothing
//
void HUlib_initIText
( hu_itext_t* it,
int x,
int y,
const patchnum_t* font,
int startchar,
int cm, //jff 2/16/98 add color range parameter
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, cm);
}
// The following deletion routines adhere to the left margin restriction
//
// HUlib_delCharFromIText()
//
// Deletes a character at the end of the text line in a hu_itext_t widget
//
// Passed the hu_itext_t
// Returns nothing
//
static void HUlib_delCharFromIText(hu_itext_t* it)
{
if (it->l.len != it->lm)
HUlib_delCharFromTextLine(&it->l);
}
//
// HUlib_eraseLineFromIText()
//
// Deletes all characters from a hu_itext_t widget
//
// Passed the hu_itext_t
// Returns nothing
//
static void HUlib_eraseLineFromIText(hu_itext_t* it)
{
while (it->lm != it->l.len)
HUlib_delCharFromTextLine(&it->l);
}
//
// HUlib_resetIText()
//
// Deletes all characters from a hu_itext_t widget
// Resets left margin as well
//
// Passed the hu_itext_t
// Returns nothing
//
void HUlib_resetIText(hu_itext_t* it)
{
it->lm = 0;
HUlib_clearTextLine(&it->l);
}
//
// HUlib_addPrefixToIText()
//
// Adds a prefix string passed to a hu_itext_t widget
// Sets left margin to length of string added
//
// Passed the hu_itext_t and the prefix string
// Returns nothing
//
void HUlib_addPrefixToIText
( hu_itext_t* it,
char* str )
{
while (*str)
HUlib_addCharToTextLine(&it->l, *(str++));
it->lm = it->l.len;
}
//
// HUlib_keyInIText()
//
// Wrapper function for handling general keyed input.
//
// Passed the hu_itext_t and the char 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) // phares
HUlib_delCharFromIText(it);
else if (ch != key_enter) // phares
return false; // did not eat key
return true; // ate the key
}
//
// HUlib_drawIText()
//
// Displays a hu_itext_t widget
//
// Passed the hu_itext_t
// Returns nothing
//
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
}
//
// HUlib_eraseIText()
//
// Erases a hu_itext_t widget when the screen is not fullsize
//
// Passed the hu_itext_t
// Returns nothing
//
void HUlib_eraseIText(hu_itext_t* it)
{
if (it->laston && !*it->on)
it->l.needsupdate = 4;
HUlib_eraseTextLine(&it->l);
it->laston = *it->on;
}

View File

@@ -0,0 +1,247 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION: none
*
*-----------------------------------------------------------------------------*/
#ifndef __HULIB__
#define __HULIB__
// We are referring to patches.
#include "r_defs.h"
#include "v_video.h" //jff 2/16/52 include color range defs
/* background and foreground screen numbers
* different from other modules. */
#define BG 1
#define FG 0
/* font stuff
* #define HU_CHARERASE KEYD_BACKSPACE / not used / phares
*/
#define HU_MAXLINES 4
#define HU_MAXLINELENGTH 80
#define HU_REFRESHSPACING 8 /*jff 2/26/98 space lines in text refresh widget*/
/*jff 2/26/98 maximum number of messages allowed in refresh list */
#define HU_MAXMESSAGES 16
/*
* 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;
const patchnum_t* f; // font
int sc; // start character
//const char *cr; //jff 2/16/52 output color range
// Proff - Made this an int again. Needed for OpenGL
int cm; //jff 2/16/52 output color range
// killough 1/23/98: Support multiple lines:
#define MAXLINES 25
int linelen;
char l[HU_MAXLINELENGTH*MAXLINES+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;
//jff 2/26/98 new widget to display last hud_msg_lines of messages
// Message refresh window widget
typedef struct
{
hu_textline_t l[HU_MAXMESSAGES]; // text lines to draw
int nl; // height in lines
int nr; // total height in rows
int cl; // current line number
int x,y,w,h; // window position and size
const patchnum_t *bg; // patches for background
// pointer to boolean stating whether to update window
boolean* on;
boolean laston; // last value of *->on.
} hu_mtext_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
//
//
// 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,
const patchnum_t *f,
int sc,
int cm //jff 2/16/98 add color range parameter
);
// returns success
boolean HUlib_addCharToTextLine(hu_textline_t *t, char ch);
// 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
//
// initialize an stext widget
void HUlib_initSText
( hu_stext_t* s,
int x,
int y,
int h,
const patchnum_t* font,
int startchar,
int cm, //jff 2/16/98 add color range parameter
boolean* on );
// add a text message to an stext widget
void HUlib_addMessageToSText(hu_stext_t* s, const char* prefix, const char* msg);
// draws stext
void HUlib_drawSText(hu_stext_t* s);
// erases all stext lines
void HUlib_eraseSText(hu_stext_t* s);
//jff 2/26/98 message refresh widget
// initialize refresh text widget
void HUlib_initMText(hu_mtext_t *m, int x, int y, int w, int h, const patchnum_t* font,
int startchar, int cm, const patchnum_t* bgfont, boolean *on);
//jff 2/26/98 message refresh widget
// add a text message to refresh text widget
void HUlib_addMessageToMText(hu_mtext_t* m, const char* prefix, const char* msg);
//jff 2/26/98 new routine to display a background on which
// the list of last hud_msg_lines are displayed
void HUlib_drawMBg
( int x,
int y,
int w,
int h,
const patchnum_t* bgp
);
//jff 2/26/98 message refresh widget
// draws mtext
void HUlib_drawMText(hu_mtext_t* m);
//jff 4/28/98 erases behind message list
void HUlib_eraseMText(hu_mtext_t* m);
// Input Text Line widget routines
void HUlib_initIText
( hu_itext_t* it,
int x,
int y,
const patchnum_t* font,
int startchar,
int cm, //jff 2/16/98 add color range parameter
boolean* on );
// 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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,90 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* 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 (0x7f) /*jff 2/16/98 '_' the last font characters */
/* Calculate # of glyphs in font. */
#define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1)
#define HU_BROADCAST 5
/*#define HU_MSGREFRESH KEYD_ENTER phares */
#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);
void HU_MoveHud(void); // jff 3/9/98 avoid glitch in HUD display
/* killough 5/2/98: moved from m_misc.c: */
/* jff 2/16/98 hud supported automap colors added */
extern int hudcolor_titl; /* color range of automap level title */
extern int hudcolor_xyco; /* color range of new coords on automap */
/* jff 2/16/98 hud text colors, controls added */
extern int hudcolor_mesg; /* color range of scrolling messages */
extern int hudcolor_chat; /* color range of chat lines */
/* jff 2/26/98 hud message list color and background enable */
extern int hudcolor_list; /* color of list of past messages */
extern int hud_list_bgon; /* solid window background for list of messages */
extern int hud_msg_lines; /* number of message lines in window up to 16 */
extern int hud_distributed; /* whether hud is all in lower left or distributed */
/* jff 2/23/98 hud is currently displayed */
extern int hud_displayed; /* hud is displayed */
/* jff 2/18/98 hud/status control */
extern int hud_active; /* hud mode 0=off, 1=small, 2=full */
extern int hud_nosecrets; /* status does not list secrets/items/kills */
#endif

View File

@@ -0,0 +1,47 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Joystick interface.
*
*-----------------------------------------------------------------------------*/
extern int joybfire;
extern int joybstrafe;
extern int joybuse;
extern int joybspeed;
extern int joyleft;
extern int joyright;
extern int joyup;
extern int joydown;
extern int usejoystick;
void I_InitJoystick(void);
void I_PollJoystick(void);

View File

@@ -0,0 +1,44 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* General system functions. Signal related stuff, exit function
* prototypes, and programmable Doom clock.
*
*-----------------------------------------------------------------------------
*/
#ifndef __I_MAIN__
#define __I_MAIN__
void I_Init(void);
void I_SafeExit(int rc);
extern int (*I_GetTime)(void);
#endif

View File

@@ -0,0 +1,74 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Low level network interface.
*-----------------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef USE_SDL_NET
#include "SDL_net.h"
#define UDP_SOCKET UDPsocket
#define UDP_PACKET UDPpacket
#define AF_INET
#define UDP_CHANNEL int
extern UDP_SOCKET udp_socket;
#else
#define UDP_CHANNEL struct sockaddr
#endif
#ifndef IPPORT_RESERVED
#define IPPORT_RESERVED 1024
#endif
void I_InitNetwork(void);
size_t I_GetPacket(packet_header_t* buffer, size_t buflen);
void I_SendPacket(packet_header_t* packet, size_t len);
void I_WaitForPacket(int ms);
#ifdef USE_SDL_NET
UDP_SOCKET I_Socket(Uint16 port);
int I_ConnectToServer(const char *serv);
UDP_CHANNEL I_RegisterPlayer(IPaddress *ipaddr);
void I_UnRegisterPlayer(UDP_CHANNEL channel);
extern IPaddress sentfrom_addr;
#endif
#ifdef AF_INET
void I_SendPacketTo(packet_header_t* packet, size_t len, UDP_CHANNEL *to);
void I_SetupSocket(int sock, int port, int family);
void I_PrintAddress(FILE* fp, UDP_CHANNEL *addr);
extern UDP_CHANNEL sentfrom;
extern int v4socket, v6socket;
#endif
extern size_t sentbytes, recvdbytes;

View File

@@ -0,0 +1,120 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* System interface, sound.
*
*-----------------------------------------------------------------------------*/
#ifndef __I_SOUND__
#define __I_SOUND__
#include "sounds.h"
#include "doomtype.h"
#define SNDSERV
#undef SNDINTR
#ifndef SNDSERV
#include "l_soundgen.h"
#endif
// Init at program start...
void I_InitSound(void);
// ... shut down and relase at program termination.
void I_ShutdownSound(void);
//
// SFX I/O
//
// Initialize channels?
void I_SetChannels(void);
// 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 channel, 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.
boolean I_SoundIsPlaying(int handle);
// Called by m_menu.c to let the quit sound play and quit right after it stops
boolean I_AnySoundStillPlaying(void);
// 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);
void I_UpdateMusic(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(const void *data, size_t len);
// cournia - tries to load a music file
int I_RegisterMusic( const char* filename, musicinfo_t *music );
// 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);
// Allegro card support jff 1/18/98
extern int snd_card;
extern int mus_card;
// CPhipps - put these in config file
extern int snd_samplerate;
#endif

View File

@@ -0,0 +1,77 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* System specific interface stuff.
*
*-----------------------------------------------------------------------------*/
#ifndef __I_SYSTEM__
#define __I_SYSTEM__
#ifdef __GNUG__
#pragma interface
#endif
extern int ms_to_next_tick;
boolean I_StartDisplay(void);
void I_EndDisplay(void);
int I_GetTime_RealTime(void); /* killough */
#ifndef PRBOOM_SERVER
fixed_t I_GetTimeFrac (void);
#endif
void I_GetTime_SaveMS(void);
unsigned long I_GetRandomTimeSeed(void); /* cphipps */
void I_uSleep(unsigned long usecs);
/* cphipps - I_GetVersionString
* Returns a version string in the given buffer
*/
const char* I_GetVersionString(char* buf, size_t sz);
/* cphipps - I_SigString
* Returns a string describing a signal number
*/
const char* I_SigString(char* buf, size_t sz, int signum);
const char *I_DoomExeDir(void); // killough 2/16/98: path to executable's dir
boolean HasTrailingSlash(const char* dn);
char* I_FindFile(const char* wfname, const char* ext);
/* cph 2001/11/18 - wrapper for read(2) which deals with partial reads */
void I_Read(int fd, void* buf, size_t sz);
/* cph 2001/11/18 - Move W_Filelength to i_system.c */
int I_Filelength(int handle);
void I_SetAffinityMask(void);
#endif

View File

@@ -0,0 +1,82 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* System specific interface stuff.
*
*-----------------------------------------------------------------------------*/
#ifndef __I_VIDEO__
#define __I_VIDEO__
#include "doomtype.h"
#include "v_video.h"
#ifdef __GNUG__
#pragma interface
#endif
void I_PreInitGraphics(void); /* CPhipps - do stuff immediately on start */
void I_CalculateRes(unsigned int width, unsigned int height); /* calculate resolution */
void I_SetRes(void); /* set resolution */
void I_InitGraphics (void);
void I_UpdateVideoMode(void);
void I_ShutdownGraphics(void);
/* Takes full 8 bit values. */
void I_SetPalette(int pal); /* CPhipps - pass down palette number */
void I_UpdateNoBlit (void);
void I_FinishUpdate (void);
int I_ScreenShot (const char *fname);
/* I_StartTic
* 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);
/* I_StartFrame
* 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);
extern int use_doublebuffer; /* proff 2001-7-4 - controls wether to use doublebuffering*/
extern int use_fullscreen; /* proff 21/05/2000 */
extern int desired_fullscreen; //e6y
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,382 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Provides a logical console output routine that allows what is
* output to console normally and when output is redirected to
* be controlled..
*
*-----------------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
#ifdef _MSC_VER
#include <io.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "doomtype.h"
#include "lprintf.h"
#include "i_main.h"
#include "m_argv.h"
int cons_error_mask = -1-LO_INFO; /* all but LO_INFO when redir'd */
int cons_output_mask = -1; /* all output enabled */
/* cphipps - enlarged message buffer and made non-static
* We still have to be careful here, this function can be called after exit
*/
#define MAX_MESSAGE_SIZE 2048
#ifdef _WIN32
// Variables for the console
HWND con_hWnd=0;
HFONT OemFont;
LONG OemWidth, OemHeight;
int ConWidth,ConHeight;
char szConName[] = "PrBoomConWinClass";
char Lines[(80+2)*25+1];
char *Last = NULL;
boolean console_inited=FALSE;
static boolean should_exit = 0;
static CALLBACK ConWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT paint;
HDC dc;
switch (iMsg) {
case WM_KEYDOWN:
if (wParam == VK_ESCAPE)
should_exit = 1;
break;
case WM_CLOSE:
return 1;
break;
case WM_PAINT:
if (dc = BeginPaint (con_hWnd, &paint))
{
if (Last)
{
char *row;
int line, last;
line = paint.rcPaint.top / OemHeight;
last = paint.rcPaint.bottom / OemHeight;
for (row = Lines + (line*(80+2)); line < last; line++)
{
if (row[1]>0)
TextOut (dc, 0, line * OemHeight, &row[2], row[1]);
row += 80 + 2;
}
}
EndPaint (con_hWnd, &paint);
}
return 0;
break;
default:
break;
}
return(DefWindowProc(hwnd,iMsg,wParam,lParam));
}
static void I_PrintStr (int xp, const char *cp, int count, BOOL scroll) {
RECT rect;
HDC conDC;
if ((!con_hWnd) || (!console_inited))
return;
if (count)
{
conDC=GetDC(con_hWnd);
TextOut (conDC, xp * OemWidth, ConHeight - OemHeight, cp, count);
ReleaseDC(con_hWnd,conDC);
}
if (scroll) {
rect.left = 0;
rect.top = 0;
rect.right = ConWidth;
rect.bottom = ConHeight;
ScrollWindowEx (con_hWnd, 0, -OemHeight, NULL, &rect, NULL, NULL, SW_ERASE|SW_INVALIDATE);
UpdateWindow (con_hWnd);
}
}
static int I_ConPrintString (const char *outline)
{
const char *cp, *newcp;
static int xp = 0;
int newxp;
BOOL scroll;
if (!console_inited)
return 0;
cp = outline;
while (*cp) {
for (newcp = cp, newxp = xp;
*newcp != '\n' && *newcp != '\0' && newxp < 80;
newcp++) {
if (*newcp == '\x08') {
newxp--;
break;
}
else if (*newcp == '\t') {
newxp = ((newxp + 8) / 8) * 8;
break;
}
else
newxp++;
}
if (*cp) {
const char *poop;
int x;
for (x = xp, poop = cp; poop < newcp; poop++, x++) {
Last[x+2] = ((*poop) < 32) ? 32 : (*poop);
}
if (*newcp == '\t')
for (x = xp; x < newxp; x++)
Last[x+2] = ' ';
if (Last[1] < xp + (newcp - cp))
Last[1] = xp + (newcp - cp);
if (*newcp == '\n' || xp == 80) {
if (*newcp != '\n') {
Last[0] = 1;
}
memmove (Lines, Lines + (80 + 2), (80 + 2) * (25 - 1));
Last[0] = 0;
Last[1] = 0;
newxp = 0;
scroll = TRUE;
} else {
scroll = FALSE;
}
I_PrintStr (xp, cp, newcp - cp, scroll);
xp = newxp;
if ((*newcp == '\n') || (*newcp == '\x08') || (*newcp == '\t'))
cp = newcp + 1;
else
cp = newcp;
}
}
return strlen (outline);
}
void I_ConTextAttr(unsigned char a)
{
int r,g,b,col;
HDC conDC;
if (!console_inited)
return;
conDC=GetDC(con_hWnd);
r=0; g=0; b=0;
if (a & FOREGROUND_INTENSITY) col=255;
else col=128;
if (a & FOREGROUND_RED) r=col;
if (a & FOREGROUND_GREEN) g=col;
if (a & FOREGROUND_BLUE) b=col;
SetTextColor(conDC, PALETTERGB(r,g,b));
r=0; g=0; b=0;
if (a & BACKGROUND_INTENSITY) col=255;
else col=128;
if (a & BACKGROUND_RED) r=col;
if (a & BACKGROUND_GREEN) g=col;
if (a & BACKGROUND_BLUE) b=col;
SetBkColor(conDC, PALETTERGB(r,g,b));
ReleaseDC(con_hWnd,conDC);
}
void I_UpdateConsole(void)
{
MSG msg;
UpdateWindow(con_hWnd);
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (should_exit)
exit(0);
}
static void Init_Console(void)
{
memset(Lines,0,25*(80+2)+1);
Last = Lines + (25 - 1) * (80 + 2);
console_inited=TRUE;
}
int Init_ConsoleWin(void)
{
HDC conDC;
WNDCLASS wndclass;
TEXTMETRIC metrics;
RECT cRect;
int width,height;
int scr_width,scr_height;
HINSTANCE hInstance;
char titlebuffer[2048];
if (con_hWnd)
return TRUE;
hInstance = GetModuleHandle(NULL);
Init_Console();
/* Register the frame class */
wndclass.style = CS_OWNDC;
wndclass.lpfnWndProc = (WNDPROC)ConWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon (hInstance, IDI_WINLOGO);
wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject (BLACK_BRUSH);
wndclass.lpszMenuName = szConName;
wndclass.lpszClassName = szConName;
if (!RegisterClass(&wndclass))
return FALSE;
width=100;
height=100;
strcpy(titlebuffer,PACKAGE);
strcat(titlebuffer," ");
strcat(titlebuffer,VERSION);
strcat(titlebuffer," console");
con_hWnd = CreateWindow(szConName, titlebuffer,
WS_CAPTION | WS_POPUP,
0, 0, width, height,
NULL, NULL, hInstance, NULL);
conDC=GetDC(con_hWnd);
OemFont = GetStockObject(OEM_FIXED_FONT);
SelectObject(conDC, OemFont);
GetTextMetrics(conDC, &metrics);
OemWidth = metrics.tmAveCharWidth;
OemHeight = metrics.tmHeight;
GetClientRect(con_hWnd, &cRect);
width += (OemWidth * 80) - cRect.right;
height += (OemHeight * 25) - cRect.bottom;
// proff 11/09/98: Added code for centering console
scr_width = GetSystemMetrics(SM_CXFULLSCREEN);
scr_height = GetSystemMetrics(SM_CYFULLSCREEN);
MoveWindow(con_hWnd, (scr_width-width)/2, (scr_height-height)/2, width, height, TRUE);
GetClientRect(con_hWnd, &cRect);
ConWidth = cRect.right;
ConHeight = cRect.bottom;
SetTextColor(conDC, RGB(192,192,192));
SetBkColor(conDC, RGB(0,0,0));
SetBkMode(conDC, OPAQUE);
ReleaseDC(con_hWnd,conDC);
ShowWindow(con_hWnd, SW_SHOW);
UpdateWindow(con_hWnd);
return TRUE;
}
void Done_ConsoleWin(void)
{
if (con_hWnd)
DestroyWindow(con_hWnd);
UnregisterClass(szConName,GetModuleHandle(NULL));
con_hWnd=0;
}
#endif
int lprintf(OutputLevels pri, const char *s, ...)
{
int r=0;
char msg[MAX_MESSAGE_SIZE];
int lvl=pri;
va_list v;
va_start(v,s);
#ifdef HAVE_VSNPRINTF
vsnprintf(msg,sizeof(msg),s,v); /* print message in buffer */
#else
vsprintf(msg,s,v);
#endif
va_end(v);
if (lvl&cons_output_mask) /* mask output as specified */
{
r=fprintf(stdout,"%s",msg);
#ifdef _WIN32
I_ConPrintString(msg);
#endif
}
if (!isatty(1) && lvl&cons_error_mask) /* if stdout redirected */
r=fprintf(stderr,"%s",msg); /* select output at console */
return r;
}
/*
* I_Error
*
* cphipps - moved out of i_* headers, to minimise source files that depend on
* the low-level headers. All this does is print the error, then call the
* low-level safe exit function.
* killough 3/20/98: add const
*/
void I_Error(const char *error, ...)
{
char errmsg[MAX_MESSAGE_SIZE];
va_list argptr;
va_start(argptr,error);
#ifdef HAVE_VSNPRINTF
vsnprintf(errmsg,sizeof(errmsg),error,argptr);
#else
vsprintf(errmsg,error,argptr);
#endif
va_end(argptr);
lprintf(LO_ERROR, "%s\n", errmsg);
#ifdef _MSC_VER
if (!M_CheckParm ("-nodraw")) {
//Init_ConsoleWin();
MessageBox(con_hWnd,errmsg,"PrBoom",MB_OK | MB_TASKMODAL | MB_TOPMOST);
}
#endif
I_SafeExit(-1);
}

View File

@@ -0,0 +1,68 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Declarations etc. for logical console output
*
*-----------------------------------------------------------------------------*/
#ifndef __LPRINTF__
#define __LPRINTF__
typedef enum /* Logical output levels */
{
LO_INFO=1, /* One of these is used in each physical output */
LO_CONFIRM=2, /* call. Which are output, or echoed to console */
LO_WARN=4, /* if output redirected is determined by the */
LO_ERROR=8, /* global masks: cons_output_mask,cons_error_mask. */
LO_FATAL=16,
LO_DEBUG=32,
LO_ALWAYS=64,
} OutputLevels;
#ifndef __GNUC__
#define __attribute__(x)
#endif
extern int lprintf(OutputLevels pri, const char *fmt, ...) __attribute__((format(printf,2,3)));
extern int cons_output_mask;
extern int cons_error_mask;
/* killough 3/20/98: add const
* killough 4/25/98: add gcc attributes
* cphipps 01/11- moved from i_system.h */
void I_Error(const char *error, ...) __attribute__((format(printf,1,2)));
#ifdef _WIN32
void I_ConTextAttr(unsigned char a);
void I_UpdateConsole(void);
int Init_ConsoleWin(void);
void Done_ConsoleWin(void);
#endif
#endif

View File

@@ -0,0 +1,58 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Some argument handling.
*
*-----------------------------------------------------------------------------*/
#include <string.h>
// CPhipps - include the correct header
#include "doomtype.h"
#include "m_argv.h"
int myargc;
const char * const * myargv; // CPhipps - not sure if ANSI C allows you to
// modify contents of argv, but I can't imagine it does.
//
// M_CheckParm
// Checks for the given parameter
// in the program's command line arguments.
// Returns the argument number (1 to argc-1)
// or 0 if not present
//
int M_CheckParm(const char *check)
{
signed int i = myargc;
while (--i>0)
if (!strcasecmp(check, myargv[i]))
return i;
return 0;
}

View File

@@ -0,0 +1,47 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Argument handling.
*
*-----------------------------------------------------------------------------*/
#ifndef __M_ARGV__
#define __M_ARGV__
/*
* MISC
*/
extern int myargc;
extern const char * const * myargv; /* CPhipps - const * const * */
/* Returns the position of the given parameter in the arg list (0 if not found). */
int M_CheckParm(const char *check);
#endif

View File

@@ -0,0 +1,58 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Main loop menu stuff.
* Random number LUT.
* Default Config File.
* PCX Screenshots.
*
*-----------------------------------------------------------------------------*/
#ifdef __GNUG__
#pragma implementation "m_bbox.h"
#endif
#include "m_bbox.h"
void M_ClearBox (fixed_t *box)
{
box[BOXTOP] = box[BOXRIGHT] = INT_MIN;
box[BOXBOTTOM] = box[BOXLEFT] = INT_MAX;
}
void M_AddToBox(fixed_t* box,fixed_t x,fixed_t y)
{
if (x<box[BOXLEFT])
box[BOXLEFT] = x;
else if (x>box[BOXRIGHT])
box[BOXRIGHT] = x;
if (y<box[BOXBOTTOM])
box[BOXBOTTOM] = y;
else if (y>box[BOXTOP])
box[BOXTOP] = y;
}

View File

@@ -0,0 +1,56 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Simple bounding box datatype and functions.
*
*-----------------------------------------------------------------------------*/
#ifndef __M_BBOX__
#define __M_BBOX__
#include <limits.h>
#include "m_fixed.h"
/* Bounding box coordinate storage. */
enum
{
BOXTOP,
BOXBOTTOM,
BOXLEFT,
BOXRIGHT
}; /* bbox coordinates */
/* Bounding box functions. */
void M_ClearBox(fixed_t* box);
void M_AddToBox(fixed_t* box,fixed_t x,fixed_t y);
#endif

View File

@@ -0,0 +1,744 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2002 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Cheat sequence checking.
*
*-----------------------------------------------------------------------------*/
#include "doomstat.h"
#include "g_game.h"
#include "r_data.h"
#include "p_inter.h"
#include "p_tick.h"
#include "m_cheat.h"
#include "m_argv.h"
#include "s_sound.h"
#include "sounds.h"
#include "dstrings.h"
#include "r_main.h"
#include "p_map.h"
#include "d_deh.h" // Ty 03/27/98 - externalized strings
/* cph 2006/07/23 - needs direct access to thinkercap */
#include "p_tick.h"
#define plyr (players+consoleplayer) /* the console player */
//-----------------------------------------------------------------------------
//
// CHEAT SEQUENCE PACKAGE
//
//-----------------------------------------------------------------------------
static void cheat_mus();
static void cheat_choppers();
static void cheat_god();
static void cheat_fa();
static void cheat_k();
static void cheat_kfa();
static void cheat_noclip();
static void cheat_pw();
static void cheat_behold();
static void cheat_clev();
static void cheat_mypos();
static void cheat_rate();
static void cheat_comp();
static void cheat_friction();
static void cheat_pushers();
static void cheat_tnttran();
static void cheat_massacre();
static void cheat_ddt();
static void cheat_hom();
static void cheat_fast();
static void cheat_tntkey();
static void cheat_tntkeyx();
static void cheat_tntkeyxx();
static void cheat_tntweap();
static void cheat_tntweapx();
static void cheat_tntammo();
static void cheat_tntammox();
static void cheat_smart();
static void cheat_pitch();
static void cheat_megaarmour();
static void cheat_health();
//-----------------------------------------------------------------------------
//
// List of cheat codes, functions, and special argument indicators.
//
// The first argument is the cheat code.
//
// The second argument is its DEH name, or NULL if it's not supported by -deh.
//
// The third argument is a combination of the bitmasks:
// {always, not_dm, not_coop, not_net, not_menu, not_demo, not_deh},
// which excludes the cheat during certain modes of play.
//
// The fourth argument is the handler function.
//
// The fifth argument is passed to the handler function if it's non-negative;
// if negative, then its negative indicates the number of extra characters
// expected after the cheat code, which are passed to the handler function
// via a pointer to a buffer (after folding any letters to lowercase).
//
//-----------------------------------------------------------------------------
struct cheat_s cheat[] = {
{"idmus", "Change music", always,
cheat_mus, -2},
{"idchoppers", "Chainsaw", not_net | not_demo,
cheat_choppers },
{"iddqd", "God mode", not_net | not_demo,
cheat_god },
#if 0
{"idk", NULL, not_net | not_demo | not_deh,
cheat_k }, // The most controversial cheat code in Doom history!!!
#endif
{"idkfa", "Ammo & Keys", not_net | not_demo,
cheat_kfa },
{"idfa", "Ammo", not_net | not_demo,
cheat_fa },
{"idspispopd", "No Clipping 1", not_net | not_demo,
cheat_noclip },
{"idclip", "No Clipping 2", not_net | not_demo,
cheat_noclip },
{"idbeholdh", "Invincibility", not_net | not_demo,
cheat_health },
{"idbeholdm", "Invincibility", not_net | not_demo,
cheat_megaarmour },
{"idbeholdv", "Invincibility", not_net | not_demo,
cheat_pw, pw_invulnerability },
{"idbeholds", "Berserk", not_net | not_demo,
cheat_pw, pw_strength },
{"idbeholdi", "Invisibility", not_net | not_demo,
cheat_pw, pw_invisibility },
{"idbeholdr", "Radiation Suit", not_net | not_demo,
cheat_pw, pw_ironfeet },
{"idbeholda", "Auto-map", not_dm,
cheat_pw, pw_allmap },
{"idbeholdl", "Lite-Amp Goggles", not_dm,
cheat_pw, pw_infrared },
{"idbehold", "BEHOLD menu", not_dm,
cheat_behold },
{"idclev", "Level Warp", not_net | not_demo | not_menu,
cheat_clev, -2},
{"idmypos", "Player Position", not_dm,
cheat_mypos },
{"idrate", "Frame rate", 0,
cheat_rate },
{"tntcomp", NULL, not_net | not_demo,
cheat_comp }, // phares
{"tntem", NULL, not_net | not_demo,
cheat_massacre }, // jff 2/01/98 kill all monsters
{"iddt", "Map cheat", not_dm,
cheat_ddt }, // killough 2/07/98: moved from am_map.c
{"tnthom", NULL, always,
cheat_hom }, // killough 2/07/98: HOM autodetector
{"tntkey", NULL, not_net | not_demo,
cheat_tntkey }, // killough 2/16/98: generalized key cheats
{"tntkeyr", NULL, not_net | not_demo,
cheat_tntkeyx },
{"tntkeyy", NULL, not_net | not_demo,
cheat_tntkeyx },
{"tntkeyb", NULL, not_net | not_demo,
cheat_tntkeyx },
{"tntkeyrc", NULL, not_net | not_demo,
cheat_tntkeyxx, it_redcard },
{"tntkeyyc", NULL, not_net | not_demo,
cheat_tntkeyxx, it_yellowcard },
{"tntkeybc", NULL, not_net | not_demo,
cheat_tntkeyxx, it_bluecard },
{"tntkeyrs", NULL, not_net | not_demo,
cheat_tntkeyxx, it_redskull },
{"tntkeyys", NULL, not_net | not_demo,
cheat_tntkeyxx, it_yellowskull},
{"tntkeybs", NULL, not_net | not_demo,
cheat_tntkeyxx, it_blueskull }, // killough 2/16/98: end generalized keys
{"tntka", NULL, not_net | not_demo,
cheat_k }, // Ty 04/11/98 - Added TNTKA
{"tntweap", NULL, not_net | not_demo,
cheat_tntweap }, // killough 2/16/98: generalized weapon cheats
{"tntweap", NULL, not_net | not_demo,
cheat_tntweapx, -1},
{"tntammo", NULL, not_net | not_demo,
cheat_tntammo },
{"tntammo", NULL, not_net | not_demo,
cheat_tntammox, -1}, // killough 2/16/98: end generalized weapons
{"tnttran", NULL, always,
cheat_tnttran }, // invoke translucency // phares
{"tntsmart", NULL, not_net | not_demo,
cheat_smart}, // killough 2/21/98: smart monster toggle
{"tntpitch", NULL, always,
cheat_pitch}, // killough 2/21/98: pitched sound toggle
// killough 2/21/98: reduce RSI injury by adding simpler alias sequences:
{"tntran", NULL, always,
cheat_tnttran }, // killough 2/21/98: same as tnttran
{"tntamo", NULL, not_net | not_demo,
cheat_tntammo }, // killough 2/21/98: same as tntammo
{"tntamo", NULL, not_net | not_demo,
cheat_tntammox, -1}, // killough 2/21/98: same as tntammo
{"tntfast", NULL, not_net | not_demo,
cheat_fast }, // killough 3/6/98: -fast toggle
{"tntice", NULL, not_net | not_demo,
cheat_friction }, // phares 3/10/98: toggle variable friction effects
{"tntpush", NULL, not_net | not_demo,
cheat_pushers }, // phares 3/10/98: toggle pushers
{NULL} // end-of-list marker
};
//-----------------------------------------------------------------------------
static void cheat_mus(buf)
char buf[3];
{
int musnum;
//jff 3/20/98 note: this cheat allowed in netgame/demorecord
//jff 3/17/98 avoid musnum being negative and crashing
if (!isdigit(buf[0]) || !isdigit(buf[1]))
return;
plyr->message = s_STSTR_MUS; // Ty 03/27/98 - externalized
if (gamemode == commercial)
{
musnum = mus_runnin + (buf[0]-'0')*10 + buf[1]-'0' - 1;
//jff 4/11/98 prevent IDMUS00 in DOOMII and IDMUS36 or greater
if (musnum < mus_runnin || ((buf[0]-'0')*10 + buf[1]-'0') > 35)
plyr->message = s_STSTR_NOMUS; // Ty 03/27/98 - externalized
else
{
S_ChangeMusic(musnum, 1);
idmusnum = musnum; //jff 3/17/98 remember idmus number for restore
}
}
else
{
musnum = mus_e1m1 + (buf[0]-'1')*9 + (buf[1]-'1');
//jff 4/11/98 prevent IDMUS0x IDMUSx0 in DOOMI and greater than introa
if (buf[0] < '1' || buf[1] < '1' || ((buf[0]-'1')*9 + buf[1]-'1') > 31)
plyr->message = s_STSTR_NOMUS; // Ty 03/27/98 - externalized
else
{
S_ChangeMusic(musnum, 1);
idmusnum = musnum; //jff 3/17/98 remember idmus number for restore
}
}
}
// 'choppers' invulnerability & chainsaw
static void cheat_choppers()
{
plyr->weaponowned[wp_chainsaw] = true;
plyr->powers[pw_invulnerability] = true;
plyr->message = s_STSTR_CHOPPERS; // Ty 03/27/98 - externalized
}
static void cheat_god()
{ // 'dqd' cheat for toggleable god mode
plyr->cheats ^= CF_GODMODE;
if (plyr->cheats & CF_GODMODE)
{
if (plyr->mo)
plyr->mo->health = god_health; // Ty 03/09/98 - deh
plyr->health = god_health;
plyr->message = s_STSTR_DQDON; // Ty 03/27/98 - externalized
}
else
plyr->message = s_STSTR_DQDOFF; // Ty 03/27/98 - externalized
}
// CPhipps - new health and armour cheat codes
static void cheat_health()
{
if (!(plyr->cheats & CF_GODMODE)) {
if (plyr->mo)
plyr->mo->health = mega_health;
plyr->health = mega_health;
plyr->message = s_STSTR_BEHOLDX; // Ty 03/27/98 - externalized
}
}
static void cheat_megaarmour()
{
plyr->armorpoints = idfa_armor; // Ty 03/09/98 - deh
plyr->armortype = idfa_armor_class; // Ty 03/09/98 - deh
plyr->message = s_STSTR_BEHOLDX; // Ty 03/27/98 - externalized
}
static void cheat_fa()
{
int i;
if (!plyr->backpack)
{
for (i=0 ; i<NUMAMMO ; i++)
plyr->maxammo[i] *= 2;
plyr->backpack = true;
}
plyr->armorpoints = idfa_armor; // Ty 03/09/98 - deh
plyr->armortype = idfa_armor_class; // Ty 03/09/98 - deh
// You can't own weapons that aren't in the game // phares 02/27/98
for (i=0;i<NUMWEAPONS;i++)
if (!(((i == wp_plasma || i == wp_bfg) && gamemode == shareware) ||
(i == wp_supershotgun && gamemode != commercial)))
plyr->weaponowned[i] = true;
for (i=0;i<NUMAMMO;i++)
if (i!=am_cell || gamemode!=shareware)
plyr->ammo[i] = plyr->maxammo[i];
plyr->message = s_STSTR_FAADDED;
}
static void cheat_k()
{
int i;
for (i=0;i<NUMCARDS;i++)
if (!plyr->cards[i]) // only print message if at least one key added
{ // however, caller may overwrite message anyway
plyr->cards[i] = true;
plyr->message = "Keys Added";
}
}
static void cheat_kfa()
{
cheat_k();
cheat_fa();
plyr->message = STSTR_KFAADDED;
}
static void cheat_noclip()
{
// Simplified, accepting both "noclip" and "idspispopd".
// no clipping mode cheat
plyr->message = (plyr->cheats ^= CF_NOCLIP) & CF_NOCLIP ?
s_STSTR_NCON : s_STSTR_NCOFF; // Ty 03/27/98 - externalized
}
// 'behold?' power-up cheats (modified for infinite duration -- killough)
static void cheat_pw(int pw)
{
if (plyr->powers[pw])
plyr->powers[pw] = pw!=pw_strength && pw!=pw_allmap; // killough
else
{
P_GivePower(plyr, pw);
if (pw != pw_strength)
plyr->powers[pw] = -1; // infinite duration -- killough
}
plyr->message = s_STSTR_BEHOLDX; // Ty 03/27/98 - externalized
}
// 'behold' power-up menu
static void cheat_behold()
{
plyr->message = s_STSTR_BEHOLD; // Ty 03/27/98 - externalized
}
// 'clev' change-level cheat
static void cheat_clev(char buf[3])
{
int epsd, map;
if (gamemode == commercial)
{
epsd = 1; //jff was 0, but espd is 1-based
map = (buf[0] - '0')*10 + buf[1] - '0';
}
else
{
epsd = buf[0] - '0';
map = buf[1] - '0';
}
// Catch invalid maps.
if (epsd < 1 || map < 1 || // Ohmygod - this is not going to work.
(gamemode == retail && (epsd > 4 || map > 9 )) ||
(gamemode == registered && (epsd > 3 || map > 9 )) ||
(gamemode == shareware && (epsd > 1 || map > 9 )) ||
(gamemode == commercial && (epsd > 1 || map > 32 )) ) //jff no 33 and 34
return; //8/14/98 allowed
// So be it.
idmusnum = -1; //jff 3/17/98 revert to normal level music on IDCLEV
plyr->message = s_STSTR_CLEV; // Ty 03/27/98 - externalized
G_DeferedInitNew(gameskill, epsd, map);
}
// 'mypos' for player position
// killough 2/7/98: simplified using dprintf and made output more user-friendly
static void cheat_mypos()
{
doom_printf("Position (%d,%d,%d)\tAngle %-.0f",
players[consoleplayer].mo->x >> FRACBITS,
players[consoleplayer].mo->y >> FRACBITS,
players[consoleplayer].mo->z >> FRACBITS,
players[consoleplayer].mo->angle * (90.0/ANG90));
}
// cph - cheat to toggle frame rate/rendering stats display
static void cheat_rate()
{
rendering_stats ^= 1;
}
// compatibility cheat
static void cheat_comp()
{
// CPhipps - modified for new compatibility system
compatibility_level++; compatibility_level %= MAX_COMPATIBILITY_LEVEL;
// must call G_Compatibility after changing compatibility_level
// (fixes sf bug number 1558738)
G_Compatibility();
doom_printf("New compatibility level:\n%s",
comp_lev_str[compatibility_level]);
}
// variable friction cheat
static void cheat_friction()
{
plyr->message = // Ty 03/27/98 - *not* externalized
(variable_friction = !variable_friction) ? "Variable Friction enabled" :
"Variable Friction disabled";
}
// Pusher cheat
// phares 3/10/98
static void cheat_pushers()
{
plyr->message = // Ty 03/27/98 - *not* externalized
(allow_pushers = !allow_pushers) ? "Pushers enabled" : "Pushers disabled";
}
// translucency cheat
static void cheat_tnttran()
{
plyr->message = // Ty 03/27/98 - *not* externalized
(general_translucency = !general_translucency) ? "Translucency enabled" :
"Translucency disabled";
// killough 3/1/98, 4/11/98: cache translucency map on a demand basis
if (general_translucency && !main_tranmap)
R_InitTranMap(0);
}
static void cheat_massacre() // jff 2/01/98 kill all monsters
{
// jff 02/01/98 'em' cheat - kill all monsters
// partially taken from Chi's .46 port
//
// killough 2/7/98: cleaned up code and changed to use dprintf;
// fixed lost soul bug (LSs left behind when PEs are killed)
int killcount=0;
thinker_t *currentthinker = NULL;
extern void A_PainDie(mobj_t *);
// killough 7/20/98: kill friendly monsters only if no others to kill
uint_64_t mask = MF_FRIEND;
P_MapStart();
do
while ((currentthinker = P_NextThinker(currentthinker,th_all)) != NULL)
if (currentthinker->function == P_MobjThinker &&
!(((mobj_t *) currentthinker)->flags & mask) && // killough 7/20/98
(((mobj_t *) currentthinker)->flags & MF_COUNTKILL ||
((mobj_t *) currentthinker)->type == MT_SKULL))
{ // killough 3/6/98: kill even if PE is dead
if (((mobj_t *) currentthinker)->health > 0)
{
killcount++;
P_DamageMobj((mobj_t *)currentthinker, NULL, NULL, 10000);
}
if (((mobj_t *) currentthinker)->type == MT_PAIN)
{
A_PainDie((mobj_t *) currentthinker); // killough 2/8/98
P_SetMobjState ((mobj_t *) currentthinker, S_PAIN_DIE6);
}
}
while (!killcount && mask ? mask=0, 1 : 0); // killough 7/20/98
P_MapEnd();
// killough 3/22/98: make more intelligent about plural
// Ty 03/27/98 - string(s) *not* externalized
doom_printf("%d Monster%s Killed", killcount, killcount==1 ? "" : "s");
}
// killough 2/7/98: move iddt cheat from am_map.c to here
// killough 3/26/98: emulate Doom better
static void cheat_ddt()
{
extern int ddt_cheating;
if (automapmode & am_active)
ddt_cheating = (ddt_cheating+1) % 3;
}
// killough 2/7/98: HOM autodetection
static void cheat_hom()
{
extern int autodetect_hom; // Ty 03/27/98 - *not* externalized
plyr->message = (autodetect_hom = !autodetect_hom) ? "HOM Detection On" :
"HOM Detection Off";
}
// killough 3/6/98: -fast parameter toggle
static void cheat_fast()
{
plyr->message = (fastparm = !fastparm) ? "Fast Monsters On" :
"Fast Monsters Off"; // Ty 03/27/98 - *not* externalized
G_SetFastParms(fastparm); // killough 4/10/98: set -fast parameter correctly
}
// killough 2/16/98: keycard/skullkey cheat functions
static void cheat_tntkey()
{
plyr->message = "Red, Yellow, Blue"; // Ty 03/27/98 - *not* externalized
}
static void cheat_tntkeyx()
{
plyr->message = "Card, Skull"; // Ty 03/27/98 - *not* externalized
}
static void cheat_tntkeyxx(int key)
{
plyr->message = (plyr->cards[key] = !plyr->cards[key]) ?
"Key Added" : "Key Removed"; // Ty 03/27/98 - *not* externalized
}
// killough 2/16/98: generalized weapon cheats
static void cheat_tntweap()
{ // Ty 03/27/98 - *not* externalized
plyr->message = gamemode==commercial ? // killough 2/28/98
"Weapon number 1-9" : "Weapon number 1-8";
}
static void cheat_tntweapx(buf)
char buf[3];
{
int w = *buf - '1';
if ((w==wp_supershotgun && gamemode!=commercial) || // killough 2/28/98
((w==wp_bfg || w==wp_plasma) && gamemode==shareware))
return;
if (w==wp_fist) // make '1' apply beserker strength toggle
cheat_pw(pw_strength);
else
if (w >= 0 && w < NUMWEAPONS) {
if ((plyr->weaponowned[w] = !plyr->weaponowned[w]))
plyr->message = "Weapon Added"; // Ty 03/27/98 - *not* externalized
else
{
plyr->message = "Weapon Removed"; // Ty 03/27/98 - *not* externalized
if (w==plyr->readyweapon) // maybe switch if weapon removed
plyr->pendingweapon = P_SwitchWeapon(plyr);
}
}
}
// killough 2/16/98: generalized ammo cheats
static void cheat_tntammo()
{
plyr->message = "Ammo 1-4, Backpack"; // Ty 03/27/98 - *not* externalized
}
static void cheat_tntammox(buf)
char buf[1];
{
int a = *buf - '1';
if (*buf == 'b') // Ty 03/27/98 - strings *not* externalized
if ((plyr->backpack = !plyr->backpack))
for (plyr->message = "Backpack Added", a=0 ; a<NUMAMMO ; a++)
plyr->maxammo[a] <<= 1;
else
for (plyr->message = "Backpack Removed", a=0 ; a<NUMAMMO ; a++)
{
if (plyr->ammo[a] > (plyr->maxammo[a] >>= 1))
plyr->ammo[a] = plyr->maxammo[a];
}
else
if (a>=0 && a<NUMAMMO) // Ty 03/27/98 - *not* externalized
{ // killough 5/5/98: switch plasma and rockets for now -- KLUDGE
a = a==am_cell ? am_misl : a==am_misl ? am_cell : a; // HACK
plyr->message = (plyr->ammo[a] = !plyr->ammo[a]) ?
plyr->ammo[a] = plyr->maxammo[a], "Ammo Added" : "Ammo Removed";
}
}
static void cheat_smart()
{
plyr->message = (monsters_remember = !monsters_remember) ?
"Smart Monsters Enabled" : "Smart Monsters Disabled";
}
static void cheat_pitch()
{
plyr->message=(pitched_sounds = !pitched_sounds) ? "Pitch Effects Enabled" :
"Pitch Effects Disabled";
}
//-----------------------------------------------------------------------------
// 2/7/98: Cheat detection rewritten by Lee Killough, to avoid
// scrambling and to use a more general table-driven approach.
//-----------------------------------------------------------------------------
#define CHEAT_ARGS_MAX 8 /* Maximum number of args at end of cheats */
boolean M_FindCheats(int key)
{
static uint_64_t sr;
static char argbuf[CHEAT_ARGS_MAX+1], *arg;
static int init, argsleft, cht;
int i, ret, matchedbefore;
// If we are expecting arguments to a cheat
// (e.g. idclev), put them in the arg buffer
if (argsleft)
{
*arg++ = tolower(key); // store key in arg buffer
if (!--argsleft) // if last key in arg list,
cheat[cht].func(argbuf); // process the arg buffer
return 1; // affirmative response
}
key = tolower(key) - 'a';
if (key < 0 || key >= 32) // ignore most non-alpha cheat letters
{
sr = 0; // clear shift register
return 0;
}
if (!init) // initialize aux entries of table
{
init = 1;
for (i=0;cheat[i].cheat;i++)
{
uint_64_t c=0, m=0;
const char *p;
for (p=cheat[i].cheat; *p; p++)
{
unsigned key = tolower(*p)-'a'; // convert to 0-31
if (key >= 32) // ignore most non-alpha cheat letters
continue;
c = (c<<5) + key; // shift key into code
m = (m<<5) + 31; // shift 1's into mask
}
cheat[i].code = c; // code for this cheat key
cheat[i].mask = m; // mask for this cheat key
}
}
sr = (sr<<5) + key; // shift this key into shift register
for (matchedbefore = ret = i = 0; cheat[i].cheat; i++)
if ((sr & cheat[i].mask) == cheat[i].code && // if match found
!(cheat[i].when & not_dm && deathmatch) && // and if cheat allowed
!(cheat[i].when & not_coop && netgame && !deathmatch) &&
!(cheat[i].when & not_demo && (demorecording || demoplayback)) &&
!(cheat[i].when & not_menu && menuactive) &&
!(cheat[i].when & not_deh && M_CheckParm("-deh"))) {
if (cheat[i].arg < 0) // if additional args are required
{
cht = i; // remember this cheat code
arg = argbuf; // point to start of arg buffer
argsleft = -cheat[i].arg; // number of args expected
ret = 1; // responder has eaten key
}
else
if (!matchedbefore) // allow only one cheat at a time
{
matchedbefore = ret = 1; // responder has eaten key
cheat[i].func(cheat[i].arg); // call cheat handler
}
}
return ret;
}

View File

@@ -0,0 +1,58 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Cheat code checking.
*
*-----------------------------------------------------------------------------*/
#ifndef __M_CHEAT__
#define __M_CHEAT__
/* killough 4/16/98: Cheat table structure */
extern struct cheat_s {
const char * cheat;
const char *const deh_cheat;
enum {
always = 0,
not_dm = 1,
not_coop = 2,
not_demo = 4,
not_menu = 8,
not_deh = 16,
not_net = not_dm | not_coop
} const when;
void (*const func)();
const int arg;
uint_64_t code, mask;
} cheat[];
boolean M_FindCheats(int key);
#endif

View File

@@ -0,0 +1,223 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Fixed point arithemtics, implementation.
*
*-----------------------------------------------------------------------------*/
#ifndef __M_FIXED__
#define __M_FIXED__
#include "config.h"
#include "doomtype.h"
/*
* Fixed point, 32bit as 16.16.
*/
#define FRACBITS 16
#define FRACUNIT (1<<FRACBITS)
typedef int fixed_t;
/*
* Absolute Value
*
* killough 5/10/98: In djgpp, use inlined assembly for performance
* killough 9/05/98: better code seems to be gotten from using inlined C
*/
#ifdef _MSC_VER
# ifdef I386_ASM
#pragma warning( disable : 4035 )
__inline static int D_abs(int x)
{
__asm
{
mov eax,x
cdq
xor eax,edx
sub eax,edx
}
}
# else /* I386_ASM */
inline static const int D_abs(x)
{
fixed_t _t = (x),_s;
_s = _t >> (8*sizeof _t-1);
return (_t^_s)-_s;
}
# endif /* I386_ASM */
#else /* _MSC_VER */
#define D_abs(x) ({fixed_t _t = (x), _s = _t >> (8*sizeof _t-1); (_t^_s)-_s;})
#endif /* _MSC_VER */
/*
* Fixed Point Multiplication
*/
#ifdef I386_ASM
# ifdef _MSC_VER
#pragma warning( disable : 4035 )
__inline static fixed_t FixedMul(fixed_t a, fixed_t b)
{
// return (fixed_t)((longlong) a*b >> FRACBITS);
__asm
{
mov eax,a
imul b
shrd eax,edx,16
}
}
#pragma warning( default : 4035 )
# else /* _MSC_VER */
/* killough 5/10/98: In djgpp, use inlined assembly for performance
* CPhipps - made __inline__ to inline, as specified in the gcc docs
* Also made const. Also __asm__ to asm, as in docs.
* Replaced inline asm with Julian's version for Eternity dated 6/7/2001
*/
inline
static CONSTFUNC fixed_t FixedMul(fixed_t a, fixed_t b)
{
fixed_t result;
asm (
" imull %2 ;"
" shrdl $16,%%edx,%0 ;"
: "=a" (result) /* eax is always the result */
: "0" (a), /* eax is also first operand */
"rm" (b) /* second operand can be reg or mem */
: "%edx", "%cc" /* edx and condition codes clobbered */
);
return result;
}
# endif /* _MSC_VER */
#else /* I386_ASM */
/* CPhipps - made __inline__ to inline, as specified in the gcc docs
* Also made const */
inline static CONSTFUNC fixed_t FixedMul(fixed_t a, fixed_t b)
{
return (fixed_t)((int_64_t) a*b >> FRACBITS);
}
#endif /* I386_ASM */
/*
* Fixed Point Division
*/
#ifdef I386_ASM
# ifdef _MSC_VER
#pragma warning( disable : 4035 )
__inline static fixed_t FixedDiv(fixed_t a, fixed_t b)
{
// e6y
// zg is a master of engineer science.
//
// Fixed crash with FixedDiv(-2147483648,x)
// Exception Number : EXCEPTION_INT_OVERFLOW(C0000095)
//
// Some other ports (Eternity, Chocolate) return wrong value instead of MAXINT.
// For example FixedDiv(-2147483648,-30576) should return INT_MAX instead of 307907126
// 307907126 is truncated correct int64 value: 4602874423 - 2^32 = 307907126
if ((unsigned)D_abs(a) >> 14 >= (unsigned)D_abs(b))
return (a^b)<0 ? INT_MIN : INT_MAX;
__asm
{
mov eax,a
mov ebx,b
mov edx,eax
shl eax,16 // proff 11/06/98: Changed from sal to shl, I think
// this is better
sar edx,16
idiv ebx // This is needed, because when I used 'idiv b' the
// compiler produced wrong code in a different place
}
}
#pragma warning( default : 4035 )
# else /* _MSC_VER */
/* killough 5/10/98: In djgpp, use inlined assembly for performance
* killough 9/5/98: optimized to reduce the number of branches
* CPhipps - made __inline__ to inline, as specified in the gcc docs
* Also made const, also __asm__ to asm as in docs.
* Replaced inline asm with Julian's version for Eternity dated 6/7/2001
*/
inline
static CONSTFUNC fixed_t FixedDiv(fixed_t a, fixed_t b)
{
//e6y: zg is a master of engineer science
if ((unsigned)D_abs(a) >> 14 < (unsigned)D_abs(b))
{
fixed_t result;
asm (
" idivl %3 ;"
: "=a" (result)
: "0" (a<<16),
"d" (a>>16),
"rm" (b)
: "%cc"
);
return result;
}
return ((a^b)>>31) ^ INT_MAX;
}
# endif /* _MSC_VER */
#else /* I386_ASM */
/* CPhipps - made __inline__ to inline, as specified in the gcc docs
* Also made const */
inline static CONSTFUNC fixed_t FixedDiv(fixed_t a, fixed_t b)
{
return ((unsigned)D_abs(a)>>14) >= (unsigned)D_abs(b) ? ((a^b)>>31) ^ INT_MAX :
(fixed_t)(((int_64_t) a << FRACBITS) / b);
}
#endif /* I386_ASM */
/* CPhipps -
* FixedMod - returns a % b, guaranteeing 0<=a<b
* (notice that the C standard for % does not guarantee this)
*/
inline static CONSTFUNC fixed_t FixedMod(fixed_t a, fixed_t b)
{
if (b & (b-1)) {
fixed_t r = a % b;
return ((r<0) ? r+b : r);
} else
return (a & (b-1));
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,182 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Menu widget stuff, episode selection and such.
*
*-----------------------------------------------------------------------------*/
#ifndef __M_MENU__
#define __M_MENU__
#include "d_event.h"
//
// MENUS
//
// Called by main loop,
// saves config file and calls I_Quit when user exits.
// Even when the menu is not displayed,
// this can resize the view and change game parameters.
// Does all the real work of the menu interaction.
boolean M_Responder (event_t *ev);
// Called by main loop,
// only used for menu (skull cursor) animation.
void M_Ticker (void);
// Called by main loop,
// draws the menus directly into the screen buffer.
void M_Drawer (void);
// Called by D_DoomMain,
// loads the config file.
void M_Init (void);
// Called by intro code to force menu up upon a keypress,
// does nothing if menu is already up.
void M_StartControlPanel (void);
void M_ForcedLoadGame(const char *msg); // killough 5/15/98: forced loadgames
void M_Trans(void); // killough 11/98: reset translucency
void M_ResetMenu(void); // killough 11/98: reset main menu ordering
void M_DrawCredits(void); // killough 11/98
/* killough 8/15/98: warn about changes not being committed until next game */
#define warn_about_changes(x) (warning_about_changes=(x), \
print_warning_about_changes = 2)
extern int warning_about_changes, print_warning_about_changes;
/****************************
*
* The following #defines are for the m_flags field of each item on every
* Setup Screen. They can be OR'ed together where appropriate
*/
#define S_HILITE 0x1 // Cursor is sitting on this item
#define S_SELECT 0x2 // We're changing this item
#define S_TITLE 0x4 // Title item
#define S_YESNO 0x8 // Yes or No item
#define S_CRITEM 0x10 // Message color
#define S_COLOR 0x20 // Automap color
#define S_CHAT 0x40 // Chat String
#define S_RESET 0x80 // Reset to Defaults Button
#define S_PREV 0x100 // Previous menu exists
#define S_NEXT 0x200 // Next menu exists
#define S_KEY 0x400 // Key Binding
#define S_WEAP 0x800 // Weapon #
#define S_NUM 0x1000 // Numerical item
#define S_SKIP 0x2000 // Cursor can't land here
#define S_KEEP 0x4000 // Don't swap key out
#define S_END 0x8000 // Last item in list (dummy)
#define S_LEVWARN 0x10000// killough 8/30/98: Always warn about pending change
#define S_PRGWARN 0x20000// killough 10/98: Warn about change until next run
#define S_BADVAL 0x40000// killough 10/98: Warn about bad value
#define S_FILE 0x80000// killough 10/98: Filenames
#define S_LEFTJUST 0x100000 // killough 10/98: items which are left-justified
#define S_CREDIT 0x200000 // killough 10/98: credit
#define S_BADVID 0x400000 // killough 12/98: video mode change error
#define S_CHOICE 0x800000 // this item has several values
/* S_SHOWDESC = the set of items whose description should be displayed
* S_SHOWSET = the set of items whose setting should be displayed
* S_STRING = the set of items whose settings are strings -- killough 10/98:
* S_HASDEFPTR = the set of items whose var field points to default array
*/
#define S_SHOWDESC (S_TITLE|S_YESNO|S_CRITEM|S_COLOR|S_CHAT|S_RESET|S_PREV|S_NEXT|S_KEY|S_WEAP|S_NUM|S_FILE|S_CREDIT|S_CHOICE)
#define S_SHOWSET (S_YESNO|S_CRITEM|S_COLOR|S_CHAT|S_KEY|S_WEAP|S_NUM|S_FILE|S_CHOICE)
#define S_STRING (S_CHAT|S_FILE)
#define S_HASDEFPTR (S_STRING|S_YESNO|S_NUM|S_WEAP|S_COLOR|S_CRITEM|S_CHOICE)
/****************************
*
* The setup_group enum is used to show which 'groups' keys fall into so
* that you can bind a key differently in each 'group'.
*/
typedef enum {
m_null, // Has no meaning; not applicable
m_scrn, // A key can not be assigned to more than one action
m_map, // in the same group. A key can be assigned to one
m_menu, // action in one group, and another action in another.
} setup_group;
/****************************
*
* phares 4/17/98:
* State definition for each item.
* This is the definition of the structure for each setup item. Not all
* fields are used by all items.
*
* A setup screen is defined by an array of these items specific to
* that screen.
*
* killough 11/98:
*
* Restructured to allow simpler table entries,
* and to Xref with defaults[] array in m_misc.c.
* Moved from m_menu.c to m_menu.h so that m_misc.c can use it.
*/
typedef struct setup_menu_s
{
const char *m_text; /* text to display */
int m_flags; /* phares 4/17/98: flag bits S_* (defined above) */
setup_group m_group; /* Group */
short m_x; /* screen x position (left is 0) */
short m_y; /* screen y position (top is 0) */
union /* killough 11/98: The first field is a union of several types */
{
const void *var; /* generic variable */
int *m_key; /* key value, or 0 if not shown */
const char *name; /* name */
struct default_s *def; /* default[] table entry */
struct setup_menu_s *menu; /* next or prev menu */
} var;
int *m_mouse; /* mouse button value, or 0 if not shown */
int *m_joy; /* joystick button value, or 0 if not shown */
void (*action)(void); /* killough 10/98: function to call after changing */
const char **selectstrings; /* list of strings for choice value */
} setup_menu_t;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,111 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* External non-system-specific stuff, like storing config settings,
* simple file handling, and saving screnshots.
*
*-----------------------------------------------------------------------------*/
#ifndef __M_MISC__
#define __M_MISC__
#include "doomtype.h"
//
// MISC
//
boolean M_WriteFile (char const* name,void* source,int length);
int M_ReadFile (char const* name,byte** buffer);
void M_ScreenShot (void);
void M_DoScreenShot (const char*); // cph
void M_LoadDefaults (void);
void M_SaveDefaults (void);
struct default_s *M_LookupDefault(const char *name); /* killough 11/98 */
// phares 4/21/98:
// Moved from m_misc.c so m_menu.c could see it.
// CPhipps - struct to hold a value in a config file
// Cannot be a union, as it must be initialised
typedef struct default_s
{
const char* name;
/* cph -
* The location struct holds the pointer to the variable holding the
* setting. For int's we do nothing special.
* For strings, the string is actually stored on our heap with Z_Strdup()
* BUT we don't want the rest of the program to be able to modify them,
* so we declare it const. It's not really const though, and m_misc.c and
* m_menu.c cast it back when they need to change it. Possibly this is
* more trouble than it's worth.
*/
struct {
int* pi;
const char** ppsz;
} location;
struct {
int i;
const char* psz;
} defaultvalue; // CPhipps - default value
// Limits (for an int)
int minvalue; // jff 3/3/98 minimum allowed value
int maxvalue; // jff 3/3/98 maximum allowed value
enum {
def_none, // Dummy entry
def_str, // A string
def_int, // Integer
def_hex, // Integer (write in hex)
def_bool = def_int, // Boolean
def_key = def_hex, // Key code (byte)
def_mouseb = def_int,// Mouse button
def_colour = def_hex // Colour (256 colour palette entry)
} type; // CPhipps - type of entry
int setupscreen; // phares 4/19/98: setup screen where this appears
int *current; /* cph - MBF-like pointer to current value */
// cph - removed the help strings from the config file
// const char* help; // jff 3/3/98 description of parameter
// CPhipps - remove unused "lousy hack" code
struct setup_menu_s *setup_menu; /* Xref to setup menu item, if any */
} default_t;
#define IS_STRING(dv) ((dv).type == def_str)
// CPhipps - What is the max. key code that X will send us?
#define MAX_KEY 65536
#define MAX_MOUSEB 2
#define UL (-123456789) /* magic number for no min or max for parameter */
#endif

View File

@@ -0,0 +1,147 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Random number LUT.
*
* 1/19/98 killough: Rewrote random number generator for better randomness,
* while at the same time maintaining demo sync and backward compatibility.
*
* 2/16/98 killough: Made each RNG local to each control-equivalent block,
* to reduce the chances of demo sync problems.
*
*-----------------------------------------------------------------------------*/
#include "doomstat.h"
#include "m_random.h"
#include "lprintf.h"
//
// M_Random
// Returns a 0-255 number
//
static const unsigned char rndtable[256] = { // 1/19/98 killough -- made const
0, 8, 109, 220, 222, 241, 149, 107, 75, 248, 254, 140, 16, 66 ,
74, 21, 211, 47, 80, 242, 154, 27, 205, 128, 161, 89, 77, 36 ,
95, 110, 85, 48, 212, 140, 211, 249, 22, 79, 200, 50, 28, 188 ,
52, 140, 202, 120, 68, 145, 62, 70, 184, 190, 91, 197, 152, 224 ,
149, 104, 25, 178, 252, 182, 202, 182, 141, 197, 4, 81, 181, 242 ,
145, 42, 39, 227, 156, 198, 225, 193, 219, 93, 122, 175, 249, 0 ,
175, 143, 70, 239, 46, 246, 163, 53, 163, 109, 168, 135, 2, 235 ,
25, 92, 20, 145, 138, 77, 69, 166, 78, 176, 173, 212, 166, 113 ,
94, 161, 41, 50, 239, 49, 111, 164, 70, 60, 2, 37, 171, 75 ,
136, 156, 11, 56, 42, 146, 138, 229, 73, 146, 77, 61, 98, 196 ,
135, 106, 63, 197, 195, 86, 96, 203, 113, 101, 170, 247, 181, 113 ,
80, 250, 108, 7, 255, 237, 129, 226, 79, 107, 112, 166, 103, 241 ,
24, 223, 239, 120, 198, 58, 60, 82, 128, 3, 184, 66, 143, 224 ,
145, 224, 81, 206, 163, 45, 63, 90, 168, 114, 59, 33, 159, 95 ,
28, 139, 123, 98, 125, 196, 15, 70, 194, 253, 54, 14, 109, 226 ,
71, 17, 161, 93, 186, 87, 244, 138, 20, 52, 123, 251, 26, 36 ,
17, 46, 52, 231, 232, 76, 31, 221, 84, 37, 216, 165, 212, 106 ,
197, 242, 98, 43, 39, 175, 254, 145, 190, 84, 118, 222, 187, 136 ,
120, 163, 236, 249
};
rng_t rng; // the random number state
unsigned long rngseed = 1993; // killough 3/26/98: The seed
int (P_Random)(pr_class_t pr_class
#ifdef INSTRUMENTED
, const char *file, int line
#endif
)
{
// killough 2/16/98: We always update both sets of random number
// generators, to ensure repeatability if the demo_compatibility
// flag is changed while the program is running. Changing the
// demo_compatibility flag does not change the sequences generated,
// only which one is selected from.
//
// All of this RNG stuff is tricky as far as demo sync goes --
// it's like playing with explosives :) Lee
#ifdef INSTRUMENTED
//lprintf(LO_DEBUG, "%.10d: %.10d - %s:%.5d\n", gametic, pr_class, file, line);
#endif
int compat = pr_class == pr_misc ?
(rng.prndindex = (rng.prndindex + 1) & 255) :
(rng. rndindex = (rng. rndindex + 1) & 255) ;
unsigned long boom;
// killough 3/31/98:
// If demo sync insurance is not requested, use
// much more unstable method by putting everything
// except pr_misc into pr_all_in_one
if (pr_class != pr_misc && !demo_insurance) // killough 3/31/98
pr_class = pr_all_in_one;
boom = rng.seed[pr_class];
// killough 3/26/98: add pr_class*2 to addend
rng.seed[pr_class] = boom * 1664525ul + 221297ul + pr_class*2;
if (demo_compatibility)
return rndtable[compat];
boom >>= 20;
/* killough 3/30/98: use gametic-levelstarttic to shuffle RNG
* killough 3/31/98: but only if demo insurance requested,
* since it's unnecessary for random shuffling otherwise
* killough 9/29/98: but use basetic now instead of levelstarttic
* cph - DEMOSYNC - this change makes MBF demos work,
* but does it break Boom ones?
*/
if (demo_insurance)
boom += (gametic-basetic)*7;
return boom & 255;
}
// Initialize all the seeds
//
// This initialization method is critical to maintaining demo sync.
// Each seed is initialized according to its class, so if new classes
// are added they must be added to end of pr_class_t list. killough
//
void M_ClearRandom (void)
{
int i;
unsigned long seed = rngseed*2+1; // add 3/26/98: add rngseed
for (i=0; i<NUMPRCLASS; i++) // go through each pr_class and set
rng.seed[i] = seed *= 69069ul; // each starting seed differently
rng.prndindex = rng.rndindex = 0; // clear two compatibility indices
}

View File

@@ -0,0 +1,154 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Functions to return random numbers.
*
*-----------------------------------------------------------------------------*/
#ifndef __M_RANDOM__
#define __M_RANDOM__
#include "doomtype.h"
// killough 1/19/98: rewritten to use to use a better random number generator
// in the new engine, although the old one is available for compatibility.
// killough 2/16/98:
//
// Make every random number generator local to each control-equivalent block.
// Critical for demo sync. Changing the order of this list breaks all previous
// versions' demos. The random number generators are made local to reduce the
// chances of sync problems. In Doom, if a single random number generator call
// was off, it would mess up all random number generators. This reduces the
// chances of it happening by making each RNG local to a control flow block.
//
// Notes to developers: if you want to reduce your demo sync hassles, follow
// this rule: for each call to P_Random you add, add a new class to the enum
// type below for each block of code which calls P_Random. If two calls to
// P_Random are not in "control-equivalent blocks", i.e. there are any cases
// where one is executed, and the other is not, put them in separate classes.
//
// Keep all current entries in this list the same, and in the order
// indicated by the #'s, because they're critical for preserving demo
// sync. Do not remove entries simply because they become unused later.
typedef enum {
pr_skullfly, // #1
pr_damage, // #2
pr_crush, // #3
pr_genlift, // #4
pr_killtics, // #5
pr_damagemobj, // #6
pr_painchance, // #7
pr_lights, // #8
pr_explode, // #9
pr_respawn, // #10
pr_lastlook, // #11
pr_spawnthing, // #12
pr_spawnpuff, // #13
pr_spawnblood, // #14
pr_missile, // #15
pr_shadow, // #16
pr_plats, // #17
pr_punch, // #18
pr_punchangle, // #19
pr_saw, // #20
pr_plasma, // #21
pr_gunshot, // #22
pr_misfire, // #23
pr_shotgun, // #24
pr_bfg, // #25
pr_slimehurt, // #26
pr_dmspawn, // #27
pr_missrange, // #28
pr_trywalk, // #29
pr_newchase, // #30
pr_newchasedir, // #31
pr_see, // #32
pr_facetarget, // #33
pr_posattack, // #34
pr_sposattack, // #35
pr_cposattack, // #36
pr_spidrefire, // #37
pr_troopattack, // #38
pr_sargattack, // #39
pr_headattack, // #40
pr_bruisattack, // #41
pr_tracer, // #42
pr_skelfist, // #43
pr_scream, // #44
pr_brainscream, // #45
pr_cposrefire, // #46
pr_brainexp, // #47
pr_spawnfly, // #48
pr_misc, // #49
pr_all_in_one, // #50
/* CPhipps - new entries from MBF, mostly unused for now */
pr_opendoor, // #51
pr_targetsearch, // #52
pr_friends, // #53
pr_threshold, // #54
pr_skiptarget, // #55
pr_enemystrafe, // #56
pr_avoidcrush, // #57
pr_stayonlift, // #58
pr_helpfriend, // #59
pr_dropoff, // #60
pr_randomjump, // #61
pr_defect, // #62 // Start new entries -- add new entries below
// End of new entries
NUMPRCLASS // MUST be last item in list
} pr_class_t;
// The random number generator's state.
typedef struct {
unsigned long seed[NUMPRCLASS]; // Each block's random seed
int rndindex, prndindex; // For compatibility support
} rng_t;
extern rng_t rng; // The rng's state
extern unsigned long rngseed; // The starting seed (not part of state)
// As M_Random, but used by the play simulation.
int P_Random(pr_class_t DA(const char *, int));
#ifdef INSTRUMENTED
#define P_Random(a) (P_Random) (a, __FILE__,__LINE__)
#endif
// Returns a number from 0 to 255,
#define M_Random() P_Random(pr_misc)
// Fix randoms for demos.
void M_ClearRandom(void);
#endif

View File

@@ -0,0 +1,134 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Endianess handling, swapping 16bit and 32bit.
*
*-----------------------------------------------------------------------------*/
#ifndef __M_SWAP__
#define __M_SWAP__
#ifdef __GNUG__
#pragma interface
#endif
/* CPhipps - now the endianness handling, converting input or output to/from
* the machine's endianness to that wanted for this type of I/O
*
* To find our own endianness, use config.h
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* Endianess handling. */
/* cph - First the macros to do the actual byte swapping */
/* leban
* rather than continue the confusing tradition of redefining the
* stardard macro, we now present the doom_ntoh and doom_hton macros....
* might as well use the xdoom macros.
*/
/* Try to use superfast macros on systems that support them */
#ifdef HAVE_ASM_BYTEORDER_H
#include <asm/byteorder.h>
#ifdef __arch__swab16
#define doom_swap_s (signed short)__arch__swab16
#endif
#ifdef __arch__swab32
#define doom_swap_l (signed long)__arch__swab32
#endif
#endif /* HAVE_ASM_BYTEORDER_H */
#ifdef HAVE_LIBKERN_OSBYTEORDER_H
#include <libkern/OSByteOrder.h>
#define doom_swap_s (short)OSSwapInt16
#define doom_swap_l (long)OSSwapInt32
#endif
#ifndef doom_swap_l
#define doom_swap_l(x) \
((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)))
#endif
#ifndef doom_swap_s
#define doom_swap_s(x) \
((short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
(((unsigned short int)(x) & 0xff00) >> 8)))
#endif
/* Macros are named doom_XtoYT, where
* X is thing to convert from, Y is thing to convert to, chosen from
* n for network, h for host (i.e our machine's), w for WAD (Doom data files)
* and T is the type, l or s for long or short
*
* CPhipps - all WADs and network packets will be little endian for now
* Use separate macros so network could be converted to big-endian later.
*/
#ifdef WORDS_BIGENDIAN
#define doom_wtohl(x) doom_swap_l(x)
#define doom_htowl(x) doom_swap_l(x)
#define doom_wtohs(x) doom_swap_s(x)
#define doom_htows(x) doom_swap_s(x)
#define doom_ntohl(x) doom_swap_l(x)
#define doom_htonl(x) doom_swap_l(x)
#define doom_ntohs(x) doom_swap_s(x)
#define doom_htons(x) doom_swap_s(x)
#else
#define doom_wtohl(x) (long int)(x)
#define doom_htowl(x) (long int)(x)
#define doom_wtohs(x) (short int)(x)
#define doom_htows(x) (short int)(x)
#define doom_ntohl(x) (long int)(x)
#define doom_htonl(x) (long int)(x)
#define doom_ntohs(x) (short int)(x)
#define doom_htons(x) (short int)(x)
#endif
/* CPhipps - Boom's old LONG and SHORT endianness macros are for WAD stuff */
#define LONG(x) doom_wtohl(x)
#define SHORT(x) doom_htows(x)
#endif

View File

@@ -0,0 +1,240 @@
/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*
* Changed so as no longer to depend on Colin Plumb's `usual.h' header
* definitions; now uses stuff from dpkg's config.h.
* - Ian Jackson <ian@chiark.greenend.org.uk>.
* Still in the public domain.
*/
#include "config.h"
#include <string.h> /* for memcpy() */
#include <sys/types.h> /* for stupid systems */
#include "md5.h"
#ifdef WORDS_BIGENDIAN
void
byteSwap(UWORD32 *buf, unsigned words)
{
md5byte *p = (md5byte *)buf;
do {
*buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 |
((unsigned)p[1] << 8 | p[0]);
p += 4;
} while (--words);
}
#else
#define byteSwap(buf,words)
#endif
/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
void
MD5Init(struct MD5Context *ctx)
{
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
ctx->buf[2] = 0x98badcfe;
ctx->buf[3] = 0x10325476;
ctx->bytes[0] = 0;
ctx->bytes[1] = 0;
}
/*
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void
MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len)
{
UWORD32 t;
/* Update byte count */
t = ctx->bytes[0];
if ((ctx->bytes[0] = t + len) < t)
ctx->bytes[1]++; /* Carry from low to high */
t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
if (t > len) {
memcpy((md5byte *)ctx->in + 64 - t, buf, len);
return;
}
/* First chunk is an odd size */
memcpy((md5byte *)ctx->in + 64 - t, buf, t);
byteSwap(ctx->in, 16);
MD5Transform(ctx->buf, ctx->in);
buf += t;
len -= t;
/* Process data in 64-byte chunks */
while (len >= 64) {
memcpy(ctx->in, buf, 64);
byteSwap(ctx->in, 16);
MD5Transform(ctx->buf, ctx->in);
buf += 64;
len -= 64;
}
/* Handle any remaining bytes of data. */
memcpy(ctx->in, buf, len);
}
/*
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void
MD5Final(md5byte digest[16], struct MD5Context *ctx)
{
int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
md5byte *p = (md5byte *)ctx->in + count;
/* Set the first char of padding to 0x80. There is always room. */
*p++ = 0x80;
/* Bytes of padding needed to make 56 bytes (-8..55) */
count = 56 - 1 - count;
if (count < 0) { /* Padding forces an extra block */
memset(p, 0, count + 8);
byteSwap(ctx->in, 16);
MD5Transform(ctx->buf, ctx->in);
p = (md5byte *)ctx->in;
count = 56;
}
memset(p, 0, count);
byteSwap(ctx->in, 14);
/* Append length in bits and transform */
ctx->in[14] = ctx->bytes[0] << 3;
ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
MD5Transform(ctx->buf, ctx->in);
byteSwap(ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
}
#ifndef ASM_MD5
/* The four core functions - F1 is optimized somewhat */
/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f,w,x,y,z,in,s) \
(w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
void
MD5Transform(UWORD32 buf[4], UWORD32 const in[16])
{
register UWORD32 a, b, c, d;
a = buf[0];
b = buf[1];
c = buf[2];
d = buf[3];
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
#endif

View File

@@ -0,0 +1,47 @@
/*
* This is the header file for the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*
* Changed so as no longer to depend on Colin Plumb's `usual.h'
* header definitions; now uses stuff from dpkg's config.h
* - Ian Jackson <ian@chiark.greenend.org.uk>.
* Still in the public domain.
*/
#ifndef MD5_H
#define MD5_H
#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define UWORD32 DWORD
#else
#include <inttypes.h>
#define UWORD32 uint32_t
#endif
#define md5byte unsigned char
struct MD5Context {
UWORD32 buf[4];
UWORD32 bytes[2];
UWORD32 in[16];
};
void MD5Init(struct MD5Context *context);
void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len);
void MD5Final(unsigned char digest[16], struct MD5Context *context);
void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]);
#endif /* !MD5_H */

View File

@@ -0,0 +1,866 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* This file supports conversion of MUS format music in memory
* to MIDI format 1 music in memory.
*
* The primary routine, mmus2mid, converts a block of memory in MUS format
* to an Allegro MIDI structure. This supports playing MUS lumps in a wad
* file with BOOM.
*
* Another routine, Midi2MIDI, converts a block of memory in MIDI format 1 to
* an Allegro MIDI structure. This supports playing MIDI lumps in a wad
* file with BOOM.
*
* For testing purposes, and to make a utility if desired, if the symbol
* STANDALONE is defined by uncommenting the definition below, a main
* routine is compiled that will convert a possibly wildcarded set of MUS
* files to a similarly named set of MIDI files.
*
* Much of the code here is thanks to S. Bacquet's source for QMUS2MID.C
*
*-----------------------------------------------------------------------------
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#ifdef MSDOS /* proff: I don't use allegro in windows */
#include <allegro.h>
#endif /* !MSDOS */
#include "mmus2mid.h"
#include "lprintf.h" // jff 08/03/98 - declaration of lprintf
//#define STANDALONE /* uncomment this to make MMUS2MID.EXE */
#ifndef STANDALONE
#include "m_swap.h"
#include "z_zone.h"
#endif
// some macros to decode mus event bit fields
#define last(e) ((UBYTE)((e) & 0x80))
#define event_type(e) ((UBYTE)(((e) & 0x7F) >> 4))
#define channel(e) ((UBYTE)((e) & 0x0F))
// event types
typedef enum
{
RELEASE_NOTE,
PLAY_NOTE,
BEND_NOTE,
SYS_EVENT,
CNTL_CHANGE,
UNKNOWN_EVENT1,
SCORE_END,
UNKNOWN_EVENT2,
} mus_event_t;
// MUS format header structure
typedef struct
{
char ID[4]; // identifier "MUS"0x1A
UWORD ScoreLength; // length of music portion
UWORD ScoreStart; // offset of music portion
UWORD channels; // count of primary channels
UWORD SecChannels; // count of secondary channels
UWORD InstrCnt; // number of instruments
} PACKEDATTR MUSheader;
// to keep track of information in a MIDI track
typedef struct Track
{
char velocity;
long deltaT;
UBYTE lastEvt;
long alloced;
} TrackInfo;
// array of info about tracks
static TrackInfo track[MIDI_TRACKS];
// initial track size allocation
#define TRACKBUFFERSIZE 1024
// lookup table MUS -> MID controls
static UBYTE MUS2MIDcontrol[15] =
{
0, // Program change - not a MIDI control change
0x00, // Bank select
0x01, // Modulation pot
0x07, // Volume
0x0A, // Pan pot
0x0B, // Expression pot
0x5B, // Reverb depth
0x5D, // Chorus depth
0x40, // Sustain pedal
0x43, // Soft pedal
0x78, // All sounds off
0x7B, // All notes off
0x7E, // Mono
0x7F, // Poly
0x79 // Reset all controllers
};
// some strings of bytes used in the midi format
static UBYTE midikey[] =
{0x00,0xff,0x59,0x02,0x00,0x00}; // C major
static UBYTE miditempo[] =
{0x00,0xff,0x51,0x03,0x09,0xa3,0x1a}; // uS/qnote
static UBYTE midihdr[] =
{'M','T','h','d',0,0,0,6,0,1,0,0,0,0}; // header (length 6, format 1)
static UBYTE trackhdr[] =
{'M','T','r','k'}; // track header
// static routine prototypes
static int TWriteByte(MIDI *mididata, int MIDItrack, UBYTE byte);
static int TWriteVarLen(MIDI *mididata, int MIDItrack, register ULONG value);
static ULONG ReadTime(const UBYTE **musptrp);
static int FirstChannelAvailable(int MUS2MIDchannel[]);
static UBYTE MidiEvent(MIDI *mididata,UBYTE midicode,UBYTE MIDIchannel,
UBYTE MIDItrack,int nocomp);
//
// TWriteByte()
//
// write one byte to the selected MIDItrack, update current position
// if track allocation exceeded, double it
// if track not allocated, initially allocate TRACKBUFFERSIZE bytes
//
// Passed pointer to Allegro MIDI structure, number of the MIDI track being
// written, and the byte to write.
//
// Returns 0 on success, MEMALLOC if a memory allocation error occurs
//
static int TWriteByte(MIDI *mididata, int MIDItrack, UBYTE byte)
{
ULONG pos ;
pos = mididata->track[MIDItrack].len;
if (pos >= (ULONG)track[MIDItrack].alloced)
{
track[MIDItrack].alloced = // double allocation
track[MIDItrack].alloced? // or set initial TRACKBUFFERSIZE
2*track[MIDItrack].alloced :
TRACKBUFFERSIZE;
if (!(mididata->track[MIDItrack].data = // attempt to reallocate
realloc(mididata->track[MIDItrack].data,
track[MIDItrack].alloced)))
return MEMALLOC;
}
mididata->track[MIDItrack].data[pos] = byte;
mididata->track[MIDItrack].len++;
return 0;
}
//
// TWriteVarLen()
//
// write the ULONG value to tracknum-th track, in midi format, which is
// big endian, 7 bits per byte, with all bytes but the last flagged by
// bit 8 being set, allowing the length to vary.
//
// Passed the Allegro MIDI structure, the track number to write,
// and the ULONG value to encode in midi format there
//
// Returns 0 if sucessful, MEMALLOC if a memory allocation error occurs
//
static int TWriteVarLen(MIDI *mididata, int tracknum, register ULONG value)
{
register ULONG buffer;
buffer = value & 0x7f;
while ((value >>= 7)) // terminates because value unsigned
{
buffer <<= 8; // note first value shifted in has bit 8 clear
buffer |= 0x80; // all succeeding values do not
buffer += (value & 0x7f);
}
while (1) // write bytes out in opposite order
{
if (TWriteByte(mididata, tracknum, (UBYTE)(buffer&0xff))) // insure buffer masked
return MEMALLOC;
if (buffer & 0x80)
buffer >>= 8;
else // terminate on the byte with bit 8 clear
break;
}
return 0;
}
//
// ReadTime()
//
// Read a time value from the MUS buffer, advancing the position in it
//
// A time value is a variable length sequence of 8 bit bytes, with all
// but the last having bit 8 set.
//
// Passed a pointer to the pointer to the MUS buffer
// Returns the integer unsigned long time value there and advances the pointer
//
static ULONG ReadTime(const UBYTE **musptrp)
{
register ULONG timeval = 0;
int byte;
do // shift each byte read up in the result until a byte with bit 8 clear
{
byte = *(*musptrp)++;
timeval = (timeval << 7) + (byte & 0x7F);
}
while(byte & 0x80);
return timeval;
}
//
// FirstChannelAvailable()
//
// Return the next unassigned MIDI channel number
//
// The assignment for MUS channel 15 is not counted in the caculation, that
// being percussion and always assigned to MIDI channel 9 (base 0).
//
// Passed the array of MIDI channels assigned to MUS channels
// Returns the maximum channel number unassigned unless that is 9 in which
// case 10 is returned.
//
// killough 10/7/98: changed char parameter, return values to int
static int FirstChannelAvailable(int MUS2MIDchannel[])
{
int i ;
int max = -1 ;
// find the largest MIDI channel assigned so far
for (i = 0; i < 15; i++)
if (MUS2MIDchannel[i] > max)
max = MUS2MIDchannel[i];
return (max == 8 ? 10 : max+1); // skip MIDI channel 9 (percussion)
}
//
// MidiEvent()
//
// Constructs a MIDI event code, and writes it to the current MIDI track
// unless its the same as the last event code and compressio is enabled
// in which case nothing is written.
//
// Passed the Allegro MIDI structure, the midi event code, the current
// MIDI channel number, the current MIDI track number, and whether compression
// (running status) is enabled.
//
// Returns the new event code if successful, 0 if a memory allocation error
//
static UBYTE MidiEvent(MIDI *mididata,UBYTE midicode,UBYTE MIDIchannel,
UBYTE MIDItrack,int nocomp)
{
UBYTE newevent;
newevent = midicode | MIDIchannel;
if ((newevent != track[MIDItrack].lastEvt) || nocomp)
{
if (TWriteByte(mididata,MIDItrack, newevent))
return 0; // indicates MEMALLOC error
track[MIDItrack].lastEvt = newevent;
}
return newevent;
}
//
// mmus2mid()
//
// Convert a memory buffer contain MUS data to an Allegro MIDI structure
// with specified time division and compression.
//
// Passed a pointer to the buffer containing MUS data, a pointer to the
// Allegro MIDI structure, the divisions, and a flag whether to compress.
//
// Returns 0 if successful, otherwise an error code (see mmus2mid.h).
//
int mmus2mid(const UBYTE *mus, MIDI *mididata, UWORD division, int nocomp)
{
UWORD TrackCnt = 0;
UBYTE evt, MUSchannel, MIDIchannel, MIDItrack=0, NewEvent;
int i, event, data;
const UBYTE *musptr;
size_t muslen;
static MUSheader MUSh;
UBYTE MIDIchan2track[MIDI_TRACKS]; // killough 10/7/98: fix too small array
int MUS2MIDchannel[MIDI_TRACKS]; // killough 10/7/98: fix too small array
// copy the MUS header from the MUS buffer to the MUSh header structure
memcpy(&MUSh,mus,sizeof(MUSheader));
MUSh.ScoreLength = doom_wtohs(MUSh.ScoreLength);
MUSh.ScoreStart = doom_wtohs(MUSh.ScoreStart);
MUSh.channels = doom_wtohs(MUSh.channels);
MUSh.SecChannels = doom_wtohs(MUSh.SecChannels);
MUSh.InstrCnt = doom_wtohs(MUSh.InstrCnt);
// check some things and set length of MUS buffer from internal data
if (!(muslen = MUSh.ScoreLength + MUSh.ScoreStart))
return MUSDATAMT; // MUS file empty
if (MUSh.channels > 15) // MUSchannels + drum channel > 16
return TOOMCHAN ;
musptr = mus+MUSh.ScoreStart; // init musptr to start of score
for (i = 0; i < MIDI_TRACKS; i++) // init the track structure's tracks
{
MUS2MIDchannel[i] = -1; // flag for channel not used yet
track[i].velocity = 64;
track[i].deltaT = 0;
track[i].lastEvt = 0;
//free(mididata->track[i].data);//jff 3/5/98 remove old allocations
mididata->track[i].data=NULL;
track[i].alloced = 0;
mididata->track[i].len = 0;
}
if (!division)
division = 70;
// allocate the first track which is a special tempo/key track
// note multiple tracks means midi format 1
// set the divisions (ticks per quarter note)
mididata->divisions = division;
// allocate for midi tempo/key track, allow for end of track
if (!(mididata->track[0].data =
realloc(mididata->track[0].data,sizeof(midikey)+sizeof(miditempo)+4)))
return MEMALLOC;
// key C major
memcpy(mididata->track[0].data,midikey,sizeof(midikey));
// tempo uS/qnote
memcpy(mididata->track[0].data+sizeof(midikey),miditempo,sizeof(miditempo));
mididata->track[0].len = sizeof(midikey)+sizeof(miditempo);
TrackCnt++; // music tracks start at 1
// process the MUS events in the MUS buffer
do
{
// get a mus event, decode its type and channel fields
event = *musptr++;
if ((evt = event_type(event)) == SCORE_END) //jff 1/23/98 use symbol
break; // if end of score event, leave
MUSchannel = channel(event);
// if this channel not initialized, do so
if (MUS2MIDchannel[MUSchannel] == -1)
{
// set MIDIchannel and MIDItrack
MIDIchannel = MUS2MIDchannel[MUSchannel] =
(MUSchannel == 15 ? 9 : FirstChannelAvailable(MUS2MIDchannel));
MIDItrack = MIDIchan2track[MIDIchannel] = (UBYTE)TrackCnt++;
}
else // channel already allocated as a track, use those values
{
MIDIchannel = MUS2MIDchannel[MUSchannel];
MIDItrack = MIDIchan2track[MIDIchannel];
}
if (TWriteVarLen(mididata, MIDItrack, track[MIDItrack].deltaT))
return MEMALLOC;
track[MIDItrack].deltaT = 0;
switch(evt)
{
case RELEASE_NOTE:
// killough 10/7/98: Fix noise problems by not allowing compression
if (!(NewEvent=MidiEvent(mididata,0x90,MIDIchannel,MIDItrack,1)))
return MEMALLOC;
data = *musptr++;
if (TWriteByte(mididata, MIDItrack, (UBYTE)(data & 0x7F)))
return MEMALLOC;
if (TWriteByte(mididata, MIDItrack, 0))
return MEMALLOC;
break;
case PLAY_NOTE:
if (!(NewEvent=MidiEvent(mididata,0x90,MIDIchannel,MIDItrack,nocomp)))
return MEMALLOC;
data = *musptr++;
if (TWriteByte(mididata, MIDItrack, (UBYTE)(data & 0x7F)))
return MEMALLOC;
if( data & 0x80 )
track[MIDItrack].velocity = (*musptr++) & 0x7f;
if (TWriteByte(mididata, MIDItrack, track[MIDItrack].velocity))
return MEMALLOC;
break;
case BEND_NOTE:
if (!(NewEvent=MidiEvent(mididata,0xE0,MIDIchannel,MIDItrack,nocomp)))
return MEMALLOC;
data = *musptr++;
if (TWriteByte(mididata, MIDItrack, (UBYTE)((data & 1) << 6)))
return MEMALLOC;
if (TWriteByte(mididata, MIDItrack, (UBYTE)(data >> 1)))
return MEMALLOC;
break;
case SYS_EVENT:
if (!(NewEvent=MidiEvent(mididata,0xB0,MIDIchannel,MIDItrack,nocomp)))
return MEMALLOC;
data = *musptr++;
if (data<10 || data>14)
return BADSYSEVT;
if (TWriteByte(mididata, MIDItrack, MUS2MIDcontrol[data]))
return MEMALLOC;
if (data == 12)
{
if (TWriteByte(mididata, MIDItrack, (UBYTE)(MUSh.channels+1)))
return MEMALLOC;
}
else
if (TWriteByte(mididata, MIDItrack, 0))
return MEMALLOC;
break;
case CNTL_CHANGE:
data = *musptr++;
if (data>9)
return BADCTLCHG;
if (data)
{
if (!(NewEvent=MidiEvent(mididata,0xB0,MIDIchannel,MIDItrack,nocomp)))
return MEMALLOC;
if (TWriteByte(mididata, MIDItrack, MUS2MIDcontrol[data]))
return MEMALLOC;
}
else
{
if (!(NewEvent=MidiEvent(mididata,0xC0,MIDIchannel,MIDItrack,nocomp)))
return MEMALLOC;
}
data = *musptr++;
if (TWriteByte(mididata, MIDItrack, (UBYTE)(data & 0x7F)))
return MEMALLOC;
break;
case UNKNOWN_EVENT1: // mus events 5 and 7
case UNKNOWN_EVENT2: // meaning not known
return BADMUSCTL;
case SCORE_END:
break;
default:
return BADMUSCTL; // exit with error
}
if (last(event))
{
ULONG DeltaTime = ReadTime(&musptr); // killough 10/7/98: make local
for (i = 0;i < MIDI_TRACKS; i++) //jff 3/13/98 update all tracks
track[i].deltaT += DeltaTime; //whether allocated yet or not
}
}
while ((evt != SCORE_END) && ((size_t)(musptr-mus) < muslen));
if (evt!=SCORE_END)
return MUSDATACOR;
// Now add an end of track to each mididata track, correct allocation
for (i = 0; i < MIDI_TRACKS; i++)
if (mididata->track[i].len)
{ // killough 10/7/98: simplify code
if (TWriteByte(mididata, i, 0x00) || // midi end of track code
TWriteByte(mididata, i, 0xFF) ||
TWriteByte(mididata, i, 0x2F) ||
TWriteByte(mididata, i, 0x00))
return MEMALLOC;
// jff 1/23/98 fix failure to set data NULL, len 0 for unused tracks
// shorten allocation to proper length (important for Allegro)
if (!(mididata->track[i].data =
realloc(mididata->track[i].data,mididata->track[i].len)))
return MEMALLOC;
}
else
{
free(mididata->track[i].data);
mididata->track[i].data = NULL;
}
return 0;
}
void free_mididata(MIDI *mid)
{
int i;
for (i = 0; i < MIDI_TRACKS; i++)
if (mid->track[i].data)
free(mid->track[i].data);
}
//
// ReadLength()
//
// Reads the length of a chunk in a midi buffer, advancing the pointer
// 4 bytes, bigendian
//
// Passed a pointer to the pointer to a MIDI buffer
// Returns the chunk length at the pointer position
//
static size_t ReadLength(UBYTE **mid)
{
UBYTE *midptr = *mid;
size_t length = (*midptr++)<<24;
length += (*midptr++)<<16;
length += (*midptr++)<<8;
length += *midptr++;
*mid = midptr;
return length;
}
//
// MidiToMIDI()
//
// Convert an in-memory copy of a MIDI format 0 or 1 file to
// an Allegro MIDI structure, that is valid or has been zeroed
//
// Passed a pointer to a memory buffer with MIDI format music in it and a
// pointer to an Allegro MIDI structure.
//
// Returns 0 if successful, BADMIDHDR if the buffer is not MIDI format
//
int MidiToMIDI(UBYTE *mid,MIDI *mididata)
{
int i;
int ntracks;
// read the midi header
if (memcmp(mid,midihdr,4))
return BADMIDHDR;
mididata->divisions = (mid[12]<<8)+mid[13];
ntracks = (mid[10]<<8)+mid[11];
if (ntracks>=MIDI_TRACKS)
return BADMIDHDR;
mid += 4;
{ // killough 10/7/98: fix mid from being modified twice before sequence pt.
size_t t = ReadLength(&mid); // seek past header
mid += t;
}
// now read each track
for (i=0;i<ntracks;i++)
{
while (memcmp(mid,trackhdr,4)) // simply skip non-track data
{
mid += 4;
{
size_t t = ReadLength(&mid); // seek past header
mid += t; // killough 10/7/98: prevent mid undefined behavior
}
}
mid += 4;
mididata->track[i].len = ReadLength(&mid); // get length, move mid past it
// read a track
mididata->track[i].data = realloc(mididata->track[i].data,mididata->track[i].len);
memcpy(mididata->track[i].data,mid,mididata->track[i].len);
mid += mididata->track[i].len;
}
for (;i<MIDI_TRACKS;i++)
if (mididata->track[i].len)
{
free(mididata->track[i].data);
mididata->track[i].data = NULL;
mididata->track[i].len = 0;
}
return 0;
}
//#ifdef STANDALONE /* this code unused by BOOM provided for future portability */
// /* it also provides a MUS to MID file converter*/
// proff: I moved this down, because I need MIDItoMidi
static void FreeTracks(MIDI *mididata);
static void TWriteLength(UBYTE **midiptr,ULONG length);
//
// FreeTracks()
//
// Free all track allocations in the MIDI structure
//
// Passed a pointer to an Allegro MIDI structure
// Returns nothing
//
static void FreeTracks(MIDI *mididata)
{
int i;
for (i=0; i<MIDI_TRACKS; i++)
{
free(mididata->track[i].data);
mididata->track[i].data = NULL;
mididata->track[i].len = 0;
}
}
//
// TWriteLength()
//
// Write the length of a MIDI chunk to a midi buffer. The length is four
// bytes and is written byte-reversed for bigendian. The pointer to the
// midi buffer is advanced.
//
// Passed a pointer to the pointer to a midi buffer, and the length to write
// Returns nothing
//
static void TWriteLength(UBYTE **midiptr,ULONG length)
{
// proff: Added typecast to avoid warning
*(*midiptr)++ = (unsigned char)((length>>24)&0xff);
*(*midiptr)++ = (unsigned char)((length>>16)&0xff);
*(*midiptr)++ = (unsigned char)((length>>8)&0xff);
*(*midiptr)++ = (unsigned char)((length)&0xff);
}
//
// MIDIToMidi()
//
// This routine converts an Allegro MIDI structure to a midi 1 format file
// in memory. It is used to support memory MUS -> MIDI conversion
//
// Passed a pointer to an Allegro MIDI structure, a pointer to a pointer to
// a buffer containing midi data, and a pointer to a length return.
// Returns 0 if successful, MEMALLOC if a memory allocation error occurs
//
int MIDIToMidi(MIDI *mididata,UBYTE **mid,int *midlen)
{
size_t total;
int i,ntrks;
UBYTE *midiptr;
// calculate how long the mid buffer must be, and allocate
total = sizeof(midihdr);
for (i=0,ntrks=0;i<MIDI_TRACKS;i++)
if (mididata->track[i].len)
{
total += 8 + mididata->track[i].len; // Track hdr + track length
ntrks++;
}
if ((*mid = malloc(total))==NULL)
return MEMALLOC;
// fill in number of tracks and bigendian divisions (ticks/qnote)
midihdr[10] = 0;
midihdr[11] = (UBYTE)ntrks; // set number of tracks in header
midihdr[12] = (mididata->divisions>>8) & 0x7f;
midihdr[13] = (mididata->divisions) & 0xff;
// write the midi header
midiptr = *mid;
memcpy(midiptr,midihdr,sizeof(midihdr));
midiptr += sizeof(midihdr);
// write the tracks
for (i=0;i<MIDI_TRACKS;i++)
{
if (mididata->track[i].len)
{
memcpy(midiptr,trackhdr,sizeof(trackhdr)); // header
midiptr += sizeof(trackhdr);
TWriteLength(&midiptr,mididata->track[i].len); // track length
// data
memcpy(midiptr,mididata->track[i].data,mididata->track[i].len);
midiptr += mididata->track[i].len;
}
}
// return length information
*midlen = midiptr - *mid;
return 0;
}
#ifdef STANDALONE /* this code unused by BOOM provided for future portability */
/* it also provides a MUS to MID file converter*/
// proff: I moved this down, because I need MIDItoMidi
//
// main()
//
// Main routine that will convert a globbed set of MUS files to the
// correspondingly named MID files using mmus2mid(). Only compiled
// if the STANDALONE symbol is defined.
//
// Passed the command line arguments, returns 0 if successful
//
int main(int argc,char **argv)
{
FILE *musst,*midst;
char musfile[FILENAME_MAX],midfile[FILENAME_MAX];
MUSheader MUSh;
UBYTE *mus,*mid;
static MIDI mididata;
int err,midlen;
char *p,*q;
int i;
if (argc<2)
{
//jff 8/3/98 use logical output routine
lprintf(LO_INFO,"Usage: MMUS2MID musfile[.MUS]\n");
lprintf(LO_INFO,"writes musfile.MID as output\n");
lprintf(LO_INFO,"musfile may contain wildcards\n");
exit(1);
}
for (i=1;i<argc;i++)
{
strcpy(musfile,argv[i]);
p = strrchr(musfile,'.');
q = strrchr(musfile,'\\');
if (p && (!q || q<p)) *p='\0';
strcpy(midfile,musfile);
strcat(musfile,".MUS");
strcat(midfile,".MID");
musst = fopen(musfile,"rb");
if (musst)
{
fread(&MUSh,sizeof(MUSheader),1,musst);
mus = malloc(MUSh.ScoreLength+MUSh.ScoreStart);
if (mus)
{
fseek(musst,0,SEEK_SET);
if (!fread(mus,MUSh.ScoreLength+MUSh.ScoreStart,1,musst))
{
//jff 8/3/98 use logical output routine
lprintf(LO_FATAL,"Error reading MUS file\n");
free(mus);
exit(1);
}
fclose(musst);
}
else
{
//jff 8/3/98 use logical output routine
lprintf(LO_FATAL,"Out of memory\n");
free(mus);
exit(1);
}
err = mmus2mid(mus,&mididata,89,1);
if (err)
{
//jff 8/3/98 use logical output routine
lprintf(LO_FATAL,"Error converting MUS file to MIDI: %d\n",err);
exit(1);
}
free(mus);
MIDIToMidi(&mididata,&mid,&midlen);
midst = fopen(midfile,"wb");
if (midst)
{
if (!fwrite(mid,midlen,1,midst))
{
//jff 8/3/98 use logical output routine
lprintf(LO_FATAL,"Error writing MIDI file\n");
FreeTracks(&mididata);
free(mid);
exit(1);
}
fclose(midst);
}
else
{
//jff 8/3/98 use logical output routine
lprintf(LO_FATAL,"Can't open MIDI file for output: %s\n", midfile);
FreeTracks(&mididata);
free(mid);
exit(1);
}
}
else
{
//jff 8/3/98 use logical output routine
lprintf(LO_FATAL,"Can't open MUS file for input: %s\n", midfile);
exit(1);
}
//jff 8/3/98 use logical output routine
lprintf(LO_CONFIRM,"MUS file %s converted to MIDI file %s\n",musfile,midfile);
FreeTracks(&mididata);
free(mid);
}
exit(0);
}
#endif

View File

@@ -0,0 +1,76 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* mmus2mid.c supports conversion of MUS format music in memory
* to MIDI format 1 music in memory.
*/
#if !defined( MMUS2MID_H )
#define MMUS2MID_H
// error codes
typedef enum
{
MUSDATACOR, // MUS data corrupt
TOOMCHAN, // Too many channels
MEMALLOC, // Memory allocation error
MUSDATAMT, // MUS file empty
BADMUSCTL, // MUS event 5 or 7 found
BADSYSEVT, // MUS system event not in 10-14 range
BADCTLCHG, // MUS control change larger than 9
TRACKOVF, // MIDI track exceeds allocation
BADMIDHDR, // bad midi header detected
} error_code_t;
// some names for integers of various sizes, all unsigned
typedef unsigned char UBYTE; // a one-byte int
typedef unsigned short UWORD; // a two-byte int
// proff: changed from unsigned int to unsigned long to avoid warning
typedef unsigned long ULONG; // a four-byte int (assumes int 4 bytes)
#ifndef MSDOS /* proff: This is from allegro.h */
#define MIDI_TRACKS 32
typedef struct MIDI /* a midi file */
{
int divisions; /* number of ticks per quarter note */
struct {
unsigned char *data; /* MIDI message stream */
int len; /* length of the track data */
} track[MIDI_TRACKS];
} MIDI;
#endif /* !MSDOS */
extern int mmus2mid(const UBYTE *mus,MIDI *mid, UWORD division, int nocomp);
extern void free_mididata(MIDI *mid);
extern int MIDIToMidi(MIDI *mididata,UBYTE **mid,int *midlen);
extern int MidiToMIDI(UBYTE *mid,MIDI *mididata);
#endif

View File

@@ -0,0 +1,467 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Ceiling aninmation (lowering, crushing, raising)
*
*-----------------------------------------------------------------------------*/
#include "doomstat.h"
#include "r_main.h"
#include "p_spec.h"
#include "p_tick.h"
#include "s_sound.h"
#include "sounds.h"
// the list of ceilings moving currently, including crushers
ceilinglist_t *activeceilings;
/////////////////////////////////////////////////////////////////
//
// Ceiling action routine and linedef type handler
//
/////////////////////////////////////////////////////////////////
//
// T_MoveCeiling
//
// Action routine that moves ceilings. Called once per tick.
//
// Passed a ceiling_t structure that contains all the info about the move.
// see P_SPEC.H for fields. No return.
//
// jff 02/08/98 all cases with labels beginning with gen added to support
// generalized line type behaviors.
//
void T_MoveCeiling (ceiling_t* ceiling)
{
result_e res;
switch(ceiling->direction)
{
case 0:
// If ceiling in stasis, do nothing
break;
case 1:
// Ceiling is moving up
res = T_MovePlane
(
ceiling->sector,
ceiling->speed,
ceiling->topheight,
false,
1,
ceiling->direction
);
// if not a silent crusher, make moving sound
if (!(leveltime&7))
{
switch(ceiling->type)
{
case silentCrushAndRaise:
case genSilentCrusher:
break;
default:
S_StartSound((mobj_t *)&ceiling->sector->soundorg,sfx_stnmov);
break;
}
}
// handle reaching destination height
if (res == pastdest)
{
switch(ceiling->type)
{
// plain movers are just removed
case raiseToHighest:
case genCeiling:
P_RemoveActiveCeiling(ceiling);
break;
// movers with texture change, change the texture then get removed
case genCeilingChgT:
case genCeilingChg0:
ceiling->sector->special = ceiling->newspecial;
//jff 3/14/98 transfer old special field as well
ceiling->sector->oldspecial = ceiling->oldspecial;
case genCeilingChg:
ceiling->sector->ceilingpic = ceiling->texture;
P_RemoveActiveCeiling(ceiling);
break;
// crushers reverse direction at the top
case silentCrushAndRaise:
S_StartSound((mobj_t *)&ceiling->sector->soundorg,sfx_pstop);
case genSilentCrusher:
case genCrusher:
case fastCrushAndRaise:
case crushAndRaise:
ceiling->direction = -1;
break;
default:
break;
}
}
break;
case -1:
// Ceiling moving down
res = T_MovePlane
(
ceiling->sector,
ceiling->speed,
ceiling->bottomheight,
ceiling->crush,
1,
ceiling->direction
);
// if not silent crusher type make moving sound
if (!(leveltime&7))
{
switch(ceiling->type)
{
case silentCrushAndRaise:
case genSilentCrusher:
break;
default:
S_StartSound((mobj_t *)&ceiling->sector->soundorg,sfx_stnmov);
}
}
// handle reaching destination height
if (res == pastdest)
{
switch(ceiling->type)
{
// 02/09/98 jff change slow crushers' speed back to normal
// start back up
case genSilentCrusher:
case genCrusher:
if (ceiling->oldspeed<CEILSPEED*3)
ceiling->speed = ceiling->oldspeed;
ceiling->direction = 1; //jff 2/22/98 make it go back up!
break;
// make platform stop at bottom of all crusher strokes
// except generalized ones, reset speed, start back up
case silentCrushAndRaise:
S_StartSound((mobj_t *)&ceiling->sector->soundorg,sfx_pstop);
case crushAndRaise:
ceiling->speed = CEILSPEED;
case fastCrushAndRaise:
ceiling->direction = 1;
break;
// in the case of ceiling mover/changer, change the texture
// then remove the active ceiling
case genCeilingChgT:
case genCeilingChg0:
ceiling->sector->special = ceiling->newspecial;
//jff add to fix bug in special transfers from changes
ceiling->sector->oldspecial = ceiling->oldspecial;
case genCeilingChg:
ceiling->sector->ceilingpic = ceiling->texture;
P_RemoveActiveCeiling(ceiling);
break;
// all other case, just remove the active ceiling
case lowerAndCrush:
case lowerToFloor:
case lowerToLowest:
case lowerToMaxFloor:
case genCeiling:
P_RemoveActiveCeiling(ceiling);
break;
default:
break;
}
}
else // ( res != pastdest )
{
// handle the crusher encountering an obstacle
if (res == crushed)
{
switch(ceiling->type)
{
//jff 02/08/98 slow down slow crushers on obstacle
case genCrusher:
case genSilentCrusher:
if (ceiling->oldspeed < CEILSPEED*3)
ceiling->speed = CEILSPEED / 8;
break;
case silentCrushAndRaise:
case crushAndRaise:
case lowerAndCrush:
ceiling->speed = CEILSPEED / 8;
break;
default:
break;
}
}
}
break;
}
}
//
// EV_DoCeiling
//
// Move a ceiling up/down or start a crusher
//
// Passed the linedef activating the function and the type of function desired
// returns true if a thinker started
//
int EV_DoCeiling
( line_t* line,
ceiling_e type )
{
int secnum;
int rtn;
sector_t* sec;
ceiling_t* ceiling;
secnum = -1;
rtn = 0;
// Reactivate in-stasis ceilings...for certain types.
// This restarts a crusher after it has been stopped
switch(type)
{
case fastCrushAndRaise:
case silentCrushAndRaise:
case crushAndRaise:
//jff 4/5/98 return if activated
rtn = P_ActivateInStasisCeiling(line);
default:
break;
}
// affects all sectors with the same tag as the linedef
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
{
sec = &sectors[secnum];
// if ceiling already moving, don't start a second function on it
if (P_SectorActive(ceiling_special,sec)) //jff 2/22/98
continue;
// create a new ceiling thinker
rtn = 1;
ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0);
memset(ceiling, 0, sizeof(*ceiling));
P_AddThinker (&ceiling->thinker);
sec->ceilingdata = ceiling; //jff 2/22/98
ceiling->thinker.function = T_MoveCeiling;
ceiling->sector = sec;
ceiling->crush = false;
// setup ceiling structure according to type of function
switch(type)
{
case fastCrushAndRaise:
ceiling->crush = true;
ceiling->topheight = sec->ceilingheight;
ceiling->bottomheight = sec->floorheight + (8*FRACUNIT);
ceiling->direction = -1;
ceiling->speed = CEILSPEED * 2;
break;
case silentCrushAndRaise:
case crushAndRaise:
ceiling->crush = true;
ceiling->topheight = sec->ceilingheight;
case lowerAndCrush:
case lowerToFloor:
ceiling->bottomheight = sec->floorheight;
if (type != lowerToFloor)
ceiling->bottomheight += 8*FRACUNIT;
ceiling->direction = -1;
ceiling->speed = CEILSPEED;
break;
case raiseToHighest:
ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
ceiling->direction = 1;
ceiling->speed = CEILSPEED;
break;
case lowerToLowest:
ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec);
ceiling->direction = -1;
ceiling->speed = CEILSPEED;
break;
case lowerToMaxFloor:
ceiling->bottomheight = P_FindHighestFloorSurrounding(sec);
ceiling->direction = -1;
ceiling->speed = CEILSPEED;
break;
default:
break;
}
// add the ceiling to the active list
ceiling->tag = sec->tag;
ceiling->type = type;
P_AddActiveCeiling(ceiling);
}
return rtn;
}
//////////////////////////////////////////////////////////////////////
//
// Active ceiling list primitives
//
/////////////////////////////////////////////////////////////////////
// jff 2/22/98 - modified Lee's plat code to work for ceilings
//
// The following were all rewritten by Lee Killough
// to use the new structure which places no limits
// on active ceilings. It also avoids spending as much
// time searching for active ceilings. Previously a
// fixed-size array was used, with NULL indicating
// empty entries, while now a doubly-linked list
// is used.
//
// P_ActivateInStasisCeiling()
//
// Reactivates all stopped crushers with the right tag
//
// Passed the line reactivating the crusher
// Returns true if a ceiling reactivated
//
//jff 4/5/98 return if activated
int P_ActivateInStasisCeiling(line_t *line)
{
ceilinglist_t *cl;
int rtn=0;
for (cl=activeceilings; cl; cl=cl->next)
{
ceiling_t *ceiling = cl->ceiling;
if (ceiling->tag == line->tag && ceiling->direction == 0)
{
ceiling->direction = ceiling->olddirection;
ceiling->thinker.function = T_MoveCeiling;
//jff 4/5/98 return if activated
rtn=1;
}
}
return rtn;
}
//
// EV_CeilingCrushStop()
//
// Stops all active ceilings with the right tag
//
// Passed the linedef stopping the ceilings
// Returns true if a ceiling put in stasis
//
int EV_CeilingCrushStop(line_t* line)
{
int rtn=0;
ceilinglist_t *cl;
for (cl=activeceilings; cl; cl=cl->next)
{
ceiling_t *ceiling = cl->ceiling;
if (ceiling->direction != 0 && ceiling->tag == line->tag)
{
ceiling->olddirection = ceiling->direction;
ceiling->direction = 0;
ceiling->thinker.function = NULL;
rtn=1;
}
}
return rtn;
}
//
// P_AddActiveCeiling()
//
// Adds a ceiling to the head of the list of active ceilings
//
// Passed the ceiling motion structure
// Returns nothing
//
void P_AddActiveCeiling(ceiling_t* ceiling)
{
ceilinglist_t *list = malloc(sizeof *list);
list->ceiling = ceiling;
ceiling->list = list;
if ((list->next = activeceilings))
list->next->prev = &list->next;
list->prev = &activeceilings;
activeceilings = list;
}
//
// P_RemoveActiveCeiling()
//
// Removes a ceiling from the list of active ceilings
//
// Passed the ceiling motion structure
// Returns nothing
//
void P_RemoveActiveCeiling(ceiling_t* ceiling)
{
ceilinglist_t *list = ceiling->list;
ceiling->sector->ceilingdata = NULL; //jff 2/22/98
P_RemoveThinker(&ceiling->thinker);
if ((*list->prev = list->next))
list->next->prev = list->prev;
free(list);
}
//
// P_RemoveAllActiveCeilings()
//
// Removes all ceilings from the active ceiling list
//
// Passed nothing, returns nothing
//
void P_RemoveAllActiveCeilings(void)
{
while (activeceilings)
{
ceilinglist_t *next = activeceilings->next;
free(activeceilings);
activeceilings = next;
}
}

View File

@@ -0,0 +1,100 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h> /* exit(), atexit() */
#include "p_checksum.h"
#include "md5.h"
#include "doomstat.h" /* players{,ingame} */
#include "lprintf.h"
/* forward decls */
static void p_checksum_cleanup(void);
void checksum_gamestate(int tic);
/* vars */
static void p_checksum_nop(int tic){} /* do nothing */
void (*P_Checksum)(int) = p_checksum_nop;
/*
* P_RecordChecksum
* sets up the file and function pointers to write out checksum data
*/
static FILE *outfile = NULL;
static struct MD5Context md5global;
void P_RecordChecksum(const char *file) {
size_t fnsize;
fnsize = strlen(file);
/* special case: write to stdout */
if(0 == strncmp("-",file,MIN(1,fnsize)))
outfile = stdout;
else {
outfile = fopen(file,"wb");
if(NULL == outfile) {
I_Error("cannot open %s for writing checksum:\n%s\n",
file, strerror(errno));
}
atexit(p_checksum_cleanup);
}
MD5Init(&md5global);
P_Checksum = checksum_gamestate;
}
void P_ChecksumFinal(void) {
int i;
unsigned char digest[16];
if (!outfile)
return;
MD5Final(digest, &md5global);
fprintf(outfile, "final: ");
for (i=0; i<16; i++)
fprintf(outfile,"%x", digest[i]);
fprintf(outfile, "\n");
MD5Init(&md5global);
}
static void p_checksum_cleanup(void) {
if (outfile && (outfile != stdout))
fclose(outfile);
}
/*
* runs on each tic when recording checksums
*/
void checksum_gamestate(int tic) {
int i;
struct MD5Context md5ctx;
unsigned char digest[16];
char buffer[2048];
fprintf(outfile,"%6d, ", tic);
/* based on "ArchivePlayers" */
MD5Init(&md5ctx);
for (i=0 ; i<MAXPLAYERS ; i++) {
if (!playeringame[i]) continue;
#ifdef HAVE_SNPRINTF
snprintf (buffer, sizeof(buffer), "%d", players[i].health);
#else
sprintf (buffer, "%d", players[i].health);
#endif
buffer[sizeof(buffer)-1] = 0;
MD5Update(&md5ctx, (md5byte const *)&buffer, strlen(buffer));
}
MD5Final(digest, &md5ctx);
for (i=0; i<16; i++) {
MD5Update(&md5global, (md5byte const *)&digest[i], sizeof(digest[i]));
fprintf(outfile,"%x", digest[i]);
}
fprintf(outfile,"\n");
}

View File

@@ -0,0 +1,4 @@
extern void (*P_Checksum)(int);
extern void P_ChecksumFinal(void);
void P_RecordChecksum(const char *file);
//void P_VerifyChecksum(const char *file);

View File

@@ -0,0 +1,711 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Door animation code (opening/closing)
*
*-----------------------------------------------------------------------------*/
#include "doomstat.h"
#include "p_spec.h"
#include "p_tick.h"
#include "s_sound.h"
#include "sounds.h"
#include "r_main.h"
#include "dstrings.h"
#include "d_deh.h" // Ty 03/27/98 - externalized
#include "lprintf.h"
///////////////////////////////////////////////////////////////
//
// Door action routines, called once per tick
//
///////////////////////////////////////////////////////////////
//
// T_VerticalDoor
//
// Passed a door structure containing all info about the door.
// See P_SPEC.H for fields.
// Returns nothing.
//
// jff 02/08/98 all cases with labels beginning with gen added to support
// generalized line type behaviors.
void T_VerticalDoor (vldoor_t* door)
{
result_e res;
// Is the door waiting, going up, or going down?
switch(door->direction)
{
case 0:
// Door is waiting
if (!--door->topcountdown) // downcount and check
{
switch(door->type)
{
case blazeRaise:
case genBlazeRaise:
door->direction = -1; // time to go back down
S_StartSound((mobj_t *)&door->sector->soundorg,sfx_bdcls);
break;
case normal:
case genRaise:
door->direction = -1; // time to go back down
S_StartSound((mobj_t *)&door->sector->soundorg,sfx_dorcls);
break;
case close30ThenOpen:
case genCdO:
door->direction = 1; // time to go back up
S_StartSound((mobj_t *)&door->sector->soundorg,sfx_doropn);
break;
case genBlazeCdO:
door->direction = 1; // time to go back up
S_StartSound((mobj_t *)&door->sector->soundorg,sfx_bdopn);
break;
default:
break;
}
}
break;
case 2:
// Special case for sector type door that opens in 5 mins
if (!--door->topcountdown) // 5 minutes up?
{
switch(door->type)
{
case raiseIn5Mins:
door->direction = 1; // time to raise then
door->type = normal; // door acts just like normal 1 DR door now
S_StartSound((mobj_t *)&door->sector->soundorg,sfx_doropn);
break;
default:
break;
}
}
break;
case -1:
// Door is moving down
res = T_MovePlane
(
door->sector,
door->speed,
door->sector->floorheight,
false,
1,
door->direction
);
/* killough 10/98: implement gradual lighting effects */
// e6y: "Tagged doors don't trigger special lighting" handled wrong
// http://sourceforge.net/tracker/index.php?func=detail&aid=1411400&group_id=148658&atid=772943
// Old code: if (door->lighttag && door->topheight - door->sector->floorheight)
if (door->lighttag && door->topheight - door->sector->floorheight && compatibility_level >= mbf_compatibility)
EV_LightTurnOnPartway(door->line,
FixedDiv(door->sector->ceilingheight -
door->sector->floorheight,
door->topheight -
door->sector->floorheight));
// handle door reaching bottom
if (res == pastdest)
{
switch(door->type)
{
// regular open and close doors are all done, remove them
case blazeRaise:
case blazeClose:
case genBlazeRaise:
case genBlazeClose:
door->sector->ceilingdata = NULL; //jff 2/22/98
P_RemoveThinker (&door->thinker); // unlink and free
// killough 4/15/98: remove double-closing sound of blazing doors
if (comp[comp_blazing])
S_StartSound((mobj_t *)&door->sector->soundorg,sfx_bdcls);
break;
case normal:
case close:
case genRaise:
case genClose:
door->sector->ceilingdata = NULL; //jff 2/22/98
P_RemoveThinker (&door->thinker); // unlink and free
break;
// close then open doors start waiting
case close30ThenOpen:
door->direction = 0;
door->topcountdown = TICRATE*30;
break;
case genCdO:
case genBlazeCdO:
door->direction = 0;
door->topcountdown = door->topwait; // jff 5/8/98 insert delay
break;
default:
break;
}
// e6y: "Tagged doors don't trigger special lighting" handled wrong
// http://sourceforge.net/tracker/index.php?func=detail&aid=1411400&group_id=148658&atid=772943
if (door->lighttag && door->topheight - door->sector->floorheight && compatibility_level < mbf_compatibility)
EV_LightTurnOnPartway(door->line,0);
}
/* jff 1/31/98 turn lighting off in tagged sectors of manual doors
* killough 10/98: replaced with gradual lighting code
*/
else if (res == crushed) // handle door meeting obstruction on way down
{
switch(door->type)
{
case genClose:
case genBlazeClose:
case blazeClose:
case close: // Close types do not bounce, merely wait
break;
case blazeRaise:
case genBlazeRaise:
door->direction = 1;
if (!comp[comp_blazing]) {
S_StartSound((mobj_t *)&door->sector->soundorg,sfx_bdopn);
break;
}
default: // other types bounce off the obstruction
door->direction = 1;
S_StartSound((mobj_t *)&door->sector->soundorg,sfx_doropn);
break;
}
}
break;
case 1:
// Door is moving up
res = T_MovePlane
(
door->sector,
door->speed,
door->topheight,
false,
1,
door->direction
);
/* killough 10/98: implement gradual lighting effects */
// e6y: "Tagged doors don't trigger special lighting" handled wrong
// http://sourceforge.net/tracker/index.php?func=detail&aid=1411400&group_id=148658&atid=772943
// Old code: if (door->lighttag && door->topheight - door->sector->floorheight)
if (door->lighttag && door->topheight - door->sector->floorheight && compatibility_level >= mbf_compatibility)
EV_LightTurnOnPartway(door->line,
FixedDiv(door->sector->ceilingheight -
door->sector->floorheight,
door->topheight -
door->sector->floorheight));
// handle door reaching the top
if (res == pastdest)
{
switch(door->type)
{
case blazeRaise: // regular open/close doors start waiting
case normal:
case genRaise:
case genBlazeRaise:
door->direction = 0; // wait at top with delay
door->topcountdown = door->topwait;
break;
case close30ThenOpen: // close and close/open doors are done
case blazeOpen:
case open:
case genBlazeOpen:
case genOpen:
case genCdO:
case genBlazeCdO:
door->sector->ceilingdata = NULL; //jff 2/22/98
P_RemoveThinker (&door->thinker); // unlink and free
break;
default:
break;
}
/* jff 1/31/98 turn lighting on in tagged sectors of manual doors
* killough 10/98: replaced with gradual lighting code */
// e6y: "Tagged doors don't trigger special lighting" handled wrong
// http://sourceforge.net/tracker/index.php?func=detail&aid=1411400&group_id=148658&atid=772943
if (door->lighttag && door->topheight - door->sector->floorheight && compatibility_level < mbf_compatibility)
EV_LightTurnOnPartway(door->line,FRACUNIT);
}
break;
}
}
///////////////////////////////////////////////////////////////
//
// Door linedef handlers
//
///////////////////////////////////////////////////////////////
//
// EV_DoLockedDoor
//
// Handle opening a tagged locked door
//
// Passed the line activating the door, the type of door,
// and the thing that activated the line
// Returns true if a thinker created
//
int EV_DoLockedDoor
( line_t* line,
vldoor_e type,
mobj_t* thing )
{
player_t* p;
// only players can open locked doors
p = thing->player;
if (!p)
return 0;
// check type of linedef, and if key is possessed to open it
switch(line->special)
{
case 99: // Blue Lock
case 133:
if (!p->cards[it_bluecard] && !p->cards[it_blueskull])
{
p->message = s_PD_BLUEO; // Ty 03/27/98 - externalized
S_StartSound(p->mo,sfx_oof); // killough 3/20/98
return 0;
}
break;
case 134: // Red Lock
case 135:
if (!p->cards[it_redcard] && !p->cards[it_redskull])
{
p->message = s_PD_REDO; // Ty 03/27/98 - externalized
S_StartSound(p->mo,sfx_oof); // killough 3/20/98
return 0;
}
break;
case 136: // Yellow Lock
case 137:
if (!p->cards[it_yellowcard] && !p->cards[it_yellowskull])
{
p->message = s_PD_YELLOWO; // Ty 03/27/98 - externalized
S_StartSound(p->mo,sfx_oof); // killough 3/20/98
return 0;
}
break;
}
// got the key, so open the door
return EV_DoDoor(line,type);
}
//
// EV_DoDoor
//
// Handle opening a tagged door
//
// Passed the line activating the door and the type of door
// Returns true if a thinker created
//
int EV_DoDoor
( line_t* line,
vldoor_e type )
{
int secnum,rtn;
sector_t* sec;
vldoor_t* door;
secnum = -1;
rtn = 0;
// open all doors with the same tag as the activating line
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
{
sec = &sectors[secnum];
// if the ceiling already moving, don't start the door action
if (P_SectorActive(ceiling_special,sec)) //jff 2/22/98
continue;
// new door thinker
rtn = 1;
door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
memset(door, 0, sizeof(*door));
P_AddThinker (&door->thinker);
sec->ceilingdata = door; //jff 2/22/98
door->thinker.function = T_VerticalDoor;
door->sector = sec;
door->type = type;
door->topwait = VDOORWAIT;
door->speed = VDOORSPEED;
door->line = line; // jff 1/31/98 remember line that triggered us
door->lighttag = 0; /* killough 10/98: no light effects with tagged doors */
// setup door parameters according to type of door
switch(type)
{
case blazeClose:
door->topheight = P_FindLowestCeilingSurrounding(sec);
door->topheight -= 4*FRACUNIT;
door->direction = -1;
door->speed = VDOORSPEED * 4;
S_StartSound((mobj_t *)&door->sector->soundorg,sfx_bdcls);
break;
case close:
door->topheight = P_FindLowestCeilingSurrounding(sec);
door->topheight -= 4*FRACUNIT;
door->direction = -1;
S_StartSound((mobj_t *)&door->sector->soundorg,sfx_dorcls);
break;
case close30ThenOpen:
door->topheight = sec->ceilingheight;
door->direction = -1;
S_StartSound((mobj_t *)&door->sector->soundorg,sfx_dorcls);
break;
case blazeRaise:
case blazeOpen:
door->direction = 1;
door->topheight = P_FindLowestCeilingSurrounding(sec);
door->topheight -= 4*FRACUNIT;
door->speed = VDOORSPEED * 4;
if (door->topheight != sec->ceilingheight)
S_StartSound((mobj_t *)&door->sector->soundorg,sfx_bdopn);
break;
case normal:
case open:
door->direction = 1;
door->topheight = P_FindLowestCeilingSurrounding(sec);
door->topheight -= 4*FRACUNIT;
if (door->topheight != sec->ceilingheight)
S_StartSound((mobj_t *)&door->sector->soundorg,sfx_doropn);
break;
default:
break;
}
}
return rtn;
}
//
// EV_VerticalDoor
//
// Handle opening a door manually, no tag value
//
// Passed the line activating the door and the thing activating it
// Returns true if a thinker created
//
// jff 2/12/98 added int return value, fixed all returns
//
int EV_VerticalDoor
( line_t* line,
mobj_t* thing )
{
player_t* player;
int secnum;
sector_t* sec;
vldoor_t* door;
// Check for locks
player = thing->player;
switch(line->special)
{
case 26: // Blue Lock
case 32:
if ( !player )
return 0;
if (!player->cards[it_bluecard] && !player->cards[it_blueskull])
{
player->message = s_PD_BLUEK; // Ty 03/27/98 - externalized
S_StartSound(player->mo,sfx_oof); // killough 3/20/98
return 0;
}
break;
case 27: // Yellow Lock
case 34:
if ( !player )
return 0;
if (!player->cards[it_yellowcard] && !player->cards[it_yellowskull])
{
player->message = s_PD_YELLOWK; // Ty 03/27/98 - externalized
S_StartSound(player->mo,sfx_oof); // killough 3/20/98
return 0;
}
break;
case 28: // Red Lock
case 33:
if ( !player )
return 0;
if (!player->cards[it_redcard] && !player->cards[it_redskull])
{
player->message = s_PD_REDK; // Ty 03/27/98 - externalized
S_StartSound(player->mo,sfx_oof); // killough 3/20/98
return 0;
}
break;
default:
break;
}
// if the wrong side of door is pushed, give oof sound
if (line->sidenum[1]==NO_INDEX) // killough
{
S_StartSound(player->mo,sfx_oof); // killough 3/20/98
return 0;
}
// get the sector on the second side of activating linedef
sec = sides[line->sidenum[1]].sector;
secnum = sec-sectors;
/* if door already has a thinker, use it
* cph 2001/04/05 -
* Ok, this is a disaster area. We're assuming that sec->ceilingdata
* is a vldoor_t! What if this door is controlled by both DR lines
* and by switches? I don't know how to fix that.
* Secondly, original Doom didn't distinguish floor/lighting/ceiling
* actions, so we need to do the same in demo compatibility mode.
*/
door = sec->ceilingdata;
if (demo_compatibility) {
if (!door) door = sec->floordata;
if (!door) door = sec->lightingdata;
}
/* If this is a repeatable line, and the door is already moving, then we can just reverse the current action. Note that in prboom 2.3.0 I erroneously removed the if-this-is-repeatable check, hence the prboom_4_compatibility clause below (foolishly assumed that already moving implies repeatable - but it could be moving due to another switch, e.g. lv19-509) */
if (door &&
((compatibility_level == prboom_4_compatibility) ||
(line->special == 1) || (line->special == 117) || (line->special == 26) || (line->special == 27) || (line->special == 28)
)
) {
/* For old demos we have to emulate the old buggy behavior and
* mess up non-T_VerticalDoor actions.
*/
if (compatibility_level < prboom_4_compatibility ||
door->thinker.function == T_VerticalDoor) {
/* cph - we are writing outval to door->direction iff it is non-zero */
signed int outval = 0;
/* An already moving repeatable door which is being re-pressed, or a
* monster is trying to open a closing door - so change direction
* DEMOSYNC: we only read door->direction now if it really is a door.
*/
if (door->thinker.function == T_VerticalDoor && door->direction == -1) {
outval = 1; /* go back up */
} else if (player) {
outval = -1; /* go back down */
}
/* Write this to the thinker. In demo compatibility mode, we might be
* overwriting a field of a non-vldoor_t thinker - we need to add any
* other thinker types here if any demos depend on specific fields
* being corrupted by this.
*/
if (outval) {
if (door->thinker.function == T_VerticalDoor) {
door->direction = outval;
} else if (door->thinker.function == T_PlatRaise) {
plat_t* p = (plat_t*)door;
p->wait = outval;
} else {
lprintf(LO_DEBUG, "EV_VerticalDoor: unknown thinker.function in thinker corruption emulation");
}
return 1;
}
}
/* Either we're in prboom >=v2.3 and it's not a door, or it's a door but
* we're a monster and don't want to shut it; exit with no action.
*/
return 0;
}
// emit proper sound
switch(line->special)
{
case 117: // blazing door raise
case 118: // blazing door open
S_StartSound((mobj_t *)&sec->soundorg,sfx_bdopn);
break;
default: // normal or locked door sound
S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn);
break;
}
// new door thinker
door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
memset(door, 0, sizeof(*door));
P_AddThinker (&door->thinker);
sec->ceilingdata = door; //jff 2/22/98
door->thinker.function = T_VerticalDoor;
door->sector = sec;
door->direction = 1;
door->speed = VDOORSPEED;
door->topwait = VDOORWAIT;
door->line = line; // jff 1/31/98 remember line that triggered us
/* killough 10/98: use gradual lighting changes if nonzero tag given */
door->lighttag = comp[comp_doorlight] ? 0 : line->tag;
// set the type of door from the activating linedef type
switch(line->special)
{
case 1:
case 26:
case 27:
case 28:
door->type = normal;
break;
case 31:
case 32:
case 33:
case 34:
door->type = open;
line->special = 0;
break;
case 117: // blazing door raise
door->type = blazeRaise;
door->speed = VDOORSPEED*4;
break;
case 118: // blazing door open
door->type = blazeOpen;
line->special = 0;
door->speed = VDOORSPEED*4;
break;
default:
door->lighttag = 0; // killough 10/98
break;
}
// find the top and bottom of the movement range
door->topheight = P_FindLowestCeilingSurrounding(sec);
door->topheight -= 4*FRACUNIT;
return 1;
}
///////////////////////////////////////////////////////////////
//
// Sector type door spawners
//
///////////////////////////////////////////////////////////////
//
// P_SpawnDoorCloseIn30()
//
// Spawn a door that closes after 30 seconds (called at level init)
//
// Passed the sector of the door, whose type specified the door action
// Returns nothing
//
void P_SpawnDoorCloseIn30 (sector_t* sec)
{
vldoor_t* door;
door = Z_Malloc ( sizeof(*door), PU_LEVSPEC, 0);
memset(door, 0, sizeof(*door));
P_AddThinker (&door->thinker);
sec->ceilingdata = door; //jff 2/22/98
sec->special = 0;
door->thinker.function = T_VerticalDoor;
door->sector = sec;
door->direction = 0;
door->type = normal;
door->speed = VDOORSPEED;
door->topcountdown = 30 * 35;
door->line = NULL; // jff 1/31/98 remember line that triggered us
door->lighttag = 0; /* killough 10/98: no lighting changes */
}
//
// P_SpawnDoorRaiseIn5Mins()
//
// Spawn a door that opens after 5 minutes (called at level init)
//
// Passed the sector of the door, whose type specified the door action
// Returns nothing
//
void P_SpawnDoorRaiseIn5Mins
( sector_t* sec,
int secnum )
{
vldoor_t* door;
door = Z_Malloc ( sizeof(*door), PU_LEVSPEC, 0);
memset(door, 0, sizeof(*door));
P_AddThinker (&door->thinker);
sec->ceilingdata = door; //jff 2/22/98
sec->special = 0;
door->thinker.function = T_VerticalDoor;
door->sector = sec;
door->direction = 2;
door->type = raiseIn5Mins;
door->speed = VDOORSPEED;
door->topheight = P_FindLowestCeilingSurrounding(sec);
door->topheight -= 4*FRACUNIT;
door->topwait = VDOORWAIT;
door->topcountdown = 5 * 60 * 35;
door->line = NULL; // jff 1/31/98 remember line that triggered us
door->lighttag = 0; /* killough 10/98: no lighting changes */
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,118 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Enemy thinking, AI.
* Action Pointer Functions
* that are associated with states/frames.
*
*-----------------------------------------------------------------------------*/
#ifndef __P_ENEMY__
#define __P_ENEMY__
#include "p_mobj.h"
void P_NoiseAlert (mobj_t *target, mobj_t *emmiter);
void P_SpawnBrainTargets(void); /* killough 3/26/98: spawn icon landings */
extern struct brain_s { /* killough 3/26/98: global state of boss brain */
int easy, targeton;
} brain;
// ********************************************************************
// Function addresses or Code Pointers
// ********************************************************************
// These function addresses are the Code Pointers that have been
// modified for years by Dehacked enthusiasts. The new BEX format
// allows more extensive changes (see d_deh.c)
// Doesn't work with g++, needs actionf_p1
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();
void A_Die();
void A_Detonate(); /* killough 8/9/98: detonate a bomb or other device */
void A_Mushroom(); /* killough 10/98: mushroom effect */
void A_Spawn(); // killough 11/98
void A_Turn(); // killough 11/98
void A_Face(); // killough 11/98
void A_Scratch(); // killough 11/98
void A_PlaySound(); // killough 11/98
void A_RandomJump(); // killough 11/98
void A_LineEffect(); // killough 11/98
#endif // __P_ENEMY__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,917 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Handling interactions (i.e., collisions).
*
*-----------------------------------------------------------------------------*/
#include "doomstat.h"
#include "dstrings.h"
#include "m_random.h"
#include "am_map.h"
#include "r_main.h"
#include "s_sound.h"
#include "sounds.h"
#include "d_deh.h" // Ty 03/22/98 - externalized strings
#include "p_tick.h"
#include "lprintf.h"
#include "p_inter.h"
#include "p_enemy.h"
#ifdef __GNUG__
#pragma implementation "p_inter.h"
#endif
#include "p_inter.h"
#define BONUSADD 6
// Ty 03/07/98 - add deh externals
// Maximums and such were hardcoded values. Need to externalize those for
// dehacked support (and future flexibility). Most var names came from the key
// strings used in dehacked.
int initial_health = 100;
int initial_bullets = 50;
int maxhealth = 100; // was MAXHEALTH as a #define, used only in this module
int max_armor = 200;
int green_armor_class = 1; // these are involved with armortype below
int blue_armor_class = 2;
int max_soul = 200;
int soul_health = 100;
int mega_health = 200;
int god_health = 100; // these are used in cheats (see st_stuff.c)
int idfa_armor = 200;
int idfa_armor_class = 2;
// not actually used due to pairing of cheat_k and cheat_fa
int idkfa_armor = 200;
int idkfa_armor_class = 2;
int bfgcells = 40; // used in p_pspr.c
int monsters_infight = 0; // e6y: Dehacked support - monsters infight
// Ty 03/07/98 - end deh externals
// a weapon is found with two clip loads,
// a big item has five clip loads
int maxammo[NUMAMMO] = {200, 50, 300, 50};
int clipammo[NUMAMMO] = { 10, 4, 20, 1};
//
// GET STUFF
//
//
// P_GiveAmmo
// Num is the number of clip loads,
// not the individual count (0= 1/2 clip).
// Returns false if the ammo can't be picked up at all
//
static boolean P_GiveAmmo(player_t *player, ammotype_t ammo, int num)
{
int oldammo;
if (ammo == am_noammo)
return false;
#ifdef RANGECHECK
if (ammo < 0 || ammo > NUMAMMO)
I_Error ("P_GiveAmmo: bad type %i", ammo);
#endif
if ( player->ammo[ammo] == player->maxammo[ammo] )
return false;
if (num)
num *= clipammo[ammo];
else
num = clipammo[ammo]/2;
// give double ammo in trainer mode, you'll need in nightmare
if (gameskill == sk_baby || gameskill == sk_nightmare)
num <<= 1;
oldammo = player->ammo[ammo];
player->ammo[ammo] += num;
if (player->ammo[ammo] > player->maxammo[ammo])
player->ammo[ammo] = player->maxammo[ammo];
// If non zero ammo, don't change up weapons, player was lower on purpose.
if (oldammo)
return true;
// We were down to zero, so select a new weapon.
// Preferences are not user selectable.
switch (ammo)
{
case am_clip:
if (player->readyweapon == wp_fist) {
if (player->weaponowned[wp_chaingun])
player->pendingweapon = wp_chaingun;
else
player->pendingweapon = wp_pistol;
}
break;
case am_shell:
if (player->readyweapon == wp_fist || player->readyweapon == wp_pistol)
if (player->weaponowned[wp_shotgun])
player->pendingweapon = wp_shotgun;
break;
case am_cell:
if (player->readyweapon == wp_fist || player->readyweapon == wp_pistol)
if (player->weaponowned[wp_plasma])
player->pendingweapon = wp_plasma;
break;
case am_misl:
if (player->readyweapon == wp_fist)
if (player->weaponowned[wp_missile])
player->pendingweapon = wp_missile;
default:
break;
}
return true;
}
//
// P_GiveWeapon
// The weapon name may have a MF_DROPPED flag ored in.
//
static boolean P_GiveWeapon(player_t *player, weapontype_t weapon, boolean dropped)
{
boolean gaveammo;
boolean gaveweapon;
if (netgame && deathmatch!=2 && !dropped)
{
// leave placed weapons forever on net games
if (player->weaponowned[weapon])
return false;
player->bonuscount += BONUSADD;
player->weaponowned[weapon] = true;
P_GiveAmmo(player, weaponinfo[weapon].ammo, deathmatch ? 5 : 2);
player->pendingweapon = weapon;
/* cph 20028/10 - for old-school DM addicts, allow old behavior
* where only consoleplayer's pickup sounds are heard */
// displayplayer, not consoleplayer, for viewing multiplayer demos
if (!comp[comp_sound] || player == &players[displayplayer])
S_StartSound (player->mo, sfx_wpnup|PICKUP_SOUND); // killough 4/25/98
return false;
}
if (weaponinfo[weapon].ammo != am_noammo)
{
// give one clip with a dropped weapon,
// two clips with a found weapon
gaveammo = P_GiveAmmo (player, weaponinfo[weapon].ammo, dropped ? 1 : 2);
}
else
gaveammo = false;
if (player->weaponowned[weapon])
gaveweapon = false;
else
{
gaveweapon = true;
player->weaponowned[weapon] = true;
player->pendingweapon = weapon;
}
return gaveweapon || gaveammo;
}
//
// P_GiveBody
// Returns false if the body isn't needed at all
//
static boolean P_GiveBody(player_t *player, int num)
{
if (player->health >= maxhealth)
return false; // Ty 03/09/98 externalized MAXHEALTH to maxhealth
player->health += num;
if (player->health > maxhealth)
player->health = maxhealth;
player->mo->health = player->health;
return true;
}
//
// P_GiveArmor
// Returns false if the armor is worse
// than the current armor.
//
static boolean P_GiveArmor(player_t *player, int armortype)
{
int hits = armortype*100;
if (player->armorpoints >= hits)
return false; // don't pick up
player->armortype = armortype;
player->armorpoints = hits;
return true;
}
//
// P_GiveCard
//
static void P_GiveCard(player_t *player, card_t card)
{
if (player->cards[card])
return;
player->bonuscount = BONUSADD;
player->cards[card] = 1;
}
//
// P_GivePower
//
// Rewritten by Lee Killough
//
boolean P_GivePower(player_t *player, int power)
{
static const int tics[NUMPOWERS] = {
INVULNTICS, 1 /* strength */, INVISTICS,
IRONTICS, 1 /* allmap */, INFRATICS,
};
switch (power)
{
case pw_invisibility:
player->mo->flags |= MF_SHADOW;
break;
case pw_allmap:
if (player->powers[pw_allmap])
return false;
break;
case pw_strength:
P_GiveBody(player,100);
break;
}
// Unless player has infinite duration cheat, set duration (killough)
if (player->powers[power] >= 0)
player->powers[power] = tics[power];
return true;
}
//
// P_TouchSpecialThing
//
void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher)
{
player_t *player;
int i;
int sound;
fixed_t delta = special->z - toucher->z;
if (delta > toucher->height || delta < -8*FRACUNIT)
return; // out of reach
sound = sfx_itemup;
player = toucher->player;
// Dead thing touching.
// Can happen with a sliding player corpse.
if (toucher->health <= 0)
return;
// Identify by sprite.
switch (special->sprite)
{
// armor
case SPR_ARM1:
if (!P_GiveArmor (player, green_armor_class))
return;
player->message = s_GOTARMOR; // Ty 03/22/98 - externalized
break;
case SPR_ARM2:
if (!P_GiveArmor (player, blue_armor_class))
return;
player->message = s_GOTMEGA; // Ty 03/22/98 - externalized
break;
// bonus items
case SPR_BON1:
player->health++; // can go over 100%
if (player->health > (maxhealth * 2))
player->health = (maxhealth * 2);
player->mo->health = player->health;
player->message = s_GOTHTHBONUS; // Ty 03/22/98 - externalized
break;
case SPR_BON2:
player->armorpoints++; // can go over 100%
if (player->armorpoints > max_armor)
player->armorpoints = max_armor;
if (!player->armortype)
player->armortype = green_armor_class;
player->message = s_GOTARMBONUS; // Ty 03/22/98 - externalized
break;
case SPR_SOUL:
player->health += soul_health;
if (player->health > max_soul)
player->health = max_soul;
player->mo->health = player->health;
player->message = s_GOTSUPER; // Ty 03/22/98 - externalized
sound = sfx_getpow;
break;
case SPR_MEGA:
if (gamemode != commercial)
return;
player->health = mega_health;
player->mo->health = player->health;
P_GiveArmor (player,blue_armor_class);
player->message = s_GOTMSPHERE; // Ty 03/22/98 - externalized
sound = sfx_getpow;
break;
// cards
// leave cards for everyone
case SPR_BKEY:
if (!player->cards[it_bluecard])
player->message = s_GOTBLUECARD; // Ty 03/22/98 - externalized
P_GiveCard (player, it_bluecard);
if (!netgame)
break;
return;
case SPR_YKEY:
if (!player->cards[it_yellowcard])
player->message = s_GOTYELWCARD; // Ty 03/22/98 - externalized
P_GiveCard (player, it_yellowcard);
if (!netgame)
break;
return;
case SPR_RKEY:
if (!player->cards[it_redcard])
player->message = s_GOTREDCARD; // Ty 03/22/98 - externalized
P_GiveCard (player, it_redcard);
if (!netgame)
break;
return;
case SPR_BSKU:
if (!player->cards[it_blueskull])
player->message = s_GOTBLUESKUL; // Ty 03/22/98 - externalized
P_GiveCard (player, it_blueskull);
if (!netgame)
break;
return;
case SPR_YSKU:
if (!player->cards[it_yellowskull])
player->message = s_GOTYELWSKUL; // Ty 03/22/98 - externalized
P_GiveCard (player, it_yellowskull);
if (!netgame)
break;
return;
case SPR_RSKU:
if (!player->cards[it_redskull])
player->message = s_GOTREDSKULL; // Ty 03/22/98 - externalized
P_GiveCard (player, it_redskull);
if (!netgame)
break;
return;
// medikits, heals
case SPR_STIM:
if (!P_GiveBody (player, 10))
return;
player->message = s_GOTSTIM; // Ty 03/22/98 - externalized
break;
case SPR_MEDI:
if (!P_GiveBody (player, 25))
return;
if (player->health < 50) // cph - 25 + the 25 just added, thanks to Quasar for reporting this bug
player->message = s_GOTMEDINEED; // Ty 03/22/98 - externalized
else
player->message = s_GOTMEDIKIT; // Ty 03/22/98 - externalized
break;
// power ups
case SPR_PINV:
if (!P_GivePower (player, pw_invulnerability))
return;
player->message = s_GOTINVUL; // Ty 03/22/98 - externalized
sound = sfx_getpow;
break;
case SPR_PSTR:
if (!P_GivePower (player, pw_strength))
return;
player->message = s_GOTBERSERK; // Ty 03/22/98 - externalized
if (player->readyweapon != wp_fist)
player->pendingweapon = wp_fist;
sound = sfx_getpow;
break;
case SPR_PINS:
if (!P_GivePower (player, pw_invisibility))
return;
player->message = s_GOTINVIS; // Ty 03/22/98 - externalized
sound = sfx_getpow;
break;
case SPR_SUIT:
if (!P_GivePower (player, pw_ironfeet))
return;
player->message = s_GOTSUIT; // Ty 03/22/98 - externalized
sound = sfx_getpow;
break;
case SPR_PMAP:
if (!P_GivePower (player, pw_allmap))
return;
player->message = s_GOTMAP; // Ty 03/22/98 - externalized
sound = sfx_getpow;
break;
case SPR_PVIS:
if (!P_GivePower (player, pw_infrared))
return;
player->message = s_GOTVISOR; // Ty 03/22/98 - externalized
sound = sfx_getpow;
break;
// ammo
case SPR_CLIP:
if (special->flags & MF_DROPPED)
{
if (!P_GiveAmmo (player,am_clip,0))
return;
}
else
{
if (!P_GiveAmmo (player,am_clip,1))
return;
}
player->message = s_GOTCLIP; // Ty 03/22/98 - externalized
break;
case SPR_AMMO:
if (!P_GiveAmmo (player, am_clip,5))
return;
player->message = s_GOTCLIPBOX; // Ty 03/22/98 - externalized
break;
case SPR_ROCK:
if (!P_GiveAmmo (player, am_misl,1))
return;
player->message = s_GOTROCKET; // Ty 03/22/98 - externalized
break;
case SPR_BROK:
if (!P_GiveAmmo (player, am_misl,5))
return;
player->message = s_GOTROCKBOX; // Ty 03/22/98 - externalized
break;
case SPR_CELL:
if (!P_GiveAmmo (player, am_cell,1))
return;
player->message = s_GOTCELL; // Ty 03/22/98 - externalized
break;
case SPR_CELP:
if (!P_GiveAmmo (player, am_cell,5))
return;
player->message = s_GOTCELLBOX; // Ty 03/22/98 - externalized
break;
case SPR_SHEL:
if (!P_GiveAmmo (player, am_shell,1))
return;
player->message = s_GOTSHELLS; // Ty 03/22/98 - externalized
break;
case SPR_SBOX:
if (!P_GiveAmmo (player, am_shell,5))
return;
player->message = s_GOTSHELLBOX; // Ty 03/22/98 - externalized
break;
case SPR_BPAK:
if (!player->backpack)
{
for (i=0 ; i<NUMAMMO ; i++)
player->maxammo[i] *= 2;
player->backpack = true;
}
for (i=0 ; i<NUMAMMO ; i++)
P_GiveAmmo (player, i, 1);
player->message = s_GOTBACKPACK; // Ty 03/22/98 - externalized
break;
// weapons
case SPR_BFUG:
if (!P_GiveWeapon (player, wp_bfg, false) )
return;
player->message = s_GOTBFG9000; // Ty 03/22/98 - externalized
sound = sfx_wpnup;
break;
case SPR_MGUN:
if (!P_GiveWeapon (player, wp_chaingun, (special->flags&MF_DROPPED)!=0) )
return;
player->message = s_GOTCHAINGUN; // Ty 03/22/98 - externalized
sound = sfx_wpnup;
break;
case SPR_CSAW:
if (!P_GiveWeapon (player, wp_chainsaw, false) )
return;
player->message = s_GOTCHAINSAW; // Ty 03/22/98 - externalized
sound = sfx_wpnup;
break;
case SPR_LAUN:
if (!P_GiveWeapon (player, wp_missile, false) )
return;
player->message = s_GOTLAUNCHER; // Ty 03/22/98 - externalized
sound = sfx_wpnup;
break;
case SPR_PLAS:
if (!P_GiveWeapon (player, wp_plasma, false) )
return;
player->message = s_GOTPLASMA; // Ty 03/22/98 - externalized
sound = sfx_wpnup;
break;
case SPR_SHOT:
if (!P_GiveWeapon (player, wp_shotgun, (special->flags&MF_DROPPED)!=0 ) )
return;
player->message = s_GOTSHOTGUN; // Ty 03/22/98 - externalized
sound = sfx_wpnup;
break;
case SPR_SGN2:
if (!P_GiveWeapon(player, wp_supershotgun, (special->flags&MF_DROPPED)!=0))
return;
player->message = s_GOTSHOTGUN2; // Ty 03/22/98 - externalized
sound = sfx_wpnup;
break;
default:
I_Error ("P_SpecialThing: Unknown gettable thing");
}
if (special->flags & MF_COUNTITEM)
player->itemcount++;
P_RemoveMobj (special);
player->bonuscount += BONUSADD;
/* cph 20028/10 - for old-school DM addicts, allow old behavior
* where only consoleplayer's pickup sounds are heard */
// displayplayer, not consoleplayer, for viewing multiplayer demos
if (!comp[comp_sound] || player == &players[displayplayer])
S_StartSound (player->mo, sound | PICKUP_SOUND); // killough 4/25/98
}
//
// KillMobj
//
// killough 11/98: make static
static void P_KillMobj(mobj_t *source, mobj_t *target)
{
mobjtype_t item;
mobj_t *mo;
target->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SKULLFLY);
if (target->type != MT_SKULL)
target->flags &= ~MF_NOGRAVITY;
target->flags |= MF_CORPSE|MF_DROPOFF;
target->height >>= 2;
if (!((target->flags ^ MF_COUNTKILL) & (MF_FRIEND | MF_COUNTKILL)))
totallive--;
if (source && source->player)
{
// count for intermission
if (target->flags & MF_COUNTKILL)
source->player->killcount++;
if (target->player)
source->player->frags[target->player-players]++;
}
else
if (target->flags & MF_COUNTKILL) { /* Add to kills tally */
if ((compatibility_level < lxdoom_1_compatibility) || !netgame) {
if (!netgame)
// count all monster deaths,
// even those caused by other monsters
players[0].killcount++;
} else
if (!deathmatch) {
// try and find a player to give the kill to, otherwise give the
// kill to a random player. this fixes the missing monsters bug
// in coop - rain
// CPhipps - not a bug as such, but certainly an inconsistency.
if (target->lastenemy && target->lastenemy->health > 0
&& target->lastenemy->player) // Fighting a player
target->lastenemy->player->killcount++;
else {
// cph - randomely choose a player in the game to be credited
// and do it uniformly between the active players
unsigned int activeplayers = 0, player, i;
for (player = 0; player<MAXPLAYERS; player++)
if (playeringame[player])
activeplayers++;
if (activeplayers) {
player = P_Random(pr_friends) % activeplayers;
for (i=0; i<MAXPLAYERS; i++)
if (playeringame[i])
if (!player--)
players[i].killcount++;
}
}
}
}
if (target->player)
{
// count environment kills against you
if (!source)
target->player->frags[target->player-players]++;
target->flags &= ~MF_SOLID;
target->player->playerstate = PST_DEAD;
P_DropWeapon (target->player);
if (target->player == &players[consoleplayer] && (automapmode & am_active))
AM_Stop(); // don't die in auto map; switch view prior to dying
}
if (target->health < -target->info->spawnhealth && target->info->xdeathstate)
P_SetMobjState (target, target->info->xdeathstate);
else
P_SetMobjState (target, target->info->deathstate);
target->tics -= P_Random(pr_killtics)&3;
if (target->tics < 1)
target->tics = 1;
// Drop stuff.
// This determines the kind of object spawned
// during the death frame of a thing.
switch (target->type)
{
case MT_WOLFSS:
case MT_POSSESSED:
item = MT_CLIP;
break;
case MT_SHOTGUY:
item = MT_SHOTGUN;
break;
case MT_CHAINGUY:
item = MT_CHAINGUN;
break;
default:
return;
}
mo = P_SpawnMobj (target->x,target->y,ONFLOORZ, item);
mo->flags |= MF_DROPPED; // special versions of items
}
//
// P_DamageMobj
// Damages both enemies and players
// "inflictor" is the thing that caused the damage
// creature or missile, can be NULL (slime, etc)
// "source" is the thing to target after taking damage
// creature or NULL
// Source and inflictor are the same for melee attacks.
// Source can be NULL for slime, barrel explosions
// and other environmental stuff.
//
void P_DamageMobj(mobj_t *target,mobj_t *inflictor, mobj_t *source, int damage)
{
player_t *player;
boolean justhit = false; /* killough 11/98 */
/* killough 8/31/98: allow bouncers to take damage */
if (!(target->flags & (MF_SHOOTABLE | MF_BOUNCES)))
return; // shouldn't happen...
if (target->health <= 0)
return;
if (target->flags & MF_SKULLFLY)
target->momx = target->momy = target->momz = 0;
player = target->player;
if (player && gameskill == sk_baby)
damage >>= 1; // take half damage in trainer mode
// Some close combat weapons should not
// inflict thrust and push the victim out of reach,
// thus kick away unless using the chainsaw.
if (inflictor && !(target->flags & MF_NOCLIP) &&
(!source || !source->player ||
source->player->readyweapon != wp_chainsaw))
{
unsigned ang = R_PointToAngle2 (inflictor->x, inflictor->y,
target->x, target->y);
fixed_t thrust = damage*(FRACUNIT>>3)*100/target->info->mass;
// make fall forwards sometimes
if ( damage < 40 && damage > target->health
&& target->z - inflictor->z > 64*FRACUNIT
&& P_Random(pr_damagemobj) & 1)
{
ang += ANG180;
thrust *= 4;
}
ang >>= ANGLETOFINESHIFT;
target->momx += FixedMul (thrust, finecosine[ang]);
target->momy += FixedMul (thrust, finesine[ang]);
/* killough 11/98: thrust objects hanging off ledges */
if (target->intflags & MIF_FALLING && target->gear >= MAXGEAR)
target->gear = 0;
}
// player specific
if (player)
{
// end of game hell hack
if (target->subsector->sector->special == 11 && damage >= target->health)
damage = target->health - 1;
// Below certain threshold,
// ignore damage in GOD mode, or with INVUL power.
// killough 3/26/98: make god mode 100% god mode in non-compat mode
if ((damage < 1000 || (!comp[comp_god] && (player->cheats&CF_GODMODE))) &&
(player->cheats&CF_GODMODE || player->powers[pw_invulnerability]))
return;
if (player->armortype)
{
int saved = player->armortype == 1 ? damage/3 : damage/2;
if (player->armorpoints <= saved)
{
// armor is used up
saved = player->armorpoints;
player->armortype = 0;
}
player->armorpoints -= saved;
damage -= saved;
}
player->health -= damage; // mirror mobj health here for Dave
if (player->health < 0)
player->health = 0;
player->attacker = source;
player->damagecount += damage; // add damage after armor / invuln
#ifdef IPHONE
if ( player == &players[consoleplayer] && !demoplayback ) { // vibe during demos is annoying
SysIPhoneVibrate();
}
#endif
if (player->damagecount > 100)
player->damagecount = 100; // teleport stomp does 10k points...
}
// do the damage
target->health -= damage;
if (target->health <= 0)
{
P_KillMobj (source, target);
return;
}
// killough 9/7/98: keep track of targets so that friends can help friends
if (mbf_features)
{
/* If target is a player, set player's target to source,
* so that a friend can tell who's hurting a player
*/
if (player)
P_SetTarget(&target->target, source);
/* killough 9/8/98:
* If target's health is less than 50%, move it to the front of its list.
* This will slightly increase the chances that enemies will choose to
* "finish it off", but its main purpose is to alert friends of danger.
*/
if (target->health*2 < target->info->spawnhealth)
{
thinker_t *cap = &thinkerclasscap[target->flags & MF_FRIEND ?
th_friends : th_enemies];
(target->thinker.cprev->cnext = target->thinker.cnext)->cprev =
target->thinker.cprev;
(target->thinker.cnext = cap->cnext)->cprev = &target->thinker;
(target->thinker.cprev = cap)->cnext = &target->thinker;
}
}
if (P_Random (pr_painchance) < target->info->painchance &&
!(target->flags & MF_SKULLFLY)) { //killough 11/98: see below
if (mbf_features)
justhit = true;
else
target->flags |= MF_JUSTHIT; // fight back!
P_SetMobjState(target, target->info->painstate);
}
target->reactiontime = 0; // we're awake now...
/* killough 9/9/98: cleaned up, made more consistent: */
if (source && source != target && source->type != MT_VILE &&
(!target->threshold || target->type == MT_VILE) &&
((source->flags ^ target->flags) & MF_FRIEND ||
monster_infighting ||
!mbf_features))
{
/* if not intent on another player, chase after this one
*
* killough 2/15/98: remember last enemy, to prevent
* sleeping early; 2/21/98: Place priority on players
* killough 9/9/98: cleaned up, made more consistent:
*/
if (!target->lastenemy || target->lastenemy->health <= 0 ||
(!mbf_features ?
!target->lastenemy->player :
!((target->flags ^ target->lastenemy->flags) & MF_FRIEND) &&
target->target != source)) // remember last enemy - killough
P_SetTarget(&target->lastenemy, target->target);
P_SetTarget(&target->target, source); // killough 11/98
target->threshold = BASETHRESHOLD;
if (target->state == &states[target->info->spawnstate]
&& target->info->seestate != S_NULL)
P_SetMobjState (target, target->info->seestate);
}
/* killough 11/98: Don't attack a friend, unless hit by that friend.
* cph 2006/04/01 - implicitly this is only if mbf_features */
if (justhit && (target->target == source || !target->target ||
!(target->flags & target->target->flags & MF_FRIEND)))
target->flags |= MF_JUSTHIT; // fight back!
}

View File

@@ -0,0 +1,75 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Thing events, and dehacked specified numbers controlling them.
*
*-----------------------------------------------------------------------------*/
#ifndef __P_INTER__
#define __P_INTER__
#include "d_player.h"
#include "p_mobj.h"
#ifdef __GNUG__
#pragma interface
#endif
/* Ty 03/09/98 Moved to an int in p_inter.c for deh and externalization */
#define MAXHEALTH maxhealth
/* follow a player exlusively for 3 seconds */
#define BASETHRESHOLD (100)
boolean P_GivePower(player_t *, int);
void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher);
void P_DamageMobj(mobj_t *target,mobj_t *inflictor,mobj_t *source,int damage);
/* killough 5/2/98: moved from d_deh.c, g_game.c, m_misc.c, others: */
extern int god_health; /* Ty 03/09/98 - deh support, see also p_inter.c */
extern int idfa_armor;
extern int idfa_armor_class;
extern int idkfa_armor;
extern int idkfa_armor_class; /* Ty - end */
/* Ty 03/13/98 - externalized initial settings for respawned player */
extern int initial_health;
extern int initial_bullets;
extern int maxhealth;
extern int max_armor;
extern int green_armor_class;
extern int blue_armor_class;
extern int max_soul;
extern int soul_health;
extern int mega_health;
extern int bfgcells;
extern int monsters_infight; // e6y: Dehacked support - monsters infight
extern int maxammo[], clipammo[];
#endif

View File

@@ -0,0 +1,443 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Action routines for lighting thinkers
* Spawn sector based lighting effects.
* Handle lighting linedef types
*
*-----------------------------------------------------------------------------*/
#include "doomstat.h" //jff 5/18/98
#include "doomdef.h"
#include "m_random.h"
#include "r_main.h"
#include "p_spec.h"
#include "p_tick.h"
//////////////////////////////////////////////////////////
//
// Lighting action routines, called once per tick
//
//////////////////////////////////////////////////////////
//
// T_FireFlicker()
//
// Firelight flicker action routine, called once per tick
//
// Passed a fireflicker_t structure containing light levels and timing
// Returns nothing
//
void T_FireFlicker (fireflicker_t* flick)
{
int amount;
if (--flick->count)
return;
amount = (P_Random(pr_lights)&3)*16;
if (flick->sector->lightlevel - amount < flick->minlight)
flick->sector->lightlevel = flick->minlight;
else
flick->sector->lightlevel = flick->maxlight - amount;
flick->count = 4;
}
//
// T_LightFlash()
//
// Broken light flashing action routine, called once per tick
//
// Passed a lightflash_t structure containing light levels and timing
// Returns nothing
//
void T_LightFlash (lightflash_t* flash)
{
if (--flash->count)
return;
if (flash->sector->lightlevel == flash->maxlight)
{
flash-> sector->lightlevel = flash->minlight;
flash->count = (P_Random(pr_lights)&flash->mintime)+1;
}
else
{
flash-> sector->lightlevel = flash->maxlight;
flash->count = (P_Random(pr_lights)&flash->maxtime)+1;
}
}
//
// T_StrobeFlash()
//
// Strobe light flashing action routine, called once per tick
//
// Passed a strobe_t structure containing light levels and timing
// Returns nothing
//
void T_StrobeFlash (strobe_t* flash)
{
if (--flash->count)
return;
if (flash->sector->lightlevel == flash->minlight)
{
flash-> sector->lightlevel = flash->maxlight;
flash->count = flash->brighttime;
}
else
{
flash-> sector->lightlevel = flash->minlight;
flash->count =flash->darktime;
}
}
//
// T_Glow()
//
// Glowing light action routine, called once per tick
//
// Passed a glow_t structure containing light levels and timing
// Returns nothing
//
void T_Glow(glow_t* g)
{
switch(g->direction)
{
case -1:
// light dims
g->sector->lightlevel -= GLOWSPEED;
if (g->sector->lightlevel <= g->minlight)
{
g->sector->lightlevel += GLOWSPEED;
g->direction = 1;
}
break;
case 1:
// light brightens
g->sector->lightlevel += GLOWSPEED;
if (g->sector->lightlevel >= g->maxlight)
{
g->sector->lightlevel -= GLOWSPEED;
g->direction = -1;
}
break;
}
}
//////////////////////////////////////////////////////////
//
// Sector lighting type spawners
//
// After the map has been loaded, each sector is scanned
// for specials that spawn thinkers
//
//////////////////////////////////////////////////////////
//
// P_SpawnFireFlicker()
//
// Spawns a fire flicker lighting thinker
//
// Passed the sector that spawned the thinker
// Returns nothing
//
void P_SpawnFireFlicker (sector_t* sector)
{
fireflicker_t* flick;
// Note that we are resetting sector attributes.
// Nothing special about it during gameplay.
sector->special &= ~31; //jff 3/14/98 clear non-generalized sector type
flick = Z_Malloc ( sizeof(*flick), PU_LEVSPEC, 0);
memset(flick, 0, sizeof(*flick));
P_AddThinker (&flick->thinker);
flick->thinker.function = T_FireFlicker;
flick->sector = sector;
flick->maxlight = sector->lightlevel;
flick->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel)+16;
flick->count = 4;
}
//
// P_SpawnLightFlash()
//
// Spawns a broken light flash lighting thinker
//
// Passed the sector that spawned the thinker
// Returns nothing
//
void P_SpawnLightFlash (sector_t* sector)
{
lightflash_t* flash;
// nothing special about it during gameplay
sector->special &= ~31; //jff 3/14/98 clear non-generalized sector type
flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
memset(flash, 0, sizeof(*flash));
P_AddThinker (&flash->thinker);
flash->thinker.function = T_LightFlash;
flash->sector = sector;
flash->maxlight = sector->lightlevel;
flash->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel);
flash->maxtime = 64;
flash->mintime = 7;
flash->count = (P_Random(pr_lights)&flash->maxtime)+1;
}
//
// P_SpawnStrobeFlash
//
// Spawns a blinking light thinker
//
// Passed the sector that spawned the thinker, speed of blinking
// and whether blinking is to by syncrhonous with other sectors
//
// Returns nothing
//
void P_SpawnStrobeFlash
( sector_t* sector,
int fastOrSlow,
int inSync )
{
strobe_t* flash;
flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
memset(flash, 0, sizeof(*flash));
P_AddThinker (&flash->thinker);
flash->sector = sector;
flash->darktime = fastOrSlow;
flash->brighttime = STROBEBRIGHT;
flash->thinker.function = T_StrobeFlash;
flash->maxlight = sector->lightlevel;
flash->minlight = P_FindMinSurroundingLight(sector, sector->lightlevel);
if (flash->minlight == flash->maxlight)
flash->minlight = 0;
// nothing special about it during gameplay
sector->special &= ~31; //jff 3/14/98 clear non-generalized sector type
if (!inSync)
flash->count = (P_Random(pr_lights)&7)+1;
else
flash->count = 1;
}
//
// P_SpawnGlowingLight()
//
// Spawns a glowing light (smooth oscillation from min to max) thinker
//
// Passed the sector that spawned the thinker
// Returns nothing
//
void P_SpawnGlowingLight(sector_t* sector)
{
glow_t* g;
g = Z_Malloc( sizeof(*g), PU_LEVSPEC, 0);
memset(g, 0, sizeof(*g));
P_AddThinker(&g->thinker);
g->sector = sector;
g->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel);
g->maxlight = sector->lightlevel;
g->thinker.function = T_Glow;
g->direction = -1;
sector->special &= ~31; //jff 3/14/98 clear non-generalized sector type
}
//////////////////////////////////////////////////////////
//
// Linedef lighting function handlers
//
//////////////////////////////////////////////////////////
//
// EV_StartLightStrobing()
//
// Start strobing lights (usually from a trigger)
//
// Passed the line that activated the strobing
// Returns true
//
// jff 2/12/98 added int return value, fixed return
//
int EV_StartLightStrobing(line_t* line)
{
int secnum;
sector_t* sec;
secnum = -1;
// start lights strobing in all sectors tagged same as line
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
{
sec = &sectors[secnum];
// if already doing a lighting function, don't start a second
if (P_SectorActive(lighting_special,sec)) //jff 2/22/98
continue;
P_SpawnStrobeFlash (sec,SLOWDARK, 0);
}
return 1;
}
//
// EV_TurnTagLightsOff()
//
// Turn line's tagged sector's lights to min adjacent neighbor level
//
// Passed the line that activated the lights being turned off
// Returns true
//
// jff 2/12/98 added int return value, fixed return
//
int EV_TurnTagLightsOff(line_t* line)
{
int j;
// search sectors for those with same tag as activating line
// killough 10/98: replaced inefficient search with fast search
for (j = -1; (j = P_FindSectorFromLineTag(line,j)) >= 0;)
{
sector_t *sector = sectors + j, *tsec;
int i, min = sector->lightlevel;
// find min neighbor light level
for (i = 0;i < sector->linecount; i++)
if ((tsec = getNextSector(sector->lines[i], sector)) &&
tsec->lightlevel < min)
min = tsec->lightlevel;
sector->lightlevel = min;
}
return 1;
}
//
// EV_LightTurnOn()
//
// Turn sectors tagged to line lights on to specified or max neighbor level
//
// Passed the activating line, and a level to set the light to
// If level passed is 0, the maximum neighbor lighting is used
// Returns true
//
// jff 2/12/98 added int return value, fixed return
//
int EV_LightTurnOn(line_t *line, int bright)
{
int i;
// search all sectors for ones with same tag as activating line
// killough 10/98: replace inefficient search with fast search
for (i = -1; (i = P_FindSectorFromLineTag(line,i)) >= 0;)
{
sector_t *temp, *sector = sectors+i;
int j, tbright = bright; //jff 5/17/98 search for maximum PER sector
// bright = 0 means to search for highest light level surrounding sector
if (!bright)
for (j = 0;j < sector->linecount; j++)
if ((temp = getNextSector(sector->lines[j],sector)) &&
temp->lightlevel > tbright)
tbright = temp->lightlevel;
sector->lightlevel = tbright;
//jff 5/17/98 unless compatibility optioned
//then maximum near ANY tagged sector
if (comp[comp_model])
bright = tbright;
}
return 1;
}
/* killough 10/98:
*
* EV_LightTurnOnPartway()
*
* Turn sectors tagged to line lights on to specified or max neighbor level
*
* Passed the activating line, and a light level fraction between 0 and 1.
* Sets the light to min on 0, max on 1, and interpolates in-between.
* Used for doors with gradual lighting effects.
*
* Returns true
*/
int EV_LightTurnOnPartway(line_t *line, fixed_t level)
{
int i;
if (level < 0) // clip at extremes
level = 0;
if (level > FRACUNIT)
level = FRACUNIT;
// search all sectors for ones with same tag as activating line
for (i = -1; (i = P_FindSectorFromLineTag(line,i)) >= 0;)
{
sector_t *temp, *sector = sectors+i;
int j, bright = 0, min = sector->lightlevel;
for (j = 0; j < sector->linecount; j++)
if ((temp = getNextSector(sector->lines[j],sector)))
{
if (temp->lightlevel > bright)
bright = temp->lightlevel;
if (temp->lightlevel < min)
min = temp->lightlevel;
}
sector->lightlevel = // Set level in-between extremes
(level * bright + (FRACUNIT-level) * min) >> FRACBITS;
}
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,92 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Map functions
*
*-----------------------------------------------------------------------------*/
#ifndef __P_MAP__
#define __P_MAP__
#include "r_defs.h"
#include "d_player.h"
#define USERANGE (64*FRACUNIT)
#define MELEERANGE (64*FRACUNIT)
#define MISSILERANGE (32*64*FRACUNIT)
// MAXRADIUS is for precalculated sector block boxes the spider demon
// is larger, but we do not have any moving sectors nearby
#define MAXRADIUS (32*FRACUNIT)
// killough 3/15/98: add fourth argument to P_TryMove
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean dropoff);
// killough 8/9/98: extra argument for telefragging
boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y,boolean boss);
void P_SlideMove(mobj_t *mo);
boolean P_CheckSight(mobj_t *t1, mobj_t *t2);
void P_UseLines(player_t *player);
// killough 8/2/98: add 'mask' argument to prevent friends autoaiming at others
fixed_t P_AimLineAttack(mobj_t *t1,angle_t angle,fixed_t distance, uint_64_t mask);
void P_LineAttack(mobj_t *t1, angle_t angle, fixed_t distance,
fixed_t slope, int damage );
void P_RadiusAttack(mobj_t *spot, mobj_t *source, int damage);
boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y);
//jff 3/19/98 P_CheckSector(): new routine to replace P_ChangeSector()
boolean P_ChangeSector(sector_t* sector,boolean crunch);
boolean P_CheckSector(sector_t *sector, boolean crunch);
void P_DelSeclist(msecnode_t*); // phares 3/16/98
void P_CreateSecNodeList(mobj_t*,fixed_t,fixed_t); // phares 3/14/98
boolean Check_Sides(mobj_t *, int, int); // phares
int P_GetMoveFactor(const mobj_t *mo, int *friction); // killough 8/28/98
int P_GetFriction(const mobj_t *mo, int *factor); // killough 8/28/98
void P_ApplyTorque(mobj_t *mo); // killough 9/12/98
/* cphipps 2004/08/30 */
void P_MapStart(void);
void P_MapEnd(void);
// If "floatok" true, move would be ok if within "tmfloorz - tmceilingz".
extern boolean floatok;
extern boolean felldown; // killough 11/98: indicates object pushed off ledge
extern fixed_t tmfloorz;
extern fixed_t tmceilingz;
extern line_t *ceilingline;
extern line_t *floorline; // killough 8/23/98
extern mobj_t *linetarget; // who got hit (or NULL)
extern msecnode_t *sector_list; // phares 3/16/98
extern fixed_t tmbbox[4]; // phares 3/20/98
extern line_t *blockline; // killough 8/11/98
#endif // __P_MAP__

View File

@@ -0,0 +1,683 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Movement/collision utility functions,
* as used by function in p_map.c.
* BLOCKMAP Iterator functions,
* and some PIT_* functions to use for iteration.
*
*-----------------------------------------------------------------------------*/
#include "doomstat.h"
#include "m_bbox.h"
#include "r_main.h"
#include "p_maputl.h"
#include "p_map.h"
#include "p_setup.h"
//
// P_AproxDistance
// Gives an estimation of distance (not exact)
//
fixed_t CONSTFUNC P_AproxDistance(fixed_t dx, fixed_t dy)
{
dx = D_abs(dx);
dy = D_abs(dy);
if (dx < dy)
return dx+dy-(dx>>1);
return dx+dy-(dy>>1);
}
//
// P_PointOnLineSide
// Returns 0 or 1
//
// killough 5/3/98: reformatted, cleaned up
int PUREFUNC P_PointOnLineSide(fixed_t x, fixed_t y, const line_t *line)
{
return
!line->dx ? x <= line->v1->x ? line->dy > 0 : line->dy < 0 :
!line->dy ? y <= line->v1->y ? line->dx < 0 : line->dx > 0 :
FixedMul(y-line->v1->y, line->dx>>FRACBITS) >=
FixedMul(line->dy>>FRACBITS, x-line->v1->x);
}
//
// P_BoxOnLineSide
// Considers the line to be infinite
// Returns side 0 or 1, -1 if box crosses the line.
//
// killough 5/3/98: reformatted, cleaned up
int PUREFUNC P_BoxOnLineSide(const fixed_t *tmbox, const line_t *ld)
{
switch (ld->slopetype)
{
int p;
default: // shut up compiler warnings -- killough
case ST_HORIZONTAL:
return
(tmbox[BOXBOTTOM] > ld->v1->y) == (p = tmbox[BOXTOP] > ld->v1->y) ?
p ^ (ld->dx < 0) : -1;
case ST_VERTICAL:
return
(tmbox[BOXLEFT] < ld->v1->x) == (p = tmbox[BOXRIGHT] < ld->v1->x) ?
p ^ (ld->dy < 0) : -1;
case ST_POSITIVE:
return
P_PointOnLineSide(tmbox[BOXRIGHT], tmbox[BOXBOTTOM], ld) ==
(p = P_PointOnLineSide(tmbox[BOXLEFT], tmbox[BOXTOP], ld)) ? p : -1;
case ST_NEGATIVE:
return
(P_PointOnLineSide(tmbox[BOXLEFT], tmbox[BOXBOTTOM], ld)) ==
(p = P_PointOnLineSide(tmbox[BOXRIGHT], tmbox[BOXTOP], ld)) ? p : -1;
}
}
//
// P_PointOnDivlineSide
// Returns 0 or 1.
//
// killough 5/3/98: reformatted, cleaned up
static int PUREFUNC P_PointOnDivlineSide(fixed_t x, fixed_t y, const divline_t *line)
{
return
!line->dx ? x <= line->x ? line->dy > 0 : line->dy < 0 :
!line->dy ? y <= line->y ? line->dx < 0 : line->dx > 0 :
(line->dy^line->dx^(x -= line->x)^(y -= line->y)) < 0 ? (line->dy^x) < 0 :
FixedMul(y>>8, line->dx>>8) >= FixedMul(line->dy>>8, x>>8);
}
//
// P_MakeDivline
//
static void P_MakeDivline(const line_t *li, divline_t *dl)
{
dl->x = li->v1->x;
dl->y = li->v1->y;
dl->dx = li->dx;
dl->dy = li->dy;
}
//
// P_InterceptVector
// Returns the fractional intercept point
// along the first divline.
// This is only called by the addthings
// and addlines traversers.
//
/* cph - this is killough's 4/19/98 version of P_InterceptVector and
* P_InterceptVector2 (which were interchangeable). We still use this
* in compatibility mode. */
fixed_t PUREFUNC P_InterceptVector2(const divline_t *v2, const divline_t *v1)
{
fixed_t den;
return (den = FixedMul(v1->dy>>8, v2->dx) - FixedMul(v1->dx>>8, v2->dy)) ?
FixedDiv(FixedMul((v1->x - v2->x)>>8, v1->dy) +
FixedMul((v2->y - v1->y)>>8, v1->dx), den) : 0;
}
fixed_t PUREFUNC P_InterceptVector(const divline_t *v2, const divline_t *v1)
{
if (compatibility_level < prboom_4_compatibility)
return P_InterceptVector2(v2, v1);
else {
/* cph - This was introduced at prboom_4_compatibility - no precision/overflow problems */
int_64_t den = (int_64_t)v1->dy * v2->dx - (int_64_t)v1->dx * v2->dy;
den >>= 16;
if (!den)
return 0;
return (fixed_t)(((int_64_t)(v1->x - v2->x) * v1->dy - (int_64_t)(v1->y - v2->y) * v1->dx) / den);
}
}
//
// P_LineOpening
// Sets opentop and openbottom to the window
// through a two sided line.
// OPTIMIZE: keep this precalculated
//
fixed_t opentop;
fixed_t openbottom;
fixed_t openrange;
fixed_t lowfloor;
// moved front and back outside P-LineOpening and changed // phares 3/7/98
// them to these so we can pick up the new friction value
// in PIT_CheckLine()
sector_t *openfrontsector; // made global // phares
sector_t *openbacksector; // made global
void P_LineOpening(const line_t *linedef)
{
if (linedef->sidenum[1] == NO_INDEX) // single sided line
{
openrange = 0;
return;
}
openfrontsector = linedef->frontsector;
openbacksector = linedef->backsector;
if (openfrontsector->ceilingheight < openbacksector->ceilingheight)
opentop = openfrontsector->ceilingheight;
else
opentop = openbacksector->ceilingheight;
if (openfrontsector->floorheight > openbacksector->floorheight)
{
openbottom = openfrontsector->floorheight;
lowfloor = openbacksector->floorheight;
}
else
{
openbottom = openbacksector->floorheight;
lowfloor = openfrontsector->floorheight;
}
openrange = opentop - openbottom;
}
//
// THING POSITION SETTING
//
//
// P_UnsetThingPosition
// Unlinks a thing from block map and sectors.
// On each position change, BLOCKMAP and other
// lookups maintaining lists ot things inside
// these structures need to be updated.
//
void P_UnsetThingPosition (mobj_t *thing)
{
if (!(thing->flags & MF_NOSECTOR))
{
/* invisible things don't need to be in sector list
* unlink from subsector
*
* killough 8/11/98: simpler scheme using pointers-to-pointers for prev
* pointers, allows head node pointers to be treated like everything else
*/
mobj_t **sprev = thing->sprev;
mobj_t *snext = thing->snext;
if ((*sprev = snext)) // unlink from sector list
snext->sprev = sprev;
// phares 3/14/98
//
// Save the sector list pointed to by touching_sectorlist.
// In P_SetThingPosition, we'll keep any nodes that represent
// sectors the Thing still touches. We'll add new ones then, and
// delete any nodes for sectors the Thing has vacated. Then we'll
// put it back into touching_sectorlist. It's done this way to
// avoid a lot of deleting/creating for nodes, when most of the
// time you just get back what you deleted anyway.
//
// If this Thing is being removed entirely, then the calling
// routine will clear out the nodes in sector_list.
sector_list = thing->touching_sectorlist;
thing->touching_sectorlist = NULL; //to be restored by P_SetThingPosition
}
if (!(thing->flags & MF_NOBLOCKMAP))
{
/* inert things don't need to be in blockmap
*
* killough 8/11/98: simpler scheme using pointers-to-pointers for prev
* pointers, allows head node pointers to be treated like everything else
*
* Also more robust, since it doesn't depend on current position for
* unlinking. Old method required computing head node based on position
* at time of unlinking, assuming it was the same position as during
* linking.
*/
mobj_t *bnext, **bprev = thing->bprev;
if (bprev && (*bprev = bnext = thing->bnext)) // unlink from block map
bnext->bprev = bprev;
}
}
//
// P_SetThingPosition
// Links a thing into both a block and a subsector
// based on it's x y.
// Sets thing->subsector properly
//
// killough 5/3/98: reformatted, cleaned up
void P_SetThingPosition(mobj_t *thing)
{ // link into subsector
subsector_t *ss = thing->subsector = R_PointInSubsector(thing->x, thing->y);
if (!(thing->flags & MF_NOSECTOR))
{
// invisible things don't go into the sector links
// killough 8/11/98: simpler scheme using pointer-to-pointer prev
// pointers, allows head nodes to be treated like everything else
mobj_t **link = &ss->sector->thinglist;
mobj_t *snext = *link;
if ((thing->snext = snext))
snext->sprev = &thing->snext;
thing->sprev = link;
*link = thing;
// phares 3/16/98
//
// If sector_list isn't NULL, it has a collection of sector
// nodes that were just removed from this Thing.
// Collect the sectors the object will live in by looking at
// the existing sector_list and adding new nodes and deleting
// obsolete ones.
// When a node is deleted, its sector links (the links starting
// at sector_t->touching_thinglist) are broken. When a node is
// added, new sector links are created.
P_CreateSecNodeList(thing,thing->x,thing->y);
thing->touching_sectorlist = sector_list; // Attach to Thing's mobj_t
sector_list = NULL; // clear for next time
}
// link into blockmap
if (!(thing->flags & MF_NOBLOCKMAP))
{
// inert things don't need to be in blockmap
int blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT;
int blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT;
if (blockx>=0 && blockx < bmapwidth && blocky>=0 && blocky < bmapheight)
{
// killough 8/11/98: simpler scheme using pointer-to-pointer prev
// pointers, allows head nodes to be treated like everything else
mobj_t **link = &blocklinks[blocky*bmapwidth+blockx];
mobj_t *bnext = *link;
if ((thing->bnext = bnext))
bnext->bprev = &thing->bnext;
thing->bprev = link;
*link = thing;
}
else // thing is off the map
thing->bnext = NULL, thing->bprev = NULL;
}
}
//
// BLOCK MAP ITERATORS
// For each line/thing in the given mapblock,
// call the passed PIT_* function.
// If the function returns false,
// exit with false without checking anything else.
//
//
// P_BlockLinesIterator
// The validcount flags are used to avoid checking lines
// that are marked in multiple mapblocks,
// so increment validcount before the first call
// to P_BlockLinesIterator, then make one or more calls
// to it.
//
// killough 5/3/98: reformatted, cleaned up
boolean P_BlockLinesIterator(int x, int y, boolean func(line_t*))
{
int offset;
const long *list; // killough 3/1/98: for removal of blockmap limit
if (x<0 || y<0 || x>=bmapwidth || y>=bmapheight)
return true;
offset = y*bmapwidth+x;
offset = *(blockmap+offset);
list = blockmaplump+offset; // original was reading // phares
// delmiting 0 as linedef 0 // phares
// killough 1/31/98: for compatibility we need to use the old method.
// Most demos go out of sync, and maybe other problems happen, if we
// don't consider linedef 0. For safety this should be qualified.
if (!demo_compatibility) // killough 2/22/98: demo_compatibility check
list++; // skip 0 starting delimiter // phares
for ( ; *list != -1 ; list++) // phares
{
line_t *ld = &lines[*list];
if (ld->validcount == validcount)
continue; // line has already been checked
ld->validcount = validcount;
if (!func(ld))
return false;
}
return true; // everything was checked
}
//
// P_BlockThingsIterator
//
// killough 5/3/98: reformatted, cleaned up
boolean P_BlockThingsIterator(int x, int y, boolean func(mobj_t*))
{
mobj_t *mobj;
if (!(x<0 || y<0 || x>=bmapwidth || y>=bmapheight))
for (mobj = blocklinks[y*bmapwidth+x]; mobj; mobj = mobj->bnext)
if (!func(mobj))
return false;
return true;
}
//
// INTERCEPT ROUTINES
//
// 1/11/98 killough: Intercept limit removed
static intercept_t *intercepts, *intercept_p;
// Check for limit and double size if necessary -- killough
static void check_intercept(void)
{
static size_t num_intercepts;
size_t offset = intercept_p - intercepts;
if (offset >= num_intercepts)
{
num_intercepts = num_intercepts ? num_intercepts*2 : 128;
intercepts = realloc(intercepts, sizeof(*intercepts)*num_intercepts);
intercept_p = intercepts + offset;
}
}
divline_t trace;
// PIT_AddLineIntercepts.
// Looks for lines in the given block
// that intercept the given trace
// to add to the intercepts list.
//
// A line is crossed if its endpoints
// are on opposite sides of the trace.
//
// killough 5/3/98: reformatted, cleaned up
boolean PIT_AddLineIntercepts(line_t *ld)
{
int s1;
int s2;
fixed_t frac;
divline_t dl;
// avoid precision problems with two routines
if (trace.dx > FRACUNIT*16 || trace.dy > FRACUNIT*16 ||
trace.dx < -FRACUNIT*16 || trace.dy < -FRACUNIT*16)
{
s1 = P_PointOnDivlineSide (ld->v1->x, ld->v1->y, &trace);
s2 = P_PointOnDivlineSide (ld->v2->x, ld->v2->y, &trace);
}
else
{
s1 = P_PointOnLineSide (trace.x, trace.y, ld);
s2 = P_PointOnLineSide (trace.x+trace.dx, trace.y+trace.dy, ld);
}
if (s1 == s2)
return true; // line isn't crossed
// hit the line
P_MakeDivline(ld, &dl);
frac = P_InterceptVector(&trace, &dl);
if (frac < 0)
return true; // behind source
check_intercept(); // killough
intercept_p->frac = frac;
intercept_p->isaline = true;
intercept_p->d.line = ld;
intercept_p++;
return true; // continue
}
//
// PIT_AddThingIntercepts
//
// killough 5/3/98: reformatted, cleaned up
boolean PIT_AddThingIntercepts(mobj_t *thing)
{
fixed_t x1, y1;
fixed_t x2, y2;
int s1, s2;
divline_t dl;
fixed_t frac;
// check a corner to corner crossection for hit
if ((trace.dx ^ trace.dy) > 0)
{
x1 = thing->x - thing->radius;
y1 = thing->y + thing->radius;
x2 = thing->x + thing->radius;
y2 = thing->y - thing->radius;
}
else
{
x1 = thing->x - thing->radius;
y1 = thing->y - thing->radius;
x2 = thing->x + thing->radius;
y2 = thing->y + thing->radius;
}
s1 = P_PointOnDivlineSide (x1, y1, &trace);
s2 = P_PointOnDivlineSide (x2, y2, &trace);
if (s1 == s2)
return true; // line isn't crossed
dl.x = x1;
dl.y = y1;
dl.dx = x2-x1;
dl.dy = y2-y1;
frac = P_InterceptVector (&trace, &dl);
if (frac < 0)
return true; // behind source
check_intercept(); // killough
intercept_p->frac = frac;
intercept_p->isaline = false;
intercept_p->d.thing = thing;
intercept_p++;
return true; // keep going
}
//
// P_TraverseIntercepts
// Returns true if the traverser function returns true
// for all lines.
//
// killough 5/3/98: reformatted, cleaned up
boolean P_TraverseIntercepts(traverser_t func, fixed_t maxfrac)
{
intercept_t *in = NULL;
int count = intercept_p - intercepts;
while (count--)
{
fixed_t dist = INT_MAX;
intercept_t *scan;
for (scan = intercepts; scan < intercept_p; scan++)
if (scan->frac < dist)
dist = (in=scan)->frac;
if (dist > maxfrac)
return true; // checked everything in range
if (!func(in))
return false; // don't bother going farther
in->frac = INT_MAX;
}
return true; // everything was traversed
}
//
// P_PathTraverse
// Traces a line from x1,y1 to x2,y2,
// calling the traverser function for each.
// Returns true if the traverser function returns true
// for all lines.
//
// killough 5/3/98: reformatted, cleaned up
boolean P_PathTraverse(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2,
int flags, boolean trav(intercept_t *))
{
fixed_t xt1, yt1;
fixed_t xt2, yt2;
fixed_t xstep, ystep;
fixed_t partial;
fixed_t xintercept, yintercept;
int mapx, mapy;
int mapxstep, mapystep;
int count;
validcount++;
intercept_p = intercepts;
if (!((x1-bmaporgx)&(MAPBLOCKSIZE-1)))
x1 += FRACUNIT; // don't side exactly on a line
if (!((y1-bmaporgy)&(MAPBLOCKSIZE-1)))
y1 += FRACUNIT; // don't side exactly on a line
trace.x = x1;
trace.y = y1;
trace.dx = x2 - x1;
trace.dy = y2 - y1;
x1 -= bmaporgx;
y1 -= bmaporgy;
xt1 = x1>>MAPBLOCKSHIFT;
yt1 = y1>>MAPBLOCKSHIFT;
x2 -= bmaporgx;
y2 -= bmaporgy;
xt2 = x2>>MAPBLOCKSHIFT;
yt2 = y2>>MAPBLOCKSHIFT;
if (xt2 > xt1)
{
mapxstep = 1;
partial = FRACUNIT - ((x1>>MAPBTOFRAC)&(FRACUNIT-1));
ystep = FixedDiv (y2-y1,D_abs(x2-x1));
}
else
if (xt2 < xt1)
{
mapxstep = -1;
partial = (x1>>MAPBTOFRAC)&(FRACUNIT-1);
ystep = FixedDiv (y2-y1,D_abs(x2-x1));
}
else
{
mapxstep = 0;
partial = FRACUNIT;
ystep = 256*FRACUNIT;
}
yintercept = (y1>>MAPBTOFRAC) + FixedMul(partial, ystep);
if (yt2 > yt1)
{
mapystep = 1;
partial = FRACUNIT - ((y1>>MAPBTOFRAC)&(FRACUNIT-1));
xstep = FixedDiv (x2-x1,D_abs(y2-y1));
}
else
if (yt2 < yt1)
{
mapystep = -1;
partial = (y1>>MAPBTOFRAC)&(FRACUNIT-1);
xstep = FixedDiv (x2-x1,D_abs(y2-y1));
}
else
{
mapystep = 0;
partial = FRACUNIT;
xstep = 256*FRACUNIT;
}
xintercept = (x1>>MAPBTOFRAC) + FixedMul (partial, xstep);
// Step through map blocks.
// Count is present to prevent a round off error
// from skipping the break.
mapx = xt1;
mapy = yt1;
for (count = 0; count < 64; count++)
{
if (flags & PT_ADDLINES)
if (!P_BlockLinesIterator(mapx, mapy,PIT_AddLineIntercepts))
return false; // early out
if (flags & PT_ADDTHINGS)
if (!P_BlockThingsIterator(mapx, mapy,PIT_AddThingIntercepts))
return false; // early out
if (mapx == xt2 && mapy == yt2)
break;
if ((yintercept >> FRACBITS) == mapy)
{
yintercept += ystep;
mapx += mapxstep;
}
else
if ((xintercept >> FRACBITS) == mapx)
{
xintercept += xstep;
mapy += mapystep;
}
}
// go through the sorted list
return P_TraverseIntercepts(trav, FRACUNIT);
}

View File

@@ -0,0 +1,89 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Map utility functions
*
*-----------------------------------------------------------------------------*/
#ifndef __P_MAPUTL__
#define __P_MAPUTL__
#include "r_defs.h"
/* mapblocks are used to check movement against lines and things */
#define MAPBLOCKUNITS 128
#define MAPBLOCKSIZE (MAPBLOCKUNITS*FRACUNIT)
#define MAPBLOCKSHIFT (FRACBITS+7)
#define MAPBMASK (MAPBLOCKSIZE-1)
#define MAPBTOFRAC (MAPBLOCKSHIFT-FRACBITS)
#define PT_ADDLINES 1
#define PT_ADDTHINGS 2
#define PT_EARLYOUT 4
typedef struct {
fixed_t x;
fixed_t y;
fixed_t dx;
fixed_t dy;
} divline_t;
typedef struct {
fixed_t frac; /* along trace line */
boolean isaline;
union {
mobj_t* thing;
line_t* line;
} d;
} intercept_t;
typedef boolean (*traverser_t)(intercept_t *in);
fixed_t CONSTFUNC P_AproxDistance (fixed_t dx, fixed_t dy);
int PUREFUNC P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line);
int PUREFUNC P_BoxOnLineSide (const fixed_t *tmbox, const line_t *ld);
fixed_t PUREFUNC P_InterceptVector (const divline_t *v2, const divline_t *v1);
/* cph - old compatibility version below */
fixed_t PUREFUNC P_InterceptVector2(const divline_t *v2, const divline_t *v1);
void P_LineOpening (const line_t *linedef);
void P_UnsetThingPosition(mobj_t *thing);
void P_SetThingPosition(mobj_t *thing);
boolean P_BlockLinesIterator (int x, int y, boolean func(line_t *));
boolean P_BlockThingsIterator(int x, int y, boolean func(mobj_t *));
boolean P_PathTraverse(fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2,
int flags, boolean trav(intercept_t *));
extern fixed_t opentop;
extern fixed_t openbottom;
extern fixed_t openrange;
extern fixed_t lowfloor;
extern divline_t trace;
#endif /* __P_MAPUTL__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,403 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Map Objects, MObj, definition and handling.
*
*-----------------------------------------------------------------------------*/
#ifndef __P_MOBJ__
#define __P_MOBJ__
// Basics.
#include "tables.h"
#include "m_fixed.h"
// We need the thinker_t stuff.
#include "d_think.h"
// We need the WAD data structure for Map things,
// from the THINGS lump.
#include "doomdata.h"
// States are tied to finite states are
// tied to animation frames.
// Needs precompiled tables/data structures.
#include "info.h"
//
// NOTES: mobj_t
//
// mobj_ts are used to tell the refresh where to draw an image,
// tell the world simulation when objects are contacted,
// and tell the sound driver how to position a sound.
//
// The refresh uses the next and prev links to follow
// lists of things in sectors as they are being drawn.
// The sprite, frame, and angle elements determine which patch_t
// is used to draw the sprite if it is visible.
// The sprite and frame values are allmost allways set
// from state_t structures.
// The statescr.exe utility generates the states.h and states.c
// files that contain the sprite/frame numbers from the
// statescr.txt source file.
// The xyz origin point represents a point at the bottom middle
// of the sprite (between the feet of a biped).
// This is the default origin position for patch_ts grabbed
// with lumpy.exe.
// A walking creature will have its z equal to the floor
// it is standing on.
//
// The sound code uses the x,y, and subsector fields
// to do stereo positioning of any sound effited by the mobj_t.
//
// The play simulation uses the blocklinks, x,y,z, radius, height
// to determine when mobj_ts are touching each other,
// touching lines in the map, or hit by trace lines (gunshots,
// lines of sight, etc).
// The mobj_t->flags element has various bit flags
// used by the simulation.
//
// Every mobj_t is linked into a single sector
// based on its origin coordinates.
// The subsector_t is found with R_PointInSubsector(x,y),
// and the sector_t can be found with subsector->sector.
// The sector links are only used by the rendering code,
// the play simulation does not care about them at all.
//
// Any mobj_t that needs to be acted upon by something else
// in the play world (block movement, be shot, etc) will also
// need to be linked into the blockmap.
// If the thing has the MF_NOBLOCK flag set, it will not use
// the block links. It can still interact with other things,
// but only as the instigator (missiles will run into other
// things, but nothing can run into a missile).
// Each block in the grid is 128*128 units, and knows about
// every line_t that it contains a piece of, and every
// interactable mobj_t that has its origin contained.
//
// A valid mobj_t is a mobj_t that has the proper subsector_t
// filled in for its xy coordinates and is linked into the
// sector from which the subsector was made, or has the
// MF_NOSECTOR flag set (the subsector_t needs to be valid
// even if MF_NOSECTOR is set), and is linked into a blockmap
// block or has the MF_NOBLOCKMAP flag set.
// Links should only be modified by the P_[Un]SetThingPosition()
// functions.
// Do not change the MF_NO? flags while a thing is valid.
//
// Any questions?
//
//
// Misc. mobj flags
//
// Call P_SpecialThing when touched.
#define MF_SPECIAL (uint_64_t)(0x0000000000000001)
// Blocks.
#define MF_SOLID (uint_64_t)(0x0000000000000002)
// Can be hit.
#define MF_SHOOTABLE (uint_64_t)(0x0000000000000004)
// Don't use the sector links (invisible but touchable).
#define MF_NOSECTOR (uint_64_t)(0x0000000000000008)
// Don't use the blocklinks (inert but displayable)
#define MF_NOBLOCKMAP (uint_64_t)(0x0000000000000010)
// Not to be activated by sound, deaf monster.
#define MF_AMBUSH (uint_64_t)(0x0000000000000020)
// Will try to attack right back.
#define MF_JUSTHIT (uint_64_t)(0x0000000000000040)
// Will take at least one step before attacking.
#define MF_JUSTATTACKED (uint_64_t)(0x0000000000000080)
// On level spawning (initial position),
// hang from ceiling instead of stand on floor.
#define MF_SPAWNCEILING (uint_64_t)(0x0000000000000100)
// Don't apply gravity (every tic),
// that is, object will float, keeping current height
// or changing it actively.
#define MF_NOGRAVITY (uint_64_t)(0x0000000000000200)
// Movement flags.
// This allows jumps from high places.
#define MF_DROPOFF (uint_64_t)(0x0000000000000400)
// For players, will pick up items.
#define MF_PICKUP (uint_64_t)(0x0000000000000800)
// Player cheat. ???
#define MF_NOCLIP (uint_64_t)(0x0000000000001000)
// Player: keep info about sliding along walls.
#define MF_SLIDE (uint_64_t)(0x0000000000002000)
// Allow moves to any height, no gravity.
// For active floaters, e.g. cacodemons, pain elementals.
#define MF_FLOAT (uint_64_t)(0x0000000000004000)
// Don't cross lines
// ??? or look at heights on teleport.
#define MF_TELEPORT (uint_64_t)(0x0000000000008000)
// Don't hit same species, explode on block.
// Player missiles as well as fireballs of various kinds.
#define MF_MISSILE (uint_64_t)(0x0000000000010000)
// Dropped by a demon, not level spawned.
// E.g. ammo clips dropped by dying former humans.
#define MF_DROPPED (uint_64_t)(0x0000000000020000)
// Use fuzzy draw (shadow demons or spectres),
// temporary player invisibility powerup.
#define MF_SHADOW (uint_64_t)(0x0000000000040000)
// Flag: don't bleed when shot (use puff),
// barrels and shootable furniture shall not bleed.
#define MF_NOBLOOD (uint_64_t)(0x0000000000080000)
// Don't stop moving halfway off a step,
// that is, have dead bodies slide down all the way.
#define MF_CORPSE (uint_64_t)(0x0000000000100000)
// Floating to a height for a move, ???
// don't auto float to target's height.
#define MF_INFLOAT (uint_64_t)(0x0000000000200000)
// On kill, count this enemy object
// towards intermission kill total.
// Happy gathering.
#define MF_COUNTKILL (uint_64_t)(0x0000000000400000)
// On picking up, count this item object
// towards intermission item total.
#define MF_COUNTITEM (uint_64_t)(0x0000000000800000)
// Special handling: skull in flight.
// Neither a cacodemon nor a missile.
#define MF_SKULLFLY (uint_64_t)(0x0000000001000000)
// Don't spawn this object
// in death match mode (e.g. key cards).
#define MF_NOTDMATCH (uint_64_t)(0x0000000002000000)
// Player sprites in multiplayer modes are modified
// using an internal color lookup table for re-indexing.
// If 0x4 0x8 or 0xc,
// use a translation table for player colormaps
#define MF_TRANSLATION (uint_64_t)(0x000000000c000000)
#define MF_TRANSLATION1 (uint_64_t)(0x0000000004000000)
#define MF_TRANSLATION2 (uint_64_t)(0x0000000008000000)
// Hmm ???.
#define MF_TRANSSHIFT 26
#define MF_UNUSED2 (uint_64_t)(0x0000000010000000)
#define MF_UNUSED3 (uint_64_t)(0x0000000020000000)
// Translucent sprite? // phares
#define MF_TRANSLUCENT (uint_64_t)(0x0000000040000000)
// this is free LONGLONG(0x0000000100000000)
// these are greater than an int. That's why the flags below are now uint_64_t
#define MF_TOUCHY LONGLONG(0x0000000100000000)
#define MF_BOUNCES LONGLONG(0x0000000200000000)
#define MF_FRIEND LONGLONG(0x0000000400000000)
// killough 9/15/98: Same, but internal flags, not intended for .deh
// (some degree of opaqueness is good, to avoid compatibility woes)
enum {
MIF_FALLING = 1, // Object is falling
MIF_ARMED = 2, // Object is armed (for MF_TOUCHY objects)
};
// Map Object definition.
//
//
// killough 2/20/98:
//
// WARNING: Special steps must be taken in p_saveg.c if C pointers are added to
// this mobj_s struct, or else savegames will crash when loaded. See p_saveg.c.
// Do not add "struct mobj_s *fooptr" without adding code to p_saveg.c to
// convert the pointers to ordinals and back for savegames. This was the whole
// reason behind monsters going to sleep when loading savegames (the "target"
// pointer was simply nullified after loading, to prevent Doom from crashing),
// and the whole reason behind loadgames crashing on savegames of AV attacks.
//
// killough 9/8/98: changed some fields to shorts,
// for better memory usage (if only for cache).
/* cph 2006/08/28 - move Prev[XYZ] fields to the end of the struct. Add any
* other new fields to the end, and make sure you don't break savegames! */
typedef struct mobj_s
{
// List: thinker links.
thinker_t thinker;
// Info for drawing: position.
fixed_t x;
fixed_t y;
fixed_t z;
// More list: links in sector (if needed)
struct mobj_s* snext;
struct mobj_s** sprev; // killough 8/10/98: change to ptr-to-ptr
//More drawing info: to determine current sprite.
angle_t angle; // orientation
spritenum_t sprite; // used to find patch_t and flip value
int frame; // might be ORed with FF_FULLBRIGHT
// Interaction info, by BLOCKMAP.
// Links in blocks (if needed).
struct mobj_s* bnext;
struct mobj_s** bprev; // killough 8/11/98: change to ptr-to-ptr
struct subsector_s* subsector;
// The closest interval over all contacted Sectors.
fixed_t floorz;
fixed_t ceilingz;
// killough 11/98: the lowest floor over all contacted Sectors.
fixed_t dropoffz;
// For movement checking.
fixed_t radius;
fixed_t height;
// Momentums, used to update position.
fixed_t momx;
fixed_t momy;
fixed_t momz;
// If == validcount, already checked.
int validcount;
mobjtype_t type;
mobjinfo_t* info; // &mobjinfo[mobj->type]
int tics; // state tic counter
state_t* state;
uint_64_t flags;
int intflags; // killough 9/15/98: internal flags
int health;
// Movement direction, movement generation (zig-zagging).
short movedir; // 0-7
short movecount; // when 0, select a new dir
short strafecount; // killough 9/8/98: monster strafing
// Thing being chased/attacked (or NULL),
// also the originator for missiles.
struct mobj_s* target;
// Reaction time: if non 0, don't attack yet.
// Used by player to freeze a bit after teleporting.
short reactiontime;
// If >0, the current target will be chased no
// matter what (even if shot by another object)
short threshold;
// killough 9/9/98: How long a monster pursues a target.
short pursuecount;
short gear; // killough 11/98: used in torque simulation
// Additional info record for player avatars only.
// Only valid if type == MT_PLAYER
struct player_s* player;
// Player number last looked for.
short lastlook;
// For nightmare respawn.
mapthing_t spawnpoint;
// Thing being chased/attacked for tracers.
struct mobj_s* tracer;
// new field: last known enemy -- killough 2/15/98
struct mobj_s* lastenemy;
// killough 8/2/98: friction properties part of sectors,
// not objects -- removed friction properties from here
// e6y: restored friction properties here
// Friction values for the sector the object is in
int friction; // phares 3/17/98
int movefactor;
// a linked list of sectors where this object appears
struct msecnode_s* touching_sectorlist; // phares 3/14/98
fixed_t PrevX;
fixed_t PrevY;
fixed_t PrevZ;
fixed_t pad; // cph - needed so I can get the size unambiguously on amd64
// SEE WARNING ABOVE ABOUT POINTER FIELDS!!!
} mobj_t;
// External declarations (fomerly in p_local.h) -- killough 5/2/98
#define VIEWHEIGHT (41*FRACUNIT)
#define GRAVITY FRACUNIT
#define MAXMOVE (30*FRACUNIT)
#define ONFLOORZ INT_MIN
#define ONCEILINGZ INT_MAX
// Time interval for item respawning.
#define ITEMQUESIZE 128
#define FLOATSPEED (FRACUNIT*4)
#define STOPSPEED (FRACUNIT/16)
// killough 11/98:
// For torque simulation:
#define OVERDRIVE 6
#define MAXGEAR (OVERDRIVE+16)
// killough 11/98:
// Whether an object is "sentient" or not. Used for environmental influences.
#define sentient(mobj) ((mobj)->health > 0 && (mobj)->info->seestate)
extern int iquehead;
extern int iquetail;
void P_RespawnSpecials(void);
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
void P_RemoveMobj(mobj_t *th);
boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
void P_MobjThinker(mobj_t *mobj);
void P_SpawnPuff(fixed_t x, fixed_t y, fixed_t z);
void P_SpawnBlood(fixed_t x, fixed_t y, fixed_t z, int damage);
mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type);
void P_SpawnPlayerMissile(mobj_t *source, mobjtype_t type);
boolean P_IsDoomnumAllowed(int doomnum);
void P_SpawnMapThing (const mapthing_t* mthing);
void P_SpawnPlayer(int n, const mapthing_t *mthing);
void P_CheckMissileSpawn(mobj_t*); // killough 8/2/98
void P_ExplodeMissile(mobj_t*); // killough
#endif

View File

@@ -0,0 +1,437 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Plats (i.e. elevator platforms) code, raising/lowering.
*
*-----------------------------------------------------------------------------*/
#include "doomstat.h"
#include "m_random.h"
#include "r_main.h"
#include "p_spec.h"
#include "p_tick.h"
#include "s_sound.h"
#include "sounds.h"
platlist_t *activeplats; // killough 2/14/98: made global again
//
// T_PlatRaise()
//
// Action routine to move a plat up and down
//
// Passed a plat structure containing all pertinent information about the move
// No return
//
// jff 02/08/98 all cases with labels beginning with gen added to support
// generalized line type behaviors.
void T_PlatRaise(plat_t* plat)
{
result_e res;
// handle plat moving, up, down, waiting, or in stasis,
switch(plat->status)
{
case up: // plat moving up
res = T_MovePlane(plat->sector,plat->speed,plat->high,plat->crush,0,1);
// if a pure raise type, make the plat moving sound
if (plat->type == raiseAndChange
|| plat->type == raiseToNearestAndChange)
{
if (!(leveltime&7))
S_StartSound((mobj_t *)&plat->sector->soundorg, sfx_stnmov);
}
// if encountered an obstacle, and not a crush type, reverse direction
if (res == crushed && (!plat->crush))
{
plat->count = plat->wait;
plat->status = down;
S_StartSound((mobj_t *)&plat->sector->soundorg, sfx_pstart);
}
else // else handle reaching end of up stroke
{
if (res == pastdest) // end of stroke
{
// if not an instant toggle type, wait, make plat stop sound
if (plat->type!=toggleUpDn)
{
plat->count = plat->wait;
plat->status = waiting;
S_StartSound((mobj_t *)&plat->sector->soundorg, sfx_pstop);
}
else // else go into stasis awaiting next toggle activation
{
plat->oldstatus = plat->status;//jff 3/14/98 after action wait
plat->status = in_stasis; //for reactivation of toggle
}
// lift types and pure raise types are done at end of up stroke
// only the perpetual type waits then goes back up
switch(plat->type)
{
case blazeDWUS:
case downWaitUpStay:
case raiseAndChange:
case raiseToNearestAndChange:
case genLift:
P_RemoveActivePlat(plat); // killough
default:
break;
}
}
}
break;
case down: // plat moving down
res = T_MovePlane(plat->sector,plat->speed,plat->low,false,0,-1);
// handle reaching end of down stroke
if (res == pastdest)
{
// if not an instant toggle, start waiting, make plat stop sound
if (plat->type!=toggleUpDn) //jff 3/14/98 toggle up down
{ // is silent, instant, no waiting
plat->count = plat->wait;
plat->status = waiting;
S_StartSound((mobj_t *)&plat->sector->soundorg,sfx_pstop);
}
else // instant toggles go into stasis awaiting next activation
{
plat->oldstatus = plat->status;//jff 3/14/98 after action wait
plat->status = in_stasis; //for reactivation of toggle
}
//jff 1/26/98 remove the plat if it bounced so it can be tried again
//only affects plats that raise and bounce
//killough 1/31/98: relax compatibility to demo_compatibility
// remove the plat if its a pure raise type
if (!comp[comp_floors])
{
switch(plat->type)
{
case raiseAndChange:
case raiseToNearestAndChange:
P_RemoveActivePlat(plat);
default:
break;
}
}
}
break;
case waiting: // plat is waiting
if (!--plat->count) // downcount and check for delay elapsed
{
if (plat->sector->floorheight == plat->low)
plat->status = up; // if at bottom, start up
else
plat->status = down; // if at top, start down
// make plat start sound
S_StartSound((mobj_t *)&plat->sector->soundorg,sfx_pstart);
}
break; //jff 1/27/98 don't pickup code added later to in_stasis
case in_stasis: // do nothing if in stasis
break;
}
}
//
// EV_DoPlat
//
// Handle Plat linedef types
//
// Passed the linedef that activated the plat, the type of plat action,
// and for some plat types, an amount to raise
// Returns true if a thinker is started, or restarted from stasis
//
int EV_DoPlat
( line_t* line,
plattype_e type,
int amount )
{
plat_t* plat;
int secnum;
int rtn;
sector_t* sec;
secnum = -1;
rtn = 0;
// Activate all <type> plats that are in_stasis
switch(type)
{
case perpetualRaise:
P_ActivateInStasis(line->tag);
break;
case toggleUpDn:
P_ActivateInStasis(line->tag);
rtn=1;
break;
default:
break;
}
// act on all sectors tagged the same as the activating linedef
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
{
sec = &sectors[secnum];
// don't start a second floor function if already moving
if (P_SectorActive(floor_special,sec)) //jff 2/23/98 multiple thinkers
continue;
// Create a thinker
rtn = 1;
plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0);
memset(plat, 0, sizeof(*plat));
P_AddThinker(&plat->thinker);
plat->type = type;
plat->sector = sec;
plat->sector->floordata = plat; //jff 2/23/98 multiple thinkers
plat->thinker.function = T_PlatRaise;
plat->crush = false;
plat->tag = line->tag;
//jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then
//going down forever -- default low to plat height when triggered
plat->low = sec->floorheight;
// set up plat according to type
switch(type)
{
case raiseToNearestAndChange:
plat->speed = PLATSPEED/2;
sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
plat->high = P_FindNextHighestFloor(sec,sec->floorheight);
plat->wait = 0;
plat->status = up;
sec->special = 0;
//jff 3/14/98 clear old field as well
sec->oldspecial = 0;
S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov);
break;
case raiseAndChange:
plat->speed = PLATSPEED/2;
sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
plat->high = sec->floorheight + amount*FRACUNIT;
plat->wait = 0;
plat->status = up;
S_StartSound((mobj_t *)&sec->soundorg,sfx_stnmov);
break;
case downWaitUpStay:
plat->speed = PLATSPEED * 4;
plat->low = P_FindLowestFloorSurrounding(sec);
if (plat->low > sec->floorheight)
plat->low = sec->floorheight;
plat->high = sec->floorheight;
plat->wait = 35*PLATWAIT;
plat->status = down;
S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
break;
case blazeDWUS:
plat->speed = PLATSPEED * 8;
plat->low = P_FindLowestFloorSurrounding(sec);
if (plat->low > sec->floorheight)
plat->low = sec->floorheight;
plat->high = sec->floorheight;
plat->wait = 35*PLATWAIT;
plat->status = down;
S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
break;
case perpetualRaise:
plat->speed = PLATSPEED;
plat->low = P_FindLowestFloorSurrounding(sec);
if (plat->low > sec->floorheight)
plat->low = sec->floorheight;
plat->high = P_FindHighestFloorSurrounding(sec);
if (plat->high < sec->floorheight)
plat->high = sec->floorheight;
plat->wait = 35*PLATWAIT;
plat->status = P_Random(pr_plats)&1;
S_StartSound((mobj_t *)&sec->soundorg,sfx_pstart);
break;
case toggleUpDn: //jff 3/14/98 add new type to support instant toggle
plat->speed = PLATSPEED; //not used
plat->wait = 35*PLATWAIT; //not used
plat->crush = true; //jff 3/14/98 crush anything in the way
// set up toggling between ceiling, floor inclusive
plat->low = sec->ceilingheight;
plat->high = sec->floorheight;
plat->status = down;
break;
default:
break;
}
P_AddActivePlat(plat); // add plat to list of active plats
}
return rtn;
}
// The following were all rewritten by Lee Killough
// to use the new structure which places no limits
// on active plats. It also avoids spending as much
// time searching for active plats. Previously a
// fixed-size array was used, with NULL indicating
// empty entries, while now a doubly-linked list
// is used.
//
// P_ActivateInStasis()
//
// Activate a plat that has been put in stasis
// (stopped perpetual floor, instant floor/ceil toggle)
//
// Passed the tag of the plat that should be reactivated
// Returns nothing
//
void P_ActivateInStasis(int tag)
{
platlist_t *pl;
for (pl=activeplats; pl; pl=pl->next) // search the active plats
{
plat_t *plat = pl->plat; // for one in stasis with right tag
if (plat->tag == tag && plat->status == in_stasis)
{
if (plat->type==toggleUpDn) //jff 3/14/98 reactivate toggle type
plat->status = plat->oldstatus==up? down : up;
else
plat->status = plat->oldstatus;
plat->thinker.function = T_PlatRaise;
}
}
}
//
// EV_StopPlat()
//
// Handler for "stop perpetual floor" linedef type
//
// Passed the linedef that stopped the plat
// Returns true if a plat was put in stasis
//
// jff 2/12/98 added int return value, fixed return
//
int EV_StopPlat(line_t* line)
{
platlist_t *pl;
for (pl=activeplats; pl; pl=pl->next) // search the active plats
{
plat_t *plat = pl->plat; // for one with the tag not in stasis
if (plat->status != in_stasis && plat->tag == line->tag)
{
plat->oldstatus = plat->status; // put it in stasis
plat->status = in_stasis;
plat->thinker.function = NULL;
}
}
return 1;
}
//
// P_AddActivePlat()
//
// Add a plat to the head of the active plat list
//
// Passed a pointer to the plat to add
// Returns nothing
//
void P_AddActivePlat(plat_t* plat)
{
platlist_t *list = malloc(sizeof *list);
list->plat = plat;
plat->list = list;
if ((list->next = activeplats))
list->next->prev = &list->next;
list->prev = &activeplats;
activeplats = list;
}
//
// P_RemoveActivePlat()
//
// Remove a plat from the active plat list
//
// Passed a pointer to the plat to remove
// Returns nothing
//
void P_RemoveActivePlat(plat_t* plat)
{
platlist_t *list = plat->list;
plat->sector->floordata = NULL; //jff 2/23/98 multiple thinkers
P_RemoveThinker(&plat->thinker);
if ((*list->prev = list->next))
list->next->prev = list->prev;
free(list);
}
//
// P_RemoveAllActivePlats()
//
// Remove all plats from the active plat list
//
// Passed nothing, returns nothing
//
void P_RemoveAllActivePlats(void)
{
while (activeplats)
{
platlist_t *next = activeplats->next;
free(activeplats);
activeplats = next;
}
}

View File

@@ -0,0 +1,865 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Weapon sprite animation, weapon objects.
* Action functions for weapons.
*
*-----------------------------------------------------------------------------*/
#include "doomstat.h"
#include "r_main.h"
#include "p_map.h"
#include "p_inter.h"
#include "p_pspr.h"
#include "p_enemy.h"
#include "m_random.h"
#include "s_sound.h"
#include "sounds.h"
#include "d_event.h"
#include "r_demo.h"
#define LOWERSPEED (FRACUNIT*6)
#define RAISESPEED (FRACUNIT*6)
#define WEAPONBOTTOM (FRACUNIT*128)
#define WEAPONTOP (FRACUNIT*32)
#define BFGCELLS bfgcells /* Ty 03/09/98 externalized in p_inter.c */
extern void P_Thrust(player_t *, angle_t, fixed_t);
// The following array holds the recoil values // phares
static const int recoil_values[] = { // phares
10, // wp_fist
10, // wp_pistol
30, // wp_shotgun
10, // wp_chaingun
100,// wp_missile
20, // wp_plasma
100,// wp_bfg
0, // wp_chainsaw
80 // wp_supershotgun
};
//
// P_SetPsprite
//
static void P_SetPsprite(player_t *player, int position, statenum_t stnum)
{
pspdef_t *psp = &player->psprites[position];
do
{
state_t *state;
if (!stnum)
{
// object removed itself
psp->state = NULL;
break;
}
state = &states[stnum];
psp->state = state;
psp->tics = state->tics; // could be 0
if (state->misc1)
{
// coordinate set
psp->sx = state->misc1 << FRACBITS;
psp->sy = state->misc2 << FRACBITS;
}
// Call action routine.
// Modified handling.
if (state->action)
{
state->action(player, psp);
if (!psp->state)
break;
}
stnum = psp->state->nextstate;
}
while (!psp->tics); // an initial state of 0 could cycle through
}
//
// P_BringUpWeapon
// Starts bringing the pending weapon up
// from the bottom of the screen.
// Uses player
//
static void P_BringUpWeapon(player_t *player)
{
statenum_t newstate;
if (player->pendingweapon == wp_nochange)
player->pendingweapon = player->readyweapon;
if (player->pendingweapon == wp_chainsaw)
S_StartSound (player->mo, sfx_sawup);
newstate = weaponinfo[player->pendingweapon].upstate;
player->pendingweapon = wp_nochange;
// killough 12/98: prevent pistol from starting visibly at bottom of screen:
player->psprites[ps_weapon].sy =
mbf_features ? WEAPONBOTTOM+FRACUNIT*2 : WEAPONBOTTOM;
P_SetPsprite(player, ps_weapon, newstate);
}
// The first set is where the weapon preferences from // killough,
// default.cfg are stored. These values represent the keys used // phares
// in DOOM2 to bring up the weapon, i.e. 6 = plasma gun. These // |
// are NOT the wp_* constants. // V
int weapon_preferences[2][NUMWEAPONS+1] = {
{6, 9, 4, 3, 2, 8, 5, 7, 1, 0}, // !compatibility preferences
{6, 9, 4, 3, 2, 8, 5, 7, 1, 0}, // compatibility preferences
};
// P_SwitchWeapon checks current ammo levels and gives you the
// most preferred weapon with ammo. It will not pick the currently
// raised weapon. When called from P_CheckAmmo this won't matter,
// because the raised weapon has no ammo anyway. When called from
// G_BuildTiccmd you want to toggle to a different weapon regardless.
int P_SwitchWeapon(player_t *player)
{
int *prefer = weapon_preferences[demo_compatibility!=0]; // killough 3/22/98
int currentweapon = player->readyweapon;
int newweapon = currentweapon;
int i = NUMWEAPONS+1; // killough 5/2/98
// killough 2/8/98: follow preferences and fix BFG/SSG bugs
do
switch (*prefer++)
{
case 1:
if (!player->powers[pw_strength]) // allow chainsaw override
break;
case 0:
newweapon = wp_fist;
break;
case 2:
if (player->ammo[am_clip])
newweapon = wp_pistol;
break;
case 3:
if (player->weaponowned[wp_shotgun] && player->ammo[am_shell])
newweapon = wp_shotgun;
break;
case 4:
if (player->weaponowned[wp_chaingun] && player->ammo[am_clip])
newweapon = wp_chaingun;
break;
case 5:
if (player->weaponowned[wp_missile] && player->ammo[am_misl])
newweapon = wp_missile;
break;
case 6:
if (player->weaponowned[wp_plasma] && player->ammo[am_cell] &&
gamemode != shareware)
newweapon = wp_plasma;
break;
case 7:
if (player->weaponowned[wp_bfg] && gamemode != shareware &&
player->ammo[am_cell] >= (demo_compatibility ? 41 : 40))
newweapon = wp_bfg;
break;
case 8:
if (player->weaponowned[wp_chainsaw])
newweapon = wp_chainsaw;
break;
case 9:
if (player->weaponowned[wp_supershotgun] && gamemode == commercial &&
player->ammo[am_shell] >= (demo_compatibility ? 3 : 2))
newweapon = wp_supershotgun;
break;
}
while (newweapon==currentweapon && --i); // killough 5/2/98
return newweapon;
}
// killough 5/2/98: whether consoleplayer prefers weapon w1 over weapon w2.
int P_WeaponPreferred(int w1, int w2)
{
return
(weapon_preferences[0][0] != ++w2 && (weapon_preferences[0][0] == ++w1 ||
(weapon_preferences[0][1] != w2 && (weapon_preferences[0][1] == w1 ||
(weapon_preferences[0][2] != w2 && (weapon_preferences[0][2] == w1 ||
(weapon_preferences[0][3] != w2 && (weapon_preferences[0][3] == w1 ||
(weapon_preferences[0][4] != w2 && (weapon_preferences[0][4] == w1 ||
(weapon_preferences[0][5] != w2 && (weapon_preferences[0][5] == w1 ||
(weapon_preferences[0][6] != w2 && (weapon_preferences[0][6] == w1 ||
(weapon_preferences[0][7] != w2 && (weapon_preferences[0][7] == w1
))))))))))))))));
}
//
// P_CheckAmmo
// Returns true if there is enough ammo to shoot.
// If not, selects the next weapon to use.
// (only in demo_compatibility mode -- killough 3/22/98)
//
boolean P_CheckAmmo(player_t *player)
{
ammotype_t ammo = weaponinfo[player->readyweapon].ammo;
int count = 1; // Regular
if (player->readyweapon == wp_bfg) // Minimal amount for one shot varies.
count = BFGCELLS;
else
if (player->readyweapon == wp_supershotgun) // Double barrel.
count = 2;
// Some do not need ammunition anyway.
// Return if current ammunition sufficient.
if (ammo == am_noammo || player->ammo[ammo] >= count)
return true;
// Out of ammo, pick a weapon to change to.
//
// killough 3/22/98: for old demos we do the switch here and now;
// for Boom games we cannot do this, and have different player
// preferences across demos or networks, so we have to use the
// G_BuildTiccmd() interface instead of making the switch here.
if (demo_compatibility)
{
player->pendingweapon = P_SwitchWeapon(player); // phares
// Now set appropriate weapon overlay.
P_SetPsprite(player,ps_weapon,weaponinfo[player->readyweapon].downstate);
}
return false;
}
//
// P_FireWeapon.
//
static void P_FireWeapon(player_t *player)
{
statenum_t newstate;
if (!P_CheckAmmo(player))
return;
P_SetMobjState(player->mo, S_PLAY_ATK1);
newstate = weaponinfo[player->readyweapon].atkstate;
P_SetPsprite(player, ps_weapon, newstate);
P_NoiseAlert(player->mo, player->mo);
}
//
// P_DropWeapon
// Player died, so put the weapon away.
//
void P_DropWeapon(player_t *player)
{
P_SetPsprite(player, ps_weapon, weaponinfo[player->readyweapon].downstate);
}
//
// A_WeaponReady
// The player can fire the weapon
// or change to another weapon at this time.
// Follows after getting weapon up,
// or after previous attack/fire sequence.
//
void A_WeaponReady(player_t *player, pspdef_t *psp)
{
// get out of attack state
if (player->mo->state == &states[S_PLAY_ATK1]
|| player->mo->state == &states[S_PLAY_ATK2] )
P_SetMobjState(player->mo, S_PLAY);
if (player->readyweapon == wp_chainsaw && psp->state == &states[S_SAW])
S_StartSound(player->mo, sfx_sawidl);
// check for change
// if player is dead, put the weapon away
if (player->pendingweapon != wp_nochange || !player->health)
{
// change weapon (pending weapon should already be validated)
statenum_t newstate = weaponinfo[player->readyweapon].downstate;
P_SetPsprite(player, ps_weapon, newstate);
return;
}
// check for fire
// the missile launcher and bfg do not auto fire
if (player->cmd.buttons & BT_ATTACK)
{
if (!player->attackdown || (player->readyweapon != wp_missile &&
player->readyweapon != wp_bfg))
{
player->attackdown = true;
P_FireWeapon(player);
return;
}
}
else
player->attackdown = false;
// bob the weapon based on movement speed
{
int angle = (128*leveltime) & FINEMASK;
psp->sx = FRACUNIT + FixedMul(player->bob, finecosine[angle]);
angle &= FINEANGLES/2-1;
psp->sy = WEAPONTOP + FixedMul(player->bob, finesine[angle]);
}
}
//
// A_ReFire
// The player can re-fire the weapon
// without lowering it entirely.
//
void A_ReFire(player_t *player, pspdef_t *psp)
{
// check for fire
// (if a weaponchange is pending, let it go through instead)
if ( (player->cmd.buttons & BT_ATTACK)
&& player->pendingweapon == wp_nochange && player->health)
{
player->refire++;
P_FireWeapon(player);
}
else
{
player->refire = 0;
P_CheckAmmo(player);
}
}
void A_CheckReload(player_t *player, pspdef_t *psp)
{
if (!P_CheckAmmo(player) && compatibility_level >= prboom_4_compatibility) {
/* cph 2002/08/08 - In old Doom, P_CheckAmmo would start the weapon lowering
* immediately. This was lost in Boom when the weapon switching logic was
* rewritten. But we must tell Doom that we don't need to complete the
* reload frames for the weapon here. G_BuildTiccmd will set ->pendingweapon
* for us later on. */
P_SetPsprite(player,ps_weapon,weaponinfo[player->readyweapon].downstate);
}
}
//
// A_Lower
// Lowers current weapon,
// and changes weapon at bottom.
//
void A_Lower(player_t *player, pspdef_t *psp)
{
psp->sy += LOWERSPEED;
// Is already down.
if (psp->sy < WEAPONBOTTOM)
return;
// Player is dead.
if (player->playerstate == PST_DEAD)
{
psp->sy = WEAPONBOTTOM;
return; // don't bring weapon back up
}
// The old weapon has been lowered off the screen,
// so change the weapon and start raising it
if (!player->health)
{ // Player is dead, so keep the weapon off screen.
P_SetPsprite(player, ps_weapon, S_NULL);
return;
}
player->readyweapon = player->pendingweapon;
P_BringUpWeapon(player);
}
//
// A_Raise
//
void A_Raise(player_t *player, pspdef_t *psp)
{
statenum_t newstate;
psp->sy -= RAISESPEED;
if (psp->sy > WEAPONTOP)
return;
psp->sy = WEAPONTOP;
// The weapon has been raised all the way,
// so change to the ready state.
newstate = weaponinfo[player->readyweapon].readystate;
P_SetPsprite(player, ps_weapon, newstate);
}
// Weapons now recoil, amount depending on the weapon. // phares
// // |
// The P_SetPsprite call in each of the weapon firing routines // V
// was moved here so the recoil could be synched with the
// muzzle flash, rather than the pressing of the trigger.
// The BFG delay caused this to be necessary.
static void A_FireSomething(player_t* player,int adder)
{
P_SetPsprite(player, ps_flash,
weaponinfo[player->readyweapon].flashstate+adder);
// killough 3/27/98: prevent recoil in no-clipping mode
if (!(player->mo->flags & MF_NOCLIP))
if (!compatibility && weapon_recoil)
P_Thrust(player,
ANG180+player->mo->angle, // ^
2048*recoil_values[player->readyweapon]); // |
} // phares
//
// A_GunFlash
//
void A_GunFlash(player_t *player, pspdef_t *psp)
{
P_SetMobjState(player->mo, S_PLAY_ATK2);
A_FireSomething(player,0); // phares
}
//
// WEAPON ATTACKS
//
//
// A_Punch
//
void A_Punch(player_t *player, pspdef_t *psp)
{
angle_t angle;
int t, slope, damage = (P_Random(pr_punch)%10+1)<<1;
if (player->powers[pw_strength])
damage *= 10;
angle = player->mo->angle;
// killough 5/5/98: remove dependence on order of evaluation:
t = P_Random(pr_punchangle);
angle += (t - P_Random(pr_punchangle))<<18;
/* killough 8/2/98: make autoaiming prefer enemies */
if (!mbf_features ||
(slope = P_AimLineAttack(player->mo, angle, MELEERANGE, MF_FRIEND),
!linetarget))
slope = P_AimLineAttack(player->mo, angle, MELEERANGE, 0);
P_LineAttack(player->mo, angle, MELEERANGE, slope, damage);
if (!linetarget)
return;
S_StartSound(player->mo, sfx_punch);
// turn to face target
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y,
linetarget->x, linetarget->y);
R_SmoothPlaying_Reset(player); // e6y
}
//
// A_Saw
//
void A_Saw(player_t *player, pspdef_t *psp)
{
int slope, damage = 2*(P_Random(pr_saw)%10+1);
angle_t angle = player->mo->angle;
// killough 5/5/98: remove dependence on order of evaluation:
int t = P_Random(pr_saw);
angle += (t - P_Random(pr_saw))<<18;
/* Use meleerange + 1 so that the puff doesn't skip the flash
* killough 8/2/98: make autoaiming prefer enemies */
if (!mbf_features ||
(slope = P_AimLineAttack(player->mo, angle, MELEERANGE+1, MF_FRIEND),
!linetarget))
slope = P_AimLineAttack(player->mo, angle, MELEERANGE+1, 0);
P_LineAttack(player->mo, angle, MELEERANGE+1, slope, damage);
if (!linetarget)
{
S_StartSound(player->mo, sfx_sawful);
return;
}
S_StartSound(player->mo, sfx_sawhit);
// turn to face target
angle = R_PointToAngle2(player->mo->x, player->mo->y,
linetarget->x, linetarget->y);
if (angle - player->mo->angle > ANG180) {
if (angle - player->mo->angle < -ANG90/20)
player->mo->angle = angle + ANG90/21;
else
player->mo->angle -= ANG90/20;
} else {
if (angle - player->mo->angle > ANG90/20)
player->mo->angle = angle - ANG90/21;
else
player->mo->angle += ANG90/20;
}
player->mo->flags |= MF_JUSTATTACKED;
R_SmoothPlaying_Reset(player); // e6y
}
//
// A_FireMissile
//
void A_FireMissile(player_t *player, pspdef_t *psp)
{
player->ammo[weaponinfo[player->readyweapon].ammo]--;
P_SpawnPlayerMissile(player->mo, MT_ROCKET);
}
//
// A_FireBFG
//
void A_FireBFG(player_t *player, pspdef_t *psp)
{
player->ammo[weaponinfo[player->readyweapon].ammo] -= BFGCELLS;
P_SpawnPlayerMissile(player->mo, MT_BFG);
}
//
// A_FirePlasma
//
void A_FirePlasma(player_t *player, pspdef_t *psp)
{
player->ammo[weaponinfo[player->readyweapon].ammo]--;
A_FireSomething(player,P_Random(pr_plasma)&1); // phares
P_SpawnPlayerMissile(player->mo, MT_PLASMA);
}
//
// P_BulletSlope
// Sets a slope so a near miss is at aproximately
// the height of the intended target
//
static fixed_t bulletslope;
#ifdef IPHONE // add some auto-aim to compensate for the touch screen controls
static angle_t autoAimAngle;
static void P_BulletSlope(mobj_t *mo)
{
int aim;
angle_t an = mo->angle; // see which target is to be aimed at
autoAimAngle = an;
for ( aim = 0 ; aim < 5 ; aim++ ) {
if ( aim & 1 ) {
an += aim<<26;
} else {
an -= aim<<26;
}
bulletslope = P_AimLineAttack(mo, an, 16*64*FRACUNIT, 0);
if ( linetarget ) {
// this will be a hit
if ( aim > 0 ) {
printf( "auto-aim hit on %i\n", aim ); // !@#
}
autoAimAngle = an;
break;
}
}
}
#else
static void P_BulletSlope(mobj_t *mo)
{
angle_t an = mo->angle; // see which target is to be aimed at
/* killough 8/2/98: make autoaiming prefer enemies */
uint_64_t mask = mbf_features ? MF_FRIEND : 0;
do
{
bulletslope = P_AimLineAttack(mo, an, 16*64*FRACUNIT, mask);
if (!linetarget)
bulletslope = P_AimLineAttack(mo, an += 1<<26, 16*64*FRACUNIT, mask);
if (!linetarget)
bulletslope = P_AimLineAttack(mo, an -= 2<<26, 16*64*FRACUNIT, mask);
}
while (mask && (mask=0, !linetarget)); /* killough 8/2/98 */
}
#endif
//
// P_GunShot
//
static void P_GunShot(mobj_t *mo, boolean accurate)
{
int damage = 5*(P_Random(pr_gunshot)%3+1);
angle_t angle = mo->angle;
#ifdef IPHONE
if ( !demoplayback ) {
angle = autoAimAngle;
}
#endif
if (!accurate)
{ // killough 5/5/98: remove dependence on order of evaluation:
int t = P_Random(pr_misfire);
angle += (t - P_Random(pr_misfire))<<18;
}
P_LineAttack(mo, angle, MISSILERANGE, bulletslope, damage);
}
//
// A_FirePistol
//
void A_FirePistol(player_t *player, pspdef_t *psp)
{
S_StartSound(player->mo, sfx_pistol);
P_SetMobjState(player->mo, S_PLAY_ATK2);
player->ammo[weaponinfo[player->readyweapon].ammo]--;
A_FireSomething(player,0); // phares
P_BulletSlope(player->mo);
P_GunShot(player->mo, !player->refire);
}
//
// A_FireShotgun
//
void A_FireShotgun(player_t *player, pspdef_t *psp)
{
int i;
S_StartSound(player->mo, sfx_shotgn);
P_SetMobjState(player->mo, S_PLAY_ATK2);
player->ammo[weaponinfo[player->readyweapon].ammo]--;
A_FireSomething(player,0); // phares
P_BulletSlope(player->mo);
for (i=0; i<7; i++)
P_GunShot(player->mo, false);
}
//
// A_FireShotgun2
//
void A_FireShotgun2(player_t *player, pspdef_t *psp)
{
int i;
S_StartSound(player->mo, sfx_dshtgn);
P_SetMobjState(player->mo, S_PLAY_ATK2);
player->ammo[weaponinfo[player->readyweapon].ammo] -= 2;
A_FireSomething(player,0); // phares
P_BulletSlope(player->mo);
for (i=0; i<20; i++)
{
int damage = 5*(P_Random(pr_shotgun)%3+1);
angle_t angle = player->mo->angle;
// killough 5/5/98: remove dependence on order of evaluation:
int t = P_Random(pr_shotgun);
angle += (t - P_Random(pr_shotgun))<<19;
t = P_Random(pr_shotgun);
P_LineAttack(player->mo, angle, MISSILERANGE, bulletslope +
((t - P_Random(pr_shotgun))<<5), damage);
}
}
//
// A_FireCGun
//
void A_FireCGun(player_t *player, pspdef_t *psp)
{
if (player->ammo[weaponinfo[player->readyweapon].ammo] || comp[comp_sound])
S_StartSound(player->mo, sfx_pistol);
if (!player->ammo[weaponinfo[player->readyweapon].ammo])
return;
P_SetMobjState(player->mo, S_PLAY_ATK2);
player->ammo[weaponinfo[player->readyweapon].ammo]--;
A_FireSomething(player,psp->state - &states[S_CHAIN1]); // phares
P_BulletSlope(player->mo);
P_GunShot(player->mo, !player->refire);
}
void A_Light0(player_t *player, pspdef_t *psp)
{
player->extralight = 0;
}
void A_Light1 (player_t *player, pspdef_t *psp)
{
player->extralight = 1;
}
void A_Light2 (player_t *player, pspdef_t *psp)
{
player->extralight = 2;
}
//
// A_BFGSpray
// Spawn a BFG explosion on every monster in view
//
void A_BFGSpray(mobj_t *mo)
{
int i;
for (i=0 ; i<40 ; i++) // offset angles from its attack angle
{
int j, damage;
angle_t an = mo->angle - ANG90/2 + ANG90/40*i;
// mo->target is the originator (player) of the missile
// killough 8/2/98: make autoaiming prefer enemies
if (!mbf_features ||
(P_AimLineAttack(mo->target, an, 16*64*FRACUNIT, MF_FRIEND),
!linetarget))
P_AimLineAttack(mo->target, an, 16*64*FRACUNIT, 0);
if (!linetarget)
continue;
P_SpawnMobj(linetarget->x, linetarget->y,
linetarget->z + (linetarget->height>>2), MT_EXTRABFG);
for (damage=j=0; j<15; j++)
damage += (P_Random(pr_bfg)&7) + 1;
P_DamageMobj(linetarget, mo->target, mo->target, damage);
}
}
//
// A_BFGsound
//
void A_BFGsound(player_t *player, pspdef_t *psp)
{
S_StartSound(player->mo, sfx_bfg);
}
//
// P_SetupPsprites
// Called at start of level for each player.
//
void P_SetupPsprites(player_t *player)
{
int i;
// remove all psprites
for (i=0; i<NUMPSPRITES; i++)
player->psprites[i].state = NULL;
// spawn the gun
player->pendingweapon = player->readyweapon;
P_BringUpWeapon(player);
}
//
// P_MovePsprites
// Called every tic by player thinking routine.
//
void P_MovePsprites(player_t *player)
{
pspdef_t *psp = player->psprites;
int i;
// a null state means not active
// drop tic count and possibly change state
// a -1 tic count never changes
for (i=0; i<NUMPSPRITES; i++, psp++)
if (psp->state && psp->tics != -1 && !--psp->tics)
P_SetPsprite(player, i, psp->state->nextstate);
player->psprites[ps_flash].sx = player->psprites[ps_weapon].sx;
player->psprites[ps_flash].sy = player->psprites[ps_weapon].sy;
}

View File

@@ -0,0 +1,119 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Sprite animation.
*
*-----------------------------------------------------------------------------*/
#ifndef __P_PSPR__
#define __P_PSPR__
/* Basic data types.
* Needs fixed point, and BAM angles. */
#include "m_fixed.h"
#include "tables.h"
/* Needs to include the precompiled sprite animation tables.
*
* Header generated by multigen utility.
* This includes all the data for thing animation,
* i.e. the Thing Atrributes table and the Frame Sequence table.
*/
#include "info.h"
#ifdef __GNUG__
#pragma interface
#endif
/*
* Frame flags:
* handles maximum brightness (torches, muzzle flare, light sources)
*/
#define FF_FULLBRIGHT 0x8000 /* flag in thing->frame */
#define FF_FRAMEMASK 0x7fff
/*
* Overlay psprites are scaled shapes
* drawn directly on the view screen,
* coordinates are given for a 320*200 view screen.
*/
typedef enum
{
ps_weapon,
ps_flash,
NUMPSPRITES
} psprnum_t;
typedef struct
{
state_t *state; /* a NULL state means not active */
int tics;
fixed_t sx;
fixed_t sy;
} pspdef_t;
extern int weapon_preferences[2][NUMWEAPONS+1]; /* killough 5/2/98 */
int P_WeaponPreferred(int w1, int w2);
struct player_s;
int P_SwitchWeapon(struct player_s *player);
boolean P_CheckAmmo(struct player_s *player);
void P_SetupPsprites(struct player_s *curplayer);
void P_MovePsprites(struct player_s *curplayer);
void P_DropWeapon(struct player_s *player);
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();
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,66 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Savegame I/O, archiving, persistence.
*
*-----------------------------------------------------------------------------*/
#ifndef __P_SAVEG__
#define __P_SAVEG__
#ifdef __GNUG__
#pragma interface
#endif
/* Persistent storage/archiving.
* These are the load / save game routines. */
void P_ArchivePlayers(void);
void P_UnArchivePlayers(void);
void P_ArchiveWorld(void);
void P_UnArchiveWorld(void);
void P_ArchiveThinkers(void);
void P_UnArchiveThinkers(void);
void P_ArchiveSpecials(void);
void P_UnArchiveSpecials(void);
void P_ThinkerToIndex(void); /* phares 9/13/98: save soundtarget in savegame */
void P_IndexToThinker(void); /* phares 9/13/98: save soundtarget in savegame */
/* 1/18/98 killough: add RNG info to savegame */
void P_ArchiveRNG(void);
void P_UnArchiveRNG(void);
/* 2/21/98 killough: add automap info to savegame */
void P_ArchiveMap(void);
void P_UnArchiveMap(void);
extern byte *save_p;
void CheckSaveGame(size_t,const char*, int); /* killough */
#define CheckSaveGame(a) (CheckSaveGame)(a, __FILE__, __LINE__)
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,57 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Setup a game, startup stuff.
*
*-----------------------------------------------------------------------------*/
#ifndef __P_SETUP__
#define __P_SETUP__
#include "p_mobj.h"
#ifdef __GNUG__
#pragma interface
#endif
void P_SetupLevel(int episode, int map, int playermask, skill_t skill);
void P_Init(void); /* Called by startup code. */
extern const byte *rejectmatrix; /* for fast sight rejection - cph - const* */
/* killough 3/1/98: change blockmap from "short" to "long" offsets: */
extern long *blockmaplump; /* offsets in blockmap are from here */
extern long *blockmap;
extern int bmapwidth;
extern int bmapheight; /* in mapblocks */
extern fixed_t bmaporgx;
extern fixed_t bmaporgy; /* origin of block map */
extern mobj_t **blocklinks; /* for thing chains */
#endif

View File

@@ -0,0 +1,338 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* LineOfSight/Visibility checks, uses REJECT Lookup Table.
*
*-----------------------------------------------------------------------------*/
#include "doomstat.h"
#include "r_main.h"
#include "p_map.h"
#include "p_maputl.h"
#include "p_setup.h"
#include "m_bbox.h"
#include "lprintf.h"
//
// P_CheckSight
//
// killough 4/19/98:
// Convert LOS info to struct for reentrancy and efficiency of data locality
typedef struct {
fixed_t sightzstart, t2x, t2y; // eye z of looker
divline_t strace; // from t1 to t2
fixed_t topslope, bottomslope; // slopes to top and bottom of target
fixed_t bbox[4];
fixed_t maxz,minz; // cph - z optimisations for 2sided lines
} los_t;
static los_t los; // cph - made static
//
// P_DivlineSide
// Returns side 0 (front), 1 (back), or 2 (on).
//
// killough 4/19/98: made static, cleaned up
inline static int P_DivlineSide(fixed_t x, fixed_t y, const divline_t *node)
{
fixed_t left, right;
return
!node->dx ? x == node->x ? 2 : x <= node->x ? node->dy > 0 : node->dy < 0 :
!node->dy ? ( compatibility_level < prboom_4_compatibility ? x : y) == node->y ? 2 : y <= node->y ? node->dx < 0 : node->dx > 0 :
(right = ((y - node->y) >> FRACBITS) * (node->dx >> FRACBITS)) <
(left = ((x - node->x) >> FRACBITS) * (node->dy >> FRACBITS)) ? 0 :
right == left ? 2 : 1;
}
//
// P_CrossSubsector
// Returns true
// if strace crosses the given subsector successfully.
//
// killough 4/19/98: made static and cleaned up
static boolean P_CrossSubsector(int num)
{
seg_t *seg = segs + subsectors[num].firstline;
int count;
fixed_t opentop = 0, openbottom = 0;
const sector_t *front = NULL, *back = NULL;
#ifdef RANGECHECK
if (num >= numsubsectors)
I_Error("P_CrossSubsector: ss %i with numss = %i", num, numsubsectors);
#endif
for (count = subsectors[num].numlines; --count >= 0; seg++) { // check lines
line_t *line = seg->linedef;
divline_t divl;
if(!line) // figgi -- skip minisegs
continue;
// allready checked other side?
if (line->validcount == validcount)
continue;
line->validcount = validcount;
/* OPTIMIZE: killough 4/20/98: Added quick bounding-box rejection test
* cph - this is causing demo desyncs on original Doom demos.
* Who knows why. Exclude test for those.
*/
if (!demo_compatibility)
if (line->bbox[BOXLEFT ] > los.bbox[BOXRIGHT ] ||
line->bbox[BOXRIGHT ] < los.bbox[BOXLEFT ] ||
line->bbox[BOXBOTTOM] > los.bbox[BOXTOP ] ||
line->bbox[BOXTOP] < los.bbox[BOXBOTTOM])
continue;
// cph - do what we can before forced to check intersection
if (line->flags & ML_TWOSIDED) {
// no wall to block sight with?
if ((front = seg->frontsector)->floorheight ==
(back = seg->backsector)->floorheight &&
front->ceilingheight == back->ceilingheight)
continue;
// possible occluder
// because of ceiling height differences
opentop = front->ceilingheight < back->ceilingheight ?
front->ceilingheight : back->ceilingheight ;
// because of floor height differences
openbottom = front->floorheight > back->floorheight ?
front->floorheight : back->floorheight ;
// cph - reject if does not intrude in the z-space of the possible LOS
if ((opentop >= los.maxz) && (openbottom <= los.minz))
continue;
}
{ // Forget this line if it doesn't cross the line of sight
const vertex_t *v1,*v2;
v1 = line->v1;
v2 = line->v2;
if (P_DivlineSide(v1->x, v1->y, &los.strace) ==
P_DivlineSide(v2->x, v2->y, &los.strace))
continue;
divl.dx = v2->x - (divl.x = v1->x);
divl.dy = v2->y - (divl.y = v1->y);
// line isn't crossed?
if (P_DivlineSide(los.strace.x, los.strace.y, &divl) ==
P_DivlineSide(los.t2x, los.t2y, &divl))
continue;
}
// cph - if bottom >= top or top < minz or bottom > maxz then it must be
// solid wrt this LOS
if (!(line->flags & ML_TWOSIDED) || (openbottom >= opentop) ||
(opentop < los.minz) || (openbottom > los.maxz))
return false;
{ // crosses a two sided line
/* cph 2006/07/15 - oops, we missed this in 2.4.0 & .1;
* use P_InterceptVector2 for those compat levels only. */
fixed_t frac = (compatibility_level == prboom_5_compatibility || compatibility_level == prboom_6_compatibility) ?
P_InterceptVector2(&los.strace, &divl) :
P_InterceptVector(&los.strace, &divl);
if (front->floorheight != back->floorheight) {
fixed_t slope = FixedDiv(openbottom - los.sightzstart , frac);
if (slope > los.bottomslope)
los.bottomslope = slope;
}
if (front->ceilingheight != back->ceilingheight)
{
fixed_t slope = FixedDiv(opentop - los.sightzstart , frac);
if (slope < los.topslope)
los.topslope = slope;
}
if (los.topslope <= los.bottomslope)
return false; // stop
}
}
// passed the subsector ok
return true;
}
//
// P_CrossBSPNode
// Returns true
// if strace crosses the given node successfully.
//
// killough 4/20/98: rewritten to remove tail recursion, clean up, and optimize
// cph - Made to use R_PointOnSide instead of P_DivlineSide, since the latter
// could return 2 which was ambigous, and the former is
// better optimised; also removes two casts :-)
static boolean P_CrossBSPNode_LxDoom(int bspnum)
{
while (!(bspnum & NF_SUBSECTOR))
{
register const node_t *bsp = nodes + bspnum;
int side,side2;
side = R_PointOnSide(los.strace.x, los.strace.y, bsp);
side2 = R_PointOnSide(los.t2x, los.t2y, bsp);
if (side == side2)
bspnum = bsp->children[side]; // doesn't touch the other side
else // the partition plane is crossed here
if (!P_CrossBSPNode_LxDoom(bsp->children[side]))
return 0; // cross the starting side
else
bspnum = bsp->children[side^1]; // cross the ending side
}
return P_CrossSubsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR);
}
static boolean P_CrossBSPNode_PrBoom(int bspnum)
{
while (!(bspnum & NF_SUBSECTOR))
{
register const node_t *bsp = nodes + bspnum;
int side,side2;
side = P_DivlineSide(los.strace.x,los.strace.y,(const divline_t *)bsp)&1;
side2= P_DivlineSide(los.t2x, los.t2y, (const divline_t *) bsp);
if (side == side2)
bspnum = bsp->children[side]; // doesn't touch the other side
else // the partition plane is crossed here
if (!P_CrossBSPNode_PrBoom(bsp->children[side]))
return 0; // cross the starting side
else
bspnum = bsp->children[side^1]; // cross the ending side
}
return P_CrossSubsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR);
}
/* proff - Moved the compatibility check outside the functions
* this gives a slight speedup
*/
static boolean P_CrossBSPNode(int bspnum)
{
/* cph - LxDoom used some R_* funcs here */
if (compatibility_level == lxdoom_1_compatibility)
return P_CrossBSPNode_LxDoom(bspnum);
else
return P_CrossBSPNode_PrBoom(bspnum);
}
//
// P_CheckSight
// Returns true
// if a straight line between t1 and t2 is unobstructed.
// Uses REJECT.
//
// killough 4/20/98: cleaned up, made to use new LOS struct
boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
{
const sector_t *s1 = t1->subsector->sector;
const sector_t *s2 = t2->subsector->sector;
int pnum = (s1-sectors)*numsectors + (s2-sectors);
// First check for trivial rejection.
// Determine subsector entries in REJECT table.
//
// Check in REJECT table.
if (rejectmatrix[pnum>>3] & (1 << (pnum&7))) // can't possibly be connected
return false;
// killough 4/19/98: make fake floors and ceilings block monster view
if ((s1->heightsec != -1 &&
((t1->z + t1->height <= sectors[s1->heightsec].floorheight &&
t2->z >= sectors[s1->heightsec].floorheight) ||
(t1->z >= sectors[s1->heightsec].ceilingheight &&
t2->z + t1->height <= sectors[s1->heightsec].ceilingheight)))
||
(s2->heightsec != -1 &&
((t2->z + t2->height <= sectors[s2->heightsec].floorheight &&
t1->z >= sectors[s2->heightsec].floorheight) ||
(t2->z >= sectors[s2->heightsec].ceilingheight &&
t1->z + t2->height <= sectors[s2->heightsec].ceilingheight))))
return false;
/* killough 11/98: shortcut for melee situations
* same subsector? obviously visible
* cph - compatibility optioned for demo sync, cf HR06-UV.LMP */
if ((t1->subsector == t2->subsector) &&
(compatibility_level >= mbf_compatibility))
return true;
// An unobstructed LOS is possible.
// Now look from eyes of t1 to any part of t2.
validcount++;
los.topslope = (los.bottomslope = t2->z - (los.sightzstart =
t1->z + t1->height -
(t1->height>>2))) + t2->height;
los.strace.dx = (los.t2x = t2->x) - (los.strace.x = t1->x);
los.strace.dy = (los.t2y = t2->y) - (los.strace.y = t1->y);
if (t1->x > t2->x)
los.bbox[BOXRIGHT] = t1->x, los.bbox[BOXLEFT] = t2->x;
else
los.bbox[BOXRIGHT] = t2->x, los.bbox[BOXLEFT] = t1->x;
if (t1->y > t2->y)
los.bbox[BOXTOP] = t1->y, los.bbox[BOXBOTTOM] = t2->y;
else
los.bbox[BOXTOP] = t2->y, los.bbox[BOXBOTTOM] = t1->y;
/* cph - calculate min and max z of the potential line of sight
* For old demos, we disable this optimisation by setting them to
* the extremes */
switch (compatibility_level) {
case lxdoom_1_compatibility:
if (los.sightzstart < t2->z) {
los.maxz = t2->z + t2->height; los.minz = los.sightzstart;
} else if (los.sightzstart > t2->z + t2->height) {
los.maxz = los.sightzstart; los.minz = t2->z;
} else {
los.maxz = t2->z + t2->height; los.minz = t2->z;
}
break;
default:
los.maxz = INT_MAX; los.minz = INT_MIN;
}
// the head node is the last node output
return P_CrossBSPNode(numnodes-1);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,345 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2002 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Teleportation.
*
*-----------------------------------------------------------------------------*/
#include "doomdef.h"
#include "doomstat.h"
#include "p_spec.h"
#include "p_maputl.h"
#include "p_map.h"
#include "r_main.h"
#include "p_tick.h"
#include "s_sound.h"
#include "sounds.h"
#include "p_user.h"
#include "r_demo.h"
static mobj_t* P_TeleportDestination(line_t* line)
{
int i;
for (i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;) {
register thinker_t* th = NULL;
while ((th = P_NextThinker(th,th_misc)) != NULL)
if (th->function == P_MobjThinker) {
register mobj_t* m = (mobj_t*)th;
if (m->type == MT_TELEPORTMAN &&
m->subsector->sector-sectors == i)
return m;
}
}
return NULL;
}
//
// TELEPORTATION
//
// killough 5/3/98: reformatted, cleaned up
int EV_Teleport(line_t *line, int side, mobj_t *thing)
{
mobj_t *m;
// don't teleport missiles
// Don't teleport if hit back of line,
// so you can get out of teleporter.
if (side || thing->flags & MF_MISSILE)
return 0;
// killough 1/31/98: improve performance by using
// P_FindSectorFromLineTag instead of simple linear search.
if ((m = P_TeleportDestination(line)) != NULL)
{
fixed_t oldx = thing->x, oldy = thing->y, oldz = thing->z;
player_t *player = thing->player;
// killough 5/12/98: exclude voodoo dolls:
if (player && player->mo != thing)
player = NULL;
if (!P_TeleportMove(thing, m->x, m->y, false)) /* killough 8/9/98 */
return 0;
if (compatibility_level != finaldoom_compatibility)
thing->z = thing->floorz;
if (player)
player->viewz = thing->z + player->viewheight;
// spawn teleport fog and emit sound at source
S_StartSound(P_SpawnMobj(oldx, oldy, oldz, MT_TFOG), sfx_telept);
// spawn teleport fog and emit sound at destination
S_StartSound(P_SpawnMobj(m->x +
20*finecosine[m->angle>>ANGLETOFINESHIFT],
m->y +
20*finesine[m->angle>>ANGLETOFINESHIFT],
thing->z, MT_TFOG),
sfx_telept);
/* don't move for a bit
* cph - DEMOSYNC - BOOM had (player) here? */
if (thing->player)
thing->reactiontime = 18;
thing->angle = m->angle;
thing->momx = thing->momy = thing->momz = 0;
/* killough 10/98: kill all bobbing momentum too */
if (player)
player->momx = player->momy = 0;
// e6y
if (player && player->mo == thing)
R_ResetAfterTeleport(player);
return 1;
}
return 0;
}
//
// Silent TELEPORTATION, by Lee Killough
// Primarily for rooms-over-rooms etc.
//
int EV_SilentTeleport(line_t *line, int side, mobj_t *thing)
{
mobj_t *m;
// don't teleport missiles
// Don't teleport if hit back of line,
// so you can get out of teleporter.
if (side || thing->flags & MF_MISSILE)
return 0;
if ((m = P_TeleportDestination(line)) != NULL)
{
// Height of thing above ground, in case of mid-air teleports:
fixed_t z = thing->z - thing->floorz;
// Get the angle between the exit thing and source linedef.
// Rotate 90 degrees, so that walking perpendicularly across
// teleporter linedef causes thing to exit in the direction
// indicated by the exit thing.
angle_t angle =
R_PointToAngle2(0, 0, line->dx, line->dy) - m->angle + ANG90;
// Sine, cosine of angle adjustment
fixed_t s = finesine[angle>>ANGLETOFINESHIFT];
fixed_t c = finecosine[angle>>ANGLETOFINESHIFT];
// Momentum of thing crossing teleporter linedef
fixed_t momx = thing->momx;
fixed_t momy = thing->momy;
// Whether this is a player, and if so, a pointer to its player_t
player_t *player = thing->player;
// Attempt to teleport, aborting if blocked
if (!P_TeleportMove(thing, m->x, m->y, false)) /* killough 8/9/98 */
return 0;
// Rotate thing according to difference in angles
thing->angle += angle;
// Adjust z position to be same height above ground as before
thing->z = z + thing->floorz;
// Rotate thing's momentum to come out of exit just like it entered
thing->momx = FixedMul(momx, c) - FixedMul(momy, s);
thing->momy = FixedMul(momy, c) + FixedMul(momx, s);
// Adjust player's view, in case there has been a height change
// Voodoo dolls are excluded by making sure player->mo == thing.
if (player && player->mo == thing)
{
// Save the current deltaviewheight, used in stepping
fixed_t deltaviewheight = player->deltaviewheight;
// Clear deltaviewheight, since we don't want any changes
player->deltaviewheight = 0;
// Set player's view according to the newly set parameters
P_CalcHeight(player);
// Reset the delta to have the same dynamics as before
player->deltaviewheight = deltaviewheight;
}
// e6y
if (player && player->mo == thing)
R_ResetAfterTeleport(player);
return 1;
}
return 0;
}
//
// Silent linedef-based TELEPORTATION, by Lee Killough
// Primarily for rooms-over-rooms etc.
// This is the complete player-preserving kind of teleporter.
// It has advantages over the teleporter with thing exits.
//
// maximum fixed_t units to move object to avoid hiccups
#define FUDGEFACTOR 10
int EV_SilentLineTeleport(line_t *line, int side, mobj_t *thing,
boolean reverse)
{
int i;
line_t *l;
if (side || thing->flags & MF_MISSILE)
return 0;
for (i = -1; (i = P_FindLineFromLineTag(line, i)) >= 0;)
if ((l=lines+i) != line && l->backsector)
{
// Get the thing's position along the source linedef
fixed_t pos = D_abs(line->dx) > D_abs(line->dy) ?
FixedDiv(thing->x - line->v1->x, line->dx) :
FixedDiv(thing->y - line->v1->y, line->dy) ;
// Get the angle between the two linedefs, for rotating
// orientation and momentum. Rotate 180 degrees, and flip
// the position across the exit linedef, if reversed.
angle_t angle = (reverse ? pos = FRACUNIT-pos, 0 : ANG180) +
R_PointToAngle2(0, 0, l->dx, l->dy) -
R_PointToAngle2(0, 0, line->dx, line->dy);
// Interpolate position across the exit linedef
fixed_t x = l->v2->x - FixedMul(pos, l->dx);
fixed_t y = l->v2->y - FixedMul(pos, l->dy);
// Sine, cosine of angle adjustment
fixed_t s = finesine[angle>>ANGLETOFINESHIFT];
fixed_t c = finecosine[angle>>ANGLETOFINESHIFT];
// Maximum distance thing can be moved away from interpolated
// exit, to ensure that it is on the correct side of exit linedef
int fudge = FUDGEFACTOR;
// Whether this is a player, and if so, a pointer to its player_t.
// Voodoo dolls are excluded by making sure thing->player->mo==thing.
player_t *player = thing->player && thing->player->mo == thing ?
thing->player : NULL;
// Whether walking towards first side of exit linedef steps down
int stepdown =
l->frontsector->floorheight < l->backsector->floorheight;
// Height of thing above ground
fixed_t z = thing->z - thing->floorz;
// Side to exit the linedef on positionally.
//
// Notes:
//
// This flag concerns exit position, not momentum. Due to
// roundoff error, the thing can land on either the left or
// the right side of the exit linedef, and steps must be
// taken to make sure it does not end up on the wrong side.
//
// Exit momentum is always towards side 1 in a reversed
// teleporter, and always towards side 0 otherwise.
//
// Exiting positionally on side 1 is always safe, as far
// as avoiding oscillations and stuck-in-wall problems,
// but may not be optimum for non-reversed teleporters.
//
// Exiting on side 0 can cause oscillations if momentum
// is towards side 1, as it is with reversed teleporters.
//
// Exiting on side 1 slightly improves player viewing
// when going down a step on a non-reversed teleporter.
int side = reverse || (player && stepdown);
// Make sure we are on correct side of exit linedef.
while (P_PointOnLineSide(x, y, l) != side && --fudge>=0)
if (D_abs(l->dx) > D_abs(l->dy))
y -= l->dx < 0 != side ? -1 : 1;
else
x += l->dy < 0 != side ? -1 : 1;
// Attempt to teleport, aborting if blocked
if (!P_TeleportMove(thing, x, y, false)) /* killough 8/9/98 */
return 0;
// e6y
if (player && player->mo == thing)
R_ResetAfterTeleport(player);
// Adjust z position to be same height above ground as before.
// Ground level at the exit is measured as the higher of the
// two floor heights at the exit linedef.
thing->z = z + sides[l->sidenum[stepdown]].sector->floorheight;
// Rotate thing's orientation according to difference in linedef angles
thing->angle += angle;
// Momentum of thing crossing teleporter linedef
x = thing->momx;
y = thing->momy;
// Rotate thing's momentum to come out of exit just like it entered
thing->momx = FixedMul(x, c) - FixedMul(y, s);
thing->momy = FixedMul(y, c) + FixedMul(x, s);
// Adjust a player's view, in case there has been a height change
if (player)
{
// Save the current deltaviewheight, used in stepping
fixed_t deltaviewheight = player->deltaviewheight;
// Clear deltaviewheight, since we don't want any changes now
player->deltaviewheight = 0;
// Set player's view according to the newly set parameters
P_CalcHeight(player);
// Reset the delta to have the same dynamics as before
player->deltaviewheight = deltaviewheight;
}
// e6y
if (player && player->mo == thing)
R_ResetAfterTeleport(player);
return 1;
}
return 0;
}

View File

@@ -0,0 +1,291 @@
/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom: a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000,2002 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
* Copyright 2005, 2006 by
* Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Thinker, Ticker.
*
*-----------------------------------------------------------------------------*/
#include "doomstat.h"
#include "p_user.h"
#include "p_spec.h"
#include "p_tick.h"
#include "p_map.h"
#include "r_fps.h"
int leveltime;
static boolean newthinkerpresent;
//
// THINKERS
// All thinkers should be allocated by Z_Malloc
// so they can be operated on uniformly.
// The actual structures will vary in size,
// but the first element must be thinker_t.
//
// killough 8/29/98: we maintain several separate threads, each containing
// a special class of thinkers, to allow more efficient searches.
thinker_t thinkerclasscap[th_all+1];
//
// P_InitThinkers
//
void P_InitThinkers(void)
{
int i;
for (i=0; i<NUMTHCLASS; i++) // killough 8/29/98: initialize threaded lists
thinkerclasscap[i].cprev = thinkerclasscap[i].cnext = &thinkerclasscap[i];
thinkercap.prev = thinkercap.next = &thinkercap;
}
//
// killough 8/29/98:
//
// We maintain separate threads of friends and enemies, to permit more
// efficient searches.
//
void P_UpdateThinker(thinker_t *thinker)
{
register thinker_t *th;
// find the class the thinker belongs to
int class =
thinker->function == P_RemoveThinkerDelayed ? th_delete :
thinker->function == P_MobjThinker &&
((mobj_t *) thinker)->health > 0 &&
(((mobj_t *) thinker)->flags & MF_COUNTKILL ||
((mobj_t *) thinker)->type == MT_SKULL) ?
((mobj_t *) thinker)->flags & MF_FRIEND ?
th_friends : th_enemies : th_misc;
{
/* Remove from current thread, if in one */
if ((th = thinker->cnext)!= NULL)
(th->cprev = thinker->cprev)->cnext = th;
}
// Add to appropriate thread
th = &thinkerclasscap[class];
th->cprev->cnext = thinker;
thinker->cnext = th;
thinker->cprev = th->cprev;
th->cprev = thinker;
}
//
// P_AddThinker
// Adds a new thinker at the end of the list.
//
void P_AddThinker(thinker_t* thinker)
{
thinkercap.prev->next = thinker;
thinker->next = &thinkercap;
thinker->prev = thinkercap.prev;
thinkercap.prev = thinker;
thinker->references = 0; // killough 11/98: init reference counter to 0
// killough 8/29/98: set sentinel pointers, and then add to appropriate list
thinker->cnext = thinker->cprev = NULL;
P_UpdateThinker(thinker);
newthinkerpresent = true;
}
//
// killough 11/98:
//
// Make currentthinker external, so that P_RemoveThinkerDelayed
// can adjust currentthinker when thinkers self-remove.
static thinker_t *currentthinker;
//
// P_RemoveThinkerDelayed()
//
// Called automatically as part of the thinker loop in P_RunThinkers(),
// on nodes which are pending deletion.
//
// If this thinker has no more pointers referencing it indirectly,
// remove it, and set currentthinker to one node preceeding it, so
// that the next step in P_RunThinkers() will get its successor.
//
void P_RemoveThinkerDelayed(thinker_t *thinker)
{
if (!thinker->references)
{
{ /* Remove from main thinker list */
thinker_t *next = thinker->next;
/* Note that currentthinker is guaranteed to point to us,
* and since we're freeing our memory, we had better change that. So
* point it to thinker->prev, so the iterator will correctly move on to
* thinker->prev->next = thinker->next */
(next->prev = currentthinker = thinker->prev)->next = next;
}
{
/* Remove from current thinker class list */
thinker_t *th = thinker->cnext;
(th->cprev = thinker->cprev)->cnext = th;
}
Z_Free(thinker);
}
}
//
// P_RemoveThinker
//
// Deallocation is lazy -- it will not actually be freed
// until its thinking turn comes up.
//
// killough 4/25/98:
//
// Instead of marking the function with -1 value cast to a function pointer,
// set the function to P_RemoveThinkerDelayed(), so that later, it will be
// removed automatically as part of the thinker process.
//
void P_RemoveThinker(thinker_t *thinker)
{
R_StopInterpolationIfNeeded(thinker);
thinker->function = P_RemoveThinkerDelayed;
P_UpdateThinker(thinker);
}
/* cph 2002/01/13 - iterator for thinker list
* WARNING: Do not modify thinkers between calls to this functin
*/
thinker_t* P_NextThinker(thinker_t* th, th_class cl)
{
thinker_t* top = &thinkerclasscap[cl];
if (!th) th = top;
th = cl == th_all ? th->next : th->cnext;
return th == top ? NULL : th;
}
/*
* P_SetTarget
*
* This function is used to keep track of pointer references to mobj thinkers.
* In Doom, objects such as lost souls could sometimes be removed despite
* their still being referenced. In Boom, 'target' mobj fields were tested
* during each gametic, and any objects pointed to by them would be prevented
* from being removed. But this was incomplete, and was slow (every mobj was
* checked during every gametic). Now, we keep a count of the number of
* references, and delay removal until the count is 0.
*/
void P_SetTarget(mobj_t **mop, mobj_t *targ)
{
if (*mop) // If there was a target already, decrease its refcount
(*mop)->thinker.references--;
if ((*mop = targ)) // Set new target and if non-NULL, increase its counter
targ->thinker.references++;
}
//
// P_RunThinkers
//
// killough 4/25/98:
//
// Fix deallocator to stop using "next" pointer after node has been freed
// (a Doom bug).
//
// Process each thinker. For thinkers which are marked deleted, we must
// load the "next" pointer prior to freeing the node. In Doom, the "next"
// pointer was loaded AFTER the thinker was freed, which could have caused
// crashes.
//
// But if we are not deleting the thinker, we should reload the "next"
// pointer after calling the function, in case additional thinkers are
// added at the end of the list.
//
// killough 11/98:
//
// Rewritten to delete nodes implicitly, by making currentthinker
// external and using P_RemoveThinkerDelayed() implicitly.
//
static void P_RunThinkers (void)
{
for (currentthinker = thinkercap.next;
currentthinker != &thinkercap;
currentthinker = currentthinker->next)
{
if (newthinkerpresent)
R_ActivateThinkerInterpolations(currentthinker);
if (currentthinker->function)
currentthinker->function(currentthinker);
}
newthinkerpresent = false;
}
//
// P_Ticker
//
void P_Ticker (void)
{
int i;
/* pause if in menu and at least one tic has been run
*
* killough 9/29/98: note that this ties in with basetic,
* since G_Ticker does the pausing during recording or
* playback, and compenates by incrementing basetic.
*
* All of this complicated mess is used to preserve demo sync.
*/
if (paused || (menuactive && !demoplayback && !netgame &&
players[consoleplayer].viewz != 1))
return;
R_UpdateInterpolations ();
P_MapStart();
// not if this is an intermission screen
if(gamestate==GS_LEVEL)
for (i=0; i<MAXPLAYERS; i++)
if (playeringame[i])
P_PlayerThink(&players[i]);
P_RunThinkers();
P_UpdateSpecials();
P_RespawnSpecials();
P_MapEnd();
leveltime++; // for par times
}

Some files were not shown because too many files have changed in this diff Show More