mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-06-02 01:51:20 +00:00
ZDoom 1.16.
This commit is contained in:
parent
25f75d4f53
commit
8dc4dd899f
165 changed files with 28224 additions and 21846 deletions
117
code/Am_map.c
117
code/Am_map.c
|
@ -29,6 +29,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "st_stuff.h"
|
||||
#include "p_local.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
#include "m_cheat.h"
|
||||
|
@ -55,7 +56,8 @@ static int Background, YourColor, WallColor, TSWallColor,
|
|||
FDWallColor, CDWallColor, ThingColor,
|
||||
SecretWallColor, GridColor, XHairColor,
|
||||
NotSeenColor,
|
||||
Key1Color, Key2Color, Key3Color;
|
||||
LockedColor,
|
||||
AlmostBackground;
|
||||
|
||||
cvar_t *am_backcolor,
|
||||
*am_yourcolor,
|
||||
|
@ -67,12 +69,7 @@ cvar_t *am_backcolor,
|
|||
*am_gridcolor,
|
||||
*am_xhaircolor,
|
||||
*am_notseencolor,
|
||||
*am_key1color,
|
||||
*am_key2color,
|
||||
*am_key3color,
|
||||
*am_key4color,
|
||||
*am_key5color,
|
||||
*am_key6color,
|
||||
*am_lockedcolor,
|
||||
*am_usecustomcolors,
|
||||
*am_ovyourcolor,
|
||||
*am_ovwallcolor,
|
||||
|
@ -499,9 +496,7 @@ void AM_initColors (BOOL overlayed)
|
|||
ThingColor = V_GetColorFromString (palette, am_ovthingcolor->string);
|
||||
FDWallColor =
|
||||
CDWallColor =
|
||||
Key1Color =
|
||||
Key2Color =
|
||||
Key3Color = V_GetColorFromString (palette, am_ovotherwallscolor->string);
|
||||
LockedColor = V_GetColorFromString (palette, am_ovotherwallscolor->string);
|
||||
NotSeenColor =
|
||||
TSWallColor = V_GetColorFromString (palette, am_ovunseencolor->string);
|
||||
} else if (am_usecustomcolors->value) {
|
||||
|
@ -517,24 +512,39 @@ void AM_initColors (BOOL overlayed)
|
|||
GridColor = V_GetColorFromString (palette, am_gridcolor->string);
|
||||
XHairColor = V_GetColorFromString (palette, am_xhaircolor->string);
|
||||
NotSeenColor = V_GetColorFromString (palette, am_notseencolor->string);
|
||||
Key1Color = V_GetColorFromString (palette, am_key1color->string);
|
||||
Key2Color = V_GetColorFromString (palette, am_key2color->string);
|
||||
Key3Color = V_GetColorFromString (palette, am_key3color->string);
|
||||
LockedColor = V_GetColorFromString (palette, am_lockedcolor->string);
|
||||
{
|
||||
unsigned int ba = V_GetColorFromString (NULL, am_backcolor->string);
|
||||
int r = RPART(ba) - 16;
|
||||
int g = GPART(ba) - 16;
|
||||
int b = BPART(ba) - 16;
|
||||
if (r < 0)
|
||||
r += 32;
|
||||
if (g < 0)
|
||||
g += 32;
|
||||
if (b < 0)
|
||||
b += 32;
|
||||
|
||||
if (screens[0].is8bit)
|
||||
AlmostBackground = BestColor (DefaultPalette->basecolors, r, g , b, DefaultPalette->numcolors);
|
||||
else
|
||||
AlmostBackground = MAKERGB(r,g,b);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Use colors corresponding to the original Doom's */
|
||||
Background = V_GetColorFromString (palette, "0000 0000 0000");
|
||||
Background = V_GetColorFromString (palette, "00 00 00");
|
||||
AlmostBackground = V_GetColorFromString (palette, "10 10 10");
|
||||
SecretWallColor =
|
||||
WallColor = V_GetColorFromString (palette, "fcfc 0000 0000");
|
||||
TSWallColor = V_GetColorFromString (palette, "8080 8080 8080");
|
||||
FDWallColor = V_GetColorFromString (palette, "bcbc 7878 4848");
|
||||
Key1Color =
|
||||
Key2Color =
|
||||
Key3Color =
|
||||
CDWallColor = V_GetColorFromString (palette, "fcfc fcfc 0000");
|
||||
ThingColor = V_GetColorFromString (palette, "7474 fcfc 6c6c");
|
||||
GridColor = V_GetColorFromString (palette, "4c4c 4c4c 4c4c");
|
||||
XHairColor = V_GetColorFromString (palette, "8080 8080 8080");
|
||||
NotSeenColor = V_GetColorFromString (palette, "6c6c 6c6c 6c6c");
|
||||
WallColor = V_GetColorFromString (palette, "fc 00 00");
|
||||
TSWallColor = V_GetColorFromString (palette, "80 80 80");
|
||||
FDWallColor = V_GetColorFromString (palette, "bc 78 48");
|
||||
LockedColor =
|
||||
CDWallColor = V_GetColorFromString (palette, "fc fc 00");
|
||||
ThingColor = V_GetColorFromString (palette, "74 fc 6c");
|
||||
GridColor = V_GetColorFromString (palette, "4c 4c 4c");
|
||||
XHairColor = V_GetColorFromString (palette, "80 80 80");
|
||||
NotSeenColor = V_GetColorFromString (palette, "6c 6c 6c");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,9 +556,9 @@ void AM_loadPics(void)
|
|||
int i;
|
||||
char namebuf[9];
|
||||
|
||||
for (i=0;i<10;i++) {
|
||||
for (i = 0; i < 10; i++) {
|
||||
sprintf(namebuf, "AMMNUM%d", i);
|
||||
marknums[i] = W_CacheLumpName(namebuf, PU_STATIC);
|
||||
marknums[i] = W_CacheLumpName (namebuf, PU_STATIC);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -556,8 +566,8 @@ void AM_unloadPics(void)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<10;i++)
|
||||
Z_ChangeTag(marknums[i], PU_CACHE);
|
||||
for (i = 0; i < 10; i++)
|
||||
Z_ChangeTag (marknums[i], PU_CACHE);
|
||||
}
|
||||
|
||||
void AM_clearMarks(void)
|
||||
|
@ -596,7 +606,7 @@ void AM_Stop (void)
|
|||
{
|
||||
static event_t st_notify = { 0, ev_keyup, AM_MSGEXITED };
|
||||
|
||||
AM_unloadPics();
|
||||
AM_unloadPics ();
|
||||
automapactive = false;
|
||||
ST_Responder(&st_notify);
|
||||
stopped = true;
|
||||
|
@ -663,7 +673,7 @@ void Cmd_Togglemap (void *plyr, int argc, char **argv)
|
|||
//
|
||||
// Handle events (user inputs) in automap mode
|
||||
//
|
||||
BOOL AM_Responder( event_t* ev )
|
||||
BOOL AM_Responder (event_t *ev)
|
||||
{
|
||||
int rc;
|
||||
static int cheatstate=0;
|
||||
|
@ -736,7 +746,7 @@ BOOL AM_Responder( event_t* ev )
|
|||
}
|
||||
}
|
||||
if (!deathmatch->value && cht_CheckCheat(&cheat_amap, (char)ev->data2)) {
|
||||
rc = false;
|
||||
rc = true; // [RH] Eat last keypress of cheat sequence
|
||||
cheating = (cheating+1) % 3;
|
||||
}
|
||||
}
|
||||
|
@ -773,7 +783,7 @@ BOOL AM_Responder( event_t* ev )
|
|||
//
|
||||
// Zooming
|
||||
//
|
||||
void AM_changeWindowScale(void)
|
||||
void AM_changeWindowScale (void)
|
||||
{
|
||||
// Change the scaling multipliers
|
||||
scale_mtof = FixedMul(scale_mtof, mtof_zoommul);
|
||||
|
@ -999,7 +1009,7 @@ AM_drawFline
|
|||
static fuck = 0;
|
||||
|
||||
// For debugging only
|
||||
if ( fl->a.x < 0 || fl->a.x >= f_w
|
||||
if ( fl->a.x < 0 || fl->a.x >= f_w
|
||||
|| fl->a.y < 0 || fl->a.y >= f_h
|
||||
|| fl->b.x < 0 || fl->b.x >= f_w
|
||||
|| fl->b.y < 0 || fl->b.y >= f_h)
|
||||
|
@ -1087,17 +1097,14 @@ AM_drawFline
|
|||
|
||||
|
||||
//
|
||||
// Clip lines, draw visible part sof lines.
|
||||
// Clip lines, draw visible parts of lines.
|
||||
//
|
||||
void
|
||||
AM_drawMline
|
||||
( mline_t* ml,
|
||||
int color )
|
||||
void AM_drawMline (mline_t *ml, int color)
|
||||
{
|
||||
static fline_t fl;
|
||||
|
||||
if (AM_clipMline(ml, &fl))
|
||||
AM_drawFline(&fl, color); // draws it on frame buffer using fb coords
|
||||
if (AM_clipMline (ml, &fl))
|
||||
AM_drawFline (&fl, color); // draws it on frame buffer using fb coords
|
||||
}
|
||||
|
||||
|
||||
|
@ -1185,21 +1192,9 @@ void AM_drawWalls(void)
|
|||
AM_drawMline(&l, SecretWallColor);
|
||||
else
|
||||
AM_drawMline(&l, WallColor);
|
||||
} else if (lines[i].special == 26 ||
|
||||
lines[i].special == 32 ||
|
||||
lines[i].special == 133 ||
|
||||
lines[i].special == 99) {
|
||||
AM_drawMline (&l, Key1Color); // blue key doors
|
||||
} else if (lines[i].special == 28 ||
|
||||
lines[i].special == 33 ||
|
||||
lines[i].special == 135 ||
|
||||
lines[i].special == 13) {
|
||||
AM_drawMline (&l, Key2Color); // red key doors
|
||||
} else if (lines[i].special == 27 ||
|
||||
lines[i].special == 34 ||
|
||||
lines[i].special == 137 ||
|
||||
lines[i].special == 136) {
|
||||
AM_drawMline (&l, Key3Color); // yellow key doors
|
||||
} else if (lines[i].special == Door_LockedRaise ||
|
||||
lines[i].special == ACS_LockedExecute) {
|
||||
AM_drawMline (&l, LockedColor); // [RH] locked special
|
||||
} else if (lines[i].backsector->floorheight
|
||||
!= lines[i].frontsector->floorheight) {
|
||||
AM_drawMline(&l, FDWallColor); // floor level change
|
||||
|
@ -1329,15 +1324,15 @@ void AM_drawPlayers(void)
|
|||
continue;
|
||||
|
||||
if (p->powers[pw_invisibility])
|
||||
color = 246; // *close* to black
|
||||
color = AlmostBackground;
|
||||
else if (screens[0].is8bit)
|
||||
color = BestColor (DefaultPalette->basecolors,
|
||||
RPART(p->userinfo->color),
|
||||
GPART(p->userinfo->color),
|
||||
BPART(p->userinfo->color),
|
||||
RPART(p->userinfo.color),
|
||||
GPART(p->userinfo.color),
|
||||
BPART(p->userinfo.color),
|
||||
DefaultPalette->numcolors);
|
||||
else
|
||||
color = p->userinfo->color;
|
||||
color = p->userinfo.color;
|
||||
|
||||
pt.x = p->mo->x;
|
||||
pt.y = p->mo->y;
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#ifndef __AMMAP_H__
|
||||
#define __AMMAP_H__
|
||||
|
||||
#include "d_event.h"
|
||||
|
||||
// Used by ST StatusBar stuff.
|
||||
#define AM_MSGHEADER (('a'<<24)+('m'<<16))
|
||||
#define AM_MSGENTERED (AM_MSGHEADER | ('e'<<8))
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "c_consol.h"
|
||||
#include "c_cmds.h"
|
||||
#include "c_dispch.h"
|
||||
|
@ -11,23 +12,32 @@
|
|||
|
||||
#include "doomstat.h"
|
||||
#include "d_englsh.h"
|
||||
#include "sounds.h"
|
||||
#include "s_sound.h"
|
||||
#include "g_game.h"
|
||||
#include "d_items.h"
|
||||
#include "p_inter.h"
|
||||
#include "z_zone.h"
|
||||
#include "w_wad.h"
|
||||
#include "g_level.h"
|
||||
|
||||
extern FILE *Logfile;
|
||||
|
||||
cvar_t *sv_cheats;
|
||||
|
||||
struct CmdDispatcher CmdList[] = {
|
||||
{ "error", Cmd_Error },
|
||||
{ "endgame", Cmd_Endgame },
|
||||
{ "mem", Cmd_Mem },
|
||||
{ "pings", Cmd_Pings },
|
||||
{ "skins", Cmd_Skins },
|
||||
{ "turn180", Cmd_Turn180 },
|
||||
{ "puke", Cmd_Puke },
|
||||
{ "spynext", Cmd_SpyNext },
|
||||
{ "spyprev", Cmd_SpyPrev },
|
||||
{ "messagemode", Cmd_MessageMode },
|
||||
{ "say", Cmd_Say },
|
||||
{ "messagemode2", Cmd_MessageMode2 },
|
||||
{ "say_team", Cmd_Say_Team },
|
||||
{ "limits", Cmd_Limits },
|
||||
{ "screenshot", Cmd_Screenshot },
|
||||
{ "vid_setmode", Cmd_Vid_SetMode },
|
||||
|
@ -42,10 +52,14 @@ struct CmdDispatcher CmdList[] = {
|
|||
{ "sizedown", Cmd_Sizedown },
|
||||
{ "sizeup", Cmd_Sizeup },
|
||||
{ "impulse", Cmd_Impulse },
|
||||
{ "weapnext", Cmd_WeapNext },
|
||||
{ "weapprev", Cmd_WeapPrev },
|
||||
{ "alias", Cmd_Alias },
|
||||
{ "cmdlist", Cmd_Cmdlist },
|
||||
{ "unbind", Cmd_Unbind },
|
||||
{ "unbindall", Cmd_Unbindall },
|
||||
{ "undoublebind", Cmd_UnDoubleBind },
|
||||
{ "doublebind", Cmd_DoubleBind },
|
||||
{ "bind", Cmd_Bind },
|
||||
{ "binddefaults", Cmd_BindDefaults },
|
||||
{ "dumpheap", Cmd_DumpHeap },
|
||||
|
@ -69,7 +83,7 @@ struct CmdDispatcher CmdList[] = {
|
|||
{ "logfile", Cmd_Logfile },
|
||||
{ "noclip", Cmd_Noclip },
|
||||
{ "notarget", Cmd_Notarget },
|
||||
{ "quit", I_Quit },
|
||||
{ "quit", Cmd_Quit },
|
||||
{ "set", Cmd_Set },
|
||||
{ "menu_main", Cmd_Menu_Main },
|
||||
{ "menu_load", Cmd_Menu_Load },
|
||||
|
@ -89,6 +103,8 @@ struct CmdDispatcher CmdList[] = {
|
|||
{ "bumpgamma", Cmd_Bumpgamma },
|
||||
{ "togglemessages", Cmd_ToggleMessages },
|
||||
{ "stop", Cmd_Stop },
|
||||
{ "soundlist", Cmd_Soundlist },
|
||||
{ "soundlinks", Cmd_Soundlinks },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -107,6 +123,11 @@ BOOL CheckCheatmode (void)
|
|||
}
|
||||
}
|
||||
|
||||
void Cmd_Quit (player_t *plyr, int argc, char **argv)
|
||||
{
|
||||
exit (0);
|
||||
}
|
||||
|
||||
void Cmd_ChangeMus (player_t *plyr, int argc, char **argv)
|
||||
{
|
||||
if (argc > 1) {
|
||||
|
@ -341,23 +362,50 @@ void Cmd_Logfile (player_t *plyr, int argc, char **argv)
|
|||
void Cmd_Limits (player_t *plyr, int argc, char **argv)
|
||||
{
|
||||
extern int MaxDeathmatchStarts;
|
||||
extern int MaxPlats;
|
||||
extern int MaxCeilings;
|
||||
extern int MaxSpecialCross;
|
||||
extern int MaxDrawSegs;
|
||||
extern int MaxSegs;
|
||||
extern int MaxVisPlanes;
|
||||
extern int MaxVisSprites;
|
||||
extern int maxopenings;
|
||||
|
||||
Printf_Bold ("Note that the following values are\n"
|
||||
"dynamic and will increase as needed.\n\n");
|
||||
Printf ("MaxCeilings: %u\n", MaxCeilings);
|
||||
Printf ("MaxDeathmatchStarts: %u\n", MaxDeathmatchStarts);
|
||||
Printf ("MaxDrawSegs: %u\n", MaxDrawSegs);
|
||||
Printf ("MaxPlats: %u\n", MaxPlats);
|
||||
Printf ("MaxSegs: %u\n", MaxSegs);
|
||||
Printf ("MaxSpecialCross: %u\n", MaxSpecialCross);
|
||||
Printf ("MaxVisPlanes: %u\n", MaxVisPlanes);
|
||||
Printf ("MaxVisSprites: %u\n", MaxVisSprites);
|
||||
}
|
||||
Printf ("MaxOpeninings: %u\n", maxopenings);
|
||||
}
|
||||
|
||||
BOOL P_StartScript (void *who, void *where, int script, char *map, int lineSide,
|
||||
int arg0, int arg1, int arg2, int always);
|
||||
void Cmd_Puke (player_t *plyr, int argc, char **argv)
|
||||
{
|
||||
if (argc < 2 || argc > 5) {
|
||||
Printf (" puke <script> [arg1] [arg2] [arg3]\n");
|
||||
} else {
|
||||
int script = atoi (argv[1]);
|
||||
int arg0=0, arg1=0, arg2=0;
|
||||
|
||||
if (argc > 2) {
|
||||
arg0 = atoi (argv[2]);
|
||||
if (argc > 3) {
|
||||
arg1 = atoi (argv[3]);
|
||||
if (argc > 4) {
|
||||
arg2 = atoi (argv[4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
P_StartScript (plyr->mo, NULL, script, level.mapname, 0, arg0, arg1, arg2, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Cmd_Error (player_t *plyr, int argc, char **argv)
|
||||
{
|
||||
char *text = BuildString (argc - 1, argv + 1);
|
||||
char *textcopy = Z_Malloc (strlen (text) + 1, PU_LEVEL, 0);
|
||||
strcpy (textcopy, text);
|
||||
free (text);
|
||||
I_Error (textcopy);
|
||||
}
|
|
@ -55,12 +55,10 @@ void UnlatchCVars (void)
|
|||
|
||||
void SetCVar (cvar_t *var, char *value)
|
||||
{
|
||||
// TODO: Find a better way to not send serverinfo updates
|
||||
// when not inside a game.
|
||||
if (var->flags & CVAR_LATCH) {
|
||||
if (var->flags & CVAR_LATCH && gamestate != GS_FULLCONSOLE && gamestate != GS_STARTUP) {
|
||||
var->modified = true;
|
||||
var->u.latched_string = copystring (value);
|
||||
} else if (var->flags & CVAR_SERVERINFO && gamestate > -1) {
|
||||
} else if (var->flags & CVAR_SERVERINFO && gamestate != GS_STARTUP) {
|
||||
if (netgame && consoleplayer != 0) {
|
||||
Printf ("Only player 1 can change %s\n", var->name);
|
||||
return;
|
||||
|
@ -85,6 +83,8 @@ void SetCVarFloat (cvar_t *var, float value)
|
|||
SetCVar (var, string);
|
||||
}
|
||||
|
||||
int cvar_defflags;
|
||||
|
||||
cvar_t *cvar (char *var_name, char *value, int flags)
|
||||
{
|
||||
cvar_t *var, *dummy;
|
||||
|
@ -104,7 +104,7 @@ cvar_t *cvar (char *var_name, char *value, int flags)
|
|||
CVars = var;
|
||||
C_AddTabCommand (var_name);
|
||||
}
|
||||
var->flags = flags;
|
||||
var->flags = flags | cvar_defflags;;
|
||||
return var;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,18 +29,7 @@ gamedir will hold progdir + the game directory (id1, id2, etc)
|
|||
|
||||
*/
|
||||
|
||||
char progdir[1024];
|
||||
|
||||
void SetProgDir (void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
GetModuleFileName (NULL, progdir, 1024);
|
||||
*(strrchr (progdir, '\\') + 1) = 0;
|
||||
FixPathSeperator (progdir);
|
||||
#else
|
||||
Printf ("SetProgDir: Rewrite this\n");
|
||||
#endif
|
||||
}
|
||||
char progdir[1024];
|
||||
|
||||
void FixPathSeperator (char *path)
|
||||
{
|
||||
|
@ -215,9 +204,27 @@ void DefaultExtension (char *path, char *extension)
|
|||
Extract file parts
|
||||
====================
|
||||
*/
|
||||
// FIXME: should include the slash, otherwise
|
||||
// backing to an empty path will be wrong when appending a slash
|
||||
void ExtractFilePath (char *path, char *dest)
|
||||
{
|
||||
char *src;
|
||||
|
||||
src = path + strlen(path) - 1;
|
||||
|
||||
//
|
||||
// back up until a \ or the start
|
||||
//
|
||||
while (src != path && *(src-1) != '\\' && *(src-1) != '/')
|
||||
src--;
|
||||
|
||||
memcpy (dest, path, src-path);
|
||||
dest[src-path] = 0;
|
||||
}
|
||||
|
||||
void ExtractFileBase (char *path, char *dest)
|
||||
{
|
||||
char *src;
|
||||
char *src;
|
||||
|
||||
src = path + strlen(path) - 1;
|
||||
|
||||
|
@ -242,8 +249,8 @@ ParseNum / ParseHex
|
|||
*/
|
||||
int ParseHex (char *hex)
|
||||
{
|
||||
char *str;
|
||||
int num;
|
||||
char *str;
|
||||
int num;
|
||||
|
||||
num = 0;
|
||||
str = hex;
|
||||
|
@ -285,7 +292,7 @@ BOOL IsNum (char *str)
|
|||
BOOL result = true;
|
||||
|
||||
while (*str) {
|
||||
if ((*str < '0') || (*str > '9')) {
|
||||
if (((*str < '0') || (*str > '9')) && (*str != '-')) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -31,10 +31,10 @@ BOOL FileExists (char *filename);
|
|||
extern char progdir[1024];
|
||||
|
||||
void FixPathSeperator (char *path);
|
||||
void SetProgDir (void);
|
||||
|
||||
void DefaultExtension (char *path, char *extension);
|
||||
|
||||
void ExtractFilePath (char *path, char *dest);
|
||||
void ExtractFileBase (char *path, char *dest);
|
||||
|
||||
int ParseHex (char *str);
|
||||
|
|
1081
code/D_dehack.c
1081
code/D_dehack.c
File diff suppressed because it is too large
Load diff
701
code/D_englsh.h
701
code/D_englsh.h
|
@ -1,701 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Printed strings for translation.
|
||||
// English language support (default).
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __D_ENGLSH__
|
||||
#define __D_ENGLSH__
|
||||
|
||||
//
|
||||
// Printed strings for translation
|
||||
//
|
||||
|
||||
//
|
||||
// D_Main.C
|
||||
//
|
||||
#define D_DEVSTR "Development mode ON.\n"
|
||||
#define D_CDROM "CD-ROM Version: default.cfg from c:\\doomdata\n"
|
||||
|
||||
//
|
||||
// M_Menu.C
|
||||
//
|
||||
#define PRESSKEY "press a key."
|
||||
#define PRESSYN "press y or n."
|
||||
#define QUITMSG "are you sure you want to\nquit this great game?"
|
||||
#define LOADNET "you can't do load while in a net game!\n\n"PRESSKEY
|
||||
#define QLOADNET "you can't quickload during a netgame!\n\n"PRESSKEY
|
||||
#define QSAVESPOT "you haven't picked a quicksave slot yet!\n\n"PRESSKEY
|
||||
#define SAVEDEAD "you can't save if you aren't playing!\n\n"PRESSKEY
|
||||
#define QSPROMPT "quicksave over your game named\n\n'%s'?\n\n"PRESSYN
|
||||
#define QLPROMPT "do you want to quickload the game named\n\n'%s'?\n\n"PRESSYN
|
||||
|
||||
#define NEWGAME \
|
||||
"you can't start a new game\n"\
|
||||
"while in a network game.\n\n"PRESSKEY
|
||||
|
||||
#define NIGHTMARE \
|
||||
"are you sure? this skill level\n"\
|
||||
"isn't even remotely fair.\n\n"PRESSYN
|
||||
|
||||
#define SWSTRING \
|
||||
"this is the shareware version of doom.\n\n"\
|
||||
"you need to order the entire trilogy.\n\n"PRESSKEY
|
||||
|
||||
#define MSGOFF "Messages OFF"
|
||||
#define MSGON "Messages ON"
|
||||
#define NETEND "you can't end a netgame!\n\n"PRESSKEY
|
||||
#define ENDGAME "are you sure you want to end the game?\n\n"PRESSYN
|
||||
|
||||
#define DOSY "(press y to quit)"
|
||||
|
||||
#define DETAILHI "High detail"
|
||||
#define DETAILLO "Low detail"
|
||||
#define GAMMALVL0 "Gamma correction OFF"
|
||||
#define GAMMALVL1 "Gamma correction level 1"
|
||||
#define GAMMALVL2 "Gamma correction level 2"
|
||||
#define GAMMALVL3 "Gamma correction level 3"
|
||||
#define GAMMALVL4 "Gamma correction level 4"
|
||||
#define EMPTYSTRING "empty slot"
|
||||
|
||||
//
|
||||
// P_inter.C
|
||||
//
|
||||
#define GOTARMOR "Picked up the armor."
|
||||
#define GOTMEGA "Picked up the MegaArmor!"
|
||||
#define GOTHTHBONUS "Picked up a health bonus."
|
||||
#define GOTARMBONUS "Picked up an armor bonus."
|
||||
#define GOTSTIM "Picked up a stimpack."
|
||||
#define GOTMEDINEED "Picked up a medikit that you REALLY need!"
|
||||
#define GOTMEDIKIT "Picked up a medikit."
|
||||
#define GOTSUPER "Supercharge!"
|
||||
|
||||
#define GOTBLUECARD "Picked up a blue keycard."
|
||||
#define GOTYELWCARD "Picked up a yellow keycard."
|
||||
#define GOTREDCARD "Picked up a red keycard."
|
||||
#define GOTBLUESKUL "Picked up a blue skull key."
|
||||
#define GOTYELWSKUL "Picked up a yellow skull key."
|
||||
#define GOTREDSKULL "Picked up a red skull key."
|
||||
|
||||
#define GOTINVUL "Invulnerability!"
|
||||
#define GOTBERSERK "Berserk!"
|
||||
#define GOTINVIS "Partial Invisibility"
|
||||
#define GOTSUIT "Radiation Shielding Suit"
|
||||
#define GOTMAP "Computer Area Map"
|
||||
#define GOTVISOR "Light Amplification Visor"
|
||||
#define GOTMSPHERE "MegaSphere!"
|
||||
|
||||
#define GOTCLIP "Picked up a clip."
|
||||
#define GOTCLIPBOX "Picked up a box of bullets."
|
||||
#define GOTROCKET "Picked up a rocket."
|
||||
#define GOTROCKBOX "Picked up a box of rockets."
|
||||
#define GOTCELL "Picked up an energy cell."
|
||||
#define GOTCELLBOX "Picked up an energy cell pack."
|
||||
#define GOTSHELLS "Picked up 4 shotgun shells."
|
||||
#define GOTSHELLBOX "Picked up a box of shotgun shells."
|
||||
#define GOTBACKPACK "Picked up a backpack full of ammo!"
|
||||
|
||||
#define GOTBFG9000 "You got the BFG9000! Oh, yes."
|
||||
#define GOTCHAINGUN "You got the chaingun!"
|
||||
#define GOTCHAINSAW "A chainsaw! Find some meat!"
|
||||
#define GOTLAUNCHER "You got the rocket launcher!"
|
||||
#define GOTPLASMA "You got the plasma gun!"
|
||||
#define GOTSHOTGUN "You got the shotgun!"
|
||||
#define GOTSHOTGUN2 "You got the super shotgun!"
|
||||
|
||||
//
|
||||
// P_Doors.C
|
||||
//
|
||||
#define PD_BLUEO "You need a blue key\nto activate this object"
|
||||
#define PD_REDO "You need a red key\nto activate this object"
|
||||
#define PD_YELLOWO "You need a yellow key\nto activate this object"
|
||||
#define PD_BLUEK "You need a blue key\nto open this door"
|
||||
#define PD_REDK "You need a red key\nto open this door"
|
||||
#define PD_YELLOWK "You need a yellow key\nto open this door"
|
||||
|
||||
//
|
||||
// G_game.C
|
||||
//
|
||||
#define GGSAVED "game saved."
|
||||
|
||||
//
|
||||
// HU_stuff.C
|
||||
//
|
||||
#define HUSTR_MSGU "[Message unsent]"
|
||||
|
||||
#define HUSTR_E1M1 "E1M1: Hangar"
|
||||
#define HUSTR_E1M2 "E1M2: Nuclear Plant"
|
||||
#define HUSTR_E1M3 "E1M3: Toxin Refinery"
|
||||
#define HUSTR_E1M4 "E1M4: Command Control"
|
||||
#define HUSTR_E1M5 "E1M5: Phobos Lab"
|
||||
#define HUSTR_E1M6 "E1M6: Central Processing"
|
||||
#define HUSTR_E1M7 "E1M7: Computer Station"
|
||||
#define HUSTR_E1M8 "E1M8: Phobos Anomaly"
|
||||
#define HUSTR_E1M9 "E1M9: Military Base"
|
||||
|
||||
#define HUSTR_E2M1 "E2M1: Deimos Anomaly"
|
||||
#define HUSTR_E2M2 "E2M2: Containment Area"
|
||||
#define HUSTR_E2M3 "E2M3: Refinery"
|
||||
#define HUSTR_E2M4 "E2M4: Deimos Lab"
|
||||
#define HUSTR_E2M5 "E2M5: Command Center"
|
||||
#define HUSTR_E2M6 "E2M6: Halls of the Damned"
|
||||
#define HUSTR_E2M7 "E2M7: Spawning Vats"
|
||||
#define HUSTR_E2M8 "E2M8: Tower of Babel"
|
||||
#define HUSTR_E2M9 "E2M9: Fortress of Mystery"
|
||||
|
||||
#define HUSTR_E3M1 "E3M1: Hell Keep"
|
||||
#define HUSTR_E3M2 "E3M2: Slough of Despair"
|
||||
#define HUSTR_E3M3 "E3M3: Pandemonium"
|
||||
#define HUSTR_E3M4 "E3M4: House of Pain"
|
||||
#define HUSTR_E3M5 "E3M5: Unholy Cathedral"
|
||||
#define HUSTR_E3M6 "E3M6: Mt. Erebus"
|
||||
#define HUSTR_E3M7 "E3M7: Limbo"
|
||||
#define HUSTR_E3M8 "E3M8: Dis"
|
||||
#define HUSTR_E3M9 "E3M9: Warrens"
|
||||
|
||||
#define HUSTR_E4M1 "E4M1: Hell Beneath"
|
||||
#define HUSTR_E4M2 "E4M2: Perfect Hatred"
|
||||
#define HUSTR_E4M3 "E4M3: Sever The Wicked"
|
||||
#define HUSTR_E4M4 "E4M4: Unruly Evil"
|
||||
#define HUSTR_E4M5 "E4M5: They Will Repent"
|
||||
#define HUSTR_E4M6 "E4M6: Against Thee Wickedly"
|
||||
#define HUSTR_E4M7 "E4M7: And Hell Followed"
|
||||
#define HUSTR_E4M8 "E4M8: Unto The Cruel"
|
||||
#define HUSTR_E4M9 "E4M9: Fear"
|
||||
|
||||
#define HUSTR_1 "level 1: entryway"
|
||||
#define HUSTR_2 "level 2: underhalls"
|
||||
#define HUSTR_3 "level 3: the gantlet"
|
||||
#define HUSTR_4 "level 4: the focus"
|
||||
#define HUSTR_5 "level 5: the waste tunnels"
|
||||
#define HUSTR_6 "level 6: the crusher"
|
||||
#define HUSTR_7 "level 7: dead simple"
|
||||
#define HUSTR_8 "level 8: tricks and traps"
|
||||
#define HUSTR_9 "level 9: the pit"
|
||||
#define HUSTR_10 "level 10: refueling base"
|
||||
#define HUSTR_11 "level 11: 'o' of destruction!"
|
||||
|
||||
#define HUSTR_12 "level 12: the factory"
|
||||
#define HUSTR_13 "level 13: downtown"
|
||||
#define HUSTR_14 "level 14: the inmost dens"
|
||||
#define HUSTR_15 "level 15: industrial zone"
|
||||
#define HUSTR_16 "level 16: suburbs"
|
||||
#define HUSTR_17 "level 17: tenements"
|
||||
#define HUSTR_18 "level 18: the courtyard"
|
||||
#define HUSTR_19 "level 19: the citadel"
|
||||
#define HUSTR_20 "level 20: gotcha!"
|
||||
|
||||
#define HUSTR_21 "level 21: nirvana"
|
||||
#define HUSTR_22 "level 22: the catacombs"
|
||||
#define HUSTR_23 "level 23: barrels o' fun"
|
||||
#define HUSTR_24 "level 24: the chasm"
|
||||
#define HUSTR_25 "level 25: bloodfalls"
|
||||
#define HUSTR_26 "level 26: the abandoned mines"
|
||||
#define HUSTR_27 "level 27: monster condo"
|
||||
#define HUSTR_28 "level 28: the spirit world"
|
||||
#define HUSTR_29 "level 29: the living end"
|
||||
#define HUSTR_30 "level 30: icon of sin"
|
||||
|
||||
#define HUSTR_31 "level 31: wolfenstein"
|
||||
#define HUSTR_32 "level 32: grosse"
|
||||
|
||||
#define PHUSTR_1 "level 1: congo"
|
||||
#define PHUSTR_2 "level 2: well of souls"
|
||||
#define PHUSTR_3 "level 3: aztec"
|
||||
#define PHUSTR_4 "level 4: caged"
|
||||
#define PHUSTR_5 "level 5: ghost town"
|
||||
#define PHUSTR_6 "level 6: baron's lair"
|
||||
#define PHUSTR_7 "level 7: caughtyard"
|
||||
#define PHUSTR_8 "level 8: realm"
|
||||
#define PHUSTR_9 "level 9: abattoire"
|
||||
#define PHUSTR_10 "level 10: onslaught"
|
||||
#define PHUSTR_11 "level 11: hunted"
|
||||
|
||||
#define PHUSTR_12 "level 12: speed"
|
||||
#define PHUSTR_13 "level 13: the crypt"
|
||||
#define PHUSTR_14 "level 14: genesis"
|
||||
#define PHUSTR_15 "level 15: the twilight"
|
||||
#define PHUSTR_16 "level 16: the omen"
|
||||
#define PHUSTR_17 "level 17: compound"
|
||||
#define PHUSTR_18 "level 18: neurosphere"
|
||||
#define PHUSTR_19 "level 19: nme"
|
||||
#define PHUSTR_20 "level 20: the death domain"
|
||||
|
||||
#define PHUSTR_21 "level 21: slayer"
|
||||
#define PHUSTR_22 "level 22: impossible mission"
|
||||
#define PHUSTR_23 "level 23: tombstone"
|
||||
#define PHUSTR_24 "level 24: the final frontier"
|
||||
#define PHUSTR_25 "level 25: the temple of darkness"
|
||||
#define PHUSTR_26 "level 26: bunker"
|
||||
#define PHUSTR_27 "level 27: anti-christ"
|
||||
#define PHUSTR_28 "level 28: the sewers"
|
||||
#define PHUSTR_29 "level 29: odyssey of noises"
|
||||
#define PHUSTR_30 "level 30: the gateway of hell"
|
||||
|
||||
#define PHUSTR_31 "level 31: cyberden"
|
||||
#define PHUSTR_32 "level 32: go 2 it"
|
||||
|
||||
#define THUSTR_1 "level 1: system control"
|
||||
#define THUSTR_2 "level 2: human bbq"
|
||||
#define THUSTR_3 "level 3: power control"
|
||||
#define THUSTR_4 "level 4: wormhole"
|
||||
#define THUSTR_5 "level 5: hanger"
|
||||
#define THUSTR_6 "level 6: open season"
|
||||
#define THUSTR_7 "level 7: prison"
|
||||
#define THUSTR_8 "level 8: metal"
|
||||
#define THUSTR_9 "level 9: stronghold"
|
||||
#define THUSTR_10 "level 10: redemption"
|
||||
#define THUSTR_11 "level 11: storage facility"
|
||||
|
||||
#define THUSTR_12 "level 12: crater"
|
||||
#define THUSTR_13 "level 13: nukage processing"
|
||||
#define THUSTR_14 "level 14: steel works"
|
||||
#define THUSTR_15 "level 15: dead zone"
|
||||
#define THUSTR_16 "level 16: deepest reaches"
|
||||
#define THUSTR_17 "level 17: processing area"
|
||||
#define THUSTR_18 "level 18: mill"
|
||||
#define THUSTR_19 "level 19: shipping/respawning"
|
||||
#define THUSTR_20 "level 20: central processing"
|
||||
|
||||
#define THUSTR_21 "level 21: administration center"
|
||||
#define THUSTR_22 "level 22: habitat"
|
||||
#define THUSTR_23 "level 23: lunar mining project"
|
||||
#define THUSTR_24 "level 24: quarry"
|
||||
#define THUSTR_25 "level 25: baron's den"
|
||||
#define THUSTR_26 "level 26: ballistyx"
|
||||
#define THUSTR_27 "level 27: mount pain"
|
||||
#define THUSTR_28 "level 28: heck"
|
||||
#define THUSTR_29 "level 29: river styx"
|
||||
#define THUSTR_30 "level 30: last call"
|
||||
|
||||
#define THUSTR_31 "level 31: pharaoh"
|
||||
#define THUSTR_32 "level 32: caribbean"
|
||||
|
||||
#define HUSTR_CHATMACRO1 "I'm ready to kick butt!"
|
||||
#define HUSTR_CHATMACRO2 "I'm OK."
|
||||
#define HUSTR_CHATMACRO3 "I'm not looking too good!"
|
||||
#define HUSTR_CHATMACRO4 "Help!"
|
||||
#define HUSTR_CHATMACRO5 "You suck!"
|
||||
#define HUSTR_CHATMACRO6 "Next time, scumbag..."
|
||||
#define HUSTR_CHATMACRO7 "Come here!"
|
||||
#define HUSTR_CHATMACRO8 "I'll take care of it."
|
||||
#define HUSTR_CHATMACRO9 "Yes"
|
||||
#define HUSTR_CHATMACRO0 "No"
|
||||
|
||||
#define HUSTR_TALKTOSELF1 "You mumble to yourself"
|
||||
#define HUSTR_TALKTOSELF2 "Who's there?"
|
||||
#define HUSTR_TALKTOSELF3 "You scare yourself"
|
||||
#define HUSTR_TALKTOSELF4 "You start to rave"
|
||||
#define HUSTR_TALKTOSELF5 "You've lost it..."
|
||||
|
||||
#define HUSTR_MESSAGESENT "[Message Sent]"
|
||||
|
||||
// The following should NOT be changed unless it seems
|
||||
// just AWFULLY necessary
|
||||
|
||||
#define HUSTR_PLRGREEN "Green: "
|
||||
#define HUSTR_PLRINDIGO "Indigo: "
|
||||
#define HUSTR_PLRBROWN "Brown: "
|
||||
#define HUSTR_PLRRED "Red: "
|
||||
|
||||
#define HUSTR_KEYGREEN 'g'
|
||||
#define HUSTR_KEYINDIGO 'i'
|
||||
#define HUSTR_KEYBROWN 'b'
|
||||
#define HUSTR_KEYRED 'r'
|
||||
|
||||
//
|
||||
// AM_map.C
|
||||
//
|
||||
|
||||
#define AMSTR_FOLLOWON "Follow Mode ON"
|
||||
#define AMSTR_FOLLOWOFF "Follow Mode OFF"
|
||||
|
||||
#define AMSTR_GRIDON "Grid ON"
|
||||
#define AMSTR_GRIDOFF "Grid OFF"
|
||||
|
||||
#define AMSTR_MARKEDSPOT "Marked Spot"
|
||||
#define AMSTR_MARKSCLEARED "All Marks Cleared"
|
||||
|
||||
//
|
||||
// ST_stuff.C
|
||||
//
|
||||
|
||||
#define STSTR_MUS "Music Change"
|
||||
#define STSTR_NOMUS "IMPOSSIBLE SELECTION"
|
||||
#define STSTR_DQDON "Degreelessness Mode ON"
|
||||
#define STSTR_DQDOFF "Degreelessness Mode OFF"
|
||||
|
||||
#define STSTR_KFAADDED "Very Happy Ammo Added"
|
||||
#define STSTR_FAADDED "Ammo (no keys) Added"
|
||||
|
||||
#define STSTR_NCON "No Clipping Mode ON"
|
||||
#define STSTR_NCOFF "No Clipping Mode OFF"
|
||||
|
||||
#define STSTR_BEHOLD "inVuln, Str, Inviso, Rad, Allmap, or Lite-amp"
|
||||
#define STSTR_BEHOLDX "Power-up Toggled"
|
||||
|
||||
#define STSTR_CHOPPERS "... doesn't suck - GM"
|
||||
#define STSTR_CLEV "Changing Level..."
|
||||
|
||||
//
|
||||
// F_Finale.C
|
||||
//
|
||||
#define E1TEXT \
|
||||
"Once you beat the big badasses and\n"\
|
||||
"clean out the moon base you're supposed\n"\
|
||||
"to win, aren't you? Aren't you? Where's\n"\
|
||||
"your fat reward and ticket home? What\n"\
|
||||
"the hell is this? It's not supposed to\n"\
|
||||
"end this way!\n"\
|
||||
"\n" \
|
||||
"It stinks like rotten meat, but looks\n"\
|
||||
"like the lost Deimos base. Looks like\n"\
|
||||
"you're stuck on The Shores of Hell.\n"\
|
||||
"The only way out is through.\n"\
|
||||
"\n"\
|
||||
"To continue the DOOM experience, play\n"\
|
||||
"The Shores of Hell and its amazing\n"\
|
||||
"sequel, Inferno!\n"
|
||||
|
||||
|
||||
#define E2TEXT \
|
||||
"You've done it! The hideous cyber-\n"\
|
||||
"demon lord that ruled the lost Deimos\n"\
|
||||
"moon base has been slain and you\n"\
|
||||
"are triumphant! But ... where are\n"\
|
||||
"you? You clamber to the edge of the\n"\
|
||||
"moon and look down to see the awful\n"\
|
||||
"truth.\n" \
|
||||
"\n"\
|
||||
"Deimos floats above Hell itself!\n"\
|
||||
"You've never heard of anyone escaping\n"\
|
||||
"from Hell, but you'll make the bastards\n"\
|
||||
"sorry they ever heard of you! Quickly,\n"\
|
||||
"you rappel down to the surface of\n"\
|
||||
"Hell.\n"\
|
||||
"\n" \
|
||||
"Now, it's on to the final chapter of\n"\
|
||||
"DOOM! -- Inferno."
|
||||
|
||||
|
||||
#define E3TEXT \
|
||||
"The loathsome spiderdemon that\n"\
|
||||
"masterminded the invasion of the moon\n"\
|
||||
"bases and caused so much death has had\n"\
|
||||
"its ass kicked for all time.\n"\
|
||||
"\n"\
|
||||
"A hidden doorway opens and you enter.\n"\
|
||||
"You've proven too tough for Hell to\n"\
|
||||
"contain, and now Hell at last plays\n"\
|
||||
"fair -- for you emerge from the door\n"\
|
||||
"to see the green fields of Earth!\n"\
|
||||
"Home at last.\n" \
|
||||
"\n"\
|
||||
"You wonder what's been happening on\n"\
|
||||
"Earth while you were battling evil\n"\
|
||||
"unleashed. It's good that no Hell-\n"\
|
||||
"spawn could have come through that\n"\
|
||||
"door with you ..."
|
||||
|
||||
|
||||
#define E4TEXT \
|
||||
"the spider mastermind must have sent forth\n"\
|
||||
"its legions of hellspawn before your\n"\
|
||||
"final confrontation with that terrible\n"\
|
||||
"beast from hell. but you stepped forward\n"\
|
||||
"and brought forth eternal damnation and\n"\
|
||||
"suffering upon the horde as a true hero\n"\
|
||||
"would in the face of something so evil.\n"\
|
||||
"\n"\
|
||||
"besides, someone was gonna pay for what\n"\
|
||||
"happened to daisy, your pet rabbit.\n"\
|
||||
"\n"\
|
||||
"but now, you see spread before you more\n"\
|
||||
"potential pain and gibbitude as a nation\n"\
|
||||
"of demons run amok among our cities.\n"\
|
||||
"\n"\
|
||||
"next stop, hell on earth!"
|
||||
|
||||
|
||||
// after level 6, put this:
|
||||
|
||||
#define C1TEXT \
|
||||
"YOU HAVE ENTERED DEEPLY INTO THE INFESTED\n" \
|
||||
"STARPORT. BUT SOMETHING IS WRONG. THE\n" \
|
||||
"MONSTERS HAVE BROUGHT THEIR OWN REALITY\n" \
|
||||
"WITH THEM, AND THE STARPORT'S TECHNOLOGY\n" \
|
||||
"IS BEING SUBVERTED BY THEIR PRESENCE.\n" \
|
||||
"\n"\
|
||||
"AHEAD, YOU SEE AN OUTPOST OF HELL, A\n" \
|
||||
"FORTIFIED ZONE. IF YOU CAN GET PAST IT,\n" \
|
||||
"YOU CAN PENETRATE INTO THE HAUNTED HEART\n" \
|
||||
"OF THE STARBASE AND FIND THE CONTROLLING\n" \
|
||||
"SWITCH WHICH HOLDS EARTH'S POPULATION\n" \
|
||||
"HOSTAGE."
|
||||
|
||||
// After level 11, put this:
|
||||
|
||||
#define C2TEXT \
|
||||
"YOU HAVE WON! YOUR VICTORY HAS ENABLED\n" \
|
||||
"HUMANKIND TO EVACUATE EARTH AND ESCAPE\n"\
|
||||
"THE NIGHTMARE. NOW YOU ARE THE ONLY\n"\
|
||||
"HUMAN LEFT ON THE FACE OF THE PLANET.\n"\
|
||||
"CANNIBAL MUTATIONS, CARNIVOROUS ALIENS,\n"\
|
||||
"AND EVIL SPIRITS ARE YOUR ONLY NEIGHBORS.\n"\
|
||||
"YOU SIT BACK AND WAIT FOR DEATH, CONTENT\n"\
|
||||
"THAT YOU HAVE SAVED YOUR SPECIES.\n"\
|
||||
"\n"\
|
||||
"BUT THEN, EARTH CONTROL BEAMS DOWN A\n"\
|
||||
"MESSAGE FROM SPACE: \"SENSORS HAVE LOCATED\n"\
|
||||
"THE SOURCE OF THE ALIEN INVASION. IF YOU\n"\
|
||||
"GO THERE, YOU MAY BE ABLE TO BLOCK THEIR\n"\
|
||||
"ENTRY. THE ALIEN BASE IS IN THE HEART OF\n"\
|
||||
"YOUR OWN HOME CITY, NOT FAR FROM THE\n"\
|
||||
"STARPORT.\" SLOWLY AND PAINFULLY YOU GET\n"\
|
||||
"UP AND RETURN TO THE FRAY."
|
||||
|
||||
|
||||
// After level 20, put this:
|
||||
|
||||
#define C3TEXT \
|
||||
"YOU ARE AT THE CORRUPT HEART OF THE CITY,\n"\
|
||||
"SURROUNDED BY THE CORPSES OF YOUR ENEMIES.\n"\
|
||||
"YOU SEE NO WAY TO DESTROY THE CREATURES'\n"\
|
||||
"ENTRYWAY ON THIS SIDE, SO YOU CLENCH YOUR\n"\
|
||||
"TEETH AND PLUNGE THROUGH IT.\n"\
|
||||
"\n"\
|
||||
"THERE MUST BE A WAY TO CLOSE IT ON THE\n"\
|
||||
"OTHER SIDE. WHAT DO YOU CARE IF YOU'VE\n"\
|
||||
"GOT TO GO THROUGH HELL TO GET TO IT?"
|
||||
|
||||
|
||||
// After level 29, put this:
|
||||
|
||||
#define C4TEXT \
|
||||
"THE HORRENDOUS VISAGE OF THE BIGGEST\n"\
|
||||
"DEMON YOU'VE EVER SEEN CRUMBLES BEFORE\n"\
|
||||
"YOU, AFTER YOU PUMP YOUR ROCKETS INTO\n"\
|
||||
"HIS EXPOSED BRAIN. THE MONSTER SHRIVELS\n"\
|
||||
"UP AND DIES, ITS THRASHING LIMBS\n"\
|
||||
"DEVASTATING UNTOLD MILES OF HELL'S\n"\
|
||||
"SURFACE.\n"\
|
||||
"\n"\
|
||||
"YOU'VE DONE IT. THE INVASION IS OVER.\n"\
|
||||
"EARTH IS SAVED. HELL IS A WRECK. YOU\n"\
|
||||
"WONDER WHERE BAD FOLKS WILL GO WHEN THEY\n"\
|
||||
"DIE, NOW. WIPING THE SWEAT FROM YOUR\n"\
|
||||
"FOREHEAD YOU BEGIN THE LONG TREK BACK\n"\
|
||||
"HOME. REBUILDING EARTH OUGHT TO BE A\n"\
|
||||
"LOT MORE FUN THAN RUINING IT WAS.\n"
|
||||
|
||||
|
||||
|
||||
// Before level 31, put this:
|
||||
|
||||
#define C5TEXT \
|
||||
"CONGRATULATIONS, YOU'VE FOUND THE SECRET\n"\
|
||||
"LEVEL! LOOKS LIKE IT'S BEEN BUILT BY\n"\
|
||||
"HUMANS, RATHER THAN DEMONS. YOU WONDER\n"\
|
||||
"WHO THE INMATES OF THIS CORNER OF HELL\n"\
|
||||
"WILL BE."
|
||||
|
||||
|
||||
// Before level 32, put this:
|
||||
|
||||
#define C6TEXT \
|
||||
"CONGRATULATIONS, YOU'VE FOUND THE\n"\
|
||||
"SUPER SECRET LEVEL! YOU'D BETTER\n"\
|
||||
"BLAZE THROUGH THIS ONE!\n"
|
||||
|
||||
|
||||
// after map 06
|
||||
|
||||
#define P1TEXT \
|
||||
"You gloat over the steaming carcass of the\n"\
|
||||
"Guardian. With its death, you've wrested\n"\
|
||||
"the Accelerator from the stinking claws\n"\
|
||||
"of Hell. You relax and glance around the\n"\
|
||||
"room. Damn! There was supposed to be at\n"\
|
||||
"least one working prototype, but you can't\n"\
|
||||
"see it. The demons must have taken it.\n"\
|
||||
"\n"\
|
||||
"You must find the prototype, or all your\n"\
|
||||
"struggles will have been wasted. Keep\n"\
|
||||
"moving, keep fighting, keep killing.\n"\
|
||||
"Oh yes, keep living, too."
|
||||
|
||||
|
||||
// after map 11
|
||||
|
||||
#define P2TEXT \
|
||||
"Even the deadly Arch-Vile labyrinth could\n"\
|
||||
"not stop you, and you've gotten to the\n"\
|
||||
"prototype Accelerator which is soon\n"\
|
||||
"efficiently and permanently deactivated.\n"\
|
||||
"\n"\
|
||||
"You're good at that kind of thing."
|
||||
|
||||
|
||||
// after map 20
|
||||
|
||||
#define P3TEXT \
|
||||
"You've bashed and battered your way into\n"\
|
||||
"the heart of the devil-hive. Time for a\n"\
|
||||
"Search-and-Destroy mission, aimed at the\n"\
|
||||
"Gatekeeper, whose foul offspring is\n"\
|
||||
"cascading to Earth. Yeah, he's bad. But\n"\
|
||||
"you know who's worse!\n"\
|
||||
"\n"\
|
||||
"Grinning evilly, you check your gear, and\n"\
|
||||
"get ready to give the bastard a little Hell\n"\
|
||||
"of your own making!"
|
||||
|
||||
// after map 30
|
||||
|
||||
#define P4TEXT \
|
||||
"The Gatekeeper's evil face is splattered\n"\
|
||||
"all over the place. As its tattered corpse\n"\
|
||||
"collapses, an inverted Gate forms and\n"\
|
||||
"sucks down the shards of the last\n"\
|
||||
"prototype Accelerator, not to mention the\n"\
|
||||
"few remaining demons. You're done. Hell\n"\
|
||||
"has gone back to pounding bad dead folks \n"\
|
||||
"instead of good live ones. Remember to\n"\
|
||||
"tell your grandkids to put a rocket\n"\
|
||||
"launcher in your coffin. If you go to Hell\n"\
|
||||
"when you die, you'll need it for some\n"\
|
||||
"final cleaning-up ..."
|
||||
|
||||
// before map 31
|
||||
|
||||
#define P5TEXT \
|
||||
"You've found the second-hardest level we\n"\
|
||||
"got. Hope you have a saved game a level or\n"\
|
||||
"two previous. If not, be prepared to die\n"\
|
||||
"aplenty. For master marines only."
|
||||
|
||||
// before map 32
|
||||
|
||||
#define P6TEXT \
|
||||
"Betcha wondered just what WAS the hardest\n"\
|
||||
"level we had ready for ya? Now you know.\n"\
|
||||
"No one gets out alive."
|
||||
|
||||
|
||||
#define T1TEXT \
|
||||
"You've fought your way out of the infested\n"\
|
||||
"experimental labs. It seems that UAC has\n"\
|
||||
"once again gulped it down. With their\n"\
|
||||
"high turnover, it must be hard for poor\n"\
|
||||
"old UAC to buy corporate health insurance\n"\
|
||||
"nowadays..\n"\
|
||||
"\n"\
|
||||
"Ahead lies the military complex, now\n"\
|
||||
"swarming with diseased horrors hot to get\n"\
|
||||
"their teeth into you. With luck, the\n"\
|
||||
"complex still has some warlike ordnance\n"\
|
||||
"laying around."
|
||||
|
||||
|
||||
#define T2TEXT \
|
||||
"You hear the grinding of heavy machinery\n"\
|
||||
"ahead. You sure hope they're not stamping\n"\
|
||||
"out new hellspawn, but you're ready to\n"\
|
||||
"ream out a whole herd if you have to.\n"\
|
||||
"They might be planning a blood feast, but\n"\
|
||||
"you feel about as mean as two thousand\n"\
|
||||
"maniacs packed into one mad killer.\n"\
|
||||
"\n"\
|
||||
"You don't plan to go down easy."
|
||||
|
||||
|
||||
#define T3TEXT \
|
||||
"The vista opening ahead looks real damn\n"\
|
||||
"familiar. Smells familiar, too -- like\n"\
|
||||
"fried excrement. You didn't like this\n"\
|
||||
"place before, and you sure as hell ain't\n"\
|
||||
"planning to like it now. The more you\n"\
|
||||
"brood on it, the madder you get.\n"\
|
||||
"Hefting your gun, an evil grin trickles\n"\
|
||||
"onto your face. Time to take some names."
|
||||
|
||||
#define T4TEXT \
|
||||
"Suddenly, all is silent, from one horizon\n"\
|
||||
"to the other. The agonizing echo of Hell\n"\
|
||||
"fades away, the nightmare sky turns to\n"\
|
||||
"blue, the heaps of monster corpses start \n"\
|
||||
"to evaporate along with the evil stench \n"\
|
||||
"that filled the air. Jeeze, maybe you've\n"\
|
||||
"done it. Have you really won?\n"\
|
||||
"\n"\
|
||||
"Something rumbles in the distance.\n"\
|
||||
"A blue light begins to glow inside the\n"\
|
||||
"ruined skull of the demon-spitter."
|
||||
|
||||
|
||||
#define T5TEXT \
|
||||
"What now? Looks totally different. Kind\n"\
|
||||
"of like King Tut's condo. Well,\n"\
|
||||
"whatever's here can't be any worse\n"\
|
||||
"than usual. Can it? Or maybe it's best\n"\
|
||||
"to let sleeping gods lie.."
|
||||
|
||||
|
||||
#define T6TEXT \
|
||||
"Time for a vacation. You've burst the\n"\
|
||||
"bowels of hell and by golly you're ready\n"\
|
||||
"for a break. You mutter to yourself,\n"\
|
||||
"Maybe someone else can kick Hell's ass\n"\
|
||||
"next time around. Ahead lies a quiet town,\n"\
|
||||
"with peaceful flowing water, quaint\n"\
|
||||
"buildings, and presumably no Hellspawn.\n"\
|
||||
"\n"\
|
||||
"As you step off the transport, you hear\n"\
|
||||
"the stomp of a cyberdemon's iron shoe."
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Character cast strings F_FINALE.C
|
||||
//
|
||||
#define CC_ZOMBIE "ZOMBIEMAN"
|
||||
#define CC_SHOTGUN "SHOTGUN GUY"
|
||||
#define CC_HEAVY "HEAVY WEAPON DUDE"
|
||||
#define CC_IMP "IMP"
|
||||
#define CC_DEMON "DEMON"
|
||||
#define CC_LOST "LOST SOUL"
|
||||
#define CC_CACO "CACODEMON"
|
||||
#define CC_HELL "HELL KNIGHT"
|
||||
#define CC_BARON "BARON OF HELL"
|
||||
#define CC_ARACH "ARACHNOTRON"
|
||||
#define CC_PAIN "PAIN ELEMENTAL"
|
||||
#define CC_REVEN "REVENANT"
|
||||
#define CC_MANCU "MANCUBUS"
|
||||
#define CC_ARCH "ARCH-VILE"
|
||||
#define CC_SPIDER "THE SPIDER MASTERMIND"
|
||||
#define CC_CYBER "THE CYBERDEMON"
|
||||
#define CC_HERO "OUR HERO"
|
||||
|
||||
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Log:$
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
|
@ -52,7 +52,7 @@ extern weaponinfo_t weaponinfo[NUMWEAPONS];
|
|||
#define IT_ARMOR 4
|
||||
#define IT_KEY 8
|
||||
#define IT_ARTIFACT 16 // Don't auto-activate item (unused)
|
||||
#define IT_POWER 32 // Auto-activate item
|
||||
#define IT_POWERUP 32 // Auto-activate item
|
||||
|
||||
struct gitem_s
|
||||
{
|
||||
|
@ -67,16 +67,18 @@ struct gitem_s
|
|||
};
|
||||
typedef struct gitem_s gitem_t;
|
||||
|
||||
extern gitem_t ItemList[];
|
||||
extern int num_items;
|
||||
|
||||
extern gitem_t itemlist[];
|
||||
|
||||
void InitItems (void);
|
||||
|
||||
// FindItem
|
||||
gitem_t *GetItemByIndex (int index);
|
||||
gitem_t *FindItemByClassname (char *classname);
|
||||
gitem_t *FindItem (char *pickup_name);
|
||||
gitem_t *FindItemByClassname (const char *classname);
|
||||
gitem_t *FindItem (const char *pickup_name);
|
||||
|
||||
#define ITEM_INDEX(i) ((i)-ItemList)
|
||||
#define ITEM_INDEX(i) ((i)-itemlist)
|
||||
|
||||
|
||||
#endif
|
||||
|
|
937
code/D_main.c
937
code/D_main.c
File diff suppressed because it is too large
Load diff
90
code/D_net.c
90
code/D_net.c
|
@ -22,7 +22,7 @@
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#include "version.h"
|
||||
#include "m_alloc.h"
|
||||
#include "m_menu.h"
|
||||
#include "i_system.h"
|
||||
|
@ -34,7 +34,6 @@
|
|||
#include "c_consol.h"
|
||||
#include "d_netinf.h"
|
||||
#include "cmdlib.h"
|
||||
#include "sounds.h"
|
||||
#include "s_sound.h"
|
||||
#include "m_cheat.h"
|
||||
|
||||
|
@ -71,6 +70,9 @@ BOOL remoteresend[MAXNETNODES]; // set when local needs tics
|
|||
int resendto[MAXNETNODES]; // set when remote needs tics
|
||||
int resendcount[MAXNETNODES];
|
||||
|
||||
unsigned int lastrecvtime[MAXPLAYERS]; // [RH] Used for pings
|
||||
unsigned int currrecvtime[MAXPLAYERS];
|
||||
|
||||
int nodeforplayer[MAXPLAYERS];
|
||||
|
||||
int maketic;
|
||||
|
@ -288,6 +290,10 @@ void GetPackets (void)
|
|||
|
||||
netconsole = netbuffer->player & ~PL_DRONE;
|
||||
netnode = doomcom->remotenode;
|
||||
|
||||
// [RH] Get "ping" times
|
||||
lastrecvtime[netconsole] = currrecvtime[netconsole];
|
||||
currrecvtime[netconsole] = I_MSTime ();
|
||||
|
||||
// to save bytes, only the low byte of tic numbers are sent
|
||||
// Figure out what the rest of the bytes are
|
||||
|
@ -305,10 +311,10 @@ void GetPackets (void)
|
|||
|
||||
if (deathmatch->value) {
|
||||
Printf ("%s left the game with %d frags\n",
|
||||
players[netconsole].userinfo->netname,
|
||||
players[netconsole].userinfo.netname,
|
||||
players[netconsole].fragcount);
|
||||
} else {
|
||||
Printf ("%s left the game\n", players[netconsole].userinfo->netname);
|
||||
Printf ("%s left the game\n", players[netconsole].userinfo.netname);
|
||||
}
|
||||
|
||||
if (demorecording) {
|
||||
|
@ -492,11 +498,12 @@ void CheckAbort (void)
|
|||
{
|
||||
event_t *ev;
|
||||
int stoptic;
|
||||
|
||||
|
||||
Printf (""); // [RH] Give the console a chance to redraw itself
|
||||
stoptic = I_GetTime () + 2;
|
||||
while (I_GetTime() < stoptic)
|
||||
I_StartTic ();
|
||||
|
||||
|
||||
I_StartTic ();
|
||||
for ( ; eventtail != eventhead
|
||||
; eventtail = (++eventtail)&(MAXEVENTS-1) )
|
||||
|
@ -531,7 +538,7 @@ void D_ArbitrateNetStart (void)
|
|||
nodesdetected[0] = 1; // Detect ourselves
|
||||
|
||||
// [RH] Rewrote this loop based on Doom Legacy 1.11's code.
|
||||
Printf ("Waiting for %d more players...\n", doomcom->numnodes - 1);
|
||||
Printf ("Waiting for %d more player%s...\n", doomcom->numnodes - 1, (doomcom->numnodes == 2) ? "" : "s");
|
||||
do {
|
||||
CheckAbort ();
|
||||
|
||||
|
@ -569,7 +576,7 @@ void D_ArbitrateNetStart (void)
|
|||
D_ReadUserInfoStrings (netbuffer->player, &stream, false);
|
||||
|
||||
Printf ("%s joined the game (node %d, player %d)\n",
|
||||
players[netbuffer->player].userinfo->netname,
|
||||
players[netbuffer->player].userinfo.netname,
|
||||
doomcom->remotenode,
|
||||
netbuffer->player);
|
||||
}
|
||||
|
@ -644,7 +651,7 @@ void D_CheckNetGame (void)
|
|||
// I_InitNetwork sets doomcom and netgame
|
||||
I_InitNetwork ();
|
||||
if (doomcom->id != DOOMCOM_ID)
|
||||
I_Error ("Doomcom buffer invalid!");
|
||||
I_FatalError ("Doomcom buffer invalid!");
|
||||
|
||||
netbuffer = &doomcom->data;
|
||||
consoleplayer = displayplayer = doomcom->consoleplayer;
|
||||
|
@ -652,36 +659,22 @@ void D_CheckNetGame (void)
|
|||
// [RH] Setup user info
|
||||
D_SetupUserInfo ();
|
||||
|
||||
UnlatchCVars ();
|
||||
|
||||
if (netgame)
|
||||
D_ArbitrateNetStart ();
|
||||
|
||||
UnlatchCVars ();
|
||||
|
||||
{
|
||||
char map[9];
|
||||
strncpy (map, startmap, 8);
|
||||
map[8] = 0;
|
||||
|
||||
Printf ("skill: %g deathmatch: %g map: %s dmflags: %i\n",
|
||||
gameskill->value, deathmatch->value, map, dmflags);
|
||||
}
|
||||
|
||||
// read values out of doomcom
|
||||
ticdup = doomcom->ticdup;
|
||||
maxsend = BACKUPTICS/(2*ticdup)-1;
|
||||
if (maxsend<1)
|
||||
maxsend = 1;
|
||||
|
||||
for (i=0 ; i<doomcom->numplayers ; i++)
|
||||
for (i = 0; i < doomcom->numplayers; i++)
|
||||
playeringame[i] = true;
|
||||
for (i=0 ; i<doomcom->numnodes ; i++)
|
||||
for (i = 0; i < doomcom->numnodes; i++)
|
||||
nodeingame[i] = true;
|
||||
|
||||
Printf ("player %i of %i (%i nodes)\n",
|
||||
consoleplayer+1, doomcom->numplayers, doomcom->numnodes);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -692,7 +685,7 @@ void D_CheckNetGame (void)
|
|||
//
|
||||
void D_QuitNetGame (void)
|
||||
{
|
||||
int i, j;
|
||||
int i, j;
|
||||
|
||||
if (debugfile)
|
||||
fclose (debugfile);
|
||||
|
@ -703,9 +696,9 @@ void D_QuitNetGame (void)
|
|||
// send a bunch of packets for security
|
||||
netbuffer->player = consoleplayer;
|
||||
netbuffer->numtics = 0;
|
||||
for (i=0 ; i<4 ; i++)
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
for (j=1 ; j<doomcom->numnodes ; j++)
|
||||
for (j = 1; j < doomcom->numnodes; j++)
|
||||
if (nodeingame[j])
|
||||
HSendPacket (j, NCMD_EXIT, myoffsetof(doomdata_t,cmds));
|
||||
I_WaitVBL (1);
|
||||
|
@ -938,16 +931,28 @@ void Net_DoCommand (int type, byte **stream, int player)
|
|||
switch (type) {
|
||||
case DEM_SAY:
|
||||
{
|
||||
int who = ReadByte (stream);
|
||||
byte who = ReadByte (stream);
|
||||
|
||||
s = ReadString (stream);
|
||||
if (!who || (who - 1) == consoleplayer) {
|
||||
Printf_Bold ("%s: %s\n", players[player].userinfo->netname, s);
|
||||
if ((who == 0) || players[player].userinfo.team[0] == 0) {
|
||||
// Said to everyone
|
||||
Printf_Bold ("%s: %s\n", players[player].userinfo.netname, s);
|
||||
|
||||
if (gamemode == commercial)
|
||||
S_StartSound(ORIGIN_AMBIENT3, sfx_radio);
|
||||
else
|
||||
S_StartSound(ORIGIN_AMBIENT3, sfx_tink);
|
||||
if (gamemode == commercial) {
|
||||
S_StartSound (ORIGIN_AMBIENT3, "misc/chat", 60);
|
||||
} else {
|
||||
S_StartSound (ORIGIN_AMBIENT3, "misc/chat2", 60);
|
||||
}
|
||||
} else if (!stricmp (players[player].userinfo.team,
|
||||
players[consoleplayer].userinfo.team)) {
|
||||
// Said only to members of the player's team
|
||||
Printf_Bold ("(%s): %s\n", players[player].userinfo.netname, s);
|
||||
|
||||
if (gamemode == commercial) {
|
||||
S_StartSound (ORIGIN_AMBIENT3, "misc/chat", 60);
|
||||
} else {
|
||||
S_StartSound (ORIGIN_AMBIENT3, "misc/chat2", 60);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -989,7 +994,7 @@ void Net_DoCommand (int type, byte **stream, int player)
|
|||
strncpy (level.nextmap, s, 8);
|
||||
// Using LEVEL_NOINTERMISSION tends to throw the game out of sync.
|
||||
level.flags |= LEVEL_CHANGEMAPCHEAT;
|
||||
G_ExitLevel ();
|
||||
G_ExitLevel (0);
|
||||
break;
|
||||
|
||||
case DEM_SUICIDE:
|
||||
|
@ -1003,4 +1008,15 @@ void Net_DoCommand (int type, byte **stream, int player)
|
|||
|
||||
if (s)
|
||||
free (s);
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] List ping times
|
||||
void Cmd_Pings (void *plyr, int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
Printf ("% 4u %s\n", currrecvtime[i] - lastrecvtime[i],
|
||||
players[i].userinfo.netname);
|
||||
}
|
||||
|
|
|
@ -157,19 +157,23 @@ typedef struct player_s
|
|||
// can be set to REDCOLORMAP for pain, etc.
|
||||
int fixedcolormap;
|
||||
|
||||
// Player skin colorshift,
|
||||
// 0-3 for which color to draw player.
|
||||
int colormap;
|
||||
// [RH] Amount to shift view horizontally (for earthquakes)
|
||||
int xviewshift;
|
||||
|
||||
// Overlay view sprites (gun, etc).
|
||||
pspdef_t psprites[NUMPSPRITES];
|
||||
|
||||
// [RH] Pointer to a userinfo struct
|
||||
userinfo_t *userinfo;
|
||||
// [RH] A userinfo struct
|
||||
userinfo_t userinfo;
|
||||
|
||||
// [RH] Tic when respawning is allowed
|
||||
int respawn_time;
|
||||
|
||||
// [RH] Used for calculating falling damage
|
||||
fixed_t oldvelocity[3];
|
||||
|
||||
// [RH] Camera to use to draw view from. Normally same as mo
|
||||
mobj_t *camera;
|
||||
} player_t;
|
||||
|
||||
|
||||
|
|
|
@ -280,7 +280,7 @@ void ReadTicCmd (ticcmd_t *tcmd, byte **stream, int player)
|
|||
}
|
||||
|
||||
|
||||
static byte *lenspot;
|
||||
byte *lenspot;
|
||||
|
||||
// Write the header of an IFF chunk and leave space
|
||||
// for the length field.
|
|
@ -30,11 +30,6 @@
|
|||
//
|
||||
// Global parameters/defines.
|
||||
//
|
||||
// DOOM version
|
||||
enum { VERSION = 114 };
|
||||
#define VERSIONSTR "114"
|
||||
#define GAMEVER (0x010e)
|
||||
|
||||
|
||||
// Game mode handling - identify IWAD version
|
||||
// to handle IWAD dependend animations etc.
|
||||
|
@ -45,7 +40,7 @@ typedef enum
|
|||
commercial, // DOOM 2 retail, E1 M34
|
||||
// DOOM 2 german edition not handled
|
||||
retail, // DOOM 1 retail, E4, M36
|
||||
indetermined // Well, no IWAD found.
|
||||
undetermined // Well, no IWAD found.
|
||||
|
||||
} GameMode_t;
|
||||
|
||||
|
@ -69,7 +64,6 @@ typedef enum
|
|||
french,
|
||||
german,
|
||||
unknown
|
||||
|
||||
} Language_t;
|
||||
|
||||
|
||||
|
@ -77,36 +71,6 @@ typedef enum
|
|||
// most parameter validation debugging code will not be compiled
|
||||
#define RANGECHECK
|
||||
|
||||
// Do or do not use external soundserver.
|
||||
// The sndserver binary to be run separately
|
||||
// has been introduced by Dave Taylor.
|
||||
// The integrated sound support is experimental,
|
||||
// and unfinished. Default is synchronous.
|
||||
// Experimental asynchronous timer based is
|
||||
// handled by SNDINTR.
|
||||
#define SNDSERV 1
|
||||
//#define SNDINTR 1
|
||||
|
||||
|
||||
// This one switches between MIT SHM (no proper mouse)
|
||||
// and XFree86 DGA (mickey sampling). The original
|
||||
// linuxdoom used SHM, which is default.
|
||||
//#define X11_DGA 1
|
||||
|
||||
|
||||
//
|
||||
// For resize of screen, at start of game.
|
||||
// It will not work dynamically, see visplanes.
|
||||
//
|
||||
#define BASE_WIDTH 320
|
||||
|
||||
// It is educational but futile to change this
|
||||
// scaling e.g. to 2. Drawing of status bar,
|
||||
// menues etc. is tied to the scale implied
|
||||
// by the graphics.
|
||||
#define SCREEN_MUL 1
|
||||
#define INV_ASPECT_RATIO 0.625 // 0.75, ideally
|
||||
|
||||
// The maximum number of players, multiplayer/networking.
|
||||
#define MAXPLAYERS 8
|
||||
|
||||
|
@ -121,7 +85,10 @@ typedef enum
|
|||
GS_LEVEL,
|
||||
GS_INTERMISSION,
|
||||
GS_FINALE,
|
||||
GS_DEMOSCREEN
|
||||
GS_DEMOSCREEN,
|
||||
GS_FULLCONSOLE, // [RH] Fullscreen console
|
||||
GS_HIDECONSOLE, // [RH] The menu just did something that should hide fs console
|
||||
GS_STARTUP // [RH] Console is fullscreen, and game is just starting
|
||||
} gamestate_t;
|
||||
|
||||
//
|
||||
|
@ -138,11 +105,11 @@ typedef enum
|
|||
|
||||
typedef float skill_t;
|
||||
|
||||
#define sk_baby 0.0
|
||||
#define sk_easy 1.0
|
||||
#define sk_medium 2.0
|
||||
#define sk_hard 3.0
|
||||
#define sk_nightmare 4.0
|
||||
#define sk_baby 0.0f
|
||||
#define sk_easy 1.0f
|
||||
#define sk_medium 2.0f
|
||||
#define sk_hard 3.0f
|
||||
#define sk_nightmare 4.0f
|
||||
|
||||
|
||||
|
||||
|
@ -288,6 +255,8 @@ typedef enum
|
|||
#define KEY_MOUSE2 0x101
|
||||
#define KEY_MOUSE3 0x102
|
||||
#define KEY_MOUSE4 0x103
|
||||
#define KEY_MWHEELUP 0x104
|
||||
#define KEY_MWHEELDOWN 0x105
|
||||
|
||||
#define KEY_JOY1 0x108
|
||||
#define KEY_JOY2 0x109
|
||||
|
@ -322,13 +291,14 @@ typedef enum
|
|||
#define KEY_JOY31 0x126
|
||||
#define KEY_JOY32 0x127
|
||||
|
||||
#define NUM_KEYS 0x128
|
||||
|
||||
// [RH] dmflags->value flags (based on Q2's)
|
||||
#define DF_NO_HEALTH 1 // Do not spawn health items (DM)
|
||||
#define DF_NO_ITEMS 2 // Do not spawn powerups (DM)
|
||||
#define DF_WEAPONS_STAY 4 // Leave weapons around after pickup (DM)
|
||||
#define DF_YES_FALLING 8 // Falling too far hurts
|
||||
#define DF_YES_FALLING_LOTS 16 // Falling too far hurts a lot
|
||||
#define DF_NO_FRIENDLY_FIRE 16 // Can't hurt teammates
|
||||
//#define DF_INVENTORY_ITEMS 32 // Wait for player to use powerups when picked up
|
||||
#define DF_SAME_LEVEL 64 // Stay on the same map when someone exits (DM)
|
||||
#define DF_SPAWN_FARTHEST 128 // Spawn players as far as possible from other players (DM)
|
||||
|
@ -343,4 +313,14 @@ typedef enum
|
|||
#define DF_NO_JUMP 65536 // Don't allow jumping
|
||||
#define DF_NO_FREELOOK 131072 // Don't allow freelook
|
||||
|
||||
// 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__
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
|
||||
// Game Mode - identify IWAD as shareware, retail etc.
|
||||
GameMode_t gamemode = indetermined;
|
||||
GameMode_t gamemode = undetermined;
|
||||
GameMission_t gamemission = doom;
|
||||
|
||||
// Language.
|
||||
|
@ -43,6 +43,9 @@ cvar_t *developer;
|
|||
// True if an old demo is being played back.
|
||||
BOOL olddemo;
|
||||
|
||||
// [RH] Feature control cvars
|
||||
cvar_t *boom_friction, *boom_pushers;
|
||||
|
||||
// [RH] Deathmatch flags
|
||||
cvar_t *dmflagsvar;
|
||||
int dmflags; // Copy of dmflagsvar->value, but as an integer.
|
||||
|
|
|
@ -83,7 +83,10 @@ extern BOOL respawnmonsters;
|
|||
extern BOOL netgame;
|
||||
|
||||
// Flag: true only if started as net deathmatch.
|
||||
extern cvar_t *deathmatch;
|
||||
extern cvar_t *deathmatch;
|
||||
|
||||
// [RH] Teamplay mode
|
||||
extern cvar_t *teamplay;
|
||||
|
||||
// -------------------------
|
||||
// Internal parameters for sound rendering.
|
||||
|
@ -278,26 +281,30 @@ void EndMMX (void);
|
|||
|
||||
#endif
|
||||
|
||||
extern cvar_t *boom_friction;
|
||||
extern cvar_t *boom_pushers;
|
||||
|
||||
|
||||
// [RH] Miscellaneous info for DeHackEd support
|
||||
|
||||
extern int deh_StartHealth;
|
||||
extern int deh_StartBullets;
|
||||
extern int deh_MaxHealth;
|
||||
extern int deh_MaxArmor;
|
||||
extern int deh_GreenAC;
|
||||
extern int deh_BlueAC;
|
||||
extern int deh_MaxSoulsphere;
|
||||
extern int deh_SoulsphereHealth;
|
||||
extern int deh_MegasphereHealth;
|
||||
extern int deh_GodHealth;
|
||||
extern int deh_FAArmor;
|
||||
extern int deh_FAAC;
|
||||
extern int deh_KFAArmor;
|
||||
extern int deh_KFAAC;
|
||||
extern int deh_BFGCells;
|
||||
extern int deh_Infight;
|
||||
|
||||
struct DehInfo {
|
||||
int StartHealth;
|
||||
int StartBullets;
|
||||
int MaxHealth;
|
||||
int MaxArmor;
|
||||
int GreenAC;
|
||||
int BlueAC;
|
||||
int MaxSoulsphere;
|
||||
int SoulsphereHealth;
|
||||
int MegasphereHealth;
|
||||
int GodHealth;
|
||||
int FAArmor;
|
||||
int FAAC;
|
||||
int KFAArmor;
|
||||
int KFAAC;
|
||||
int BFGCells;
|
||||
int Infight;
|
||||
};
|
||||
extern struct DehInfo deh;
|
||||
|
||||
// [RH] Deathmatch flags
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ typedef unsigned char byte;
|
|||
// Predefined with some OS.
|
||||
#ifdef __GNUC__
|
||||
#include <values.h>
|
||||
typedef long long __int64;
|
||||
#else
|
||||
/* [Petteri] Don't redefine if we already have these */
|
||||
#ifndef MAXCHAR
|
||||
|
@ -68,8 +69,10 @@ typedef unsigned char byte;
|
|||
|
||||
|
||||
#ifndef NOASM
|
||||
#ifndef USEASM
|
||||
#define USEASM
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
671
code/Dstrings.c
671
code/Dstrings.c
|
@ -34,8 +34,6 @@
|
|||
#include "cmdlib.h"
|
||||
#include "g_level.h"
|
||||
|
||||
cvar_t *var_language;
|
||||
|
||||
char* endmsg[NUM_QUITMESSAGES+1]=
|
||||
{
|
||||
// DOOM1
|
||||
|
@ -60,228 +58,228 @@ char* endmsg[NUM_QUITMESSAGES+1]=
|
|||
|
||||
|
||||
gamestring_t Strings[NUMSTRINGS] = {
|
||||
{ 0, "Development mode ON.\n", NULL },
|
||||
{ 0, "CD-ROM Version: default.cfg from c:\\doomdata\n", NULL },
|
||||
{ 0, "press a key.", NULL },
|
||||
{ 0, "press y or n.", NULL },
|
||||
{ 0, "are you sure you want to\nquit this great game?", NULL },
|
||||
{ 0, "you can't do load while in a net game!\n\npress a key.", NULL },
|
||||
{ 0, "you can't quickload during a netgame!\n\npress a key.", NULL },
|
||||
{ 0, "you haven't picked a quicksave slot yet!\n\npress a key.", NULL },
|
||||
{ 0, "you can't save if you aren't playing!\n\npress a key.", NULL },
|
||||
{ 0, "quicksave over your game named\n\n'%s'?\n\npress y or n.", NULL },
|
||||
{ 0, "do you want to quickload the game named\n\n'%s'?\n\npress y or n.", NULL },
|
||||
{ 0, "you can't start a new game\nwhile in a network game.\n\npress a key.", NULL },
|
||||
{ 0, "are you sure? this skill level\nisn't even remotely fair.\n\npress y or n.", NULL },
|
||||
{ 0, "this is the shareware version of doom.\n\nyou need to order the entire trilogy.\n\npress a key.", NULL },
|
||||
{ 0, "Messages OFF", NULL },
|
||||
{ 0, "Messages ON", NULL },
|
||||
{ 0, "you can't end a netgame!\n\npress a key.", NULL },
|
||||
{ 0, "are you sure you want to end the game?\n\npress y or n.", NULL },
|
||||
{ 0, "(press y to quit)", NULL },
|
||||
{ 0, "empty slot", NULL },
|
||||
{ 0, "Picked up the armor.", NULL },
|
||||
{ 0, "Picked up the MegaArmor!", NULL },
|
||||
{ 0, "Picked up a health bonus.", NULL },
|
||||
{ 0, "Picked up an armor bonus.", NULL },
|
||||
{ 0, "Picked up a stimpack.", NULL },
|
||||
{ 0, "Picked up a medikit that you REALLY need!", NULL },
|
||||
{ 0, "Picked up a medikit.", NULL },
|
||||
{ 0, "Supercharge!", NULL },
|
||||
{ 0, "Picked up a blue keycard.", NULL },
|
||||
{ 0, "Picked up a yellow keycard.", NULL },
|
||||
{ 0, "Picked up a red keycard.", NULL },
|
||||
{ 0, "Picked up a blue skull key.", NULL },
|
||||
{ 0, "Picked up a yellow skull key.", NULL },
|
||||
{ 0, "Picked up a red skull key.", NULL },
|
||||
{ 0, "Invulnerability!", NULL },
|
||||
{ 0, "Berserk!", NULL },
|
||||
{ 0, "Partial Invisibility", NULL },
|
||||
{ 0, "Radiation Shielding Suit", NULL },
|
||||
{ 0, "Computer Area Map", NULL },
|
||||
{ 0, "Light Amplification Visor", NULL },
|
||||
{ 0, "MegaSphere!", NULL },
|
||||
{ 0, "Picked up a clip.", NULL },
|
||||
{ 0, "Picked up a box of bullets.", NULL },
|
||||
{ 0, "Picked up a rocket.", NULL },
|
||||
{ 0, "Picked up a box of rockets.", NULL },
|
||||
{ 0, "Picked up an energy cell.", NULL },
|
||||
{ 0, "Picked up an energy cell pack.", NULL },
|
||||
{ 0, "Picked up 4 shotgun shells.", NULL },
|
||||
{ 0, "Picked up a box of shotgun shells.", NULL },
|
||||
{ 0, "Picked up a backpack full of ammo!", NULL },
|
||||
{ 0, "You got the BFG9000! Oh, yes.", NULL },
|
||||
{ 0, "You got the chaingun!", NULL },
|
||||
{ 0, "A chainsaw! Find some meat!", NULL },
|
||||
{ 0, "You got the rocket launcher!", NULL },
|
||||
{ 0, "You got the plasma gun!", NULL },
|
||||
{ 0, "You got the shotgun!", NULL },
|
||||
{ 0, "You got the super shotgun!", NULL },
|
||||
{ 0, "You need a blue key to activate this object", NULL },
|
||||
{ 0, "You need a red key to activate this object", NULL },
|
||||
{ 0, "You need a yellow key to activate this object", NULL },
|
||||
{ 0, "You need a blue key to open this door", NULL },
|
||||
{ 0, "You need a red key to open this door", NULL },
|
||||
{ 0, "You need a yellow key to open this door", NULL },
|
||||
{ 0, "game saved.", NULL },
|
||||
{ 0, "[Message unsent]", NULL },
|
||||
{ 0, "E1M1: Hangar", NULL },
|
||||
{ 0, "E1M2: Nuclear Plant", NULL },
|
||||
{ 0, "E1M3: Toxin Refinery", NULL },
|
||||
{ 0, "E1M4: Command Control", NULL },
|
||||
{ 0, "E1M5: Phobos Lab", NULL },
|
||||
{ 0, "E1M6: Central Processing", NULL },
|
||||
{ 0, "E1M7: Computer Station", NULL },
|
||||
{ 0, "E1M8: Phobos Anomaly", NULL },
|
||||
{ 0, "E1M9: Military Base", NULL },
|
||||
{ 0, "E2M1: Deimos Anomaly", NULL },
|
||||
{ 0, "E2M2: Containment Area", NULL },
|
||||
{ 0, "E2M3: Refinery", NULL },
|
||||
{ 0, "E2M4: Deimos Lab", NULL },
|
||||
{ 0, "E2M5: Command Center", NULL },
|
||||
{ 0, "E2M6: Halls of the Damned", NULL },
|
||||
{ 0, "E2M7: Spawning Vats", NULL },
|
||||
{ 0, "E2M8: Tower of Babel", NULL },
|
||||
{ 0, "E2M9: Fortress of Mystery", NULL },
|
||||
{ 0, "E3M1: Hell Keep", NULL },
|
||||
{ 0, "E3M2: Slough of Despair", NULL },
|
||||
{ 0, "E3M3: Pandemonium", NULL },
|
||||
{ 0, "E3M4: House of Pain", NULL },
|
||||
{ 0, "E3M5: Unholy Cathedral", NULL },
|
||||
{ 0, "E3M6: Mt. Erebus", NULL },
|
||||
{ 0, "E3M7: Limbo", NULL },
|
||||
{ 0, "E3M8: Dis", NULL },
|
||||
{ 0, "E3M9: Warrens", NULL },
|
||||
{ 0, "E4M1: Hell Beneath", NULL },
|
||||
{ 0, "E4M2: Perfect Hatred", NULL },
|
||||
{ 0, "E4M3: Sever The Wicked", NULL },
|
||||
{ 0, "E4M4: Unruly Evil", NULL },
|
||||
{ 0, "E4M5: They Will Repent", NULL },
|
||||
{ 0, "E4M6: Against Thee Wickedly", NULL },
|
||||
{ 0, "E4M7: And Hell Followed", NULL },
|
||||
{ 0, "E4M8: Unto The Cruel", NULL },
|
||||
{ 0, "E4M9: Fear", NULL },
|
||||
{ 0, "level 1: entryway", NULL },
|
||||
{ 0, "level 2: underhalls", NULL },
|
||||
{ 0, "level 3: the gantlet", NULL },
|
||||
{ 0, "level 4: the focus", NULL },
|
||||
{ 0, "level 5: the waste tunnels", NULL },
|
||||
{ 0, "level 6: the crusher", NULL },
|
||||
{ 0, "level 7: dead simple", NULL },
|
||||
{ 0, "level 8: tricks and traps", NULL },
|
||||
{ 0, "level 9: the pit", NULL },
|
||||
{ 0, "level 10: refueling base", NULL },
|
||||
{ 0, "level 11: 'o' of destruction!", NULL },
|
||||
{ 0, "level 12: the factory", NULL },
|
||||
{ 0, "level 13: downtown", NULL },
|
||||
{ 0, "level 14: the inmost dens", NULL },
|
||||
{ 0, "level 15: industrial zone", NULL },
|
||||
{ 0, "level 16: suburbs", NULL },
|
||||
{ 0, "level 17: tenements", NULL },
|
||||
{ 0, "level 18: the courtyard", NULL },
|
||||
{ 0, "level 19: the citadel", NULL },
|
||||
{ 0, "level 20: gotcha!", NULL },
|
||||
{ 0, "level 21: nirvana", NULL },
|
||||
{ 0, "level 22: the catacombs", NULL },
|
||||
{ 0, "level 23: barrels o' fun", NULL },
|
||||
{ 0, "level 24: the chasm", NULL },
|
||||
{ 0, "level 25: bloodfalls", NULL },
|
||||
{ 0, "level 26: the abandoned mines", NULL },
|
||||
{ 0, "level 27: monster condo", NULL },
|
||||
{ 0, "level 28: the spirit world", NULL },
|
||||
{ 0, "level 29: the living end", NULL },
|
||||
{ 0, "level 30: icon of sin", NULL },
|
||||
{ 0, "level 31: wolfenstein", NULL },
|
||||
{ 0, "level 32: grosse", NULL },
|
||||
{ 0, "level 1: congo", NULL },
|
||||
{ 0, "level 2: well of souls", NULL },
|
||||
{ 0, "level 3: aztec", NULL },
|
||||
{ 0, "level 4: caged", NULL },
|
||||
{ 0, "level 5: ghost town", NULL },
|
||||
{ 0, "level 6: baron's lair", NULL },
|
||||
{ 0, "level 7: caughtyard", NULL },
|
||||
{ 0, "level 8: realm", NULL },
|
||||
{ 0, "level 9: abattoire", NULL },
|
||||
{ 0, "level 10: onslaught", NULL },
|
||||
{ 0, "level 11: hunted", NULL },
|
||||
{ 0, "level 12: speed", NULL },
|
||||
{ 0, "level 13: the crypt", NULL },
|
||||
{ 0, "level 14: genesis", NULL },
|
||||
{ 0, "level 15: the twilight", NULL },
|
||||
{ 0, "level 16: the omen", NULL },
|
||||
{ 0, "level 17: compound", NULL },
|
||||
{ 0, "level 18: neurosphere", NULL },
|
||||
{ 0, "level 19: nme", NULL },
|
||||
{ 0, "level 20: the death domain", NULL },
|
||||
{ 0, "level 21: slayer", NULL },
|
||||
{ 0, "level 22: impossible mission", NULL },
|
||||
{ 0, "level 23: tombstone", NULL },
|
||||
{ 0, "level 24: the final frontier", NULL },
|
||||
{ 0, "level 25: the temple of darkness", NULL },
|
||||
{ 0, "level 26: bunker", NULL },
|
||||
{ 0, "level 27: anti-christ", NULL },
|
||||
{ 0, "level 28: the sewers", NULL },
|
||||
{ 0, "level 29: odyssey of noises", NULL },
|
||||
{ 0, "level 30: the gateway of hell", NULL },
|
||||
{ 0, "level 31: cyberden", NULL },
|
||||
{ 0, "level 32: go 2 it", NULL },
|
||||
{ 0, "level 1: system control", NULL },
|
||||
{ 0, "level 2: human bbq", NULL },
|
||||
{ 0, "level 3: power control", NULL },
|
||||
{ 0, "level 4: wormhole", NULL },
|
||||
{ 0, "level 5: hanger", NULL },
|
||||
{ 0, "level 6: open season", NULL },
|
||||
{ 0, "level 7: prison", NULL },
|
||||
{ 0, "level 8: metal", NULL },
|
||||
{ 0, "level 9: stronghold", NULL },
|
||||
{ 0, "level 10: redemption", NULL },
|
||||
{ 0, "level 11: storage facility", NULL },
|
||||
{ 0, "level 12: crater", NULL },
|
||||
{ 0, "level 13: nukage processing", NULL },
|
||||
{ 0, "level 14: steel works", NULL },
|
||||
{ 0, "level 15: dead zone", NULL },
|
||||
{ 0, "level 16: deepest reaches", NULL },
|
||||
{ 0, "level 17: processing area", NULL },
|
||||
{ 0, "level 18: mill", NULL },
|
||||
{ 0, "level 19: shipping/respawning", NULL },
|
||||
{ 0, "level 20: central processing", NULL },
|
||||
{ 0, "level 21: administration center", NULL },
|
||||
{ 0, "level 22: habitat", NULL },
|
||||
{ 0, "level 23: lunar mining project", NULL },
|
||||
{ 0, "level 24: quarry", NULL },
|
||||
{ 0, "level 25: baron's den", NULL },
|
||||
{ 0, "level 26: ballistyx", NULL },
|
||||
{ 0, "level 27: mount pain", NULL },
|
||||
{ 0, "level 28: heck", NULL },
|
||||
{ 0, "level 29: river styx", NULL },
|
||||
{ 0, "level 30: last call", NULL },
|
||||
{ 0, "level 31: pharaoh", NULL },
|
||||
{ 0, "level 32: caribbean", NULL },
|
||||
{ 0, "You mumble to yourself", NULL },
|
||||
{ 0, "Who's there?", NULL },
|
||||
{ 0, "You scare yourself", NULL },
|
||||
{ 0, "You start to rave", NULL },
|
||||
{ 0, "You've lost it...", NULL },
|
||||
{ 0, "[Message Sent]", NULL },
|
||||
{ 0, "Follow Mode ON", NULL },
|
||||
{ 0, "Follow Mode OFF", NULL },
|
||||
{ 0, "Grid ON", NULL },
|
||||
{ 0, "Grid OFF", NULL },
|
||||
{ 0, "Marked Spot", NULL },
|
||||
{ 0, "All Marks Cleared", NULL },
|
||||
{ 0, "Music Change", NULL },
|
||||
{ 0, "IMPOSSIBLE SELECTION", NULL },
|
||||
{ 0, "Degreelessness Mode ON", NULL },
|
||||
{ 0, "Degreelessness Mode OFF", NULL },
|
||||
{ 0, "Very Happy Ammo Added", NULL },
|
||||
{ 0, "Ammo (no keys) Added", NULL },
|
||||
{ 0, "No Clipping Mode ON", NULL },
|
||||
{ 0, "No Clipping Mode OFF", NULL },
|
||||
{ 0, "inVuln, Str, Inviso, Rad, Allmap, or Lite-amp", NULL },
|
||||
{ 0, "Power-up Toggled", NULL },
|
||||
{ 0, "... doesn't suck - GM", NULL },
|
||||
{ 0, "Changing Level...\n", NULL },
|
||||
{ 0, "Once you beat the big badasses and\n"\
|
||||
{ 0, "D_DEVSTR", "Useless mode ON.\n", NULL },
|
||||
{ 0, "D_CDROM", "CD-ROM Version: zdoom.cfg from c:\\zdoomdat\n", NULL },
|
||||
{ 0, "PRESSKEY", "press a key.", NULL },
|
||||
{ 0, "PRESSYN", "press y or n.", NULL },
|
||||
{ 0, "QUITMSG", "are you sure you want to\nquit this great game?", NULL },
|
||||
{ 0, "LOADNET", "you can't do load while in a net game!\n\npress a key.", NULL },
|
||||
{ 0, "QLOADNET", "you can't quickload during a netgame!\n\npress a key.", NULL },
|
||||
{ 0, "QSAVESPOT", "you haven't picked a quicksave slot yet!\n\npress a key.", NULL },
|
||||
{ 0, "SAVEDEAD", "you can't save if you aren't playing!\n\npress a key.", NULL },
|
||||
{ 0, "QSPROMPT", "quicksave over your game named\n\n'%s'?\n\npress y or n.", NULL },
|
||||
{ 0, "QLPROMPT", "do you want to quickload the game named\n\n'%s'?\n\npress y or n.", NULL },
|
||||
{ 0, "NEWGAME", "you can't start a new game\nwhile in a network game.\n\npress a key.", NULL },
|
||||
{ 0, "NIGHTMARE", "are you sure? this skill level\nisn't even remotely fair.\n\npress y or n.", NULL },
|
||||
{ 0, "SWSTRING", "this is the shareware version of doom.\n\nyou need to order the entire trilogy.\n\npress a key.", NULL },
|
||||
{ 0, "MSGOFF", "Messages OFF", NULL },
|
||||
{ 0, "MSGON", "Messages ON", NULL },
|
||||
{ 0, "NETEND", "you can't end a netgame!\n\npress a key.", NULL },
|
||||
{ 0, "ENDGAME", "are you sure you want to end the game?\n\npress y or n.", NULL },
|
||||
{ 0, "DOSY", "(press y to quit)", NULL },
|
||||
{ 0, "EMPTYSTRING", "empty slot", NULL },
|
||||
{ 0, "GOTARMOR", "Picked up the armor.", NULL },
|
||||
{ 0, "GOTMEGA", "Picked up the MegaArmor!", NULL },
|
||||
{ 0, "GOTHTHBONUS", "Picked up a health bonus.", NULL },
|
||||
{ 0, "GOTARMBONUS", "Picked up an armor bonus.", NULL },
|
||||
{ 0, "GOTSTIM", "Picked up a stimpack.", NULL },
|
||||
{ 0, "GOTMEDINEED", "Picked up a medikit that you REALLY need!", NULL },
|
||||
{ 0, "GOTMEDIKIT", "Picked up a medikit.", NULL },
|
||||
{ 0, "GOTSUPER", "Supercharge!", NULL },
|
||||
{ 0, "GOTBLUECARD", "Picked up a blue keycard.", NULL },
|
||||
{ 0, "GOTYELWCARD", "Picked up a yellow keycard.", NULL },
|
||||
{ 0, "GOTREDCARD", "Picked up a red keycard.", NULL },
|
||||
{ 0, "GOTBLUESKUL", "Picked up a blue skull key.", NULL },
|
||||
{ 0, "GOTYELWSKUL", "Picked up a yellow skull key.", NULL },
|
||||
{ 0, "GOTREDSKUL", "Picked up a red skull key.", NULL },
|
||||
{ 0, "GOTINVUL", "Invulnerability!", NULL },
|
||||
{ 0, "GOTBERSERK", "Berserk!", NULL },
|
||||
{ 0, "GOTINVIS", "Partial Invisibility", NULL },
|
||||
{ 0, "GOTSUIT", "Radiation Shielding Suit", NULL },
|
||||
{ 0, "GOTMAP", "Computer Area Map", NULL },
|
||||
{ 0, "GOTVISOR", "Light Amplification Visor", NULL },
|
||||
{ 0, "GOTMSPHERE", "MegaSphere!", NULL },
|
||||
{ 0, "GOTCLIP", "Picked up a clip.", NULL },
|
||||
{ 0, "GOTCLIPBOX", "Picked up a box of bullets.", NULL },
|
||||
{ 0, "GOTROCKET", "Picked up a rocket.", NULL },
|
||||
{ 0, "GOTROCKBOX", "Picked up a box of rockets.", NULL },
|
||||
{ 0, "GOTCELL", "Picked up an energy cell.", NULL },
|
||||
{ 0, "GOTCELLBOX", "Picked up an energy cell pack.", NULL },
|
||||
{ 0, "GOTSHELLS", "Picked up 4 shotgun shells.", NULL },
|
||||
{ 0, "GOTSHELLBOX", "Picked up a box of shotgun shells.", NULL },
|
||||
{ 0, "GOTBACKPACK", "Picked up a backpack full of ammo!", NULL },
|
||||
{ 0, "GOTBFG9000", "You got the BFG9000! Oh, yes.", NULL },
|
||||
{ 0, "GOTCHAINGUN", "You got the chaingun!", NULL },
|
||||
{ 0, "GOTCHAINSAW", "A chainsaw! Find some meat!", NULL },
|
||||
{ 0, "GOTLAUNCHER", "You got the rocket launcher!", NULL },
|
||||
{ 0, "GOTPLASMA", "You got the plasma gun!", NULL },
|
||||
{ 0, "GOTSHOTGUN", "You got the shotgun!", NULL },
|
||||
{ 0, "GOTSHOTGUN2", "You got the super shotgun!", NULL },
|
||||
{ 0, "PD_BLUEO", "You need a blue key to activate this object", NULL },
|
||||
{ 0, "PD_REDO", "You need a red key to activate this object", NULL },
|
||||
{ 0, "PD_YELLOWO", "You need a yellow key to activate this object", NULL },
|
||||
{ 0, "PD_BLUEK", "You need a blue key to open this door", NULL },
|
||||
{ 0, "PD_REDK", "You need a red key to open this door", NULL },
|
||||
{ 0, "PD_YELLOWK", "You need a yellow key to open this door", NULL },
|
||||
{ 0, "GGSAVED", "game saved.", NULL },
|
||||
{ 0, "HUSTR_MSGU", "[Message unsent]", NULL },
|
||||
{ 0, "HUSTR_E1M1", "E1M1: Hangar", NULL },
|
||||
{ 0, "HUSTR_E1M2", "E1M2: Nuclear Plant", NULL },
|
||||
{ 0, "HUSTR_E1M3", "E1M3: Toxin Refinery", NULL },
|
||||
{ 0, "HUSTR_E1M4", "E1M4: Command Control", NULL },
|
||||
{ 0, "HUSTR_E1M5", "E1M5: Phobos Lab", NULL },
|
||||
{ 0, "HUSTR_E1M6", "E1M6: Central Processing", NULL },
|
||||
{ 0, "HUSTR_E1M7", "E1M7: Computer Station", NULL },
|
||||
{ 0, "HUSTR_E1M8", "E1M8: Phobos Anomaly", NULL },
|
||||
{ 0, "HUSTR_E1M9", "E1M9: Military Base", NULL },
|
||||
{ 0, "HUSTR_E2M1", "E2M1: Deimos Anomaly", NULL },
|
||||
{ 0, "HUSTR_E2M2", "E2M2: Containment Area", NULL },
|
||||
{ 0, "HUSTR_E2M3", "E2M3: Refinery", NULL },
|
||||
{ 0, "HUSTR_E2M4", "E2M4: Deimos Lab", NULL },
|
||||
{ 0, "HUSTR_E2M5", "E2M5: Command Center", NULL },
|
||||
{ 0, "HUSTR_E2M6", "E2M6: Halls of the Damned", NULL },
|
||||
{ 0, "HUSTR_E2M7", "E2M7: Spawning Vats", NULL },
|
||||
{ 0, "HUSTR_E2M8", "E2M8: Tower of Babel", NULL },
|
||||
{ 0, "HUSTR_E2M9", "E2M9: Fortress of Mystery", NULL },
|
||||
{ 0, "HUSTR_E3M1", "E3M1: Hell Keep", NULL },
|
||||
{ 0, "HUSTR_E3M2", "E3M2: Slough of Despair", NULL },
|
||||
{ 0, "HUSTR_E3M3", "E3M3: Pandemonium", NULL },
|
||||
{ 0, "HUSTR_E3M4", "E3M4: House of Pain", NULL },
|
||||
{ 0, "HUSTR_E3M5", "E3M5: Unholy Cathedral", NULL },
|
||||
{ 0, "HUSTR_E3M6", "E3M6: Mt. Erebus", NULL },
|
||||
{ 0, "HUSTR_E3M7", "E3M7: Limbo", NULL },
|
||||
{ 0, "HUSTR_E3M8", "E3M8: Dis", NULL },
|
||||
{ 0, "HUSTR_E3M9", "E3M9: Warrens", NULL },
|
||||
{ 0, "HUSTR_E4M1", "E4M1: Hell Beneath", NULL },
|
||||
{ 0, "HUSTR_E4M2", "E4M2: Perfect Hatred", NULL },
|
||||
{ 0, "HUSTR_E4M3", "E4M3: Sever The Wicked", NULL },
|
||||
{ 0, "HUSTR_E4M4", "E4M4: Unruly Evil", NULL },
|
||||
{ 0, "HUSTR_E4M5", "E4M5: They Will Repent", NULL },
|
||||
{ 0, "HUSTR_E4M6", "E4M6: Against Thee Wickedly", NULL },
|
||||
{ 0, "HUSTR_E4M7", "E4M7: And Hell Followed", NULL },
|
||||
{ 0, "HUSTR_E4M8", "E4M8: Unto The Cruel", NULL },
|
||||
{ 0, "HUSTR_E4M9", "E4M9: Fear", NULL },
|
||||
{ 0, "HUSTR_1", "level 1: entryway", NULL },
|
||||
{ 0, "HUSTR_2", "level 2: underhalls", NULL },
|
||||
{ 0, "HUSTR_3", "level 3: the gantlet", NULL },
|
||||
{ 0, "HUSTR_4", "level 4: the focus", NULL },
|
||||
{ 0, "HUSTR_5", "level 5: the waste tunnels", NULL },
|
||||
{ 0, "HUSTR_6", "level 6: the crusher", NULL },
|
||||
{ 0, "HUSTR_7", "level 7: dead simple", NULL },
|
||||
{ 0, "HUSTR_8", "level 8: tricks and traps", NULL },
|
||||
{ 0, "HUSTR_9", "level 9: the pit", NULL },
|
||||
{ 0, "HUSTR_10", "level 10: refueling base", NULL },
|
||||
{ 0, "HUSTR_11", "level 11: 'o' of destruction!", NULL },
|
||||
{ 0, "HUSTR_12", "level 12: the factory", NULL },
|
||||
{ 0, "HUSTR_13", "level 13: downtown", NULL },
|
||||
{ 0, "HUSTR_14", "level 14: the inmost dens", NULL },
|
||||
{ 0, "HUSTR_15", "level 15: industrial zone", NULL },
|
||||
{ 0, "HUSTR_16", "level 16: suburbs", NULL },
|
||||
{ 0, "HUSTR_17", "level 17: tenements", NULL },
|
||||
{ 0, "HUSTR_18", "level 18: the courtyard", NULL },
|
||||
{ 0, "HUSTR_19", "level 19: the citadel", NULL },
|
||||
{ 0, "HUSTR_20", "level 20: gotcha!", NULL },
|
||||
{ 0, "HUSTR_21", "level 21: nirvana", NULL },
|
||||
{ 0, "HUSTR_22", "level 22: the catacombs", NULL },
|
||||
{ 0, "HUSTR_23", "level 23: barrels o' fun", NULL },
|
||||
{ 0, "HUSTR_24", "level 24: the chasm", NULL },
|
||||
{ 0, "HUSTR_25", "level 25: bloodfalls", NULL },
|
||||
{ 0, "HUSTR_26", "level 26: the abandoned mines", NULL },
|
||||
{ 0, "HUSTR_27", "level 27: monster condo", NULL },
|
||||
{ 0, "HUSTR_28", "level 28: the spirit world", NULL },
|
||||
{ 0, "HUSTR_29", "level 29: the living end", NULL },
|
||||
{ 0, "HUSTR_30", "level 30: icon of sin", NULL },
|
||||
{ 0, "HUSTR_31", "level 31: wolfenstein", NULL },
|
||||
{ 0, "HUSTR_32", "level 32: grosse", NULL },
|
||||
{ 0, "PHUSTR_1", "level 1: congo", NULL },
|
||||
{ 0, "PHUSTR_2", "level 2: well of souls", NULL },
|
||||
{ 0, "PHUSTR_3", "level 3: aztec", NULL },
|
||||
{ 0, "PHUSTR_4", "level 4: caged", NULL },
|
||||
{ 0, "PHUSTR_5", "level 5: ghost town", NULL },
|
||||
{ 0, "PHUSTR_6", "level 6: baron's lair", NULL },
|
||||
{ 0, "PHUSTR_7", "level 7: caughtyard", NULL },
|
||||
{ 0, "PHUSTR_8", "level 8: realm", NULL },
|
||||
{ 0, "PHUSTR_9", "level 9: abattoire", NULL },
|
||||
{ 0, "PHUSTR_10", "level 10: onslaught", NULL },
|
||||
{ 0, "PHUSTR_11", "level 11: hunted", NULL },
|
||||
{ 0, "PHUSTR_12", "level 12: speed", NULL },
|
||||
{ 0, "PHUSTR_13", "level 13: the crypt", NULL },
|
||||
{ 0, "PHUSTR_14", "level 14: genesis", NULL },
|
||||
{ 0, "PHUSTR_15", "level 15: the twilight", NULL },
|
||||
{ 0, "PHUSTR_16", "level 16: the omen", NULL },
|
||||
{ 0, "PHUSTR_17", "level 17: compound", NULL },
|
||||
{ 0, "PHUSTR_18", "level 18: neurosphere", NULL },
|
||||
{ 0, "PHUSTR_19", "level 19: nme", NULL },
|
||||
{ 0, "PHUSTR_20", "level 20: the death domain", NULL },
|
||||
{ 0, "PHUSTR_21", "level 21: slayer", NULL },
|
||||
{ 0, "PHUSTR_22", "level 22: impossible mission", NULL },
|
||||
{ 0, "PHUSTR_23", "level 23: tombstone", NULL },
|
||||
{ 0, "PHUSTR_24", "level 24: the final frontier", NULL },
|
||||
{ 0, "PHUSTR_25", "level 25: the temple of darkness", NULL },
|
||||
{ 0, "PHUSTR_26", "level 26: bunker", NULL },
|
||||
{ 0, "PHUSTR_27", "level 27: anti-christ", NULL },
|
||||
{ 0, "PHUSTR_28", "level 28: the sewers", NULL },
|
||||
{ 0, "PHUSTR_29", "level 29: odyssey of noises", NULL },
|
||||
{ 0, "PHUSTR_30", "level 30: the gateway of hell", NULL },
|
||||
{ 0, "PHUSTR_31", "level 31: cyberden", NULL },
|
||||
{ 0, "PHUSTR_32", "level 32: go 2 it", NULL },
|
||||
{ 0, "THUSTR_1", "level 1: system control", NULL },
|
||||
{ 0, "THUSTR_2", "level 2: human bbq", NULL },
|
||||
{ 0, "THUSTR_3", "level 3: power control", NULL },
|
||||
{ 0, "THUSTR_4", "level 4: wormhole", NULL },
|
||||
{ 0, "THUSTR_5", "level 5: hanger", NULL },
|
||||
{ 0, "THUSTR_6", "level 6: open season", NULL },
|
||||
{ 0, "THUSTR_7", "level 7: prison", NULL },
|
||||
{ 0, "THUSTR_8", "level 8: metal", NULL },
|
||||
{ 0, "THUSTR_9", "level 9: stronghold", NULL },
|
||||
{ 0, "THUSTR_10", "level 10: redemption", NULL },
|
||||
{ 0, "THUSTR_11", "level 11: storage facility", NULL },
|
||||
{ 0, "THUSTR_12", "level 12: crater", NULL },
|
||||
{ 0, "THUSTR_13", "level 13: nukage processing", NULL },
|
||||
{ 0, "THUSTR_14", "level 14: steel works", NULL },
|
||||
{ 0, "THUSTR_15", "level 15: dead zone", NULL },
|
||||
{ 0, "THUSTR_16", "level 16: deepest reaches", NULL },
|
||||
{ 0, "THUSTR_17", "level 17: processing area", NULL },
|
||||
{ 0, "THUSTR_18", "level 18: mill", NULL },
|
||||
{ 0, "THUSTR_19", "level 19: shipping/respawning", NULL },
|
||||
{ 0, "THUSTR_20", "level 20: central processing", NULL },
|
||||
{ 0, "THUSTR_21", "level 21: administration center", NULL },
|
||||
{ 0, "THUSTR_22", "level 22: habitat", NULL },
|
||||
{ 0, "THUSTR_23", "level 23: lunar mining project", NULL },
|
||||
{ 0, "THUSTR_24", "level 24: quarry", NULL },
|
||||
{ 0, "THUSTR_25", "level 25: baron's den", NULL },
|
||||
{ 0, "THUSTR_26", "level 26: ballistyx", NULL },
|
||||
{ 0, "THUSTR_27", "level 27: mount pain", NULL },
|
||||
{ 0, "THUSTR_28", "level 28: heck", NULL },
|
||||
{ 0, "THUSTR_29", "level 29: river styx", NULL },
|
||||
{ 0, "THUSTR_30", "level 30: last call", NULL },
|
||||
{ 0, "THUSTR_31", "level 31: pharaoh", NULL },
|
||||
{ 0, "THUSTR_32", "level 32: caribbean", NULL },
|
||||
{ 0, "HUSTR_TALKTOSELF1", "You mumble to yourself", NULL },
|
||||
{ 0, "HUSTR_TALKTOSELF2", "Who's there?", NULL },
|
||||
{ 0, "HUSTR_TALKTOSELF3", "You scare yourself", NULL },
|
||||
{ 0, "HUSTR_TALKTOSELF4", "You start to rave", NULL },
|
||||
{ 0, "HUSTR_TALKTOSELF5", "You've lost it...", NULL },
|
||||
{ 0, "HUSTR_MESSAGESENT", "[Message Sent]", NULL },
|
||||
{ 0, "AMSTR_FOLLOWON", "Follow Mode ON", NULL },
|
||||
{ 0, "AMSTR_FOLLOWOFF", "Follow Mode OFF", NULL },
|
||||
{ 0, "AMSTR_GRIDON", "Grid ON", NULL },
|
||||
{ 0, "AMSTR_GRIDOFF", "Grid OFF", NULL },
|
||||
{ 0, "AMSTR_MARKEDSPOT", "Marked Spot", NULL },
|
||||
{ 0, "AMSTR_MARKSCLEARED", "All Marks Cleared", NULL },
|
||||
{ 0, "STSTR_MUS", "Music Change", NULL },
|
||||
{ 0, "STSTR_NOMUS", "IMPOSSIBLE SELECTION", NULL },
|
||||
{ 0, "STSTR_DQDON", "Degreelessness Mode ON", NULL },
|
||||
{ 0, "STSTR_DQDOFF", "Degreelessness Mode OFF", NULL },
|
||||
{ 0, "STSTR_KFAADDED", "Very Happy Ammo Added", NULL },
|
||||
{ 0, "STSTR_FAADDED", "Ammo (no keys) Added", NULL },
|
||||
{ 0, "STSTR_NCON", "No Clipping Mode ON", NULL },
|
||||
{ 0, "STSTR_NCOFF", "No Clipping Mode OFF", NULL },
|
||||
{ 0, "STSTR_BEHOLD", "inVuln, Str, Inviso, Rad, Allmap, or Lite-amp", NULL },
|
||||
{ 0, "STSTR_BEHOLDX", "Power-up Toggled", NULL },
|
||||
{ 0, "STSTR_CHOPPERS", "... doesn't suck - GM", NULL },
|
||||
{ 0, "STSTR_CLEV", "Changing Level...\n", NULL },
|
||||
{ 0, "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"\
|
||||
|
@ -297,7 +295,7 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"The Shores of Hell and its amazing\n"\
|
||||
"sequel, Inferno!\n"
|
||||
, NULL },
|
||||
{ 0, "You've done it! The hideous cyber-\n"\
|
||||
{ 0, "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"\
|
||||
|
@ -315,7 +313,7 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"Now, it's on to the final chapter of\n"\
|
||||
"DOOM! -- Inferno."
|
||||
, NULL },
|
||||
{ 0, "The loathsome spiderdemon that\n"\
|
||||
{ 0, "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"\
|
||||
|
@ -333,7 +331,7 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"spawn could have come through that\n"\
|
||||
"door with you ..."
|
||||
, NULL },
|
||||
{ 0, "the spider mastermind must have sent forth\n"\
|
||||
{ 0, "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"\
|
||||
|
@ -350,7 +348,7 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"\n"\
|
||||
"next stop, hell on earth!"
|
||||
, NULL },
|
||||
{ 0, "YOU HAVE ENTERED DEEPLY INTO THE INFESTED\n" \
|
||||
{ 0, "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" \
|
||||
|
@ -363,7 +361,7 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"SWITCH WHICH HOLDS EARTH'S POPULATION\n" \
|
||||
"HOSTAGE."
|
||||
, NULL },
|
||||
{ 0, "YOU HAVE WON! YOUR VICTORY HAS ENABLED\n" \
|
||||
{ 0, "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"\
|
||||
|
@ -381,7 +379,7 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"STARPORT.\" SLOWLY AND PAINFULLY YOU GET\n"\
|
||||
"UP AND RETURN TO THE FRAY."
|
||||
, NULL },
|
||||
{ 0, "YOU ARE AT THE CORRUPT HEART OF THE CITY,\n"\
|
||||
{ 0, "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"\
|
||||
|
@ -391,7 +389,7 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"OTHER SIDE. WHAT DO YOU CARE IF YOU'VE\n"\
|
||||
"GOT TO GO THROUGH HELL TO GET TO IT?"
|
||||
, NULL },
|
||||
{ 0, "THE HORRENDOUS VISAGE OF THE BIGGEST\n"\
|
||||
{ 0, "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"\
|
||||
|
@ -407,17 +405,17 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"HOME. REBUILDING EARTH OUGHT TO BE A\n"\
|
||||
"LOT MORE FUN THAN RUINING IT WAS.\n"
|
||||
, NULL },
|
||||
{ 0, "CONGRATULATIONS, YOU'VE FOUND THE SECRET\n"\
|
||||
{ 0, "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."
|
||||
, NULL },
|
||||
{ 0, "CONGRATULATIONS, YOU'VE FOUND THE\n"\
|
||||
{ 0, "C6TEXT", "CONGRATULATIONS, YOU'VE FOUND THE\n"\
|
||||
"SUPER SECRET LEVEL! YOU'D BETTER\n"\
|
||||
"BLAZE THROUGH THIS ONE!\n"
|
||||
, NULL },
|
||||
{ 0, "You gloat over the steaming carcass of the\n"\
|
||||
{ 0, "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"\
|
||||
|
@ -430,14 +428,14 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"moving, keep fighting, keep killing.\n"\
|
||||
"Oh yes, keep living, too."
|
||||
, NULL },
|
||||
{ 0, "Even the deadly Arch-Vile labyrinth could\n"\
|
||||
{ 0, "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."
|
||||
, NULL },
|
||||
{ 0, "You've bashed and battered your way into\n"\
|
||||
{ 0, "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"\
|
||||
|
@ -448,7 +446,7 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"get ready to give the bastard a little Hell\n"\
|
||||
"of your own making!"
|
||||
, NULL },
|
||||
{ 0, "The Gatekeeper's evil face is splattered\n"\
|
||||
{ 0, "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"\
|
||||
|
@ -461,16 +459,16 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"when you die, you'll need it for some\n"\
|
||||
"final cleaning-up ..."
|
||||
, NULL },
|
||||
{ 0, "You've found the second-hardest level we\n"\
|
||||
{ 0, "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."
|
||||
, NULL },
|
||||
{ 0, "Betcha wondered just what WAS the hardest\n"\
|
||||
{ 0, "P6TEXT", "Betcha wondered just what WAS the hardest\n"\
|
||||
"level we had ready for ya? Now you know.\n"\
|
||||
"No one gets out alive."
|
||||
, NULL },
|
||||
{ 0, "You've fought your way out of the infested\n"\
|
||||
{ 0, "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"\
|
||||
|
@ -483,7 +481,7 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"complex still has some warlike ordnance\n"\
|
||||
"laying around."
|
||||
, NULL },
|
||||
{ 0, "You hear the grinding of heavy machinery\n"\
|
||||
{ 0, "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"\
|
||||
|
@ -493,7 +491,7 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"\n"\
|
||||
"You don't plan to go down easy."
|
||||
, NULL },
|
||||
{ 0, "The vista opening ahead looks real damn\n"\
|
||||
{ 0, "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"\
|
||||
|
@ -502,7 +500,7 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"Hefting your gun, an evil grin trickles\n"\
|
||||
"onto your face. Time to take some names."
|
||||
, NULL },
|
||||
{ 0, "Suddenly, all is silent, from one horizon\n"\
|
||||
{ 0, "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"\
|
||||
|
@ -514,13 +512,13 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"A blue light begins to glow inside the\n"\
|
||||
"ruined skull of the demon-spitter."
|
||||
, NULL },
|
||||
{ 0, "What now? Looks totally different. Kind\n"\
|
||||
{ 0, "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.."
|
||||
, NULL },
|
||||
{ 0, "Time for a vacation. You've burst the\n"\
|
||||
{ 0, "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"\
|
||||
|
@ -531,93 +529,114 @@ gamestring_t Strings[NUMSTRINGS] = {
|
|||
"As you step off the transport, you hear\n"\
|
||||
"the stomp of a cyberdemon's iron shoe."
|
||||
, NULL },
|
||||
{ 0, "ZOMBIEMAN", NULL },
|
||||
{ 0, "SHOTGUN GUY", NULL },
|
||||
{ 0, "HEAVY WEAPON DUDE", NULL },
|
||||
{ 0, "IMP", NULL },
|
||||
{ 0, "DEMON", NULL },
|
||||
{ 0, "LOST SOUL", NULL },
|
||||
{ 0, "CACODEMON", NULL },
|
||||
{ 0, "HELL KNIGHT", NULL },
|
||||
{ 0, "BARON OF HELL", NULL },
|
||||
{ 0, "ARACHNOTRON", NULL },
|
||||
{ 0, "PAIN ELEMENTAL", NULL },
|
||||
{ 0, "REVENANT", NULL },
|
||||
{ 0, "MANCUBUS", NULL },
|
||||
{ 0, "ARCH-VILE", NULL },
|
||||
{ 0, "THE SPIDER MASTERMIND", NULL },
|
||||
{ 0, "THE CYBERDEMON", NULL },
|
||||
{ 0, "OUR HERO", NULL }
|
||||
};
|
||||
{ 0, "CC_ZOMBIE", "ZOMBIEMAN", NULL },
|
||||
{ 0, "CC_SHOTGUN", "SHOTGUN GUY", NULL },
|
||||
{ 0, "CC_HEAVY", "HEAVY WEAPON DUDE", NULL },
|
||||
{ 0, "CC_IMP", "IMP", NULL },
|
||||
{ 0, "CC_DEMON", "DEMON", NULL },
|
||||
{ 0, "CC_LOST", "LOST SOUL", NULL },
|
||||
{ 0, "CC_CACO", "CACODEMON", NULL },
|
||||
{ 0, "CC_HELL", "HELL KNIGHT", NULL },
|
||||
{ 0, "CC_BARON", "BARON OF HELL", NULL },
|
||||
{ 0, "CC_ARACH", "ARACHNOTRON", NULL },
|
||||
{ 0, "CC_PAIN", "PAIN ELEMENTAL", NULL },
|
||||
{ 0, "CC_REVEN", "REVENANT", NULL },
|
||||
{ 0, "CC_MANCU", "MANCUBUS", NULL },
|
||||
{ 0, "CC_ARCH", "ARCH-VILE", NULL },
|
||||
{ 0, "CC_SPIDER", "THE SPIDER MASTERMIND", NULL },
|
||||
{ 0, "CC_CYBER", "THE CYBERDEMON", NULL },
|
||||
{ 0, "CC_HERO", "OUR HERO", NULL },
|
||||
|
||||
void newlanguage (cvar_t *var)
|
||||
{
|
||||
D_InitStrings ();
|
||||
G_SetLevelStrings ();
|
||||
}
|
||||
// [RH] New strings from BOOM
|
||||
{ 0, "PD_BLUEC", "You need a blue card to open this door", NULL },
|
||||
{ 0, "PD_REDC", "You need a red card to open this door", NULL },
|
||||
{ 0, "PD_YELLOWC", "You need a yellow card to open this door", NULL },
|
||||
{ 0, "PD_BLUES", "You need a blue skull to open this door", NULL },
|
||||
{ 0, "PD_REDS", "You need a red skull to open this door", NULL },
|
||||
{ 0, "PD_YELLOWS", "You need a yellow skull to open this door", NULL },
|
||||
{ 0, "PD_ANY", "Any key will open this door", NULL },
|
||||
{ 0, "PD_ALL3", "You need all three keys to open this door", NULL },
|
||||
{ 0, "PD_ALL6", "You need all six keys to open this door", NULL },
|
||||
|
||||
// [RH] Obituary strings
|
||||
{ 0, "OB_SUICIDE", "suicides", NULL },
|
||||
{ 0, "OB_FALLING", "fell too far", NULL },
|
||||
{ 0, "OB_CRUSH", "was squished", NULL },
|
||||
{ 0, "OB_EXIT", "tried to leave", NULL },
|
||||
{ 0, "OB_WATER", "can't swim", NULL },
|
||||
{ 0, "OB_SLIME", "mutated", NULL },
|
||||
{ 0, "OB_LAVA", "melted", NULL },
|
||||
{ 0, "OB_BARREL", "went boom", NULL },
|
||||
{ 0, "OB_SPLASH", "stood in the wrong spot", NULL },
|
||||
{ 0, "OB_R_SPLASH", "should have stood back", NULL },
|
||||
{ 0, "OB_ROCKET", "should have stood back", NULL },
|
||||
{ 0, "OB_KILLEDSELF", "killed %hself", NULL },
|
||||
{ 0, "OB_STEALTHBABY", "thought %g saw an arachnotron", NULL },
|
||||
{ 0, "OB_STEALTHVILE", "thought %g saw an archvile", NULL },
|
||||
{ 0, "OB_STEALTHBARON", "thought %g saw a Baron of Hell", NULL },
|
||||
{ 0, "OB_STEALTHCACO", "thought %g saw a cacodemon", NULL },
|
||||
{ 0, "OB_STEALTHCHAINGUY", "thought %g saw a chaingunner", NULL },
|
||||
{ 0, "OB_STEALTHDEMON", "thought %g saw a demon", NULL },
|
||||
{ 0, "OB_STEALTHKNIGHT", "thought %g saw a Hell Knight", NULL },
|
||||
{ 0, "OB_STEALTHIMP", "thought %g saw an imp", NULL },
|
||||
{ 0, "OB_STEALTHFATSO", "thought %g saw a mancubus", NULL },
|
||||
{ 0, "OB_STEALTHUNDEAD", "thought %g saw a revenant", NULL },
|
||||
{ 0, "OB_STEALTHSHOTGUY", "thought %g saw a sargeant", NULL },
|
||||
{ 0, "OB_STEALTHZOMBIE", "thought %g saw a zombieman", NULL },
|
||||
{ 0, "OB_UNDEADHIT", "was punched by a revenant", NULL },
|
||||
{ 0, "OB_IMPHIT", "was slashed by an imp", NULL },
|
||||
{ 0, "OB_CACOHIT", "got too close to a cacodemon", NULL },
|
||||
{ 0, "OB_DEMONHIT", "was bit by a demon", NULL },
|
||||
{ 0, "OB_SPECTREHIT", "was eaten by a spectre", NULL },
|
||||
{ 0, "OB_BARONHIT", "was ripped open by a Baron of Hell", NULL },
|
||||
{ 0, "OB_KNIGHTHIT", "was gutted by a Hell Knight", NULL },
|
||||
{ 0, "OB_ZOMBIE", "was killed by a zombieman", NULL },
|
||||
{ 0, "OB_SHOTGUY", "was shot by a sargeant", NULL },
|
||||
{ 0, "OB_VILE", "was incinerated by an archvile", NULL },
|
||||
{ 0, "OB_UNDEAD", "couldn't evade a revevant's fireball", NULL },
|
||||
{ 0, "OB_FATSO", "was squashed by a mancubus", NULL },
|
||||
{ 0, "OB_CHAINGUY", "was perforated by a chaingunner", NULL },
|
||||
{ 0, "OB_SKULL", "was spooked by a lost soul", NULL },
|
||||
{ 0, "OB_IMP", "was burned by an imp", NULL },
|
||||
{ 0, "OB_CACO", "was smitten by a cacodemon", NULL },
|
||||
{ 0, "OB_BARON", "was bruised by a Baron of Hell", NULL },
|
||||
{ 0, "OB_KNIGHT", "was splayed by a Hell Knight", NULL },
|
||||
{ 0, "OB_SPIDER", "stood in awe of the spider demon", NULL },
|
||||
{ 0, "OB_BABY", "let an arachnotron get %h", NULL },
|
||||
{ 0, "OB_CYBORG", "was splattered by a cyberdemon", NULL },
|
||||
{ 0, "OB_WOLFSS", "was no match for the past", NULL },
|
||||
{ 0, "OB_MPFIST", "chewed on %s's fist", NULL },
|
||||
{ 0, "OB_MPCHAINSAW", "was mowed over by %s's chainsaw", NULL },
|
||||
{ 0, "OB_MPPISTOL", "was tickled by %s", NULL },
|
||||
{ 0, "OB_MPSHOTGUN", "chewed on %s's boomstick", NULL },
|
||||
{ 0, "OB_MPSSHOTGUN", "was splattered by %s's super shotgun", NULL },
|
||||
{ 0, "OB_MPCHAINGUN", "was mowed down by %s", NULL },
|
||||
{ 0, "OB_MPROCKET", "rode %s's rocket", NULL },
|
||||
{ 0, "OB_MPR_SPLASH", "almost dodged %s's rocket", NULL },
|
||||
{ 0, "OB_MPPLASMARIFLE", "was melted by %s", NULL },
|
||||
{ 0, "OB_MPBFG_BOOM", "was splintered by %s's BFG", NULL },
|
||||
{ 0, "OB_MPBFG_SPLASH", "couldn't hide from %s's BFG", NULL },
|
||||
{ 0, "OB_MPTELEFRAG", "was telefragged by %s", NULL },
|
||||
{ 0, "OB_DEFAULT", "died", NULL },
|
||||
{ 0, "OB_FRIENDLY1", "mows down a teammate", NULL },
|
||||
{ 0, "OB_FRIENDLY2", "checks %p glasses", NULL },
|
||||
{ 0, "OB_FRIENDLY3", "gets a frag for the other team", NULL },
|
||||
{ 0, "OB_FRIENDLY4", "loses another friend", NULL },
|
||||
{ 0, "SAVEGAMENAME", "zdoomsv", NULL },
|
||||
{ 0, "STARTUP1", "", NULL },
|
||||
{ 0, "STARTUP2", "", NULL },
|
||||
{ 0, "STARTUP3", "", NULL },
|
||||
{ 0, "STARTUP4", "", NULL },
|
||||
{ 0, "STARTUP5", "", NULL },
|
||||
};
|
||||
|
||||
void D_InitStrings (void)
|
||||
{
|
||||
byte *strings;
|
||||
char *str;
|
||||
char *languagename;
|
||||
int i;
|
||||
int chunksize;
|
||||
|
||||
var_language->u.callback = newlanguage;
|
||||
languagename = var_language->string;
|
||||
|
||||
if (languagename) {
|
||||
i = W_CheckNumForName ("LANGDATA");
|
||||
str = "";
|
||||
if (i != -1) {
|
||||
strings = W_CacheLumpNum (i, PU_CACHE);
|
||||
|
||||
while (1) {
|
||||
str = ReadString (&strings);
|
||||
if (*str == 0)
|
||||
break; // No more languages
|
||||
|
||||
chunksize = ReadLong (&strings);
|
||||
if (!stricmp (str, languagename))
|
||||
break;
|
||||
|
||||
strings += chunksize;
|
||||
}
|
||||
|
||||
if (*str) {
|
||||
language = english + 1;
|
||||
for (i = 0; i < NUMSTRINGS; i++) {
|
||||
str = ReadString (&strings);
|
||||
chunksize -= strlen (str) + 1;
|
||||
if (chunksize < 0) {
|
||||
Printf ("Language \"%s\" is missing %d strings\n", languagename, NUMSTRINGS - i);
|
||||
languagename = NULL;
|
||||
break;
|
||||
}
|
||||
if (Strings[i].type == str_notchanged || Strings[i].type == str_foreign) {
|
||||
ReplaceString (&Strings[i].string, str);
|
||||
Strings[i].type = str_foreign;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (languagename && !stricmp (languagename, "English")) {
|
||||
languagename = NULL;
|
||||
} else if (*str == 0) {
|
||||
Printf ("Unknown language \"%s\"\n", languagename);
|
||||
languagename = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!languagename) {
|
||||
for (i = 0; i < NUMSTRINGS; i++) {
|
||||
if (Strings[i].type == str_notchanged || Strings[i].type == str_foreign) {
|
||||
ReplaceString (&Strings[i].string, Strings[i].builtin);
|
||||
Strings[i].type = str_notchanged;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NUMSTRINGS; i++) {
|
||||
if (Strings[i].type == str_notchanged)
|
||||
ReplaceString (&Strings[i].string, Strings[i].builtin);
|
||||
}
|
||||
|
||||
endmsg[0] = QUITMSG;
|
||||
|
|
|
@ -31,9 +31,6 @@ void D_InitStrings (void);
|
|||
void ReplaceString (char **ptr, char *str);
|
||||
|
||||
|
||||
// Misc. other strings.
|
||||
#define SAVEGAMENAME "zdoomsv"
|
||||
|
||||
// QuitDOOM messages
|
||||
#define NUM_QUITMESSAGES 14
|
||||
|
||||
|
@ -42,13 +39,13 @@ extern char* endmsg[];
|
|||
// [RH] String handling has changed significantly and is no longer static per build.
|
||||
typedef enum {
|
||||
str_notchanged,
|
||||
str_foreign,
|
||||
str_patched,
|
||||
str_custom
|
||||
} strtype_t;
|
||||
|
||||
typedef struct gamestring_s {
|
||||
strtype_t type;
|
||||
char *name;
|
||||
char *builtin;
|
||||
char *string;
|
||||
} gamestring_t;
|
||||
|
@ -370,7 +367,89 @@ typedef struct gamestring_s {
|
|||
#define CC_CYBER (Strings[258].string)
|
||||
#define CC_HERO (Strings[259].string)
|
||||
|
||||
#define NUMSTRINGS 260
|
||||
#define PD_BLUEC (Strings[260].string)
|
||||
#define PD_REDC (Strings[261].string)
|
||||
#define PD_YELLOWC (Strings[262].string)
|
||||
#define PD_BLUES (Strings[263].string)
|
||||
#define PD_REDS (Strings[264].string)
|
||||
#define PD_YELLOWS (Strings[265].string)
|
||||
#define PD_ANY (Strings[266].string)
|
||||
#define PD_ALL3 (Strings[267].string)
|
||||
#define PD_ALL6 (Strings[268].string)
|
||||
|
||||
#define OB_SUICIDE (Strings[269].string)
|
||||
#define OB_FALLING (Strings[270].string)
|
||||
#define OB_CRUSH (Strings[271].string)
|
||||
#define OB_EXIT (Strings[272].string)
|
||||
#define OB_WATER (Strings[273].string)
|
||||
#define OB_SLIME (Strings[274].string)
|
||||
#define OB_LAVA (Strings[275].string)
|
||||
#define OB_BARREL (Strings[276].string)
|
||||
#define OB_SPLASH (Strings[277].string)
|
||||
#define OB_R_SPLASH (Strings[278].string)
|
||||
#define OB_ROCKET (Strings[279].string)
|
||||
#define OB_KILLEDSELF (Strings[280].string)
|
||||
#define OB_STEALTHBABY (Strings[281].string)
|
||||
#define OB_STEALTHVILE (Strings[282].string)
|
||||
#define OB_STEALTHBARON (Strings[283].string)
|
||||
#define OB_STEALTHCACO (Strings[284].string)
|
||||
#define OB_STEALTHCHAINGUY (Strings[285].string)
|
||||
#define OB_STEALTHDEMON (Strings[286].string)
|
||||
#define OB_STEALTHKNIGHT (Strings[287].string)
|
||||
#define OB_STEALTHIMP (Strings[288].string)
|
||||
#define OB_STEALTHFATSO (Strings[289].string)
|
||||
#define OB_STEALTHUNDEAD (Strings[290].string)
|
||||
#define OB_STEALTHSHOTGUY (Strings[291].string)
|
||||
#define OB_STEALTHZOMBIE (Strings[292].string)
|
||||
#define OB_UNDEADHIT (Strings[293].string)
|
||||
#define OB_IMPHIT (Strings[294].string)
|
||||
#define OB_CACOHIT (Strings[295].string)
|
||||
#define OB_DEMONHIT (Strings[296].string)
|
||||
#define OB_SPECTREHIT (Strings[297].string)
|
||||
#define OB_BARONHIT (Strings[298].string)
|
||||
#define OB_KNIGHTHIT (Strings[299].string)
|
||||
#define OB_ZOMBIE (Strings[300].string)
|
||||
#define OB_SHOTGUY (Strings[301].string)
|
||||
#define OB_VILE (Strings[302].string)
|
||||
#define OB_UNDEAD (Strings[303].string)
|
||||
#define OB_FATSO (Strings[304].string)
|
||||
#define OB_CHAINGUY (Strings[305].string)
|
||||
#define OB_SKULL (Strings[306].string)
|
||||
#define OB_IMP (Strings[307].string)
|
||||
#define OB_CACO (Strings[308].string)
|
||||
#define OB_BARON (Strings[309].string)
|
||||
#define OB_KNIGHT (Strings[310].string)
|
||||
#define OB_SPIDER (Strings[311].string)
|
||||
#define OB_BABY (Strings[312].string)
|
||||
#define OB_CYBORG (Strings[313].string)
|
||||
#define OB_WOLFSS (Strings[314].string)
|
||||
#define OB_MPFIST (Strings[315].string)
|
||||
#define OB_MPCHAINSAW (Strings[316].string)
|
||||
#define OB_MPPISTOL (Strings[317].string)
|
||||
#define OB_MPSHOTGUN (Strings[318].string)
|
||||
#define OB_MPSSHOTGUN (Strings[319].string)
|
||||
#define OB_MPCHAINGUN (Strings[320].string)
|
||||
#define OB_MPROCKET (Strings[321].string)
|
||||
#define OB_MPR_SPLASH (Strings[322].string)
|
||||
#define OB_MPPLASMARIFLE (Strings[323].string)
|
||||
#define OB_MPBFG_BOOM (Strings[324].string)
|
||||
#define OB_MPBFG_SPLASH (Strings[325].string)
|
||||
#define OB_MPTELEFRAG (Strings[326].string)
|
||||
#define OB_DEFAULT (Strings[327].string)
|
||||
#define OB_FRIENDLY1 (Strings[328].string)
|
||||
#define OB_FRIENDLY2 (Strings[329].string)
|
||||
#define OB_FRIENDLY3 (Strings[330].string)
|
||||
#define OB_FRIENDLY4 (Strings[331].string)
|
||||
|
||||
#define SAVEGAMENAME (Strings[332].string)
|
||||
|
||||
#define STARTUP1 (Strings[333].string)
|
||||
#define STARTUP2 (Strings[334].string)
|
||||
#define STARTUP3 (Strings[335].string)
|
||||
#define STARTUP4 (Strings[336].string)
|
||||
#define STARTUP5 (Strings[337].string)
|
||||
|
||||
#define NUMSTRINGS 338
|
||||
|
||||
extern gamestring_t Strings[];
|
||||
|
||||
|
|
143
code/F_finale.c
143
code/F_finale.c
|
@ -31,16 +31,18 @@
|
|||
#include "m_swap.h"
|
||||
#include "z_zone.h"
|
||||
#include "v_video.h"
|
||||
#include "v_text.h"
|
||||
#include "w_wad.h"
|
||||
#include "s_sound.h"
|
||||
|
||||
// Data.
|
||||
#include "dstrings.h"
|
||||
#include "sounds.h"
|
||||
|
||||
#include "doomstat.h"
|
||||
#include "r_state.h"
|
||||
|
||||
#include "hu_stuff.h"
|
||||
|
||||
// ?
|
||||
//#include "doomstat.h"
|
||||
//#include "r_local.h"
|
||||
|
@ -129,7 +131,7 @@ BOOL F_Responder (event_t *event)
|
|||
//
|
||||
void F_Ticker (void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
// check for skipping
|
||||
// [RH] Non-commercial can be skipped now, too
|
||||
|
@ -176,9 +178,7 @@ void F_Ticker (void)
|
|||
//
|
||||
// F_TextWrite
|
||||
//
|
||||
|
||||
#include "hu_stuff.h"
|
||||
extern patch_t *hu_font[HU_FONTSIZE];
|
||||
extern patch_t *hu_font[HU_FONTSIZE];
|
||||
|
||||
|
||||
void F_TextWrite (void)
|
||||
|
@ -270,6 +270,7 @@ castinfo_t castorder[] = {
|
|||
|
||||
int castnum;
|
||||
int casttics;
|
||||
int castsprite; // [RH] For overriding the player sprite with a skin
|
||||
state_t* caststate;
|
||||
BOOL castdeath;
|
||||
int castframes;
|
||||
|
@ -307,6 +308,10 @@ void F_StartCast (void)
|
|||
wipegamestate = -1; // force a screen wipe
|
||||
castnum = 0;
|
||||
caststate = &states[mobjinfo[castorder[castnum].type].seestate];
|
||||
if (castorder[castnum].type == MT_PLAYER)
|
||||
castsprite = skins[players[consoleplayer].userinfo.skin].sprite;
|
||||
else
|
||||
castsprite = caststate->sprite;
|
||||
casttics = caststate->tics;
|
||||
castdeath = false;
|
||||
finalestage = 2;
|
||||
|
@ -322,9 +327,8 @@ void F_StartCast (void)
|
|||
//
|
||||
void F_CastTicker (void)
|
||||
{
|
||||
int st;
|
||||
int sfx;
|
||||
void *origin;
|
||||
int st;
|
||||
void *origin;
|
||||
|
||||
if (--casttics > 0)
|
||||
return; // not time to change state yet
|
||||
|
@ -346,13 +350,19 @@ void F_CastTicker (void)
|
|||
origin = ORIGIN_AMBIENT;
|
||||
break;
|
||||
}
|
||||
S_StartSound (origin, mobjinfo[castorder[castnum].type].seesound);
|
||||
S_StartSound (origin, mobjinfo[castorder[castnum].type].seesound, 90);
|
||||
}
|
||||
caststate = &states[mobjinfo[castorder[castnum].type].seestate];
|
||||
if (castorder[castnum].type == MT_PLAYER)
|
||||
castsprite = skins[players[consoleplayer].userinfo.skin].sprite;
|
||||
else
|
||||
castsprite = caststate->sprite;
|
||||
castframes = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *sfx;
|
||||
|
||||
// just advance to next state in animation
|
||||
if (caststate == &states[S_PLAY_ATK1])
|
||||
goto stopattack; // Oh, gross hack!
|
||||
|
@ -363,37 +373,37 @@ void F_CastTicker (void)
|
|||
// 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_PLAY_ATK1: sfx = "weapons/sshotf"; break;
|
||||
case S_POSS_ATK2: sfx = "grunt/attack"; break;
|
||||
case S_SPOS_ATK2: sfx = "shotguy/attack"; break;
|
||||
case S_VILE_ATK2: sfx = "vile/start"; break;
|
||||
case S_SKEL_FIST2: sfx = "skeleton/swing"; break;
|
||||
case S_SKEL_FIST4: sfx = "skeleton/melee"; break;
|
||||
case S_SKEL_MISS2: sfx = "skeleton/attack"; break;
|
||||
case S_FATT_ATK8:
|
||||
case S_FATT_ATK5:
|
||||
case S_FATT_ATK2: sfx = sfx_firsht; break;
|
||||
case S_FATT_ATK2: sfx = "fatso/attack"; 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_CPOS_ATK4: sfx = "chainguy/attack"; break;
|
||||
case S_TROO_ATK3: sfx = "imp/attack"; break;
|
||||
case S_SARG_ATK2: sfx = "demon/melee"; 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_HEAD_ATK2: sfx = "caco/attack"; break;
|
||||
case S_SKULL_ATK2: sfx = "skull/melee"; break;
|
||||
case S_SPID_ATK2:
|
||||
case S_SPID_ATK3: sfx = sfx_shotgn; break;
|
||||
case S_BSPI_ATK2: sfx = sfx_plasma; break;
|
||||
case S_SPID_ATK3: sfx = "spider/attack"; break;
|
||||
case S_BSPI_ATK2: sfx = "baby/attack"; 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;
|
||||
case S_CYBER_ATK6: sfx = "weapons/rocklf"; break;
|
||||
case S_PAIN_ATK3: sfx = "skull/melee"; break;
|
||||
default: sfx = 0; break;
|
||||
}
|
||||
|
||||
if (sfx)
|
||||
S_StartSound (ORIGIN_AMBIENT, sfx);
|
||||
S_StartSound (ORIGIN_AMBIENT, sfx, 90);
|
||||
}
|
||||
|
||||
if (castframes == 12)
|
||||
|
@ -464,61 +474,38 @@ BOOL F_CastResponder (event_t* ev)
|
|||
origin = ORIGIN_AMBIENT;
|
||||
break;
|
||||
}
|
||||
S_StartSound (origin, mobjinfo[castorder[castnum].type].deathsound);
|
||||
if (castorder[castnum].type == MT_PLAYER) {
|
||||
static const char sndtemplate[] = "player/%s/death1";
|
||||
static const char *genders[] = { "male", "female", "neuter" };
|
||||
char nametest[128];
|
||||
int sndnum;
|
||||
|
||||
sprintf (nametest, sndtemplate, skins[players[consoleplayer].userinfo.skin].name);
|
||||
sndnum = S_FindSound (nametest);
|
||||
if (sndnum == -1) {
|
||||
sprintf (nametest, sndtemplate, genders);
|
||||
sndnum = S_FindSound (nametest);
|
||||
if (sndnum == -1)
|
||||
sndnum = S_FindSound ("player/male/death1");
|
||||
}
|
||||
S_StartSfx (origin, sndnum, 90);
|
||||
} else
|
||||
S_StartSound (origin, mobjinfo[castorder[castnum].type].deathsound, 90);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void F_CastPrint (char* text)
|
||||
void F_CastPrint (char *text)
|
||||
{
|
||||
char* ch;
|
||||
int c;
|
||||
int cx;
|
||||
int w;
|
||||
int width;
|
||||
|
||||
// find width
|
||||
ch = text;
|
||||
width = 0;
|
||||
|
||||
while (ch)
|
||||
{
|
||||
c = *ch++;
|
||||
if (!c)
|
||||
break;
|
||||
c = toupper(c) - HU_FONTSTART;
|
||||
if (c < 0 || c> HU_FONTSIZE)
|
||||
{
|
||||
width += 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
w = SHORT (hu_font[c]->width);
|
||||
width += w;
|
||||
}
|
||||
|
||||
// draw it
|
||||
cx = (CleanWidth-width)/2;
|
||||
ch = text;
|
||||
while (ch)
|
||||
{
|
||||
c = *ch++;
|
||||
if (!c)
|
||||
break;
|
||||
c = toupper(c) - HU_FONTSTART;
|
||||
if (c < 0 || c> HU_FONTSIZE)
|
||||
{
|
||||
cx += 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
w = SHORT (hu_font[c]->width);
|
||||
V_DrawPatchCleanNoMove (cx, (screens[0].height * 180) / 200, &screens[0], hu_font[c]);
|
||||
cx+=w;
|
||||
}
|
||||
|
||||
char text2[80], *t2 = text2;
|
||||
|
||||
while (*text)
|
||||
*t2++ = *text++ ^ 0x80;
|
||||
*t2 = 0;
|
||||
V_DrawTextClean ((screens[0].width - V_StringWidth (text2) * CleanXfac) >> 1,
|
||||
(screens[0].height * 180) / 200, text2);
|
||||
}
|
||||
|
||||
int V_DrawPatchFlipped (int, int, screen_t *, patch_t *);
|
||||
|
@ -539,12 +526,12 @@ void F_CastDrawer (void)
|
|||
F_CastPrint (castorder[castnum].name);
|
||||
|
||||
// draw the current frame in the middle of the screen
|
||||
sprdef = &sprites[caststate->sprite];
|
||||
sprdef = &sprites[castsprite];
|
||||
sprframe = &sprdef->spriteframes[ caststate->frame & FF_FRAMEMASK];
|
||||
lump = sprframe->lump[0];
|
||||
flip = (BOOL)sprframe->flip[0];
|
||||
|
||||
patch = W_CacheLumpNum (lump+firstspritelump, PU_CACHE);
|
||||
patch = W_CacheLumpNum (lump, PU_CACHE);
|
||||
if (flip)
|
||||
V_DrawPatchFlipped (160,170,&screens[0],patch);
|
||||
else
|
||||
|
@ -703,7 +690,7 @@ void F_BunnyScroll (void)
|
|||
stage = 6;
|
||||
if (stage > laststage)
|
||||
{
|
||||
S_StartSound (ORIGIN_AMBIENT, sfx_pistol);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/pistol", 64);
|
||||
laststage = stage;
|
||||
}
|
||||
|
||||
|
|
534
code/G_game.c
534
code/G_game.c
|
@ -24,13 +24,16 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "minilzo.h"
|
||||
#include "m_alloc.h"
|
||||
#include "doomdef.h"
|
||||
#include "doomstat.h"
|
||||
|
||||
#include "d_proto.h"
|
||||
#include "d_netinf.h"
|
||||
|
||||
#include "z_zone.h"
|
||||
#include "f_finale.h"
|
||||
#include "m_argv.h"
|
||||
|
@ -38,42 +41,26 @@
|
|||
#include "m_menu.h"
|
||||
#include "m_random.h"
|
||||
#include "i_system.h"
|
||||
|
||||
#include "p_setup.h"
|
||||
#include "p_saveg.h"
|
||||
#include "p_tick.h"
|
||||
|
||||
#include "d_main.h"
|
||||
|
||||
#include "wi_stuff.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "st_stuff.h"
|
||||
#include "am_map.h"
|
||||
|
||||
#include "c_consol.h"
|
||||
#include "c_cvars.h"
|
||||
#include "c_bind.h"
|
||||
#include "c_dispch.h"
|
||||
|
||||
// Needs access to LFB.
|
||||
#include "v_video.h"
|
||||
|
||||
#include "w_wad.h"
|
||||
|
||||
#include "p_local.h"
|
||||
|
||||
#include "s_sound.h"
|
||||
|
||||
// Data.
|
||||
#include "dstrings.h"
|
||||
#include "sounds.h"
|
||||
|
||||
// SKY handling - still the wrong place.
|
||||
#include "r_data.h"
|
||||
#include "r_sky.h"
|
||||
|
||||
#include "r_draw.h"
|
||||
|
||||
#include "g_game.h"
|
||||
#include "g_level.h"
|
||||
|
||||
|
@ -81,6 +68,9 @@
|
|||
#define SAVEGAMESIZE 0x2c000
|
||||
#define SAVESTRINGSIZE 24
|
||||
|
||||
#define TURN180_TICKS 9 // [RH] # of ticks to complete a turn180
|
||||
|
||||
size_t savegamesize = SAVEGAMESIZE; // killough // [RH] made global
|
||||
|
||||
BOOL G_CheckDemoStatus (void);
|
||||
void G_ReadDemoTiccmd (ticcmd_t* cmd, int player);
|
||||
|
@ -89,7 +79,6 @@ void G_PlayerReborn (int player);
|
|||
|
||||
void G_DoReborn (int playernum);
|
||||
|
||||
void G_DoLoadLevel (void);
|
||||
void G_DoNewGame (void);
|
||||
void G_DoLoadGame (void);
|
||||
void G_DoPlayDemo (void);
|
||||
|
@ -116,7 +105,8 @@ BOOL noblit; // for comparative timing purposes
|
|||
|
||||
BOOL viewactive;
|
||||
|
||||
cvar_t *deathmatch; // only if started as net death
|
||||
cvar_t *deathmatch; // deathmatch?
|
||||
cvar_t *teamplay; // [RH] teamplay flag
|
||||
BOOL netgame; // only true if packets are broadcast
|
||||
BOOL playeringame[MAXPLAYERS];
|
||||
player_t players[MAXPLAYERS];
|
||||
|
@ -131,7 +121,7 @@ BOOL demoplayback;
|
|||
BOOL netdemo;
|
||||
byte* demobuffer;
|
||||
byte* demo_p;
|
||||
byte* demoend;
|
||||
size_t maxdemosize;
|
||||
byte* zdemformend; // end of FORM ZDEM chunk
|
||||
byte* zdembodyend; // end of ZDEM BODY chunk
|
||||
BOOL singledemo; // quit after playing a demo from cmdline
|
||||
|
@ -171,7 +161,10 @@ int turnheld; // for accelerative turning
|
|||
int mousex;
|
||||
int mousey;
|
||||
|
||||
// joystick values are repeated
|
||||
// joystick values are repeated
|
||||
// [RH] now, if the joystick is enabled, it will generate an event every tick
|
||||
// so the values here are reset to zero after each tic build (in case
|
||||
// use_joystick gets set to 0 when the joystick is off center)
|
||||
int joyxmove;
|
||||
int joyymove;
|
||||
|
||||
|
@ -181,8 +174,6 @@ char savedescription[32];
|
|||
// [RH] Name of screenshot file to generate (usually NULL)
|
||||
char *shotfile;
|
||||
|
||||
#define BODYQUESIZE 32
|
||||
|
||||
mobj_t* bodyque[BODYQUESIZE];
|
||||
int bodyqueslot;
|
||||
|
||||
|
@ -227,14 +218,86 @@ void Cmd_Pause (player_t *plyr, int argc, char **argv)
|
|||
sendpause = true;
|
||||
}
|
||||
|
||||
static int turntick;
|
||||
|
||||
void Cmd_Turn180 (player_t *plyr, int argc, char **argv)
|
||||
{
|
||||
turntick = TURN180_TICKS;
|
||||
}
|
||||
|
||||
//
|
||||
// [RH] WeapNext and WeapPrev commands
|
||||
//
|
||||
|
||||
static const char *weaponnames[] = {
|
||||
"Fist",
|
||||
"Pistol",
|
||||
"Shotgun",
|
||||
"Chaingun",
|
||||
"Rocket Launcher",
|
||||
"Plasma Gun",
|
||||
"BFG9000",
|
||||
"Chainsaw",
|
||||
"Super Shotgun",
|
||||
"Chainsaw"
|
||||
};
|
||||
|
||||
void Cmd_WeapNext (player_t *plyr, int argc, char **argv)
|
||||
{
|
||||
gitem_t *item = FindItem (weaponnames[plyr->readyweapon]);
|
||||
int selected_weapon;
|
||||
int i, index;
|
||||
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
selected_weapon = ITEM_INDEX(item);
|
||||
|
||||
for (i = 1; i <= num_items; i++) {
|
||||
index = (selected_weapon + i) % num_items;
|
||||
if (!(itemlist[index].flags & IT_WEAPON))
|
||||
continue;
|
||||
if (!plyr->weaponowned[itemlist[index].offset])
|
||||
continue;
|
||||
if (!plyr->ammo[weaponinfo[itemlist[index].offset].ammo])
|
||||
continue;
|
||||
Impulse = itemlist[index].offset + 50;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Cmd_WeapPrev (player_t *plyr, int argc, char **argv)
|
||||
{
|
||||
gitem_t *item = FindItem (weaponnames[plyr->readyweapon]);
|
||||
int selected_weapon;
|
||||
int i, index;
|
||||
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
selected_weapon = ITEM_INDEX(item);
|
||||
|
||||
for (i = 1; i <= num_items; i++) {
|
||||
index = (selected_weapon + num_items - i) % num_items;
|
||||
if (!(itemlist[index].flags & IT_WEAPON))
|
||||
continue;
|
||||
if (!plyr->weaponowned[itemlist[index].offset])
|
||||
continue;
|
||||
if (!plyr->ammo[weaponinfo[itemlist[index].offset].ammo])
|
||||
continue;
|
||||
Impulse = itemlist[index].offset + 50;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// G_BuildTiccmd
|
||||
// Builds a ticcmd from all of the available inputs
|
||||
// or reads it from the demo buffer.
|
||||
// If recording a demo, write it out
|
||||
//
|
||||
void G_BuildTiccmd (ticcmd_t* cmd)
|
||||
{
|
||||
// or reads it from the demo buffer.
|
||||
// If recording a demo, write it out
|
||||
//
|
||||
void G_BuildTiccmd (ticcmd_t *cmd)
|
||||
{
|
||||
BOOL strafe;
|
||||
int speed;
|
||||
int tspeed;
|
||||
|
@ -242,66 +305,53 @@ void G_BuildTiccmd (ticcmd_t* cmd)
|
|||
int side;
|
||||
int look;
|
||||
int fly;
|
||||
|
||||
|
||||
ticcmd_t* base;
|
||||
|
||||
base = I_BaseTiccmd (); // empty, or external driver
|
||||
memcpy (cmd,base,sizeof(*cmd));
|
||||
|
||||
cmd->consistancy =
|
||||
consistancy[consoleplayer][maketic%BACKUPTICS];
|
||||
memcpy (cmd,base,sizeof(*cmd));
|
||||
|
||||
cmd->consistancy = consistancy[consoleplayer][maketic%BACKUPTICS];
|
||||
|
||||
|
||||
strafe = Actions & ACTION_STRAFE;
|
||||
speed = ((Actions & ACTION_SPEED) || (cl_run->value)) ? 1 : 0;
|
||||
|
||||
forward = side = look = fly = 0;
|
||||
|
||||
// use two stage accelerative turning
|
||||
// on the keyboard and joystick
|
||||
if (joyxmove < 0
|
||||
|| joyxmove > 0
|
||||
|| (Actions & ACTION_LEFT)
|
||||
|| (Actions & ACTION_RIGHT))
|
||||
turnheld += ticdup;
|
||||
else
|
||||
turnheld = 0;
|
||||
|
||||
if (turnheld < SLOWTURNTICS)
|
||||
tspeed = 2; // slow turn
|
||||
else
|
||||
forward = side = look = fly = 0;
|
||||
|
||||
// [RH] only use two stage accelerative turning on the keyboard
|
||||
// and not the joystick, since we treat the joystick as
|
||||
// the analog device it is.
|
||||
if ((Actions & ACTION_LEFT) || (Actions & ACTION_RIGHT))
|
||||
turnheld += ticdup;
|
||||
else
|
||||
turnheld = 0;
|
||||
|
||||
if (turnheld < SLOWTURNTICS)
|
||||
tspeed = 2; // slow turn
|
||||
else
|
||||
tspeed = speed;
|
||||
|
||||
// let movement keys cancel each other out
|
||||
if (strafe)
|
||||
{
|
||||
if (Actions & ACTION_RIGHT)
|
||||
if (strafe)
|
||||
{
|
||||
if (Actions & ACTION_RIGHT)
|
||||
{
|
||||
// fprintf(stderr, "strafe right\n");
|
||||
side += sidemove[speed];
|
||||
side += sidemove[speed];
|
||||
}
|
||||
if (Actions & ACTION_LEFT)
|
||||
if (Actions & ACTION_LEFT)
|
||||
{
|
||||
// fprintf(stderr, "strafe left\n");
|
||||
side -= sidemove[speed];
|
||||
side -= sidemove[speed];
|
||||
}
|
||||
if (joyxmove > 0)
|
||||
side += sidemove[speed];
|
||||
if (joyxmove < 0)
|
||||
side -= sidemove[speed];
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Actions & ACTION_RIGHT)
|
||||
cmd->ucmd.yaw -= angleturn[tspeed];
|
||||
if (Actions & ACTION_LEFT)
|
||||
cmd->ucmd.yaw += angleturn[tspeed];
|
||||
if (joyxmove > 0)
|
||||
cmd->ucmd.yaw -= angleturn[tspeed];
|
||||
if (joyxmove < 0)
|
||||
cmd->ucmd.yaw += angleturn[tspeed];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Actions & ACTION_RIGHT)
|
||||
cmd->ucmd.yaw -= angleturn[tspeed];
|
||||
if (Actions & ACTION_LEFT)
|
||||
cmd->ucmd.yaw += angleturn[tspeed];
|
||||
}
|
||||
|
||||
if (Actions & ACTION_LOOKUP)
|
||||
look += lookspeed[speed];
|
||||
|
@ -325,30 +375,45 @@ void G_BuildTiccmd (ticcmd_t* cmd)
|
|||
forward -= forwardmove[speed];
|
||||
}
|
||||
|
||||
if (joyymove < 0)
|
||||
forward += forwardmove[speed];
|
||||
if (joyymove > 0)
|
||||
forward -= forwardmove[speed];
|
||||
if (Actions & ACTION_MOVERIGHT)
|
||||
side += sidemove[speed];
|
||||
if (Actions & ACTION_MOVELEFT)
|
||||
if (Actions & ACTION_MOVERIGHT)
|
||||
side += sidemove[speed];
|
||||
if (Actions & ACTION_MOVELEFT)
|
||||
side -= sidemove[speed];
|
||||
|
||||
// buttons
|
||||
if (Actions & ACTION_ATTACK)
|
||||
cmd->ucmd.buttons |= BT_ATTACK;
|
||||
|
||||
if (Actions & ACTION_USE)
|
||||
if (Actions & ACTION_ATTACK)
|
||||
cmd->ucmd.buttons |= BT_ATTACK;
|
||||
|
||||
if (Actions & ACTION_USE)
|
||||
cmd->ucmd.buttons |= BT_USE;
|
||||
|
||||
if (Actions & ACTION_JUMP)
|
||||
cmd->ucmd.buttons |= BT_JUMP;
|
||||
|
||||
// chainsaw overrides
|
||||
if (Impulse >= 1 && Impulse <= NUMWEAPONS-1) {
|
||||
// [RH] Handle impulses. If they are between 1 and 7,
|
||||
// they get sent as weapon change events.
|
||||
if (Impulse >= 1 && Impulse <= 7) {
|
||||
cmd->ucmd.buttons |= BT_CHANGE;
|
||||
cmd->ucmd.buttons |= (Impulse - 1) << BT_WEAPONSHIFT;
|
||||
Impulse = 0;
|
||||
} else {
|
||||
cmd->ucmd.impulse = Impulse;
|
||||
}
|
||||
Impulse = 0;
|
||||
|
||||
// [RH] Scale joystick moves to full range of allowed speeds
|
||||
if (strafe || lookstrafe->value)
|
||||
side += (MAXPLMOVE * joyxmove) / 256;
|
||||
else
|
||||
cmd->ucmd.yaw -= (angleturn[1] * joyxmove) / 256;
|
||||
|
||||
// [RH] Scale joystick moves over full range
|
||||
if (Actions & ACTION_MLOOK) {
|
||||
if (invertmouse->value)
|
||||
look -= (joyymove * 32767) / 256;
|
||||
else
|
||||
look += (joyymove * 32767) / 256;
|
||||
} else {
|
||||
forward += (MAXPLMOVE * joyymove) / 256;
|
||||
}
|
||||
|
||||
if ((Actions & ACTION_MLOOK) || freelook->value) {
|
||||
|
@ -359,10 +424,6 @@ void G_BuildTiccmd (ticcmd_t* cmd)
|
|||
look -= val;
|
||||
else
|
||||
look += val;
|
||||
if (look > 32767)
|
||||
look = 32767;
|
||||
else if (look < -32767)
|
||||
look = -32767;
|
||||
} else {
|
||||
forward += (int)((float)mousey * m_forward->value);
|
||||
}
|
||||
|
@ -370,6 +431,11 @@ void G_BuildTiccmd (ticcmd_t* cmd)
|
|||
if (sendcenterview) {
|
||||
sendcenterview = false;
|
||||
look = -32768;
|
||||
} else {
|
||||
if (look > 32767)
|
||||
look = 32767;
|
||||
else if (look < -32767)
|
||||
look = -32767;
|
||||
}
|
||||
|
||||
if (strafe || lookstrafe->value)
|
||||
|
@ -378,7 +444,7 @@ void G_BuildTiccmd (ticcmd_t* cmd)
|
|||
cmd->ucmd.yaw -= (int)((float)(mousex*0x8) * m_yaw->value);
|
||||
|
||||
mousex = mousey = 0;
|
||||
|
||||
|
||||
if (forward > MAXPLMOVE)
|
||||
forward = MAXPLMOVE;
|
||||
else if (forward < -MAXPLMOVE)
|
||||
|
@ -408,6 +474,15 @@ void G_BuildTiccmd (ticcmd_t* cmd)
|
|||
|
||||
cmd->ucmd.forwardmove <<= 8;
|
||||
cmd->ucmd.sidemove <<= 8;
|
||||
|
||||
// [RH] 180-degree turn overrides all other yaws
|
||||
if (turntick) {
|
||||
turntick--;
|
||||
cmd->ucmd.yaw = (ANG180 / TURN180_TICKS) >> 16;
|
||||
}
|
||||
|
||||
joyxmove = 0;
|
||||
joyymove = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -418,7 +493,8 @@ static void ChangeSpy (void)
|
|||
// [RH] Use some BOOM code here:
|
||||
ST_Start(); // killough 3/7/98: switch status bar views too
|
||||
HU_Start();
|
||||
S_UpdateSounds(players[displayplayer].mo);
|
||||
players[consoleplayer].camera = players[displayplayer].mo;
|
||||
S_UpdateSounds(players[consoleplayer].camera);
|
||||
}
|
||||
|
||||
void Cmd_SpyNext (player_t *plyr, int argc, char **argv)
|
||||
|
@ -461,8 +537,7 @@ BOOL G_Responder (event_t* ev)
|
|||
// any other key pops up menu if in demos
|
||||
// [RH] But only if the key isn't bound to a "special" command
|
||||
if (gameaction == ga_nothing && !singledemo &&
|
||||
(demoplayback || gamestate == GS_DEMOSCREEN)
|
||||
)
|
||||
(demoplayback || gamestate == GS_DEMOSCREEN))
|
||||
{
|
||||
char *cmd = C_GetBinding (ev->data1);
|
||||
|
||||
|
@ -483,11 +558,11 @@ BOOL G_Responder (event_t* ev)
|
|||
M_StartControlPanel ();
|
||||
return true;
|
||||
} else {
|
||||
return C_DoKey (ev->data1, false);
|
||||
return C_DoKey (ev);
|
||||
}
|
||||
}
|
||||
if (cmd && cmd[0] == '+')
|
||||
return C_DoKey (ev->data1, true);
|
||||
return C_DoKey (ev);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -520,12 +595,12 @@ BOOL G_Responder (event_t* ev)
|
|||
switch (ev->type)
|
||||
{
|
||||
case ev_keydown:
|
||||
if (C_DoKey (ev->data1, false))
|
||||
return true;
|
||||
if (C_DoKey (ev))
|
||||
return true;
|
||||
break;
|
||||
|
||||
case ev_keyup:
|
||||
C_DoKey (ev->data1, true);
|
||||
C_DoKey (ev);
|
||||
break;
|
||||
|
||||
// [RH] mouse buttons are now sent with key up/down events
|
||||
|
@ -578,7 +653,7 @@ void G_Ticker (void)
|
|||
switch (gameaction)
|
||||
{
|
||||
case ga_loadlevel:
|
||||
G_DoLoadLevel ();
|
||||
G_DoLoadLevel (-1);
|
||||
break;
|
||||
case ga_newgame:
|
||||
G_DoNewGame ();
|
||||
|
@ -610,9 +685,14 @@ void G_Ticker (void)
|
|||
}
|
||||
gameaction = ga_nothing;
|
||||
break;
|
||||
case ga_fullconsole:
|
||||
C_FullConsole ();
|
||||
gameaction = ga_nothing;
|
||||
break;
|
||||
case ga_nothing:
|
||||
break;
|
||||
}
|
||||
}
|
||||
C_AdjustBottom ();
|
||||
}
|
||||
|
||||
// get commands, check consistancy,
|
||||
|
@ -636,7 +716,7 @@ void G_Ticker (void)
|
|||
if (cmd->ucmd.forwardmove > TURBOTHRESHOLD
|
||||
&& !(gametic&31) && ((gametic>>5)&3) == i )
|
||||
{
|
||||
Printf ("%s is turbo!\n",players[i].userinfo->netname);
|
||||
Printf ("%s is turbo!\n", players[i].userinfo.netname);
|
||||
}
|
||||
|
||||
if (netgame && !netdemo && !(gametic%ticdup) )
|
||||
|
@ -764,7 +844,7 @@ void G_PlayerReborn (int player)
|
|||
int killcount;
|
||||
int itemcount;
|
||||
int secretcount;
|
||||
userinfo_t *userinfo; // [RH] Save userinfo
|
||||
userinfo_t userinfo; // [RH] Save userinfo
|
||||
|
||||
p = &players[player];
|
||||
|
||||
|
@ -773,7 +853,7 @@ void G_PlayerReborn (int player)
|
|||
killcount = p->killcount;
|
||||
itemcount = p->itemcount;
|
||||
secretcount = p->secretcount;
|
||||
userinfo = p->userinfo;
|
||||
memcpy (&userinfo, &p->userinfo, sizeof(userinfo));
|
||||
|
||||
memset (p, 0, sizeof(*p));
|
||||
|
||||
|
@ -782,17 +862,17 @@ void G_PlayerReborn (int player)
|
|||
p->killcount = killcount;
|
||||
p->itemcount = itemcount;
|
||||
p->secretcount = secretcount;
|
||||
p->userinfo = userinfo;
|
||||
memcpy (&p->userinfo, &userinfo, sizeof(userinfo));
|
||||
|
||||
p->usedown = p->attackdown = p->jumpdown = true; // don't do anything immediately
|
||||
p->playerstate = PST_LIVE;
|
||||
p->health = deh_StartHealth; // [RH] Used to be MAXHEALTH
|
||||
p->health = deh.StartHealth; // [RH] Used to be MAXHEALTH
|
||||
p->readyweapon = p->pendingweapon = wp_pistol;
|
||||
p->weaponowned[wp_fist] = true;
|
||||
p->weaponowned[wp_pistol] = true;
|
||||
p->ammo[am_clip] = deh_StartBullets; // [RH] Used to be 50
|
||||
p->ammo[am_clip] = deh.StartBullets; // [RH] Used to be 50
|
||||
|
||||
for (i=0 ; i<NUMAMMO ; i++)
|
||||
for (i = 0; i < NUMAMMO; i++)
|
||||
p->maxammo[i] = maxammo[i];
|
||||
}
|
||||
|
||||
|
@ -824,15 +904,25 @@ BOOL G_CheckSpot (int playernum, mapthing2_t *mthing)
|
|||
if (!players[playernum].mo)
|
||||
{
|
||||
// first spawn of level, before corpses
|
||||
for (i=0 ; i<playernum ; i++)
|
||||
if (players[i].mo->x == x
|
||||
&& players[i].mo->y == y)
|
||||
for (i = 0; i < playernum; i++)
|
||||
if (players[i].mo->x == x && players[i].mo->y == y)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
players[playernum].mo->z = z; // [RH] Checks are now full 3-D
|
||||
if (!P_CheckPosition (players[playernum].mo, x, y))
|
||||
|
||||
// killough 4/2/98: fix bug where P_CheckPosition() uses a non-solid
|
||||
// corpse to detect collisions with other players in DM starts
|
||||
//
|
||||
// Old code:
|
||||
// if (!P_CheckPosition (players[playernum].mo, x, y))
|
||||
// return false;
|
||||
|
||||
players[playernum].mo->flags |= MF_SOLID;
|
||||
i = P_CheckPosition(players[playernum].mo, x, y);
|
||||
players[playernum].mo->flags &= ~MF_SOLID;
|
||||
if (!i)
|
||||
return false;
|
||||
|
||||
// flush an old corpse if needed
|
||||
|
@ -848,9 +938,8 @@ BOOL G_CheckSpot (int playernum, mapthing2_t *mthing)
|
|||
, z
|
||||
, MT_TFOG, 0);
|
||||
|
||||
// [RH] consoleplayer changed to displayplayer
|
||||
if (players[displayplayer].viewz != 1)
|
||||
S_StartSound (mo, sfx_telept); // don't start sound on first frame
|
||||
if (level.time)
|
||||
S_StartSound (mo, "misc/teleport", 32); // don't start sound on first frame
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -912,12 +1001,12 @@ static mapthing2_t *SelectRandomDeathmatchSpot (int playernum, int selections)
|
|||
i = P_Random (pr_dmspawn) % selections;
|
||||
if (G_CheckSpot (playernum, &deathmatchstarts[i]) )
|
||||
{
|
||||
|
||||
return &deathmatchstarts[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
// [RH] return a spot anyway, since we allow telefragging when a player spawns
|
||||
return olddemo ? NULL : &deathmatchstarts[i];
|
||||
}
|
||||
|
||||
void G_DeathMatchSpawnPlayer (int playernum)
|
||||
|
@ -926,10 +1015,9 @@ void G_DeathMatchSpawnPlayer (int playernum)
|
|||
mapthing2_t *spot;
|
||||
|
||||
selections = deathmatch_p - deathmatchstarts;
|
||||
// [RH] 4 changed to doomcom->numplayers
|
||||
if (selections < doomcom->numplayers)
|
||||
I_Error ("Only %i deathmatch spots, %d required",
|
||||
selections, doomcom->numplayers);
|
||||
// [RH] We can get by with just 1 deathmatch start
|
||||
if (selections < 1)
|
||||
I_Error ("No deathmatch starts");
|
||||
|
||||
// At level start, none of the players have mobjs attached to them,
|
||||
// so we always use the random deathmatch spawn. During the game,
|
||||
|
@ -969,7 +1057,8 @@ void G_DoReborn (int playernum)
|
|||
// respawn at the start
|
||||
|
||||
// first dissasociate the corpse
|
||||
players[playernum].mo->player = NULL;
|
||||
if (players[playernum].mo)
|
||||
players[playernum].mo->player = NULL;
|
||||
|
||||
// spawn at random spot if in death match
|
||||
if (deathmatch->value)
|
||||
|
@ -990,10 +1079,9 @@ void G_DoReborn (int playernum)
|
|||
if (G_CheckSpot (playernum, &playerstarts[i]) )
|
||||
{
|
||||
int oldtype = playerstarts[i].type;
|
||||
if (playernum < 4)
|
||||
playerstarts[i].type = playernum+1; // fake as other player
|
||||
else
|
||||
playerstarts[i].type = playernum+4001-4; // [RH] fake as high player
|
||||
|
||||
// fake as other player
|
||||
playerstarts[i].type = (playernum < 4) ? playernum + 1 : playernum + 4001 - 4;
|
||||
P_SpawnPlayer (&playerstarts[i]);
|
||||
playerstarts[i].type = oldtype; // restore
|
||||
return;
|
||||
|
@ -1022,7 +1110,7 @@ void G_ScreenShot (char *filename)
|
|||
extern BOOL setsizeneeded;
|
||||
void R_ExecuteSetViewSize (void);
|
||||
|
||||
char savename[256];
|
||||
char savename[256];
|
||||
|
||||
void G_LoadGame (char* name)
|
||||
{
|
||||
|
@ -1030,52 +1118,59 @@ void G_LoadGame (char* name)
|
|||
gameaction = ga_loadgame;
|
||||
}
|
||||
|
||||
#define VERSIONSIZE 16
|
||||
|
||||
|
||||
void G_DoLoadGame (void)
|
||||
{
|
||||
int length;
|
||||
int i;
|
||||
char vcheck[VERSIONSIZE];
|
||||
char mapname[9];
|
||||
|
||||
gameaction = ga_nothing;
|
||||
|
||||
length = M_ReadFile (savename, &savebuffer);
|
||||
save_p = savebuffer + SAVESTRINGSIZE;
|
||||
save_p = savebuffer + SAVESTRINGSIZE; // skip the description field
|
||||
|
||||
// skip the description field
|
||||
memset (vcheck,0,sizeof(vcheck));
|
||||
sprintf (vcheck,"version %ia",VERSION);
|
||||
if (strcmp (save_p, vcheck))
|
||||
return; // bad version
|
||||
save_p += VERSIONSIZE;
|
||||
if (strncmp (save_p, SAVESIG, 16)) // Bad version
|
||||
I_Error ("Savegame is from a different version\n");
|
||||
|
||||
save_p += 16;
|
||||
|
||||
memcpy (mapname, save_p, 8);
|
||||
mapname[8] = 0;
|
||||
|
||||
save_p += 8;
|
||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
||||
playeringame[i] = *save_p++;
|
||||
|
||||
C_ReadCVars (&save_p); // [RH] Read server info cvars
|
||||
|
||||
// load a base level
|
||||
G_InitNew (mapname);
|
||||
C_ReadCVars (&save_p); // [RH] read server info cvars
|
||||
|
||||
// dearchive all the modifications
|
||||
P_UnArchiveLevelLocals (); // [RH] dearchive level locals
|
||||
G_UnArchiveSnapshots (); // [RH] restore all level snapshots
|
||||
P_UnArchivePlayers ();
|
||||
P_UnArchiveWorld ();
|
||||
P_UnArchiveThinkers ();
|
||||
P_UnArchiveSpecials ();
|
||||
P_UnArchiveRNGState (); // [RH] retrieve the state of the RNG
|
||||
P_UnArchiveACSDefereds (); // [RH] restore script info on other maps
|
||||
|
||||
// load a base level
|
||||
{
|
||||
// [RH] G_InitNew zaps these
|
||||
byte *saved = save_p, *savedbuffer = savebuffer;
|
||||
savegamerestore = true; // [RH] Use the player mobjs in the savegame
|
||||
G_InitNew (mapname);
|
||||
savegamerestore = false;
|
||||
save_p = saved;
|
||||
savebuffer = savedbuffer;
|
||||
}
|
||||
level.time = ReadLong (&save_p);
|
||||
|
||||
memcpy (WorldVars, save_p, sizeof(WorldVars)); // [RH] restore world vars
|
||||
save_p += sizeof(WorldVars);
|
||||
|
||||
if (*save_p != 0x1d)
|
||||
I_Error ("Bad savegame");
|
||||
|
||||
// done
|
||||
Z_Free (savebuffer);
|
||||
save_p = savebuffer = NULL;
|
||||
|
||||
if (setsizeneeded)
|
||||
R_ExecuteSetViewSize ();
|
||||
|
@ -1097,56 +1192,85 @@ void G_SaveGame (int slot, char *description)
|
|||
sendsave = true;
|
||||
}
|
||||
|
||||
void G_BuildSaveName (char *name, int slot)
|
||||
{
|
||||
if (M_CheckParm ("-cdrom"))
|
||||
sprintf(name, "c:\\zdoomdat\\%s%d.zds", SAVEGAMENAME, slot);
|
||||
else
|
||||
sprintf (name, "%s%d.zds", SAVEGAMENAME, slot);
|
||||
}
|
||||
|
||||
// Check for overrun and realloc if necessary -- Lee Killough 1/22/98
|
||||
void CheckSaveGame (size_t size)
|
||||
{
|
||||
size_t pos = save_p - savebuffer;
|
||||
size += 1024; // breathing room
|
||||
if (pos+size > savegamesize)
|
||||
save_p = (savebuffer = Realloc (savebuffer,
|
||||
savegamesize += (size+1023) & ~1023)) + pos;
|
||||
}
|
||||
|
||||
void G_DoSaveGame (void)
|
||||
{
|
||||
char name[100];
|
||||
char name2[VERSIONSIZE];
|
||||
char* description;
|
||||
int length;
|
||||
int i;
|
||||
|
||||
if (M_CheckParm("-cdrom"))
|
||||
sprintf(name,"c:\\doomdata\\"SAVEGAMENAME"%d.dsg",savegameslot);
|
||||
else
|
||||
sprintf (name,SAVEGAMENAME"%d.dsg",savegameslot);
|
||||
G_SnapshotLevel ();
|
||||
|
||||
G_BuildSaveName (name, savegameslot);
|
||||
description = savedescription;
|
||||
|
||||
save_p = savebuffer = Z_Malloc (SAVEGAMESIZE + 0x4000, PU_STATIC, 0);
|
||||
save_p = savebuffer = Malloc (savegamesize);
|
||||
|
||||
CheckSaveGame (SAVESTRINGSIZE+16+sizeof(unsigned long));
|
||||
memcpy (save_p, description, SAVESTRINGSIZE);
|
||||
save_p += SAVESTRINGSIZE;
|
||||
memset (name2,0,sizeof(name2));
|
||||
sprintf (name2,"version %ia",VERSION);
|
||||
memcpy (save_p, name2, VERSIONSIZE);
|
||||
save_p += VERSIONSIZE;
|
||||
|
||||
strncpy (save_p, SAVESIG, 16);
|
||||
save_p += 16;
|
||||
|
||||
memcpy (save_p, level.mapname, 8);
|
||||
save_p += 8;
|
||||
|
||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
||||
*save_p++ = playeringame[i];
|
||||
C_WriteCVars (&save_p, CVAR_SERVERINFO); // [RH] Save serverinfo cvars
|
||||
|
||||
P_ArchiveLevelLocals (); // [RH] Archive level locals
|
||||
// killough 3/22/98: add Z_CheckHeap after each call to ensure consistency
|
||||
Z_CheckHeap ();
|
||||
G_ArchiveSnapshots (); // [RH] save level snapshots
|
||||
Z_CheckHeap ();
|
||||
P_ArchivePlayers ();
|
||||
P_ArchiveWorld ();
|
||||
P_ArchiveThinkers ();
|
||||
P_ArchiveSpecials ();
|
||||
Z_CheckHeap ();
|
||||
P_ArchiveRNGState (); // [RH] save the state of the RNG
|
||||
Z_CheckHeap ();
|
||||
P_ArchiveACSDefereds (); // [RH] archive script info on other maps
|
||||
Z_CheckHeap ();
|
||||
WriteLong (level.time, &save_p);
|
||||
memcpy (save_p, WorldVars, sizeof(WorldVars)); // [RH] Save world vars
|
||||
save_p += sizeof(WorldVars);
|
||||
|
||||
*save_p++ = 0x1d; // consistancy marker
|
||||
|
||||
length = save_p - savebuffer;
|
||||
if (length > SAVEGAMESIZE)
|
||||
I_Error ("Savegame buffer overrun");
|
||||
M_WriteFile (name, savebuffer, length);
|
||||
Z_Free (savebuffer);
|
||||
{
|
||||
FILE *file = fopen (name, "wb");
|
||||
|
||||
if (file) {
|
||||
fwrite (savebuffer, 1, save_p - savebuffer, file);
|
||||
fclose (file);
|
||||
} else {
|
||||
Printf ("Could not create savegame\n");
|
||||
}
|
||||
}
|
||||
|
||||
free (savebuffer);
|
||||
savebuffer = save_p = NULL;
|
||||
|
||||
gameaction = ga_nothing;
|
||||
savedescription[0] = 0;
|
||||
|
||||
players[consoleplayer].message = GGSAVED;
|
||||
|
||||
// draw the pattern into the back screen
|
||||
R_FillBackScreen ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1228,6 +1352,7 @@ void Cmd_Stop (player_t *plyr, int argc, char **argv)
|
|||
{
|
||||
stoprecording = true;
|
||||
}
|
||||
extern byte *lenspot;
|
||||
|
||||
void G_WriteDemoTiccmd (ticcmd_t *cmd, int player)
|
||||
{
|
||||
|
@ -1263,10 +1388,15 @@ void G_WriteDemoTiccmd (ticcmd_t *cmd, int player)
|
|||
memcpy (&LastUserCmd, &cmd->ucmd, sizeof(usercmd_t));
|
||||
}
|
||||
|
||||
if (demo_p > demoend - 16) {
|
||||
// no more space
|
||||
G_CheckDemoStatus ();
|
||||
return;
|
||||
// [RH] Bigger safety margin
|
||||
if (demo_p > demobuffer + maxdemosize - 64) {
|
||||
ptrdiff_t pos = demo_p - demobuffer;
|
||||
ptrdiff_t spot = lenspot - demobuffer;
|
||||
// [RH] Allocate more space for the demo
|
||||
maxdemosize += 0x20000;
|
||||
demobuffer = Realloc (demobuffer, maxdemosize);
|
||||
demo_p = demobuffer + pos;
|
||||
lenspot = demobuffer + spot;
|
||||
}
|
||||
|
||||
// if (!clonecount)
|
||||
|
@ -1281,21 +1411,17 @@ void G_WriteDemoTiccmd (ticcmd_t *cmd, int player)
|
|||
void G_RecordDemo (char* name)
|
||||
{
|
||||
int i;
|
||||
int maxsize;
|
||||
|
||||
usergame = false;
|
||||
strcpy (demoname, name);
|
||||
FixPathSeperator (demoname);
|
||||
DefaultExtension (demoname, ".lmp");
|
||||
maxsize = 0x20000;
|
||||
i = M_CheckParm ("-maxdemo");
|
||||
if (i && i<myargc-1) {
|
||||
maxsize = atoi(myargv[i+1])*1024;
|
||||
if (maxsize < 0x20000)
|
||||
maxsize = 0x20000;
|
||||
}
|
||||
demobuffer = Z_Malloc (maxsize,PU_STATIC,NULL);
|
||||
demoend = demobuffer + maxsize;
|
||||
if (i && i<myargc-1)
|
||||
maxdemosize = atoi(myargv[i+1])*1024;
|
||||
if (maxdemosize < 0x20000)
|
||||
maxdemosize = 0x20000;
|
||||
demobuffer = Malloc (maxdemosize);
|
||||
|
||||
demorecording = true;
|
||||
}
|
||||
|
@ -1521,25 +1647,23 @@ void G_DoPlayDemo (void)
|
|||
|
||||
SetCVarFloat (gameskill, skill);
|
||||
|
||||
AddCommandString ("set fraglimit 0; set timelimit 0; set cheats 0, sv_gravity 800");
|
||||
AddCommandString ("set fraglimit 0; set timelimit 0; set cheats 0; sv_gravity 800");
|
||||
|
||||
{
|
||||
// Setup compatible userinfo
|
||||
static char greenPlayer[] = "\\name\\Green\\autoaim\\50000\\color\\74 fc 6c";
|
||||
static char indigoPlayer[] = "\\name\\Indigo\\autoaim\\50000\\color\\80 80 80";
|
||||
static char brownPlayer[] = "\\name\\Brown\\autoaim\\50000\\color\\bc 78 48";
|
||||
static char redPlayer[] = "\\name\\Red\\autoaim\\50000\\color\\fc 00 00";
|
||||
static char *playerStreams[4] = {
|
||||
"\\name\\Green\\autoaim\\5000\\color\\74 fc 6c\\skin\\base\\gender\\male",
|
||||
"\\name\\Indigo\\autoaim\\5000\\color\\80 80 80\\skin\\base\\gender\\male",
|
||||
"\\name\\Brown\\autoaim\\5000\\color\\bc 78 48\\skin\\base\\gender\\male",
|
||||
"\\name\\Red\\autoaim\\5000\\color\\fc 00 00\\skin\\base\\gender\\male"
|
||||
};
|
||||
byte *stream;
|
||||
int jookie;
|
||||
|
||||
stream = greenPlayer;
|
||||
D_ReadUserInfoStrings (0, &stream, false);
|
||||
stream = indigoPlayer;
|
||||
D_ReadUserInfoStrings (1, &stream, false);
|
||||
stream = brownPlayer;
|
||||
D_ReadUserInfoStrings (2, &stream, false);
|
||||
stream = redPlayer;
|
||||
D_ReadUserInfoStrings (3, &stream, false);
|
||||
|
||||
for (jookie = 0; jookie < 4; jookie++) {
|
||||
stream = playerStreams[jookie];
|
||||
D_ReadUserInfoStrings (jookie, &stream, false);
|
||||
}
|
||||
R_BuildCompatiblePlayerTranslations ();
|
||||
}
|
||||
} else {
|
||||
|
@ -1589,10 +1713,12 @@ extern cvar_t *color;
|
|||
|
||||
BOOL G_CheckDemoStatus (void)
|
||||
{
|
||||
if (!demorecording) {
|
||||
// [RH] Restore the player's userinfo settings.
|
||||
D_UserInfoChanged (name);
|
||||
D_UserInfoChanged (autoaim);
|
||||
D_UserInfoChanged (color);
|
||||
D_UserInfoChanged (name);
|
||||
D_UserInfoChanged (autoaim);
|
||||
D_UserInfoChanged (color);
|
||||
}
|
||||
|
||||
if (timingdemo)
|
||||
{
|
||||
|
@ -1602,8 +1728,8 @@ BOOL G_CheckDemoStatus (void)
|
|||
endtime = I_GetTimeReally () - starttime;
|
||||
C_RestoreCVars (); // [RH] Restore cvars demo might have changed
|
||||
|
||||
I_Error ("timed %i gametics in %i realtics (%.1f fps)",gametic
|
||||
, endtime, (float)gametic/(float)endtime*(float)TICRATE);
|
||||
I_Error ("timed %i gametics in %i realtics (%.1f fps)", gametic,
|
||||
endtime, (float)gametic/(float)endtime*(float)TICRATE);
|
||||
}
|
||||
|
||||
if (demoplayback)
|
||||
|
@ -1611,7 +1737,7 @@ BOOL G_CheckDemoStatus (void)
|
|||
C_RestoreCVars (); // [RH] Restore cvars demo might have changed
|
||||
|
||||
if (singledemo)
|
||||
I_Quit ();
|
||||
exit (0);
|
||||
|
||||
Z_ChangeTag (demobuffer, PU_CACHE);
|
||||
olddemo = false;
|
||||
|
@ -1644,10 +1770,10 @@ BOOL G_CheckDemoStatus (void)
|
|||
WriteLong (demo_p - demobuffer - 8, &formlen);
|
||||
|
||||
M_WriteFile (demoname, demobuffer, demo_p - demobuffer);
|
||||
Z_Free (demobuffer);
|
||||
free (demobuffer);
|
||||
demorecording = false;
|
||||
stoprecording = false;
|
||||
I_Error ("Demo %s recorded",demoname);
|
||||
Printf ("Demo %s recorded\n", demoname);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -42,6 +42,7 @@ void G_LoadGame (char* name);
|
|||
void G_DoLoadGame (void);
|
||||
|
||||
// Called by M_Responder.
|
||||
void G_BuildSaveName (char *name, int slot);
|
||||
void G_SaveGame (int slot, char* description);
|
||||
|
||||
// Only called by startup code.
|
||||
|
@ -62,10 +63,10 @@ void G_ScreenShot (char *filename);
|
|||
|
||||
void G_PlayerFinishLevel (int player);
|
||||
|
||||
#define BODYQUESIZE 32
|
||||
struct mobj_s;
|
||||
extern struct mobj_s *bodyque[BODYQUESIZE];
|
||||
extern int bodyqueslot;
|
||||
|
||||
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Log:$
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
516
code/G_level.c
516
code/G_level.c
|
@ -22,6 +22,16 @@
|
|||
#include "v_video.h"
|
||||
#include "st_stuff.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "p_saveg.h"
|
||||
#include "p_acs.h"
|
||||
#include "d_proto.h"
|
||||
|
||||
#include "minilzo.h"
|
||||
|
||||
// [RH] Output buffer size for LZO compression.
|
||||
// Extra space in case uncompressable.
|
||||
#define OUT_LEN(a) ((a) + (a) / 64 + 16 + 3)
|
||||
|
||||
|
||||
static level_info_t *FindDefLevelInfo (char *mapname);
|
||||
static cluster_info_t *FindDefClusterInfo (int cluster);
|
||||
|
@ -32,7 +42,12 @@ extern int timingdemo;
|
|||
int starttime;
|
||||
|
||||
|
||||
// ACS variables with world scope
|
||||
int WorldVars[NUM_WORLDVARS];
|
||||
|
||||
|
||||
extern BOOL netdemo;
|
||||
BOOL savegamerestore;
|
||||
|
||||
extern int mousex, mousey, joyxmove, joyymove, Impulse;
|
||||
extern BOOL sendpause, sendsave, sendcenterview;
|
||||
|
@ -46,6 +61,9 @@ static cluster_info_t *wadclusterinfos;
|
|||
static int numwadlevelinfos = 0;
|
||||
static int numwadclusterinfos = 0;
|
||||
|
||||
BOOL HexenHack;
|
||||
|
||||
|
||||
static int FindWadLevelInfo (char *name)
|
||||
{
|
||||
int i;
|
||||
|
@ -110,6 +128,9 @@ void G_ParseMapInfo (void)
|
|||
int map = atoi (com_token);
|
||||
sprintf (com_token, "MAP%02u", map);
|
||||
SKYFLATNAME[5] = 0;
|
||||
// Hexen levels are automatically nointermission
|
||||
levelflags = LEVEL_NOINTERMISSION;
|
||||
HexenHack = true;
|
||||
}
|
||||
if ((levelindex = FindWadLevelInfo (com_token)) == -1)
|
||||
{
|
||||
|
@ -118,14 +139,27 @@ void G_ParseMapInfo (void)
|
|||
memset (wadlevelinfos + levelindex, 0, sizeof(level_pwad_info_t));
|
||||
}
|
||||
levelinfo = wadlevelinfos + levelindex;
|
||||
levelinfo->snapshot = NULL;
|
||||
levelinfo->outsidefog = 0xff000000;
|
||||
strncpy (levelinfo->mapname, com_token, 8);
|
||||
strncpy (levelinfo->fadetable, "COLORMAP", 8);
|
||||
|
||||
data = COM_Parse (data);
|
||||
ReplaceString (&levelinfo->level_name, com_token);
|
||||
|
||||
mapinfo = data;
|
||||
|
||||
// Set up levelnum now so that the Teleport_NewMap specials
|
||||
// in hexen.wad work without modification.
|
||||
if (!strnicmp (levelinfo->mapname, "MAP", 3) && levelinfo->mapname[5] == 0) {
|
||||
int mapnum = atoi (levelinfo->mapname + 3);
|
||||
|
||||
if (mapnum >= 1 && mapnum <= 99)
|
||||
levelinfo->levelnum = mapnum;
|
||||
}
|
||||
|
||||
} else if (levelindex > -1) {
|
||||
if (!stricmp (com_token, "levelnum") ||
|
||||
!stricmp (com_token, "warptrans")) {
|
||||
if (!stricmp (com_token, "levelnum")) {
|
||||
// levelnum <levelnum>
|
||||
mapinfo = COM_Parse (data);
|
||||
levelinfo->levelnum = atoi (com_token);
|
||||
|
@ -149,6 +183,11 @@ void G_ParseMapInfo (void)
|
|||
// cluster <clusternum>
|
||||
mapinfo = COM_Parse (data);
|
||||
levelinfo->cluster = atoi (com_token);
|
||||
if (HexenHack) {
|
||||
cluster_info_t *cluster = FindClusterInfo (levelinfo->cluster);
|
||||
if (cluster)
|
||||
cluster->flags |= CLUSTER_HUB;
|
||||
}
|
||||
|
||||
} else if (!stricmp (com_token, "sky1")) {
|
||||
// sky1 <sky1texture> <sky1scrollspeed>
|
||||
|
@ -176,6 +215,18 @@ void G_ParseMapInfo (void)
|
|||
levelinfo->fadeto = V_GetColorFromString (NULL, com_token);
|
||||
}
|
||||
|
||||
} else if (!stricmp (com_token, "outsidefog")) {
|
||||
// outsidefog <colorname> OR fade <colordescriptor>
|
||||
char *colorstring;
|
||||
|
||||
mapinfo = COM_Parse (data);
|
||||
if ( (colorstring = V_GetColorStringByName (com_token)) ) {
|
||||
levelinfo->outsidefog = V_GetColorFromString (NULL, colorstring);
|
||||
free (colorstring);
|
||||
} else {
|
||||
levelinfo->outsidefog = V_GetColorFromString (NULL, com_token);
|
||||
}
|
||||
|
||||
} else if (!stricmp (com_token, "titlepatch")) {
|
||||
// titlepatch <patchname>
|
||||
mapinfo = COM_Parse (data);
|
||||
|
@ -250,14 +301,19 @@ void G_ParseMapInfo (void)
|
|||
// lightning
|
||||
mapinfo = data;
|
||||
|
||||
} else if (!stricmp (com_token, "fadetable")) {
|
||||
// fadetable
|
||||
mapinfo = COM_Parse (data);
|
||||
uppercopy (levelinfo->fadetable, com_token);
|
||||
|
||||
} else if (!stricmp (com_token, "cdtrack") ||
|
||||
!stricmp (com_token, "fadetable") ||
|
||||
!stricmp (com_token, "cd_start_track") ||
|
||||
!stricmp (com_token, "cd_end1_track") ||
|
||||
!stricmp (com_token, "cd_end2_track") ||
|
||||
!stricmp (com_token, "cd_end3_track") ||
|
||||
!stricmp (com_token, "cd_intermission_track") ||
|
||||
!stricmp (com_token, "cd_title_track")) {
|
||||
!stricmp (com_token, "cd_title_track") ||
|
||||
!stricmp (com_token, "warptrans")) {
|
||||
mapinfo = COM_Parse (data);
|
||||
|
||||
}
|
||||
|
@ -301,6 +357,11 @@ void G_ParseMapInfo (void)
|
|||
mapinfo = COM_Parse (data);
|
||||
strncpy (clusterinfo->finaleflat, com_token, 8);
|
||||
|
||||
} else if (!stricmp (com_token, "hub")) {
|
||||
// hub
|
||||
mapinfo = data;
|
||||
clusterinfo->flags |= CLUSTER_HUB;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -312,12 +373,38 @@ void G_ParseMapInfo (void)
|
|||
}
|
||||
}
|
||||
|
||||
static void zapDefereds (acsdefered_t *def)
|
||||
{
|
||||
while (def) {
|
||||
acsdefered_t *next = def->next;
|
||||
Z_Free (def);
|
||||
def = next;
|
||||
}
|
||||
}
|
||||
|
||||
void P_RemoveDefereds (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Remove any existing defereds
|
||||
for (i = 0; i < numwadlevelinfos; i++)
|
||||
if (wadlevelinfos[i].defered) {
|
||||
zapDefereds (wadlevelinfos[i].defered);
|
||||
wadlevelinfos[i].defered = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; LevelInfos[i].level_name; i++)
|
||||
if (LevelInfos[i].defered) {
|
||||
zapDefereds (LevelInfos[i].defered);
|
||||
LevelInfos[i].defered = NULL;
|
||||
}
|
||||
}
|
||||
//
|
||||
// G_InitNew
|
||||
// Can be called by the startup code or the menu task,
|
||||
// consoleplayer, displayplayer, playeringame[] should be set.
|
||||
//
|
||||
static char d_mapname[9];
|
||||
static char d_mapname[9];
|
||||
|
||||
void G_DeferedInitNew (char *mapname)
|
||||
{
|
||||
|
@ -367,12 +454,17 @@ void G_InitNew (char *mapname)
|
|||
{
|
||||
int i;
|
||||
|
||||
// [RH] Mark all levels as not visited
|
||||
for (i = 0; i < numwadlevelinfos; i++)
|
||||
wadlevelinfos[i].flags &= ~LEVEL_VISITED;
|
||||
if (!savegamerestore)
|
||||
G_ClearSnapshots ();
|
||||
|
||||
for (i = 0; LevelInfos[i].mapname[0]; i++)
|
||||
LevelInfos[i].flags &= ~LEVEL_VISITED;
|
||||
// [RH] Mark all levels as not visited
|
||||
if (!savegamerestore) {
|
||||
for (i = 0; i < numwadlevelinfos; i++)
|
||||
wadlevelinfos[i].flags &= ~LEVEL_VISITED;
|
||||
|
||||
for (i = 0; LevelInfos[i].mapname[0]; i++)
|
||||
LevelInfos[i].flags &= ~LEVEL_VISITED;
|
||||
}
|
||||
|
||||
UnlatchCVars ();
|
||||
|
||||
|
@ -391,7 +483,7 @@ void G_InitNew (char *mapname)
|
|||
|
||||
// [RH] If this map doesn't exist, bomb out
|
||||
if (W_CheckNumForName (mapname) == -1) {
|
||||
I_Error ("Could not start map %s\n", mapname);
|
||||
I_Error ("Could not find map %s\n", mapname);
|
||||
}
|
||||
|
||||
if ((gameskill->value == sk_nightmare) || (dmflags & DF_MONSTERS_RESPAWN) )
|
||||
|
@ -418,44 +510,70 @@ void G_InitNew (char *mapname)
|
|||
mobjinfo[MT_TROOPSHOT].speed = 10*FRACUNIT;
|
||||
}
|
||||
|
||||
M_ClearRandom ();
|
||||
if (!savegamerestore)
|
||||
M_ClearRandom ();
|
||||
|
||||
// [RH] Clear ACS world variables and time
|
||||
// (Savegame restores them after calling G_InitNew)
|
||||
memset (WorldVars, 0, sizeof(WorldVars));
|
||||
level.time = 0;
|
||||
|
||||
// force players to be initialized upon first level load
|
||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
||||
players[i].playerstate = PST_REBORN;
|
||||
if (!savegamerestore)
|
||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
||||
players[i].playerstate = PST_REBORN;
|
||||
|
||||
usergame = true; // will be set false if a demo
|
||||
paused = false;
|
||||
demoplayback = false;
|
||||
automapactive = false;
|
||||
viewactive = true;
|
||||
|
||||
viewactive = true;
|
||||
|
||||
strncpy (level.mapname, mapname, 8);
|
||||
G_DoLoadLevel ();
|
||||
G_DoLoadLevel (0);
|
||||
}
|
||||
|
||||
//
|
||||
// G_DoCompleted
|
||||
//
|
||||
BOOL secretexit;
|
||||
static int startpos; // [RH] Support for multiple starts per level
|
||||
extern char* pagename;
|
||||
|
||||
void G_ExitLevel (void)
|
||||
extern BOOL NoWipe; // [RH] Don't wipe when travelling in hubs
|
||||
|
||||
// [RH] The position parameter to these next two functions should
|
||||
// match the first parameter of the single player start spots
|
||||
// that should appear in the next map.
|
||||
static void goOn (int position)
|
||||
{
|
||||
cluster_info_t *thiscluster = FindClusterInfo (level.cluster);
|
||||
cluster_info_t *nextcluster = FindClusterInfo (FindLevelInfo (level.nextmap)->cluster);
|
||||
|
||||
|
||||
startpos = position;
|
||||
gameaction = ga_completed;
|
||||
|
||||
if (thiscluster && (thiscluster->flags & CLUSTER_HUB)) {
|
||||
if ((level.flags & LEVEL_NOINTERMISSION) || (nextcluster == thiscluster))
|
||||
NoWipe = 4;
|
||||
D_DrawIcon = "TELEICON";
|
||||
}
|
||||
}
|
||||
|
||||
void G_ExitLevel (int position)
|
||||
{
|
||||
secretexit = false;
|
||||
gameaction = ga_completed;
|
||||
goOn (position);
|
||||
}
|
||||
|
||||
// Here's for the german edition.
|
||||
void G_SecretExitLevel (void)
|
||||
void G_SecretExitLevel (int position)
|
||||
{
|
||||
// [RH] Check for secret levels is done in
|
||||
// G_DoCompleted()
|
||||
|
||||
secretexit = true;
|
||||
gameaction = ga_completed;
|
||||
goOn (position);
|
||||
}
|
||||
|
||||
void G_DoCompleted (void)
|
||||
|
@ -468,18 +586,9 @@ void G_DoCompleted (void)
|
|||
if (!(level.flags & LEVEL_CHANGEMAPCHEAT))
|
||||
FindLevelInfo (level.mapname)->flags |= LEVEL_VISITED;
|
||||
|
||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
||||
if (playeringame[i])
|
||||
G_PlayerFinishLevel (i); // take away cards and stuff
|
||||
|
||||
if (automapactive)
|
||||
AM_Stop ();
|
||||
|
||||
if (level.flags & LEVEL_NOINTERMISSION) {
|
||||
G_WorldDone ();
|
||||
return;
|
||||
}
|
||||
|
||||
wminfo.epsd = level.cluster - 1; // Only used for DOOM I.
|
||||
strncpy (wminfo.lname0, level.info->pname, 8);
|
||||
strncpy (wminfo.current, level.mapname, 8);
|
||||
|
@ -524,11 +633,46 @@ void G_DoCompleted (void)
|
|||
wminfo.plyr[i].fragcount = players[i].fragcount;
|
||||
}
|
||||
|
||||
// [RH] If we're in a hub and staying within that hub, take a snapshot
|
||||
// of the level. If we're traveling to a new hub, take stuff from
|
||||
// the player and clear the world vars. If this is just an
|
||||
// ordinary cluster (not a hub), take stuff from the player, but
|
||||
// leave the world vars alone.
|
||||
{
|
||||
cluster_info_t *thiscluster = FindClusterInfo (level.cluster);
|
||||
cluster_info_t *nextcluster = FindClusterInfo (FindLevelInfo (level.nextmap)->cluster);
|
||||
|
||||
if (thiscluster != nextcluster ||
|
||||
deathmatch->value ||
|
||||
!(thiscluster->flags & CLUSTER_HUB)) {
|
||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
||||
if (playeringame[i])
|
||||
G_PlayerFinishLevel (i); // take away cards and stuff
|
||||
|
||||
if (nextcluster->flags & CLUSTER_HUB) {
|
||||
memset (WorldVars, 0, sizeof(WorldVars));
|
||||
P_RemoveDefereds ();
|
||||
G_ClearSnapshots ();
|
||||
}
|
||||
} else {
|
||||
G_SnapshotLevel ();
|
||||
}
|
||||
if (!(nextcluster->flags & CLUSTER_HUB) || !(thiscluster->flags & CLUSTER_HUB))
|
||||
level.time = 0; // Reset time to zero if not entering/staying in a hub
|
||||
|
||||
if (!deathmatch->value &&
|
||||
(level.flags & LEVEL_NOINTERMISSION) ||
|
||||
((nextcluster == thiscluster) && (thiscluster->flags & CLUSTER_HUB))) {
|
||||
G_WorldDone ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gamestate = GS_INTERMISSION;
|
||||
viewactive = false;
|
||||
automapactive = false;
|
||||
|
||||
// [RH] If you ever get a statistics driver operational, uncomment this.
|
||||
// [RH] If you ever get a statistics driver operational, adapt this.
|
||||
// if (statcopy)
|
||||
// memcpy (statcopy, &wminfo, sizeof(wminfo));
|
||||
|
||||
|
@ -538,19 +682,33 @@ void G_DoCompleted (void)
|
|||
//
|
||||
// G_DoLoadLevel
|
||||
//
|
||||
extern gamestate_t wipegamestate;
|
||||
extern gamestate_t wipegamestate;
|
||||
extern float BaseBlendA;
|
||||
|
||||
void G_DoLoadLevel (void)
|
||||
void G_DoLoadLevel (int position)
|
||||
{
|
||||
int i;
|
||||
static int lastposition = 0;
|
||||
gamestate_t oldgs = gamestate;
|
||||
int i;
|
||||
|
||||
if (position == -1)
|
||||
position = lastposition;
|
||||
else
|
||||
lastposition = position;
|
||||
|
||||
G_InitLevelLocals ();
|
||||
|
||||
Printf ("\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36"
|
||||
"\36\36\36\36\36\36\36\36\36\36\36\36\37\n%s\n\n",
|
||||
level.level_name);
|
||||
|
||||
if (wipegamestate == GS_LEVEL)
|
||||
wipegamestate = -1; // force a wipe
|
||||
|
||||
gamestate = GS_LEVEL;
|
||||
|
||||
C_HideConsole ();
|
||||
if (demoplayback || oldgs == GS_STARTUP)
|
||||
C_HideConsole ();
|
||||
C_FlushDisplay ();
|
||||
|
||||
// Set the sky map.
|
||||
|
@ -569,11 +727,6 @@ void G_DoLoadLevel (void)
|
|||
// [RH] Set up details about sky rendering
|
||||
R_InitSkyMap (r_stretchsky);
|
||||
|
||||
if (wipegamestate == GS_LEVEL)
|
||||
wipegamestate = -1; // force a wipe
|
||||
|
||||
gamestate = GS_LEVEL;
|
||||
|
||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
||||
{
|
||||
if (playeringame[i] && players[i].playerstate == PST_DEAD)
|
||||
|
@ -592,9 +745,7 @@ void G_DoLoadLevel (void)
|
|||
headsecnode = NULL;
|
||||
}
|
||||
|
||||
|
||||
S_ClearAmbients (); // [RH] Clear all ambient sounds
|
||||
P_SetupLevel (level.mapname);
|
||||
P_SetupLevel (level.mapname, position);
|
||||
displayplayer = consoleplayer; // view the guy you are playing
|
||||
ST_Start(); // [RH] Make sure status bar knows who we are
|
||||
HU_Start();
|
||||
|
@ -610,6 +761,10 @@ void G_DoLoadLevel (void)
|
|||
|
||||
level.starttime = I_GetTime ();
|
||||
|
||||
G_UnSnapshotLevel (!savegamerestore); // [RH] Restore the state of the level.
|
||||
|
||||
P_DoDeferedScripts (); // [RH] Do script actions that were triggerd on another map.
|
||||
|
||||
if (timingdemo) {
|
||||
static BOOL firstTime = true;
|
||||
|
||||
|
@ -643,8 +798,9 @@ void G_WorldDone (void)
|
|||
else
|
||||
nextcluster = FindClusterInfo (FindLevelInfo (level.secretmap)->cluster);
|
||||
|
||||
if (nextcluster->cluster != level.cluster) {
|
||||
// Only start the finale if the next level's cluster is different than the current one.
|
||||
if (nextcluster->cluster != level.cluster && !deathmatch->value) {
|
||||
// Only start the finale if the next level's cluster is different
|
||||
// than the current one and we're not in deathmatch.
|
||||
if (nextcluster->entertext) {
|
||||
F_StartFinale (nextcluster->messagemusic, nextcluster->finaleflat, nextcluster->entertext);
|
||||
} else if (thiscluster->exittext) {
|
||||
|
@ -664,12 +820,14 @@ void G_DoWorldDone (void)
|
|||
} else {
|
||||
strncpy (level.mapname, wminfo.next, 8);
|
||||
}
|
||||
G_DoLoadLevel ();
|
||||
G_DoLoadLevel (startpos);
|
||||
startpos = 0;
|
||||
gameaction = ga_nothing;
|
||||
viewactive = true;
|
||||
}
|
||||
|
||||
|
||||
extern dyncolormap_t NormalLight;
|
||||
|
||||
void G_InitLevelLocals ()
|
||||
{
|
||||
|
@ -677,21 +835,32 @@ void G_InitLevelLocals ()
|
|||
level_info_t *info;
|
||||
int i;
|
||||
|
||||
BaseBlendA = 0.0f; // Remove underwater blend effect, if any
|
||||
NormalLight.maps = realcolormaps;
|
||||
|
||||
if ((i = FindWadLevelInfo (level.mapname)) > -1) {
|
||||
level_pwad_info_t *pinfo = wadlevelinfos + i;
|
||||
|
||||
level.info = (level_info_t *)pinfo;
|
||||
level.skyspeed1 = pinfo->skyspeed1;
|
||||
level.skyspeed2 = pinfo->skyspeed2;
|
||||
level.fadeto = pinfo->fadeto;
|
||||
info = (level_info_t *)pinfo;
|
||||
strncpy (level.skypic2, pinfo->skypic2, 8);
|
||||
level.fadeto = pinfo->fadeto;
|
||||
if (level.fadeto) {
|
||||
NormalLight.maps = DefaultPalette->maps.colormaps;
|
||||
} else {
|
||||
R_SetDefaultColormap (pinfo->fadetable);
|
||||
}
|
||||
level.outsidefog = pinfo->outsidefog;
|
||||
} else {
|
||||
info = FindDefLevelInfo (level.mapname);
|
||||
level.info = info;
|
||||
level.skyspeed1 = level.skyspeed2 = 0;
|
||||
level.fadeto = 0;
|
||||
level.outsidefog = 0xff000000; // 0xff000000 signals not to handle it special
|
||||
level.skypic2[0] = 0;
|
||||
R_SetDefaultColormap ("COLORMAP");
|
||||
}
|
||||
|
||||
if (info->level_name) {
|
||||
|
@ -719,6 +888,8 @@ void G_InitLevelLocals ()
|
|||
level.levelnum = 1;
|
||||
}
|
||||
|
||||
memset (level.vars, 0, sizeof(level.vars));
|
||||
|
||||
if (oldfade != level.fadeto)
|
||||
RefreshPalettes ();
|
||||
}
|
||||
|
@ -867,6 +1038,255 @@ void G_SetLevelStrings (void)
|
|||
strncpy (level.level_name, level.info->level_name, 63);
|
||||
}
|
||||
|
||||
|
||||
// Archives the current level
|
||||
void G_SnapshotLevel (void)
|
||||
{
|
||||
save_p = savebuffer = Malloc (savegamesize);
|
||||
|
||||
if (level.info->snapshot)
|
||||
Z_Free (level.info->snapshot);
|
||||
|
||||
WriteLong (level.flags, &save_p);
|
||||
WriteLong (level.fadeto, &save_p);
|
||||
WriteLong (level.found_secrets, &save_p);
|
||||
WriteLong (level.found_items, &save_p);
|
||||
WriteLong (level.killed_monsters, &save_p);
|
||||
memcpy (save_p, level.vars, sizeof(level.vars));
|
||||
save_p += sizeof(level.vars);
|
||||
|
||||
P_ArchiveWorld ();
|
||||
Z_CheckHeap ();
|
||||
P_ArchiveThinkers ();
|
||||
Z_CheckHeap ();
|
||||
P_ArchiveSpecials ();
|
||||
Z_CheckHeap ();
|
||||
P_ArchiveScripts ();
|
||||
Z_CheckHeap ();
|
||||
|
||||
// Now compress it. This seems to shrink the data down to
|
||||
// about 20% of its original size fairly consistantly.
|
||||
{
|
||||
int outlen;
|
||||
int len = save_p - savebuffer;
|
||||
lzo_byte *compressed;
|
||||
lzo_byte *wrkmem;
|
||||
int r;
|
||||
|
||||
compressed = Z_Malloc (OUT_LEN(len), PU_STATIC, 0);
|
||||
wrkmem = Z_Malloc (LZO1X_1_MEM_COMPRESS, PU_STATIC, 0);
|
||||
r = lzo1x_1_compress (savebuffer, len, compressed, &outlen, wrkmem);
|
||||
Z_Free (wrkmem);
|
||||
|
||||
// If the data could not be compressed, store it as-is.
|
||||
if (r != LZO_E_OK || outlen > len) {
|
||||
DPrintf ("Snapshot uncompressable\n");
|
||||
outlen = 0;
|
||||
} else {
|
||||
DPrintf ("Snapshot: %d .. %d bytes\n", len, outlen);
|
||||
}
|
||||
|
||||
level.info->snapshot = Z_Malloc (((outlen == 0) ? len : outlen) + sizeof(int)*2, PU_STATIC, 0);
|
||||
((int *)(level.info->snapshot))[0] = outlen;
|
||||
((int *)(level.info->snapshot))[1] = len;
|
||||
if (outlen == 0)
|
||||
memcpy (level.info->snapshot + sizeof(int)*2, savebuffer, len);
|
||||
else
|
||||
memcpy (level.info->snapshot + sizeof(int)*2, compressed, outlen);
|
||||
Z_Free (compressed);
|
||||
}
|
||||
free (savebuffer);
|
||||
savebuffer = save_p = NULL;
|
||||
}
|
||||
|
||||
// Unarchives the current level based on its snapshot
|
||||
// The level should have already been loaded and setup.
|
||||
void G_UnSnapshotLevel (BOOL keepPlayers)
|
||||
{
|
||||
int expandsize, cprlen;
|
||||
byte *expand;
|
||||
|
||||
if (!level.info->snapshot)
|
||||
return;
|
||||
|
||||
cprlen = ((int *)(level.info->snapshot))[0];
|
||||
expandsize = ((int *)(level.info->snapshot))[1];
|
||||
|
||||
if (cprlen) {
|
||||
int r, newlen;
|
||||
|
||||
expand = Z_Malloc (expandsize, PU_STATIC, 0);
|
||||
r = lzo1x_decompress (level.info->snapshot + sizeof(int)*2, cprlen, expand, &newlen, NULL);
|
||||
if (r != LZO_E_OK || newlen != expandsize) {
|
||||
Printf ("Could not decompress snapshot");
|
||||
Z_Free (expand);
|
||||
return;
|
||||
}
|
||||
save_p = expand;
|
||||
} else {
|
||||
save_p = level.info->snapshot + sizeof(int)*2;
|
||||
expand = NULL;
|
||||
}
|
||||
|
||||
level.flags = ReadLong (&save_p);
|
||||
level.fadeto = ReadLong (&save_p);
|
||||
level.found_secrets = ReadLong (&save_p);
|
||||
level.found_items = ReadLong (&save_p);
|
||||
level.killed_monsters = ReadLong (&save_p);
|
||||
memcpy (level.vars, save_p, sizeof(level.vars));
|
||||
save_p += sizeof(level.vars);
|
||||
|
||||
P_UnArchiveWorld ();
|
||||
P_UnArchiveThinkers (keepPlayers);
|
||||
P_UnArchiveSpecials ();
|
||||
P_UnArchiveScripts ();
|
||||
|
||||
if (expand)
|
||||
Z_Free (expand);
|
||||
|
||||
// No reason to keep the snapshot around once the level's been entered.
|
||||
Z_Free (level.info->snapshot);
|
||||
level.info->snapshot = NULL;
|
||||
|
||||
save_p = NULL;
|
||||
}
|
||||
|
||||
void G_ClearSnapshots (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numwadlevelinfos; i++)
|
||||
if (wadlevelinfos[i].snapshot) {
|
||||
Z_Free (wadlevelinfos[i].snapshot);
|
||||
wadlevelinfos[i].snapshot = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; LevelInfos[i].level_name; i++)
|
||||
if (LevelInfos[i].snapshot) {
|
||||
Z_Free (LevelInfos[i].snapshot);
|
||||
LevelInfos[i].snapshot = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void writeSnapShot (level_info_t *i)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = ((int *)(i->snapshot))[0];
|
||||
if (len == 0)
|
||||
len = ((int *)(i->snapshot))[1];
|
||||
|
||||
CheckSaveGame (len + 8 + sizeof(int)*2 + 4);
|
||||
|
||||
memcpy (save_p, i->mapname, 8);
|
||||
save_p += 8;
|
||||
PADSAVEP();
|
||||
memcpy (save_p, i->snapshot, len + sizeof(int)*2);
|
||||
save_p += len + sizeof(int)*2;
|
||||
}
|
||||
|
||||
void G_ArchiveSnapshots (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numwadlevelinfos; i++)
|
||||
if (wadlevelinfos[i].snapshot)
|
||||
writeSnapShot ((level_info_t *)&wadlevelinfos[i]);
|
||||
|
||||
for (i = 0; LevelInfos[i].level_name; i++)
|
||||
if (LevelInfos[i].snapshot)
|
||||
writeSnapShot (&LevelInfos[i]);
|
||||
|
||||
// Signal end of snapshots
|
||||
CheckSaveGame (1);
|
||||
*save_p++ = 0;
|
||||
}
|
||||
|
||||
void G_UnArchiveSnapshots (void)
|
||||
{
|
||||
level_info_t *i;
|
||||
int shortsize, fullsize, savesize;
|
||||
|
||||
G_ClearSnapshots ();
|
||||
while (*save_p) {
|
||||
i = FindLevelInfo (save_p);
|
||||
save_p += 8;
|
||||
PADSAVEP();
|
||||
shortsize = ((int *)save_p)[0];
|
||||
fullsize = ((int *)save_p)[1];
|
||||
savesize = (shortsize ? shortsize : fullsize) + sizeof(int)*2;
|
||||
if (i) {
|
||||
i->snapshot = Z_Malloc (savesize, PU_STATIC, 0);
|
||||
memcpy (i->snapshot, save_p, savesize);
|
||||
}
|
||||
save_p += savesize;
|
||||
}
|
||||
save_p++;
|
||||
}
|
||||
|
||||
|
||||
static void writeDefereds (level_info_t *i)
|
||||
{
|
||||
acsdefered_t *def = i->defered;
|
||||
|
||||
memcpy (save_p, i->mapname, 8);
|
||||
save_p += 8;
|
||||
|
||||
while (def) {
|
||||
CheckSaveGame (sizeof (*def));
|
||||
memcpy (save_p, def, sizeof(*def));
|
||||
save_p += sizeof(*def);
|
||||
def = def->next;
|
||||
}
|
||||
}
|
||||
|
||||
void P_ArchiveACSDefereds (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numwadlevelinfos; i++)
|
||||
if (wadlevelinfos[i].defered)
|
||||
writeDefereds ((level_info_t *)&wadlevelinfos[i]);
|
||||
|
||||
for (i = 0; LevelInfos[i].level_name; i++)
|
||||
if (LevelInfos[i].defered)
|
||||
writeDefereds (&LevelInfos[i]);
|
||||
|
||||
// Signal end of defereds
|
||||
CheckSaveGame (1);
|
||||
*save_p++ = 0;
|
||||
}
|
||||
|
||||
void P_UnArchiveACSDefereds (void)
|
||||
{
|
||||
level_info_t *i;
|
||||
acsdefered_t *def, **prev;
|
||||
|
||||
P_RemoveDefereds ();
|
||||
|
||||
while (*save_p) {
|
||||
i = FindLevelInfo (save_p);
|
||||
if (!i) {
|
||||
char name[9];
|
||||
|
||||
strncpy (name, save_p, 8);
|
||||
name[8] = 0;
|
||||
I_Error ("Unknown map %s in savegame", name);
|
||||
}
|
||||
save_p += 8;
|
||||
prev = &i->defered;
|
||||
do {
|
||||
def = Z_Malloc (sizeof(*def), PU_STATIC, 0);
|
||||
memcpy (def, save_p, sizeof(*def));
|
||||
save_p += sizeof(*def);
|
||||
*prev = def;
|
||||
prev = &def->next;
|
||||
} while (*prev);
|
||||
}
|
||||
save_p++;
|
||||
}
|
||||
|
||||
|
||||
// Static level info from original game
|
||||
// The level names and cluster messages now get filled in
|
||||
// by G_SetLevelStrings().
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#include "doomdef.h"
|
||||
#include "m_fixed.h"
|
||||
|
||||
#define NUM_MAPVARS 32
|
||||
#define NUM_WORLDVARS 64
|
||||
|
||||
#define LEVEL_NOINTERMISSION 0x00000001
|
||||
#define LEVEL_DOUBLESKY 0x00000004
|
||||
#define LEVEL_NOSOUNDCLIPPING 0x00000008
|
||||
|
@ -23,6 +26,7 @@
|
|||
#define LEVEL_CHANGEMAPCHEAT 0x40000000 // Don't display cluster messages
|
||||
#define LEVEL_VISITED 0x80000000 // Used for intermission map
|
||||
|
||||
struct acsdefered_s;
|
||||
|
||||
struct level_info_s {
|
||||
char mapname[8];
|
||||
|
@ -36,6 +40,8 @@ struct level_info_s {
|
|||
char music[8];
|
||||
unsigned flags;
|
||||
int cluster;
|
||||
byte *snapshot;
|
||||
struct acsdefered_s *defered;
|
||||
};
|
||||
typedef struct level_info_s level_info_t;
|
||||
|
||||
|
@ -51,11 +57,15 @@ struct level_pwad_info_s {
|
|||
char music[8];
|
||||
unsigned flags;
|
||||
int cluster;
|
||||
byte *snapshot;
|
||||
struct acsdefered_s *defered;
|
||||
|
||||
char skypic2[8];
|
||||
fixed_t skyspeed1;
|
||||
fixed_t skyspeed2;
|
||||
unsigned fadeto;
|
||||
char fadetable[8];
|
||||
unsigned outsidefog;
|
||||
};
|
||||
typedef struct level_pwad_info_s level_pwad_info_t;
|
||||
|
||||
|
@ -76,6 +86,7 @@ struct level_locals_s {
|
|||
unsigned flags;
|
||||
|
||||
unsigned fadeto; // The color the palette fades to (usually black)
|
||||
unsigned outsidefog; // The fog for sectors with sky ceilings
|
||||
|
||||
char music[8];
|
||||
char skypic1[8];
|
||||
|
@ -92,6 +103,12 @@ struct level_locals_s {
|
|||
|
||||
int total_monsters;
|
||||
int killed_monsters;
|
||||
|
||||
// The following are all used for ACS scripting
|
||||
byte *behavior;
|
||||
int *scripts;
|
||||
int *strings;
|
||||
int vars[NUM_MAPVARS];
|
||||
};
|
||||
typedef struct level_locals_s level_locals_t;
|
||||
|
||||
|
@ -101,13 +118,21 @@ struct cluster_info_s {
|
|||
char finaleflat[8];
|
||||
char *exittext;
|
||||
char *entertext;
|
||||
int flags;
|
||||
};
|
||||
typedef struct cluster_info_s cluster_info_t;
|
||||
|
||||
// Only one cluster flag right now
|
||||
#define CLUSTER_HUB 0x00000001
|
||||
|
||||
extern level_locals_t level;
|
||||
extern level_info_t LevelInfos[];
|
||||
extern cluster_info_t ClusterInfos[];
|
||||
|
||||
extern int WorldVars[NUM_WORLDVARS];
|
||||
|
||||
extern BOOL savegamerestore;
|
||||
|
||||
void G_InitNew (char *mapname);
|
||||
|
||||
// Can be called by the startup code or M_Responder.
|
||||
|
@ -115,10 +140,10 @@ void G_InitNew (char *mapname);
|
|||
// but a warp test can start elsewhere
|
||||
void G_DeferedInitNew (char *mapname);
|
||||
|
||||
void G_ExitLevel (void);
|
||||
void G_SecretExitLevel (void);
|
||||
void G_ExitLevel (int position);
|
||||
void G_SecretExitLevel (int position);
|
||||
|
||||
void G_DoLoadLevel (void);
|
||||
void G_DoLoadLevel (int position);
|
||||
|
||||
void G_InitLevelLocals (void);
|
||||
|
||||
|
@ -132,4 +157,10 @@ char *CalcMapName (int episode, int level);
|
|||
|
||||
void G_ParseMapInfo (void);
|
||||
|
||||
void G_ClearSnapshots (void);
|
||||
void G_SnapshotLevel (void);
|
||||
void G_UnSnapshotLevel (BOOL keepPlayers);
|
||||
void G_ArchiveSnapshots (void);
|
||||
void G_UnArchiveSnapshots (void);
|
||||
|
||||
#endif //__G_LEVEL_H__
|
|
@ -40,7 +40,6 @@
|
|||
|
||||
// Data.
|
||||
#include "dstrings.h"
|
||||
#include "sounds.h"
|
||||
|
||||
#include "c_consol.h"
|
||||
#include "c_dispch.h"
|
||||
|
@ -71,7 +70,7 @@ cvar_t *chat_macros[10];
|
|||
|
||||
static player_t* plr;
|
||||
patch_t* hu_font[HU_FONTSIZE];
|
||||
BOOL chat_on;
|
||||
int chat_on;
|
||||
static hu_itext_t w_chat;
|
||||
|
||||
static BOOL message_on;
|
||||
|
@ -120,11 +119,15 @@ void HU_Start(void)
|
|||
if (headsupactive)
|
||||
HU_Stop();
|
||||
|
||||
plr = &players[displayplayer]; // [RH] Not consoleplayer
|
||||
// [RH] Give status bar preference to the camera
|
||||
if (players[consoleplayer].camera && players[consoleplayer].camera->player)
|
||||
plr = players[consoleplayer].camera->player;
|
||||
else
|
||||
plr = &players[consoleplayer];
|
||||
message_on = false;
|
||||
message_dontfuckwithme = false;
|
||||
message_nottobefuckedwith = false;
|
||||
chat_on = false;
|
||||
chat_on = 0;
|
||||
|
||||
// create the chat widget
|
||||
HUlib_initIText(&w_chat,
|
||||
|
@ -139,8 +142,8 @@ void HU_Drawer(void)
|
|||
{
|
||||
HUlib_drawIText(&w_chat);
|
||||
|
||||
if (deathmatch->value && ((Actions & ACTION_SHOWSCORES) || players[displayplayer].health <= 0))
|
||||
HU_DrawScores (displayplayer);
|
||||
if (deathmatch->value && ((Actions & ACTION_SHOWSCORES) || plr->health <= 0))
|
||||
HU_DrawScores (plr - players);
|
||||
}
|
||||
|
||||
void HU_Erase(void)
|
||||
|
@ -170,7 +173,9 @@ void HU_DrawScores (int player)
|
|||
maxwidth = 0;
|
||||
for (i = 0; i < MAXPLAYERS; i++) {
|
||||
if (playeringame[i]) {
|
||||
int width = V_StringWidth (players[i].userinfo->netname);
|
||||
int width = V_StringWidth (players[i].userinfo.netname);
|
||||
if (teamplay->value)
|
||||
width += V_StringWidth (players[i].userinfo.team) + 24;
|
||||
if (width > maxwidth)
|
||||
maxwidth = width;
|
||||
}
|
||||
|
@ -183,7 +188,7 @@ void HU_DrawScores (int player)
|
|||
if (y < 48) y = 48;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS && y < ST_Y - 12 * CleanYfac; i++) {
|
||||
int color = players[sortedplayers[i]].userinfo->color;
|
||||
int color = players[sortedplayers[i]].userinfo.color;
|
||||
char str[24];
|
||||
|
||||
if (playeringame[sortedplayers[i]]) {
|
||||
|
@ -197,7 +202,11 @@ void HU_DrawScores (int player)
|
|||
sprintf (str, "%d", players[sortedplayers[i]].fragcount);
|
||||
V_DrawTextClean (margin, y, str);
|
||||
|
||||
strcpy (str, players[sortedplayers[i]].userinfo->netname);
|
||||
if (teamplay->value)
|
||||
sprintf (str, "%s (%s)", players[sortedplayers[i]].userinfo.netname,
|
||||
players[sortedplayers[i]].userinfo.team);
|
||||
else
|
||||
strcpy (str, players[sortedplayers[i]].userinfo.netname);
|
||||
|
||||
if (sortedplayers[i] != player)
|
||||
for (j = 0; j < 23 && str[j]; j++)
|
||||
|
@ -258,6 +267,12 @@ BOOL HU_Responder (event_t *ev)
|
|||
|
||||
if (chat_on)
|
||||
{
|
||||
// [RH] You can actually cancel out of messagemode now
|
||||
if (ev->data1 == KEY_ESCAPE) {
|
||||
chat_on = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
c = ev->data3; // [RH] Use localized keymap
|
||||
|
||||
// send a macro
|
||||
|
@ -268,10 +283,10 @@ BOOL HU_Responder (event_t *ev)
|
|||
if (c > 9)
|
||||
return false;
|
||||
|
||||
ShoveChatStr (chat_macros[c]->string, 0);
|
||||
ShoveChatStr (chat_macros[c]->string, chat_on - 1);
|
||||
|
||||
// leave chat mode
|
||||
chat_on = false;
|
||||
chat_on = 0;
|
||||
eatkey = true;
|
||||
}
|
||||
else
|
||||
|
@ -281,10 +296,10 @@ BOOL HU_Responder (event_t *ev)
|
|||
eatkey = HUlib_keyInIText(&w_chat, c);
|
||||
|
||||
if (ev->data1 == KEY_ENTER) {
|
||||
chat_on = false;
|
||||
ShoveChatStr (w_chat.l.l, 0);
|
||||
ShoveChatStr (w_chat.l.l, chat_on - 1);
|
||||
chat_on = 0;
|
||||
} else if (ev->data1 == KEY_ESCAPE)
|
||||
chat_on = false;
|
||||
chat_on = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,11 +308,9 @@ BOOL HU_Responder (event_t *ev)
|
|||
|
||||
void Cmd_MessageMode (player_t *plyr, int argc, char **argv)
|
||||
{
|
||||
if (netgame) {
|
||||
chat_on = true;
|
||||
C_HideConsole ();
|
||||
HUlib_resetIText (&w_chat);
|
||||
}
|
||||
chat_on = 1;
|
||||
C_HideConsole ();
|
||||
HUlib_resetIText (&w_chat);
|
||||
}
|
||||
|
||||
void Cmd_Say (player_t *plyr, int argc, char **argv)
|
||||
|
@ -305,4 +318,18 @@ void Cmd_Say (player_t *plyr, int argc, char **argv)
|
|||
if (argc > 1) {
|
||||
ShoveChatStr (BuildString (argc - 1, argv + 1), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cmd_MessageMode2 (player_t *plyr, int argc, char **argv)
|
||||
{
|
||||
chat_on = 2;
|
||||
C_HideConsole ();
|
||||
HUlib_resetIText (&w_chat);
|
||||
}
|
||||
|
||||
void Cmd_Say_Team (player_t *plyr, int argc, char **argv)
|
||||
{
|
||||
if (argc > 1) {
|
||||
ShoveChatStr (BuildString (argc - 1, argv + 1), 1);
|
||||
}
|
||||
}
|
||||
|
|
354
code/I_music.c
354
code/I_music.c
|
@ -1,354 +0,0 @@
|
|||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "m_argv.h"
|
||||
#include "i_music.h"
|
||||
#include "w_wad.h"
|
||||
#include "c_consol.h"
|
||||
|
||||
#include "../midas/include/midasdll.h"
|
||||
|
||||
#define TYPE_MIDI 0
|
||||
#define TYPE_MOD 1
|
||||
#define TYPE_CD 2
|
||||
|
||||
#define STATE_STOPPED 0
|
||||
#define STATE_PLAYING 1
|
||||
#define STATE_PAUSED 2
|
||||
|
||||
struct MusInfo {
|
||||
int type;
|
||||
int status;
|
||||
union {
|
||||
MIDASmodule module;
|
||||
MCIDEVICEID mciDevice;
|
||||
};
|
||||
union {
|
||||
DWORD unpausePosition;
|
||||
int cdTrack;
|
||||
MIDASmodulePlayHandle handle;
|
||||
};
|
||||
char *filename;
|
||||
BOOL looping;
|
||||
};
|
||||
typedef struct MusInfo info_t;
|
||||
|
||||
static info_t *currSong;
|
||||
|
||||
extern HWND Window;
|
||||
|
||||
/* Music using Windows MIDI device - yuck */
|
||||
|
||||
static int nomusic = 0;
|
||||
static char musName[512];
|
||||
static char midName[512];
|
||||
static int musicdies=-1;
|
||||
static int musicvolume;
|
||||
|
||||
void I_SetMusicVolume (int volume)
|
||||
{
|
||||
if (volume != 127) {
|
||||
// Internal state variable.
|
||||
musicvolume = volume;
|
||||
// Now set volume on output device.
|
||||
if (currSong && currSong->type == TYPE_MOD)
|
||||
MIDASsetMusicVolume (currSong->handle, musicvolume);
|
||||
}
|
||||
}
|
||||
|
||||
void I_InitMusic (void)
|
||||
{
|
||||
char *temp;
|
||||
|
||||
Printf ("I_InitMusic\n");
|
||||
|
||||
nomusic = !!M_CheckParm("-nomusic") || !!M_CheckParm("-nosound");
|
||||
|
||||
/* Create temporary file names: */
|
||||
|
||||
temp = getenv("TEMP");
|
||||
if ( temp == NULL )
|
||||
temp = ".";
|
||||
strcpy(musName, temp);
|
||||
|
||||
while ( musName[strlen(musName)-1] == '\\' )
|
||||
musName[strlen(musName)-1] = 0;
|
||||
|
||||
strcat(musName, "\\");
|
||||
strcpy(midName, musName);
|
||||
|
||||
strcat(musName, "doomtemp.mus");
|
||||
strcat(midName, "doomtemp.mid");
|
||||
}
|
||||
|
||||
|
||||
void I_ShutdownMusic(void)
|
||||
{
|
||||
if (currSong) {
|
||||
I_UnRegisterSong ((int)currSong);
|
||||
currSong = NULL;
|
||||
}
|
||||
remove (midName);
|
||||
remove (musName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int SendMCI(MCIDEVICEID device, UINT msg, DWORD command, DWORD param)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = mciSendCommand(device, msg, command, param);
|
||||
if (res) {
|
||||
char errorStr[256];
|
||||
|
||||
mciGetErrorString(res, errorStr, 255);
|
||||
Printf_Bold ("MCI error:\n");
|
||||
Printf ("%s\n", errorStr);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void I_PlaySong (int handle, int _looping)
|
||||
{
|
||||
info_t *info = (info_t *)handle;
|
||||
|
||||
if (!info || nomusic)
|
||||
return;
|
||||
|
||||
info->status = STATE_STOPPED;
|
||||
info->looping = _looping;
|
||||
|
||||
switch (info->type) {
|
||||
case TYPE_MIDI: {
|
||||
MCI_OPEN_PARMS openParms;
|
||||
MCI_PLAY_PARMS playParms;
|
||||
|
||||
openParms.lpstrDeviceType = "sequencer";
|
||||
openParms.lpstrElementName = info->filename;
|
||||
if (SendMCI (0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_ELEMENT, (DWORD)&openParms))
|
||||
return;
|
||||
|
||||
playParms.dwCallback = (DWORD)Window;
|
||||
if(SendMCI (openParms.wDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)&playParms)) {
|
||||
SendMCI (openParms.wDeviceID, MCI_CLOSE, 0, (DWORD)NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
info->mciDevice = openParms.wDeviceID;
|
||||
info->status = STATE_PLAYING;
|
||||
break;
|
||||
}
|
||||
case TYPE_MOD:
|
||||
if (info->handle = MIDASplayModule (info->module, _looping)) {
|
||||
MIDASsetMusicVolume (info->handle, musicvolume);
|
||||
info->status = STATE_PLAYING;
|
||||
}
|
||||
break;
|
||||
}
|
||||
currSong = info;
|
||||
}
|
||||
|
||||
void I_RestartSong (void)
|
||||
{
|
||||
MCI_PLAY_PARMS playParms;
|
||||
|
||||
if (!currSong ||
|
||||
currSong->type != TYPE_MIDI ||
|
||||
currSong->status != STATE_PLAYING)
|
||||
return;
|
||||
|
||||
if (!currSong->looping) {
|
||||
I_StopSong ((int)currSong);
|
||||
return;
|
||||
}
|
||||
|
||||
playParms.dwFrom = 0;
|
||||
playParms.dwCallback = (DWORD)Window;
|
||||
if (SendMCI (currSong->mciDevice, MCI_PLAY, MCI_NOTIFY | MCI_FROM, (DWORD)(LPVOID)&playParms)) {
|
||||
SendMCI (currSong->mciDevice, MCI_CLOSE, 0, (DWORD)NULL);
|
||||
currSong->mciDevice = 0;
|
||||
currSong = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void I_PauseSong (int handle)
|
||||
{
|
||||
info_t *info = (info_t *)handle;
|
||||
|
||||
if (!info || info->status != STATE_PLAYING)
|
||||
return;
|
||||
|
||||
switch (info->type) {
|
||||
case TYPE_MIDI: {
|
||||
MCI_SET_PARMS setParms;
|
||||
MCI_STATUS_PARMS statusParms;
|
||||
|
||||
setParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
|
||||
if (SendMCI (info->mciDevice, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)&setParms))
|
||||
return;
|
||||
|
||||
statusParms.dwCallback = (DWORD)Window;
|
||||
statusParms.dwItem = MCI_STATUS_POSITION;
|
||||
if (SendMCI (info->mciDevice, MCI_STATUS, MCI_STATUS_ITEM, (DWORD)&statusParms))
|
||||
return;
|
||||
|
||||
info->unpausePosition = statusParms.dwReturn;
|
||||
SendMCI (info->mciDevice, MCI_STOP, 0, (DWORD)NULL);
|
||||
info->status = STATE_PAUSED;
|
||||
}
|
||||
break;
|
||||
case TYPE_MOD:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void I_ResumeSong (int handle)
|
||||
{
|
||||
info_t *info = (info_t *)handle;
|
||||
|
||||
if (!info || info->status != STATE_PAUSED)
|
||||
return;
|
||||
|
||||
switch (info->type) {
|
||||
case TYPE_MIDI: {
|
||||
MCI_SET_PARMS setParms;
|
||||
MCI_PLAY_PARMS playParms;
|
||||
|
||||
setParms.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
|
||||
if (SendMCI (info->mciDevice, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)&setParms))
|
||||
return;
|
||||
|
||||
playParms.dwCallback = (DWORD)Window;
|
||||
playParms.dwTo = 0;
|
||||
playParms.dwFrom = info->unpausePosition;
|
||||
if (SendMCI (info->mciDevice, MCI_PLAY, MCI_NOTIFY | MCI_FROM, (DWORD)&playParms))
|
||||
return;
|
||||
|
||||
info->status = STATE_PLAYING;
|
||||
}
|
||||
break;
|
||||
case TYPE_MOD:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void I_StopSong(int handle)
|
||||
{
|
||||
info_t *info = (info_t *)handle;
|
||||
|
||||
if (!info || info->status == STATE_STOPPED)
|
||||
return;
|
||||
|
||||
info->status = STATE_STOPPED;
|
||||
|
||||
switch (info->type) {
|
||||
case TYPE_MIDI:
|
||||
SendMCI (info->mciDevice, MCI_STOP, 0, (DWORD)NULL);
|
||||
SendMCI (info->mciDevice, MCI_CLOSE, 0, (DWORD)NULL);
|
||||
info->mciDevice = 0;
|
||||
break;
|
||||
case TYPE_MOD:
|
||||
MIDASstopModule (info->handle);
|
||||
info->handle = 0;
|
||||
break;
|
||||
}
|
||||
if (info == currSong)
|
||||
currSong = NULL;
|
||||
}
|
||||
|
||||
void I_UnRegisterSong(int handle)
|
||||
{
|
||||
info_t *info = (info_t *)handle;
|
||||
|
||||
if (info) {
|
||||
I_StopSong (handle);
|
||||
switch (info->type) {
|
||||
case TYPE_MIDI:
|
||||
if (info->filename)
|
||||
remove (info->filename);
|
||||
break;
|
||||
case TYPE_MOD:
|
||||
MIDASfreeModule (info->module);
|
||||
break;
|
||||
}
|
||||
free (info);
|
||||
}
|
||||
}
|
||||
|
||||
extern int convert( const char *mus, const char *mid, int nodisplay, int div,
|
||||
int size, int nocomp, int *ow );
|
||||
|
||||
|
||||
int I_RegisterSong(void* data, int musicLen)
|
||||
{
|
||||
FILE *f;
|
||||
int ow = 2;
|
||||
info_t *info;
|
||||
|
||||
if (!(info = malloc (sizeof(info_t))))
|
||||
return 0;
|
||||
|
||||
info->status = STATE_STOPPED;
|
||||
info->unpausePosition = 0;
|
||||
|
||||
if ( (f = fopen(musName, "wb")) == NULL ) {
|
||||
Printf ("Unable to open temporary music file %s", musName);
|
||||
free (info);
|
||||
return 0;
|
||||
}
|
||||
if ( fwrite(data, musicLen, 1, f) != 1 ) {
|
||||
fclose (f);
|
||||
Printf ("Unable to write temporary music file\n");
|
||||
free (info);
|
||||
return 0;
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
if (*(int *)data == (('M')|(('U')<<8)|(('S')<<16)|((0x1a)<<24))) {
|
||||
// This is a mus file
|
||||
info->type = TYPE_MIDI;
|
||||
|
||||
convert(musName, midName, 1, 89, 0, 1, &ow);
|
||||
|
||||
remove (musName);
|
||||
info->filename = midName;
|
||||
} else if (*(int *)data == (('M')|(('T')<<8)|(('h')<<16)|(('d')<<24))) {
|
||||
// This is a midi file
|
||||
info->type = TYPE_MIDI;
|
||||
remove (midName);
|
||||
rename (musName, midName);
|
||||
info->filename = midName;
|
||||
} else {
|
||||
if (info->module = MIDASloadModule (musName)) {
|
||||
// This is a module
|
||||
info->type = TYPE_MOD;
|
||||
remove (musName);
|
||||
info->filename = NULL;
|
||||
} else {
|
||||
// This is not any known music format
|
||||
// (or could not load mod)
|
||||
remove (musName);
|
||||
free (info);
|
||||
info = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (int)info;
|
||||
}
|
||||
|
||||
// Is the song playing?
|
||||
int I_QrySongPlaying(int handle)
|
||||
{
|
||||
info_t *info = (info_t *)handle;
|
||||
|
||||
if (!info)
|
||||
return 0;
|
||||
else if (info->looping == 1)
|
||||
return 1;
|
||||
else
|
||||
return info->status;
|
||||
}
|
2039
code/Info.c
2039
code/Info.c
File diff suppressed because it is too large
Load diff
97
code/Info.h
97
code/Info.h
|
@ -167,6 +167,7 @@ typedef enum
|
|||
SPR_BRS1,
|
||||
SPR_TLMP,
|
||||
SPR_TLP2,
|
||||
SPR_TNT1,
|
||||
// [RH] Gibs
|
||||
SPR_GIB0,
|
||||
SPR_GIB1,
|
||||
|
@ -178,6 +179,7 @@ typedef enum
|
|||
SPR_GIB7,
|
||||
// [RH] Dummy for unknown mapthing
|
||||
SPR_UNKN,
|
||||
SPR_TLGL,
|
||||
NUMSPRITES
|
||||
|
||||
} spritenum_t;
|
||||
|
@ -1151,6 +1153,7 @@ typedef enum
|
|||
S_TECH2LAMP2,
|
||||
S_TECH2LAMP3,
|
||||
S_TECH2LAMP4,
|
||||
S_TNT1,
|
||||
// [RH] gibs
|
||||
S_GIB0,
|
||||
S_GIB1,
|
||||
|
@ -1162,6 +1165,12 @@ typedef enum
|
|||
S_GIB7,
|
||||
S_AMBIENTSOUND,
|
||||
S_UNKNOWNTHING,
|
||||
S_BRIDGE1,
|
||||
S_BRIDGE2,
|
||||
S_BRIDGE3,
|
||||
S_BRIDGE4,
|
||||
S_BRIDGE5,
|
||||
S_SWITCHTEMP,
|
||||
NUMSTATES
|
||||
} statenum_t;
|
||||
|
||||
|
@ -1333,7 +1342,7 @@ typedef enum {
|
|||
MT_STEALTHUNDEAD,
|
||||
MT_STEALTHSHOTGUY,
|
||||
MT_STEALTHZOMBIE,
|
||||
// [RH] Gibs
|
||||
// [RH] Gibs (code is disabled)
|
||||
MT_GIB0,
|
||||
MT_GIB1,
|
||||
MT_GIB2,
|
||||
|
@ -1342,72 +1351,18 @@ typedef enum {
|
|||
MT_GIB5,
|
||||
MT_GIB6,
|
||||
MT_GIB7,
|
||||
// [RH] Miscellaneous things
|
||||
MT_UNKNOWNTHING,
|
||||
// [RH] Ambient sounds (up to 64)
|
||||
MT_AMBIENT0,
|
||||
MT_AMBIENT1,
|
||||
MT_AMBIENT2,
|
||||
MT_AMBIENT3,
|
||||
MT_AMBIENT4,
|
||||
MT_AMBIENT5,
|
||||
MT_AMBIENT6,
|
||||
MT_AMBIENT7,
|
||||
MT_AMBIENT8,
|
||||
MT_AMBIENT9,
|
||||
MT_AMBIENT10,
|
||||
MT_AMBIENT11,
|
||||
MT_AMBIENT12,
|
||||
MT_AMBIENT13,
|
||||
MT_AMBIENT14,
|
||||
MT_AMBIENT15,
|
||||
MT_AMBIENT16,
|
||||
MT_AMBIENT17,
|
||||
MT_AMBIENT18,
|
||||
MT_AMBIENT19,
|
||||
MT_AMBIENT20,
|
||||
MT_AMBIENT21,
|
||||
MT_AMBIENT22,
|
||||
MT_AMBIENT23,
|
||||
MT_AMBIENT24,
|
||||
MT_AMBIENT25,
|
||||
MT_AMBIENT26,
|
||||
MT_AMBIENT27,
|
||||
MT_AMBIENT28,
|
||||
MT_AMBIENT29,
|
||||
MT_AMBIENT30,
|
||||
MT_AMBIENT31,
|
||||
MT_AMBIENT32,
|
||||
MT_AMBIENT33,
|
||||
MT_AMBIENT34,
|
||||
MT_AMBIENT35,
|
||||
MT_AMBIENT36,
|
||||
MT_AMBIENT37,
|
||||
MT_AMBIENT38,
|
||||
MT_AMBIENT39,
|
||||
MT_AMBIENT40,
|
||||
MT_AMBIENT41,
|
||||
MT_AMBIENT42,
|
||||
MT_AMBIENT43,
|
||||
MT_AMBIENT44,
|
||||
MT_AMBIENT45,
|
||||
MT_AMBIENT46,
|
||||
MT_AMBIENT47,
|
||||
MT_AMBIENT48,
|
||||
MT_AMBIENT49,
|
||||
MT_AMBIENT50,
|
||||
MT_AMBIENT51,
|
||||
MT_AMBIENT52,
|
||||
MT_AMBIENT53,
|
||||
MT_AMBIENT54,
|
||||
MT_AMBIENT55,
|
||||
MT_AMBIENT56,
|
||||
MT_AMBIENT57,
|
||||
MT_AMBIENT58,
|
||||
MT_AMBIENT59,
|
||||
MT_AMBIENT60,
|
||||
MT_AMBIENT61,
|
||||
MT_AMBIENT62,
|
||||
MT_AMBIENT63,
|
||||
MT_MAPSPOT,
|
||||
MT_MAPSPOTGRAV,
|
||||
MT_BRIDGE,
|
||||
MT_PUSH, // Boom's push thing
|
||||
MT_PULL, // Boom's pull thing
|
||||
MT_PATHNODE,
|
||||
MT_AMBIENT, // Ambient sounds
|
||||
MT_SWITCHTEMP, // Temporary mobj for switch sounds
|
||||
MT_TELEPORTMAN2,// Teleport destination that pays attention to its height
|
||||
MT_CAMERA, // Camera used for "cutscenes"
|
||||
NUMMOBJTYPES
|
||||
|
||||
} mobjtype_t;
|
||||
|
@ -1418,23 +1373,23 @@ typedef struct
|
|||
int spawnstate;
|
||||
int spawnhealth;
|
||||
int seestate;
|
||||
int seesound;
|
||||
char *seesound; // [RH] not int
|
||||
int reactiontime;
|
||||
int attacksound;
|
||||
char *attacksound; // [RH] not int
|
||||
int painstate;
|
||||
int painchance;
|
||||
int painsound;
|
||||
char *painsound; // [RH] not int
|
||||
int meleestate;
|
||||
int missilestate;
|
||||
int deathstate;
|
||||
int xdeathstate;
|
||||
int deathsound;
|
||||
char *deathsound; // [RH] not int
|
||||
int speed;
|
||||
int radius;
|
||||
int height;
|
||||
int mass;
|
||||
int damage;
|
||||
int activesound;
|
||||
char *activesound; // [RH] not int
|
||||
int flags;
|
||||
int raisestate;
|
||||
|
||||
|
|
|
@ -114,9 +114,9 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
case CHT_IDDQD:
|
||||
if (!(player->cheats & CF_GODMODE)) {
|
||||
if (player->mo)
|
||||
player->mo->health = deh_GodHealth;
|
||||
player->mo->health = deh.GodHealth;
|
||||
|
||||
player->health = deh_GodHealth;
|
||||
player->health = deh.GodHealth;
|
||||
}
|
||||
case CHT_GOD:
|
||||
player->cheats ^= CF_GODMODE;
|
||||
|
@ -153,8 +153,8 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
cht_Give (player, "weapons");
|
||||
cht_Give (player, "ammo");
|
||||
cht_Give (player, "keys");
|
||||
player->armorpoints = deh_KFAArmor;
|
||||
player->armortype = deh_KFAAC;
|
||||
player->armorpoints = deh.KFAArmor;
|
||||
player->armortype = deh.KFAAC;
|
||||
msg = STSTR_KFAADDED;
|
||||
break;
|
||||
|
||||
|
@ -162,8 +162,8 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
cht_Give (player, "backpack");
|
||||
cht_Give (player, "weapons");
|
||||
cht_Give (player, "ammo");
|
||||
player->armorpoints = deh_FAArmor;
|
||||
player->armortype = deh_FAAC;
|
||||
player->armorpoints = deh.FAArmor;
|
||||
player->armortype = deh.FAAC;
|
||||
msg = STSTR_FAADDED;
|
||||
break;
|
||||
|
||||
|
@ -201,10 +201,15 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
if (currentthinker->function.acp1 == (actionf_p1) P_MobjThinker &&
|
||||
(((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)->flags2 & MF2_INDESTRUCTABLE)
|
||||
continue; // [RH] Don't kill if indestructable
|
||||
|
||||
// killough 3/6/98: kill even if PE is dead
|
||||
if (((mobj_t *) currentthinker)->health > 0)
|
||||
{
|
||||
killcount++;
|
||||
((mobj_t *)currentthinker)->flags2 &= ~MF2_INVULNERABLE;
|
||||
P_DamageMobj((mobj_t *)currentthinker, NULL, NULL, 10000, MOD_UNKNOWN);
|
||||
}
|
||||
if (((mobj_t *) currentthinker)->type == MT_PAIN)
|
||||
|
@ -223,7 +228,7 @@ void cht_DoCheat (player_t *player, int cheat)
|
|||
if (player == &players[consoleplayer])
|
||||
Printf ("%s\n", msg);
|
||||
else
|
||||
Printf ("%s is cheating: %s\n", player->userinfo->netname, msg);
|
||||
Printf ("%s is a cheater: %s\n", player->userinfo.netname, msg);
|
||||
}
|
||||
|
||||
void cht_Give (player_t *player, char *name)
|
||||
|
@ -233,7 +238,7 @@ void cht_Give (player_t *player, char *name)
|
|||
gitem_t *it;
|
||||
|
||||
if (player != &players[consoleplayer])
|
||||
Printf ("%s is cheating: give %s\n", player->userinfo->netname, name);
|
||||
Printf ("%s is a cheater: give %s\n", player->userinfo.netname, name);
|
||||
|
||||
if (stricmp (name, "all") == 0)
|
||||
giveall = true;
|
||||
|
@ -252,9 +257,9 @@ void cht_Give (player_t *player, char *name)
|
|||
}
|
||||
} else {
|
||||
if (player->mo)
|
||||
player->mo->health = deh_GodHealth;
|
||||
player->mo->health = deh.GodHealth;
|
||||
|
||||
player->health = deh_GodHealth;
|
||||
player->health = deh.GodHealth;
|
||||
}
|
||||
|
||||
if (!giveall)
|
||||
|
@ -332,7 +337,7 @@ void cht_Give (player_t *player, char *name)
|
|||
P_GiveWeapon (player, it->offset, 0);
|
||||
} else if (it->flags & IT_KEY) {
|
||||
P_GiveCard (player, it->offset);
|
||||
} else if (it->flags & IT_POWER) {
|
||||
} else if (it->flags & IT_POWERUP) {
|
||||
P_GivePower (player, it->offset);
|
||||
} else if (it->flags & IT_ARMOR) {
|
||||
P_GiveArmor (player, it->offset);
|
||||
|
|
615
code/M_menu.c
615
code/M_menu.c
File diff suppressed because it is too large
Load diff
|
@ -26,6 +26,7 @@
|
|||
|
||||
|
||||
#include "d_event.h"
|
||||
#include "c_cvars.h"
|
||||
|
||||
//
|
||||
// MENUS
|
||||
|
@ -37,7 +38,6 @@
|
|||
// Does all the real work of the menu interaction.
|
||||
BOOL M_Responder (event_t *ev);
|
||||
|
||||
|
||||
// Called by main loop,
|
||||
// only used for menu (skull cursor) animation.
|
||||
void M_Ticker (void);
|
||||
|
@ -66,8 +66,102 @@ void M_OptDrawer (void);
|
|||
// [RH] Initialize options menu
|
||||
void M_OptInit (void);
|
||||
|
||||
void M_SwitchMenu (struct menu_s *menu);
|
||||
|
||||
|
||||
//
|
||||
// MENU TYPEDEFS
|
||||
//
|
||||
typedef enum {
|
||||
whitetext,
|
||||
redtext,
|
||||
more,
|
||||
slider,
|
||||
discrete,
|
||||
control,
|
||||
screenres,
|
||||
bitflag,
|
||||
listelement
|
||||
} itemtype;
|
||||
|
||||
typedef struct menuitem_s {
|
||||
itemtype type;
|
||||
char *label;
|
||||
union {
|
||||
cvar_t **cvar;
|
||||
int selmode;
|
||||
int flagmask;
|
||||
} a;
|
||||
union {
|
||||
float min; /* aka numvalues aka invflag */
|
||||
int key1;
|
||||
char *res1;
|
||||
} b;
|
||||
union {
|
||||
float max;
|
||||
int key2;
|
||||
char *res2;
|
||||
} c;
|
||||
union {
|
||||
float step;
|
||||
char *res3;
|
||||
} d;
|
||||
union {
|
||||
struct value_s *values;
|
||||
char *command;
|
||||
void (*cfunc)(cvar_t *cvar, float newval);
|
||||
void (*mfunc)(void);
|
||||
void (*lfunc)(int);
|
||||
int highlight;
|
||||
int *flagint;
|
||||
} e;
|
||||
} menuitem_t;
|
||||
|
||||
typedef struct menu_s {
|
||||
char title[8];
|
||||
int lastOn;
|
||||
int numitems;
|
||||
int indent;
|
||||
menuitem_t *items;
|
||||
struct menu_s *prevmenu;
|
||||
} menu_t;
|
||||
|
||||
typedef struct value_s {
|
||||
float value;
|
||||
char *name;
|
||||
} value_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// -1 = no cursor here, 1 = ok, 2 = arrows ok
|
||||
short status;
|
||||
|
||||
char name[10];
|
||||
|
||||
// choice = menu item #.
|
||||
// if status = 2,
|
||||
// choice=0:leftarrow,1:rightarrow
|
||||
void (*routine)(int choice);
|
||||
|
||||
// hotkey in menu
|
||||
char alphaKey;
|
||||
} oldmenuitem_t;
|
||||
|
||||
typedef struct oldmenu_s
|
||||
{
|
||||
short numitems; // # of menu items
|
||||
struct oldmenu_s* prevMenu; // previous menu
|
||||
oldmenuitem_t *menuitems; // menu items
|
||||
void (*routine)(); // draw routine
|
||||
short x;
|
||||
short y; // x,y of menu
|
||||
short lastOn; // last item user was on in menu
|
||||
} oldmenu_t;
|
||||
|
||||
extern value_t YesNo[2];
|
||||
extern value_t NoYes[2];
|
||||
extern value_t OnOff[2];
|
||||
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -146,6 +147,9 @@ char *GetConfigPath (void)
|
|||
return copystring (myargv[p+1]);
|
||||
}
|
||||
|
||||
if (M_CheckParm ("-cdrom"))
|
||||
return copystring ("c:\\zdoomdat\\zdoom.cfg");
|
||||
|
||||
path = Malloc (strlen (progdir) + 11);
|
||||
|
||||
strcpy (path, progdir);
|
||||
|
@ -156,24 +160,36 @@ char *GetConfigPath (void)
|
|||
char *GetAutoexecPath (void)
|
||||
{
|
||||
cvar_t *autovar;
|
||||
char *path = Malloc (strlen (progdir) + 13);
|
||||
|
||||
strcpy (path, progdir);
|
||||
strcat (path, "autoexec.cfg");
|
||||
if (M_CheckParm ("-cdrom")) {
|
||||
return copystring ("c:\\zdoomdat\\autoexec.cfg");
|
||||
} else {
|
||||
char *path = Malloc (strlen (progdir) + 13);
|
||||
|
||||
autovar = cvar ("autoexec", path, CVAR_ARCHIVE);
|
||||
free (path);
|
||||
strcpy (path, progdir);
|
||||
strcat (path, "autoexec.cfg");
|
||||
|
||||
return autovar->string;
|
||||
autovar = cvar ("autoexec", path, CVAR_ARCHIVE);
|
||||
free (path);
|
||||
|
||||
return autovar->string;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// M_SaveDefaults
|
||||
//
|
||||
|
||||
// [RH] Don't write a config file if M_LoadDefaults hasn't been called.
|
||||
static BOOL DefaultsLoaded;
|
||||
|
||||
void M_SaveDefaults (void)
|
||||
{
|
||||
FILE* f;
|
||||
char* configfile;
|
||||
FILE *f;
|
||||
char *configfile;
|
||||
|
||||
if (!DefaultsLoaded)
|
||||
return;
|
||||
|
||||
configfile = GetConfigPath ();
|
||||
|
||||
|
@ -201,7 +217,8 @@ void M_SaveDefaults (void)
|
|||
//
|
||||
// M_LoadDefaults
|
||||
//
|
||||
extern byte scantokey[128];
|
||||
extern byte scantokey[128];
|
||||
extern int cvar_defflags;
|
||||
|
||||
void M_LoadDefaults (void)
|
||||
{
|
||||
|
@ -220,15 +237,17 @@ void M_LoadDefaults (void)
|
|||
configver = cvar ("configver", VERSIONSTR, CVAR_ARCHIVE);
|
||||
|
||||
configfile = GetConfigPath ();
|
||||
execcommand = Malloc (strlen (configfile) + 6);
|
||||
sprintf (execcommand, "exec %s", configfile);
|
||||
execcommand = Malloc (strlen (configfile) + 8);
|
||||
sprintf (execcommand, "exec \"%s\"", configfile);
|
||||
free (configfile);
|
||||
cvar_defflags = CVAR_ARCHIVE;
|
||||
AddCommandString (execcommand);
|
||||
cvar_defflags = 0;
|
||||
free (execcommand);
|
||||
|
||||
configfile = GetAutoexecPath ();
|
||||
execcommand = Malloc (strlen (configfile) + 6);
|
||||
sprintf (execcommand, "exec %s", configfile);
|
||||
execcommand = Malloc (strlen (configfile) + 8);
|
||||
sprintf (execcommand, "exec \"%s\"", configfile);
|
||||
AddCommandString (execcommand);
|
||||
free (execcommand);
|
||||
|
||||
|
@ -237,6 +256,8 @@ void M_LoadDefaults (void)
|
|||
if (!stricmp (C_GetBinding (KEY_F5), "menu_video"))
|
||||
AddCommandString ("bind f5 menu_display");
|
||||
}
|
||||
|
||||
DefaultsLoaded = true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -354,16 +375,23 @@ extern unsigned IndexedPalette[256];
|
|||
|
||||
void M_ScreenShot (char *filename)
|
||||
{
|
||||
byte* linear;
|
||||
char lbmname[16];
|
||||
byte *linear;
|
||||
char autoname[32];
|
||||
char *lbmname;
|
||||
|
||||
// find a file name to save it to
|
||||
if (!filename) {
|
||||
if (M_CheckParm ("-cdrom")) {
|
||||
strcpy (autoname, "C:\\ZDOOMDAT\\");
|
||||
lbmname = autoname + 12;
|
||||
} else {
|
||||
lbmname = autoname;
|
||||
}
|
||||
if (!FindFreeName (lbmname, "tga\0pcx" + (screens[0].is8bit << 2))) {
|
||||
Printf ("M_ScreenShot: Delete some screenshots\n");
|
||||
return;
|
||||
}
|
||||
filename = lbmname;
|
||||
filename = autoname;
|
||||
}
|
||||
|
||||
if (screens[0].is8bit) {
|
||||
|
|
476
code/P_ceilng.c
Normal file
476
code/P_ceilng.c
Normal file
|
@ -0,0 +1,476 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// $Log:$
|
||||
//
|
||||
// DESCRIPTION: Ceiling aninmation (lowering, crushing, raising)
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "m_alloc.h"
|
||||
|
||||
#include "z_zone.h"
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
|
||||
#include "s_sound.h"
|
||||
|
||||
// State.
|
||||
#include "doomstat.h"
|
||||
#include "r_state.h"
|
||||
|
||||
//
|
||||
// CEILINGS
|
||||
//
|
||||
|
||||
|
||||
// [RH] Active ceilings are now linked together in a list instead
|
||||
// of stored in an array. Similar to what Lee Killough did
|
||||
// with BOOM except I link the ceilings themselves together.
|
||||
ceiling_t *activeceilings;
|
||||
|
||||
|
||||
//
|
||||
// T_MoveCeiling
|
||||
//
|
||||
void T_MoveCeiling (ceiling_t* ceiling)
|
||||
{
|
||||
result_e res;
|
||||
|
||||
switch(ceiling->direction)
|
||||
{
|
||||
case 0:
|
||||
// IN STASIS
|
||||
break;
|
||||
case 1:
|
||||
// UP
|
||||
res = T_MovePlane(ceiling->sector,
|
||||
ceiling->speed,
|
||||
ceiling->topheight,
|
||||
-1,1,ceiling->direction);
|
||||
|
||||
// Make moving sound
|
||||
if (!(level.time&7) && (ceiling->silent == 0))
|
||||
S_StartSound ((mobj_t *)&ceiling->sector->soundorg, "plats/pt1_mid", 119);
|
||||
|
||||
if (res == pastdest)
|
||||
{
|
||||
switch (ceiling->type)
|
||||
{
|
||||
case ceilCrushAndRaise:
|
||||
if (ceiling->silent == 1)
|
||||
S_StartSound((mobj_t *)&ceiling->sector->soundorg, "plats/pt1_stop", 100);
|
||||
ceiling->direction = -1;
|
||||
ceiling->speed = ceiling->speed1;
|
||||
break;
|
||||
|
||||
// movers with texture change, change the texture then get removed
|
||||
case genCeilingChgT:
|
||||
case genCeilingChg0:
|
||||
ceiling->sector->special = ceiling->newspecial;
|
||||
case genCeilingChg:
|
||||
ceiling->sector->ceilingpic = ceiling->texture;
|
||||
// fall through
|
||||
default:
|
||||
P_RemoveActiveCeiling(ceiling);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case -1:
|
||||
// DOWN
|
||||
res = T_MovePlane(ceiling->sector,
|
||||
ceiling->speed,
|
||||
ceiling->bottomheight,
|
||||
ceiling->crush,1,ceiling->direction);
|
||||
|
||||
// Make moving noise
|
||||
if (!(level.time&7) && !ceiling->silent)
|
||||
S_StartSound((mobj_t *)&ceiling->sector->soundorg, "plats/pt1_mid", 119);
|
||||
|
||||
if (res == pastdest)
|
||||
{
|
||||
switch (ceiling->type)
|
||||
{
|
||||
case ceilCrushAndRaise:
|
||||
case ceilCrushRaiseAndStay:
|
||||
if (ceiling->silent == 1)
|
||||
S_StartSound ((mobj_t *)&ceiling->sector->soundorg, "plats/pt1_stop", 100);
|
||||
ceiling->speed = ceiling->speed2;
|
||||
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;
|
||||
case genCeilingChg:
|
||||
ceiling->sector->ceilingpic = ceiling->texture;
|
||||
// fall through
|
||||
default:
|
||||
P_RemoveActiveCeiling(ceiling);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // ( res != pastdest )
|
||||
{
|
||||
if (res == crushed)
|
||||
{
|
||||
switch (ceiling->type)
|
||||
{
|
||||
case ceilCrushAndRaise:
|
||||
case ceilLowerAndCrush:
|
||||
if (ceiling->speed1 == FRACUNIT && ceiling->speed2 == FRACUNIT)
|
||||
ceiling->speed = FRACUNIT / 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// EV_DoCeiling
|
||||
// Move a ceiling up/down and all around!
|
||||
//
|
||||
// [RH] Added tag, speed, speed2, height, crush, silent, change params
|
||||
BOOL EV_DoCeiling (ceiling_e type, line_t *line,
|
||||
int tag, fixed_t speed, fixed_t speed2, fixed_t height,
|
||||
int crush, int silent, int change)
|
||||
{
|
||||
int secnum;
|
||||
BOOL rtn;
|
||||
sector_t* sec;
|
||||
ceiling_t* ceiling;
|
||||
BOOL manual = false;
|
||||
fixed_t targheight;
|
||||
|
||||
rtn = false;
|
||||
|
||||
// check if a manual trigger, if so do just the sector on the backside
|
||||
if (tag == 0)
|
||||
{
|
||||
if (!line || !(sec = line->backsector))
|
||||
return rtn;
|
||||
secnum = sec-sectors;
|
||||
manual = true;
|
||||
// [RH] Hack to let manual crushers be retriggerable, too
|
||||
tag ^= secnum | 0x1000000;
|
||||
P_ActivateInStasisCeiling (tag);
|
||||
goto manual_ceiling;
|
||||
}
|
||||
|
||||
// Reactivate in-stasis ceilings...for certain types.
|
||||
// This restarts a crusher after it has been stopped
|
||||
if (type == ceilCrushAndRaise)
|
||||
{
|
||||
P_ActivateInStasisCeiling (tag);
|
||||
}
|
||||
|
||||
secnum = -1;
|
||||
// affects all sectors with the same tag as the linedef
|
||||
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
manual_ceiling:
|
||||
// if ceiling already moving, don't start a second function on it
|
||||
if (P_SectorActive (ceiling_special,sec)) //jff 2/22/98
|
||||
continue;
|
||||
|
||||
// new door thinker
|
||||
rtn = 1;
|
||||
ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0);
|
||||
P_AddThinker (&ceiling->thinker);
|
||||
sec->ceilingdata = ceiling; //jff 2/22/98
|
||||
ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling;
|
||||
ceiling->sector = sec;
|
||||
ceiling->crush = -1;
|
||||
ceiling->speed = ceiling->speed1 = speed;
|
||||
ceiling->speed2 = speed2;
|
||||
ceiling->silent = silent;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case ceilCrushAndRaise:
|
||||
case ceilCrushRaiseAndStay:
|
||||
ceiling->topheight = sec->ceilingheight;
|
||||
case ceilLowerAndCrush:
|
||||
ceiling->crush = crush;
|
||||
targheight = ceiling->bottomheight = sec->floorheight + 8*FRACUNIT;
|
||||
ceiling->direction = -1;
|
||||
break;
|
||||
|
||||
case ceilRaiseToHighest:
|
||||
targheight = ceiling->topheight = P_FindHighestCeilingSurrounding (sec);
|
||||
ceiling->direction = 1;
|
||||
break;
|
||||
|
||||
case ceilLowerByValue:
|
||||
targheight = ceiling->bottomheight = sec->ceilingheight - height;
|
||||
ceiling->direction = -1;
|
||||
break;
|
||||
|
||||
case ceilRaiseByValue:
|
||||
targheight = ceiling->topheight = sec->ceilingheight + height;
|
||||
ceiling->direction = 1;
|
||||
break;
|
||||
|
||||
case ceilMoveToValue:
|
||||
{
|
||||
int diff = height - sec->ceilingheight;
|
||||
|
||||
if (diff < 0) {
|
||||
targheight = ceiling->bottomheight = height;
|
||||
ceiling->direction = -1;
|
||||
} else {
|
||||
targheight = ceiling->topheight = height;
|
||||
ceiling->direction = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ceilLowerToHighestFloor:
|
||||
targheight = ceiling->bottomheight = P_FindHighestFloorSurrounding (sec);
|
||||
ceiling->direction = -1;
|
||||
break;
|
||||
|
||||
case ceilRaiseToHighestFloor:
|
||||
targheight = ceiling->topheight = P_FindHighestFloorSurrounding (sec);
|
||||
ceiling->direction = 1;
|
||||
break;
|
||||
|
||||
case ceilLowerInstant:
|
||||
targheight = ceiling->bottomheight = sec->ceilingheight - height;
|
||||
ceiling->direction = -1;
|
||||
ceiling->speed = height;
|
||||
break;
|
||||
|
||||
case ceilRaiseInstant:
|
||||
targheight = ceiling->topheight = sec->ceilingheight + height;
|
||||
ceiling->direction = 1;
|
||||
ceiling->speed = height;
|
||||
break;
|
||||
|
||||
case ceilLowerToNearest:
|
||||
targheight = ceiling->bottomheight =
|
||||
P_FindNextLowestCeiling (sec, sec->ceilingheight);
|
||||
ceiling->direction = 1;
|
||||
break;
|
||||
|
||||
case ceilRaiseToNearest:
|
||||
targheight = ceiling->topheight =
|
||||
P_FindNextHighestCeiling (sec, sec->ceilingheight);
|
||||
ceiling->direction = 1;
|
||||
break;
|
||||
|
||||
case ceilLowerToLowest:
|
||||
targheight = ceiling->bottomheight = P_FindLowestCeilingSurrounding (sec);
|
||||
ceiling->direction = -1;
|
||||
break;
|
||||
|
||||
case ceilRaiseToLowest:
|
||||
targheight = ceiling->topheight = P_FindLowestCeilingSurrounding (sec);
|
||||
ceiling->direction = -1;
|
||||
break;
|
||||
|
||||
case ceilLowerToFloor:
|
||||
targheight = ceiling->bottomheight = sec->floorheight;
|
||||
ceiling->direction = -1;
|
||||
break;
|
||||
|
||||
case ceilRaiseToFloor:
|
||||
targheight = ceiling->topheight = sec->floorheight;
|
||||
ceiling->direction = 1;
|
||||
break;
|
||||
|
||||
case ceilLowerToHighest:
|
||||
targheight = ceiling->bottomheight = P_FindHighestCeilingSurrounding (sec);
|
||||
ceiling->direction = -1;
|
||||
break;
|
||||
|
||||
case ceilLowerByTexture:
|
||||
targheight = ceiling->bottomheight =
|
||||
sec->ceilingheight - P_FindShortestUpperAround (secnum);
|
||||
ceiling->direction = -1;
|
||||
break;
|
||||
|
||||
case ceilRaiseByTexture:
|
||||
targheight = ceiling->topheight =
|
||||
sec->ceilingheight + P_FindShortestUpperAround (secnum);
|
||||
ceiling->direction = 1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
ceiling->tag = tag;
|
||||
ceiling->type = type;
|
||||
|
||||
// set texture/type change properties
|
||||
if (change & 3) // if a texture change is indicated
|
||||
{
|
||||
if (change & 4) // if a numeric model change
|
||||
{
|
||||
sector_t *sec;
|
||||
|
||||
//jff 5/23/98 find model with floor at target height if target
|
||||
//is a floor type
|
||||
sec = (type == ceilRaiseToHighest ||
|
||||
type == ceilRaiseToFloor ||
|
||||
type == ceilLowerToHighest ||
|
||||
type == ceilLowerToFloor) ?
|
||||
P_FindModelFloorSector (targheight, secnum) :
|
||||
P_FindModelCeilingSector (targheight, secnum);
|
||||
if (sec)
|
||||
{
|
||||
ceiling->texture = sec->ceilingpic;
|
||||
switch (change & 3)
|
||||
{
|
||||
case 1: // type is zeroed
|
||||
ceiling->newspecial = 0;
|
||||
ceiling->type = genCeilingChg0;
|
||||
break;
|
||||
case 2: // type is copied
|
||||
ceiling->newspecial = sec->special;
|
||||
ceiling->type = genCeilingChgT;
|
||||
break;
|
||||
case 3: // type is left alone
|
||||
ceiling->type = genCeilingChg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (line) // else if a trigger model change
|
||||
{
|
||||
|
||||
ceiling->texture = line->frontsector->ceilingpic;
|
||||
switch (change & 3)
|
||||
{
|
||||
case 1: // type is zeroed
|
||||
ceiling->newspecial = 0;
|
||||
ceiling->type = genCeilingChg0;
|
||||
break;
|
||||
case 2: // type is copied
|
||||
ceiling->newspecial = line->frontsector->special;
|
||||
ceiling->type = genCeilingChgT;
|
||||
break;
|
||||
case 3: // type is left alone
|
||||
ceiling->type = genCeilingChg;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
P_AddActiveCeiling(ceiling);
|
||||
|
||||
if (manual)
|
||||
return rtn;
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Add an active ceiling
|
||||
// [RH] Rewritten to use list
|
||||
//
|
||||
void P_AddActiveCeiling (ceiling_t *c)
|
||||
{
|
||||
c->next = activeceilings;
|
||||
c->prev = NULL;
|
||||
activeceilings = c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Remove a ceiling's thinker
|
||||
// [RH] Rewritten to use list
|
||||
//
|
||||
void P_RemoveActiveCeiling (ceiling_t *c)
|
||||
{
|
||||
ceiling_t *scan = activeceilings;
|
||||
|
||||
while (scan) {
|
||||
if (scan == c) {
|
||||
c->sector->ceilingdata = NULL;
|
||||
if (c == activeceilings) {
|
||||
activeceilings = c->next;
|
||||
} else {
|
||||
if (c->prev)
|
||||
c->prev->next = c->next;
|
||||
if (c->next)
|
||||
c->next->prev = c->prev;
|
||||
}
|
||||
P_RemoveThinker (&c->thinker);
|
||||
break;
|
||||
}
|
||||
scan = scan->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Restart a ceiling that's in-stasis
|
||||
// [RH] Passed a tag instead of a line and rewritten to use list
|
||||
//
|
||||
void P_ActivateInStasisCeiling (int tag)
|
||||
{
|
||||
ceiling_t *scan = activeceilings;
|
||||
|
||||
while (scan) {
|
||||
if (scan->tag == tag && scan->direction == 0) {
|
||||
scan->direction = scan->olddirection;
|
||||
scan->thinker.function.acp1 = (actionf_p1) T_MoveCeiling;
|
||||
}
|
||||
scan = scan->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// EV_CeilingCrushStop
|
||||
// Stop a ceiling from crushing!
|
||||
// [RH] Passed a tag instead of a line and rewritten to use list
|
||||
//
|
||||
BOOL EV_CeilingCrushStop (int tag)
|
||||
{
|
||||
BOOL rtn = false;
|
||||
ceiling_t *scan = activeceilings;
|
||||
|
||||
while (scan) {
|
||||
if (scan->tag == tag && scan->direction != 0) {
|
||||
scan->olddirection = scan->direction;
|
||||
scan->thinker.function.acv = (actionf_v) NULL;
|
||||
scan->direction = 0; // in-stasis;
|
||||
rtn = true;
|
||||
}
|
||||
scan = scan->next;
|
||||
}
|
||||
|
||||
return rtn;
|
||||
}
|
693
code/P_doors.c
693
code/P_doors.c
|
@ -17,6 +17,7 @@
|
|||
// $Log:$
|
||||
//
|
||||
// DESCRIPTION: Door animation code (opening/closing)
|
||||
// [RH] Removed sliding door code and simplified for Hexen-ish specials
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -35,36 +36,35 @@
|
|||
|
||||
// Data.
|
||||
#include "dstrings.h"
|
||||
#include "sounds.h"
|
||||
|
||||
#include "c_consol.h"
|
||||
|
||||
#if 0
|
||||
//
|
||||
// Sliding door frame information
|
||||
//
|
||||
slidename_t slideFrameNames[MAXSLIDEDOORS] =
|
||||
{
|
||||
{"GDOORF1","GDOORF2","GDOORF3","GDOORF4", // front
|
||||
"GDOORB1","GDOORB2","GDOORB3","GDOORB4"}, // back
|
||||
|
||||
{"\0","\0","\0","\0"}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// VERTICAL DOORS
|
||||
//
|
||||
|
||||
// [RH] DoorSound: Plays door sound depending on its direction and speed
|
||||
static void DoorSound (vldoor_t *door, fixed_t speed, BOOL raise)
|
||||
{
|
||||
char *snd;
|
||||
|
||||
if (raise)
|
||||
snd = (speed >= FRACUNIT*8) ? "doors/dr2_open" : "doors/dr1_open";
|
||||
else
|
||||
snd = (speed >= FRACUNIT*8) ? "doors/dr2_clos" : "doors/dr1_clos";
|
||||
|
||||
S_StartSound ((mobj_t *)&door->sector->soundorg, snd, 100);
|
||||
}
|
||||
|
||||
//
|
||||
// T_VerticalDoor
|
||||
//
|
||||
void T_VerticalDoor (vldoor_t* door)
|
||||
void T_VerticalDoor (vldoor_t *door)
|
||||
{
|
||||
result_e res;
|
||||
result_e res;
|
||||
|
||||
switch(door->direction)
|
||||
switch (door->direction)
|
||||
{
|
||||
case 0:
|
||||
// WAITING
|
||||
|
@ -72,22 +72,14 @@ void T_VerticalDoor (vldoor_t* door)
|
|||
{
|
||||
switch(door->type)
|
||||
{
|
||||
case blazeRaise:
|
||||
case doorRaise:
|
||||
door->direction = -1; // time to go back down
|
||||
S_StartSound((mobj_t *)&door->sector->soundorg,
|
||||
sfx_bdcls);
|
||||
DoorSound (door, door->speed, false);
|
||||
break;
|
||||
|
||||
case normal:
|
||||
door->direction = -1; // time to go back down
|
||||
S_StartSound((mobj_t *)&door->sector->soundorg,
|
||||
sfx_dorcls);
|
||||
break;
|
||||
|
||||
case close30ThenOpen:
|
||||
case doorCloseWaitOpen:
|
||||
door->direction = 1;
|
||||
S_StartSound((mobj_t *)&door->sector->soundorg,
|
||||
sfx_doropn);
|
||||
DoorSound (door, door->speed, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -102,11 +94,10 @@ void T_VerticalDoor (vldoor_t* door)
|
|||
{
|
||||
switch(door->type)
|
||||
{
|
||||
case raiseIn5Mins:
|
||||
case doorRaiseIn5Mins:
|
||||
door->direction = 1;
|
||||
door->type = normal;
|
||||
S_StartSound((mobj_t *)&door->sector->soundorg,
|
||||
sfx_doropn);
|
||||
door->type = doorRaise;
|
||||
DoorSound (door, door->speed, true);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -120,27 +111,20 @@ void T_VerticalDoor (vldoor_t* door)
|
|||
res = T_MovePlane(door->sector,
|
||||
door->speed,
|
||||
door->sector->floorheight,
|
||||
false,1,door->direction);
|
||||
-1,1,door->direction);
|
||||
if (res == pastdest)
|
||||
{
|
||||
switch(door->type)
|
||||
{
|
||||
case blazeRaise:
|
||||
case blazeClose:
|
||||
door->sector->ceilingdata = NULL; //jff 2/22/98
|
||||
P_RemoveThinker (&door->thinker); // unlink and free
|
||||
S_StartSound((mobj_t *)&door->sector->soundorg, sfx_bdcls);
|
||||
break;
|
||||
|
||||
case normal:
|
||||
case close:
|
||||
case doorRaise:
|
||||
case doorClose:
|
||||
door->sector->ceilingdata = NULL; //jff 2/22/98
|
||||
P_RemoveThinker (&door->thinker); // unlink and free
|
||||
break;
|
||||
|
||||
case close30ThenOpen:
|
||||
case doorCloseWaitOpen:
|
||||
door->direction = 0;
|
||||
door->topcountdown = TICRATE*30;
|
||||
door->topcountdown = door->topwait;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -151,14 +135,12 @@ void T_VerticalDoor (vldoor_t* door)
|
|||
{
|
||||
switch(door->type)
|
||||
{
|
||||
case blazeClose:
|
||||
case close: // DO NOT GO BACK UP!
|
||||
case doorClose: // DO NOT GO BACK UP!
|
||||
break;
|
||||
|
||||
default:
|
||||
door->direction = 1;
|
||||
S_StartSound((mobj_t *)&door->sector->soundorg,
|
||||
sfx_doropn);
|
||||
DoorSound (door, door->speed, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -169,21 +151,19 @@ void T_VerticalDoor (vldoor_t* door)
|
|||
res = T_MovePlane(door->sector,
|
||||
door->speed,
|
||||
door->topheight,
|
||||
false,1,door->direction);
|
||||
-1,1,door->direction);
|
||||
|
||||
if (res == pastdest)
|
||||
{
|
||||
switch(door->type)
|
||||
{
|
||||
case blazeRaise:
|
||||
case normal:
|
||||
case doorRaise:
|
||||
door->direction = 0; // wait at top
|
||||
door->topcountdown = door->topwait;
|
||||
break;
|
||||
|
||||
case close30ThenOpen:
|
||||
case blazeOpen:
|
||||
case open:
|
||||
case doorCloseWaitOpen:
|
||||
case doorOpen:
|
||||
door->sector->ceilingdata = NULL; //jff 2/22/98
|
||||
P_RemoveThinker (&door->thinker); // unlink and free
|
||||
break;
|
||||
|
@ -197,139 +177,110 @@ void T_VerticalDoor (vldoor_t* door)
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// EV_DoLockedDoor
|
||||
// Move a locked door up/down
|
||||
//
|
||||
// [RH] Merged EV_VerticalDoor and EV_DoLockedDoor into EV_DoDoor
|
||||
// and made them more general to support the new specials.
|
||||
|
||||
int
|
||||
EV_DoLockedDoor
|
||||
( line_t* line,
|
||||
vldoor_e type,
|
||||
mobj_t* thing )
|
||||
// [RH] SpawnDoor: Helper function for EV_DoDoor
|
||||
static BOOL SpawnDoor (sector_t *sec, vldoor_e type, fixed_t speed, int delay)
|
||||
{
|
||||
player_t* p;
|
||||
|
||||
p = thing->player;
|
||||
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
switch(line->special)
|
||||
// new door thinker
|
||||
vldoor_t *door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
|
||||
P_AddThinker (&door->thinker);
|
||||
sec->ceilingdata = door; //jff 2/22/98
|
||||
|
||||
door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
door->type = type;
|
||||
door->topwait = delay;
|
||||
door->speed = speed;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case 99: // Blue Lock
|
||||
case 133:
|
||||
if (!p->cards[it_bluecard] && !p->cards[it_blueskull])
|
||||
{
|
||||
C_MidPrint (PD_BLUEO);
|
||||
S_StartSound(ORIGIN_AMBIENT,sfx_oof);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 134: // Red Lock
|
||||
case 135:
|
||||
if (!p->cards[it_redcard] && !p->cards[it_redskull])
|
||||
{
|
||||
C_MidPrint (PD_REDO);
|
||||
S_StartSound(ORIGIN_AMBIENT,sfx_oof);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 136: // Yellow Lock
|
||||
case 137:
|
||||
if (!p->cards[it_yellowcard] &&
|
||||
!p->cards[it_yellowskull])
|
||||
{
|
||||
C_MidPrint (PD_YELLOWO);
|
||||
S_StartSound(ORIGIN_AMBIENT,sfx_oof);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return EV_DoDoor(line,type);
|
||||
}
|
||||
|
||||
|
||||
int EV_DoDoor (line_t *line, vldoor_e type)
|
||||
{
|
||||
int secnum,rtn;
|
||||
sector_t* sec;
|
||||
vldoor_t* door;
|
||||
|
||||
secnum = -1;
|
||||
rtn = 0;
|
||||
|
||||
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[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);
|
||||
P_AddThinker (&door->thinker);
|
||||
sec->ceilingdata = door; //jff 2/22/98
|
||||
|
||||
door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
door->type = type;
|
||||
door->topwait = VDOORWAIT;
|
||||
door->speed = VDOORSPEED;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case blazeClose:
|
||||
door->topheight = P_FindLowestCeilingSurrounding(sec);
|
||||
case doorClose:
|
||||
door->topheight = P_FindLowestCeilingSurrounding (sec) - 4*FRACUNIT;
|
||||
door->topheight -= 4*FRACUNIT;
|
||||
door->direction = -1;
|
||||
door->speed = VDOORSPEED * 4;
|
||||
S_StartSound((mobj_t *)&door->sector->soundorg,
|
||||
sfx_bdcls);
|
||||
DoorSound (door, speed, false);
|
||||
break;
|
||||
|
||||
case close:
|
||||
door->topheight = P_FindLowestCeilingSurrounding(sec);
|
||||
door->topheight -= 4*FRACUNIT;
|
||||
door->direction = -1;
|
||||
S_StartSound((mobj_t *)&door->sector->soundorg,
|
||||
sfx_dorcls);
|
||||
|
||||
case doorOpen:
|
||||
case doorRaise:
|
||||
door->direction = 1;
|
||||
door->topheight = P_FindLowestCeilingSurrounding (sec) - 4*FRACUNIT;
|
||||
if (door->topheight != sec->ceilingheight)
|
||||
DoorSound (door, speed, true);
|
||||
break;
|
||||
|
||||
case close30ThenOpen:
|
||||
|
||||
case doorCloseWaitOpen:
|
||||
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:
|
||||
DoorSound (door, speed, false);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL EV_DoDoor (vldoor_e type, line_t *line, mobj_t *thing,
|
||||
int tag, int speed, int delay, keytype_t lock)
|
||||
{
|
||||
BOOL rtn = false;
|
||||
int secnum;
|
||||
sector_t* sec;
|
||||
|
||||
if (lock && !P_CheckKeys (thing->player, lock, tag))
|
||||
return false;
|
||||
|
||||
if (tag == 0) { // [RH] manual door
|
||||
if (!line)
|
||||
return false;
|
||||
|
||||
// if the wrong side of door is pushed, give oof sound
|
||||
if (line->sidenum[1]==-1) // killough
|
||||
{
|
||||
S_StartSound (thing, "*grunt1", 78);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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
|
||||
if (sec->ceilingdata) //jff 2/22/98
|
||||
{
|
||||
vldoor_t *door = sec->ceilingdata; //jff 2/22/98
|
||||
if (type == doorRaise) {
|
||||
// ONLY FOR "RAISE" DOORS, NOT "OPEN"s
|
||||
if (door->direction == -1) {
|
||||
door->direction = 1; // go back up
|
||||
}
|
||||
else if ((line->flags & ML_ACTIVATIONMASK) != ML_ACTIVATEPUSH)
|
||||
// [RH] activate push doors don't go back down when you
|
||||
// run into them (otherwise opening them would be
|
||||
// a real pain).
|
||||
{
|
||||
if (!thing->player)
|
||||
return false; // JDC: bad guys never close doors
|
||||
|
||||
door->direction = -1; // start going down immediately
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
rtn = SpawnDoor (sec, type, speed, delay);
|
||||
|
||||
} else { // [RH] Remote door
|
||||
|
||||
secnum = -1;
|
||||
while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
// if the ceiling already moving, don't start the door action
|
||||
if (P_SectorActive (ceiling_special,sec)) //jff 2/22/98
|
||||
continue;
|
||||
|
||||
rtn |= SpawnDoor (sec, type, speed, delay);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -337,171 +288,14 @@ int EV_DoDoor (line_t *line, vldoor_e type)
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// EV_VerticalDoor : open a door manually, no tag value
|
||||
//
|
||||
void EV_VerticalDoor (line_t *line, mobj_t *thing)
|
||||
{
|
||||
player_t* player;
|
||||
int secnum;
|
||||
sector_t* sec;
|
||||
vldoor_t* door;
|
||||
int side;
|
||||
|
||||
side = 0; // only front sides can be used
|
||||
|
||||
// Check for locks
|
||||
player = thing->player;
|
||||
|
||||
switch(line->special)
|
||||
{
|
||||
case 26: // Blue Lock
|
||||
case 32:
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
if (!player->cards[it_bluecard] && !player->cards[it_blueskull])
|
||||
{
|
||||
C_MidPrint (PD_BLUEK);
|
||||
S_StartSound(ORIGIN_AMBIENT,sfx_oof);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 27: // Yellow Lock
|
||||
case 34:
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
if (!player->cards[it_yellowcard] &&
|
||||
!player->cards[it_yellowskull])
|
||||
{
|
||||
C_MidPrint (PD_YELLOWK);
|
||||
S_StartSound(ORIGIN_AMBIENT,sfx_oof);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 28: // Red Lock
|
||||
case 33:
|
||||
if ( !player )
|
||||
return;
|
||||
|
||||
if (!player->cards[it_redcard] && !player->cards[it_redskull])
|
||||
{
|
||||
C_MidPrint (PD_REDK);
|
||||
S_StartSound(ORIGIN_AMBIENT,sfx_oof);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// if the wrong side of door is pushed, give oof sound
|
||||
if (line->sidenum[1]==-1) // 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
|
||||
if (sec->ceilingdata) //jff 2/22/98
|
||||
{
|
||||
door = sec->ceilingdata; //jff 2/22/98
|
||||
switch(line->special)
|
||||
{
|
||||
case 1: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s
|
||||
case 26:
|
||||
case 27:
|
||||
case 28:
|
||||
case 117:
|
||||
if (door->direction == -1)
|
||||
door->direction = 1; // go back up
|
||||
else
|
||||
{
|
||||
if (!thing->player)
|
||||
return; // JDC: bad guys never close doors
|
||||
|
||||
door->direction = -1; // start going down immediately
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// for proper sound
|
||||
switch(line->special)
|
||||
{
|
||||
case 117: // BLAZING DOOR RAISE
|
||||
case 118: // BLAZING DOOR OPEN
|
||||
S_StartSound((mobj_t *)&sec->soundorg,sfx_bdopn);
|
||||
break;
|
||||
|
||||
case 1: // NORMAL DOOR SOUND
|
||||
case 31:
|
||||
S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn);
|
||||
break;
|
||||
|
||||
default: // LOCKED DOOR SOUND
|
||||
S_StartSound((mobj_t *)&sec->soundorg,sfx_doropn);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// new door thinker
|
||||
door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
|
||||
P_AddThinker (&door->thinker);
|
||||
sec->ceilingdata = door; //jff 2/22/98
|
||||
door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
door->direction = 1;
|
||||
door->speed = VDOORSPEED;
|
||||
door->topwait = VDOORWAIT;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// find the top and bottom of the movement range
|
||||
door->topheight = P_FindLowestCeilingSurrounding(sec);
|
||||
door->topheight -= 4*FRACUNIT;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Spawn a door that closes after 30 seconds
|
||||
//
|
||||
void P_SpawnDoorCloseIn30 (sector_t* sec)
|
||||
{
|
||||
vldoor_t* door;
|
||||
vldoor_t *door;
|
||||
|
||||
door = Z_Malloc ( sizeof(*door), PU_LEVSPEC, 0);
|
||||
door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
|
||||
|
||||
P_AddThinker (&door->thinker);
|
||||
|
||||
|
@ -511,17 +305,17 @@ void P_SpawnDoorCloseIn30 (sector_t* sec)
|
|||
door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
door->direction = 0;
|
||||
door->type = normal;
|
||||
door->speed = VDOORSPEED;
|
||||
door->type = doorRaise;
|
||||
door->speed = FRACUNIT*2;
|
||||
door->topcountdown = 30 * TICRATE;
|
||||
}
|
||||
|
||||
//
|
||||
// Spawn a door that opens after 5 minutes
|
||||
//
|
||||
void P_SpawnDoorRaiseIn5Mins (sector_t *sec, int secnum)
|
||||
void P_SpawnDoorRaiseIn5Mins (sector_t *sec)
|
||||
{
|
||||
vldoor_t* door;
|
||||
vldoor_t *door;
|
||||
|
||||
door = Z_Malloc ( sizeof(*door), PU_LEVSPEC, 0);
|
||||
|
||||
|
@ -533,221 +327,10 @@ void P_SpawnDoorRaiseIn5Mins (sector_t *sec, int secnum)
|
|||
door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
door->direction = 2;
|
||||
door->type = raiseIn5Mins;
|
||||
door->speed = VDOORSPEED;
|
||||
door->type = doorRaiseIn5Mins;
|
||||
door->speed = FRACUNIT * 2;
|
||||
door->topheight = P_FindLowestCeilingSurrounding(sec);
|
||||
door->topheight -= 4*FRACUNIT;
|
||||
door->topwait = VDOORWAIT;
|
||||
door->topwait = (150*TICRATE)/35;
|
||||
door->topcountdown = 5 * 60 * TICRATE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// UNUSED
|
||||
// Separate into p_slidoor.c?
|
||||
|
||||
#if 0 // ABANDONED TO THE MISTS OF TIME!!!
|
||||
//
|
||||
// EV_SlidingDoor : slide a door horizontally
|
||||
// (animate midtexture, then set noblocking line)
|
||||
//
|
||||
|
||||
|
||||
slideframe_t slideFrames[MAXSLIDEDOORS];
|
||||
|
||||
void P_InitSlidingDoorFrames (void)
|
||||
{
|
||||
int i;
|
||||
int f1;
|
||||
int f2;
|
||||
int f3;
|
||||
int f4;
|
||||
|
||||
// DOOM II ONLY...
|
||||
if ( gamemode != commercial)
|
||||
return;
|
||||
|
||||
for (i = 0;i < MAXSLIDEDOORS; i++)
|
||||
{
|
||||
if (!slideFrameNames[i].frontFrame1[0])
|
||||
break;
|
||||
|
||||
f1 = R_TextureNumForName(slideFrameNames[i].frontFrame1);
|
||||
f2 = R_TextureNumForName(slideFrameNames[i].frontFrame2);
|
||||
f3 = R_TextureNumForName(slideFrameNames[i].frontFrame3);
|
||||
f4 = R_TextureNumForName(slideFrameNames[i].frontFrame4);
|
||||
|
||||
slideFrames[i].frontFrames[0] = f1;
|
||||
slideFrames[i].frontFrames[1] = f2;
|
||||
slideFrames[i].frontFrames[2] = f3;
|
||||
slideFrames[i].frontFrames[3] = f4;
|
||||
|
||||
f1 = R_TextureNumForName(slideFrameNames[i].backFrame1);
|
||||
f2 = R_TextureNumForName(slideFrameNames[i].backFrame2);
|
||||
f3 = R_TextureNumForName(slideFrameNames[i].backFrame3);
|
||||
f4 = R_TextureNumForName(slideFrameNames[i].backFrame4);
|
||||
|
||||
slideFrames[i].backFrames[0] = f1;
|
||||
slideFrames[i].backFrames[1] = f2;
|
||||
slideFrames[i].backFrames[2] = f3;
|
||||
slideFrames[i].backFrames[3] = f4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Return index into "slideFrames" array
|
||||
// for which door type to use
|
||||
//
|
||||
int P_FindSlidingDoorType (line_t *line)
|
||||
{
|
||||
int i;
|
||||
int val;
|
||||
|
||||
for (i = 0;i < MAXSLIDEDOORS;i++)
|
||||
{
|
||||
val = sides[line->sidenum[0]].midtexture;
|
||||
if (val == slideFrames[i].frontFrames[0])
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void T_SlidingDoor (slidedoor_t *door)
|
||||
{
|
||||
switch(door->status)
|
||||
{
|
||||
case sd_opening:
|
||||
if (!door->timer--)
|
||||
{
|
||||
if (++door->frame == SNUMFRAMES)
|
||||
{
|
||||
// IF DOOR IS DONE OPENING...
|
||||
sides[door->line->sidenum[0]].midtexture = 0;
|
||||
sides[door->line->sidenum[1]].midtexture = 0;
|
||||
door->line->flags &= ML_BLOCKING^0xff;
|
||||
|
||||
if (door->type == sdt_openOnly)
|
||||
{
|
||||
door->frontsector->specialdata = NULL;
|
||||
P_RemoveThinker (&door->thinker);
|
||||
break;
|
||||
}
|
||||
|
||||
door->timer = SDOORWAIT;
|
||||
door->status = sd_waiting;
|
||||
}
|
||||
else
|
||||
{
|
||||
// IF DOOR NEEDS TO ANIMATE TO NEXT FRAME...
|
||||
door->timer = SWAITTICS;
|
||||
|
||||
sides[door->line->sidenum[0]].midtexture =
|
||||
slideFrames[door->whichDoorIndex].
|
||||
frontFrames[door->frame];
|
||||
sides[door->line->sidenum[1]].midtexture =
|
||||
slideFrames[door->whichDoorIndex].
|
||||
backFrames[door->frame];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case sd_waiting:
|
||||
// IF DOOR IS DONE WAITING...
|
||||
if (!door->timer--)
|
||||
{
|
||||
// CAN DOOR CLOSE?
|
||||
if (door->frontsector->thinglist != NULL ||
|
||||
door->backsector->thinglist != NULL)
|
||||
{
|
||||
door->timer = SDOORWAIT;
|
||||
break;
|
||||
}
|
||||
|
||||
//door->frame = SNUMFRAMES-1;
|
||||
door->status = sd_closing;
|
||||
door->timer = SWAITTICS;
|
||||
}
|
||||
break;
|
||||
|
||||
case sd_closing:
|
||||
if (!door->timer--)
|
||||
{
|
||||
if (--door->frame < 0)
|
||||
{
|
||||
// IF DOOR IS DONE CLOSING...
|
||||
door->line->flags |= ML_BLOCKING;
|
||||
door->frontsector->specialdata = NULL;
|
||||
P_RemoveThinker (&door->thinker);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
// IF DOOR NEEDS TO ANIMATE TO NEXT FRAME...
|
||||
door->timer = SWAITTICS;
|
||||
|
||||
sides[door->line->sidenum[0]].midtexture =
|
||||
slideFrames[door->whichDoorIndex].
|
||||
frontFrames[door->frame];
|
||||
sides[door->line->sidenum[1]].midtexture =
|
||||
slideFrames[door->whichDoorIndex].
|
||||
backFrames[door->frame];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EV_SlidingDoor (line_t *line, mobj_t *thing)
|
||||
{
|
||||
sector_t* sec;
|
||||
slidedoor_t* door;
|
||||
|
||||
// DOOM II ONLY...
|
||||
if (gamemode != commercial)
|
||||
return;
|
||||
|
||||
// Make sure door isn't already being animated
|
||||
sec = line->frontsector;
|
||||
door = NULL;
|
||||
if (sec->specialdata)
|
||||
{
|
||||
if (!thing->player)
|
||||
return;
|
||||
|
||||
door = sec->specialdata;
|
||||
if (door->type == sdt_openAndClose)
|
||||
{
|
||||
if (door->status == sd_waiting)
|
||||
door->status = sd_closing;
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
// Init sliding door vars
|
||||
if (!door)
|
||||
{
|
||||
door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
|
||||
P_AddThinker (&door->thinker);
|
||||
sec->specialdata = door;
|
||||
|
||||
door->type = sdt_openAndClose;
|
||||
door->status = sd_opening;
|
||||
door->whichDoorIndex = P_FindSlidingDoorType(line);
|
||||
|
||||
if (door->whichDoorIndex < 0)
|
||||
I_Error("EV_SlidingDoor: Can't use texture for sliding door!");
|
||||
|
||||
door->frontsector = sec;
|
||||
door->backsector = line->backsector;
|
||||
door->thinker.function = T_SlidingDoor;
|
||||
door->timer = SWAITTICS;
|
||||
door->frame = 0;
|
||||
door->line = line;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
690
code/P_enemy.c
690
code/P_enemy.c
File diff suppressed because it is too large
Load diff
921
code/P_floor.c
921
code/P_floor.c
File diff suppressed because it is too large
Load diff
712
code/P_inter.c
712
code/P_inter.c
|
@ -27,7 +27,6 @@
|
|||
// Data.
|
||||
#include "doomdef.h"
|
||||
#include "dstrings.h"
|
||||
#include "sounds.h"
|
||||
|
||||
#include "doomstat.h"
|
||||
|
||||
|
@ -43,6 +42,7 @@
|
|||
#include "s_sound.h"
|
||||
|
||||
#include "p_inter.h"
|
||||
#include "p_lnspec.h"
|
||||
|
||||
|
||||
#define BONUSADD 6
|
||||
|
@ -177,8 +177,8 @@ BOOL P_GiveWeapon (player_t *player, weapontype_t weapon, BOOL dropped)
|
|||
P_GiveAmmo (player, weaponinfo[weapon].ammo, 2);
|
||||
player->pendingweapon = weapon;
|
||||
|
||||
if (player == &players[displayplayer]) // [RH] Not consoleplayer
|
||||
S_StartSound (ORIGIN_AMBIENT, sfx_wpnup);
|
||||
if (player->mo == players[consoleplayer].camera) // [RH] Use camera
|
||||
S_StartSound (ORIGIN_AMBIENT, "misc/w_pkup", 78);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -327,7 +327,7 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
|
|||
}
|
||||
|
||||
|
||||
sound = sfx_itemup;
|
||||
sound = 0;
|
||||
player = toucher->player;
|
||||
|
||||
// Dead thing touching.
|
||||
|
@ -340,13 +340,13 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
|
|||
{
|
||||
// armor
|
||||
case SPR_ARM1:
|
||||
if (!P_GiveArmor (player, deh_GreenAC))
|
||||
if (!P_GiveArmor (player, deh.GreenAC))
|
||||
return;
|
||||
player->message = GOTARMOR;
|
||||
break;
|
||||
|
||||
case SPR_ARM2:
|
||||
if (!P_GiveArmor (player, deh_BlueAC))
|
||||
if (!P_GiveArmor (player, deh.BlueAC))
|
||||
return;
|
||||
player->message = GOTMEGA;
|
||||
break;
|
||||
|
@ -354,38 +354,38 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
|
|||
// bonus items
|
||||
case SPR_BON1:
|
||||
player->health++; // can go over 100%
|
||||
if (player->health > deh_MaxSoulsphere)
|
||||
player->health = deh_MaxSoulsphere;
|
||||
if (player->health > deh.MaxSoulsphere)
|
||||
player->health = deh.MaxSoulsphere;
|
||||
player->mo->health = player->health;
|
||||
player->message = GOTHTHBONUS;
|
||||
break;
|
||||
|
||||
case SPR_BON2:
|
||||
player->armorpoints++; // can go over 100%
|
||||
if (player->armorpoints > deh_MaxArmor)
|
||||
player->armorpoints = deh_MaxArmor;
|
||||
if (player->armorpoints > deh.MaxArmor)
|
||||
player->armorpoints = deh.MaxArmor;
|
||||
if (!player->armortype)
|
||||
player->armortype = deh_GreenAC;
|
||||
player->armortype = deh.GreenAC;
|
||||
player->message = GOTARMBONUS;
|
||||
break;
|
||||
|
||||
case SPR_SOUL:
|
||||
player->health += deh_SoulsphereHealth;
|
||||
if (player->health > deh_MaxSoulsphere)
|
||||
player->health = deh_MaxSoulsphere;
|
||||
player->health += deh.SoulsphereHealth;
|
||||
if (player->health > deh.MaxSoulsphere)
|
||||
player->health = deh.MaxSoulsphere;
|
||||
player->mo->health = player->health;
|
||||
player->message = GOTSUPER;
|
||||
sound = sfx_getpow;
|
||||
sound = 1;
|
||||
break;
|
||||
|
||||
case SPR_MEGA:
|
||||
if (gamemode != commercial)
|
||||
return;
|
||||
player->health = deh_MegasphereHealth;
|
||||
player->health = deh.MegasphereHealth;
|
||||
player->mo->health = player->health;
|
||||
P_GiveArmor (player,deh_BlueAC);
|
||||
P_GiveArmor (player,deh.BlueAC);
|
||||
player->message = GOTMSPHERE;
|
||||
sound = sfx_getpow;
|
||||
sound = 1;
|
||||
break;
|
||||
|
||||
// cards
|
||||
|
@ -394,6 +394,7 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
|
|||
if (!player->cards[it_bluecard])
|
||||
player->message = GOTBLUECARD;
|
||||
P_GiveCard (player, it_bluecard);
|
||||
sound = 3;
|
||||
if (!netgame)
|
||||
break;
|
||||
return;
|
||||
|
@ -402,6 +403,7 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
|
|||
if (!player->cards[it_yellowcard])
|
||||
player->message = GOTYELWCARD;
|
||||
P_GiveCard (player, it_yellowcard);
|
||||
sound = 3;
|
||||
if (!netgame)
|
||||
break;
|
||||
return;
|
||||
|
@ -410,6 +412,7 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
|
|||
if (!player->cards[it_redcard])
|
||||
player->message = GOTREDCARD;
|
||||
P_GiveCard (player, it_redcard);
|
||||
sound = 3;
|
||||
if (!netgame)
|
||||
break;
|
||||
return;
|
||||
|
@ -418,6 +421,7 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
|
|||
if (!player->cards[it_blueskull])
|
||||
player->message = GOTBLUESKUL;
|
||||
P_GiveCard (player, it_blueskull);
|
||||
sound = 3;
|
||||
if (!netgame)
|
||||
break;
|
||||
return;
|
||||
|
@ -426,6 +430,7 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
|
|||
if (!player->cards[it_yellowskull])
|
||||
player->message = GOTYELWSKUL;
|
||||
P_GiveCard (player, it_yellowskull);
|
||||
sound = 3;
|
||||
if (!netgame)
|
||||
break;
|
||||
return;
|
||||
|
@ -434,6 +439,7 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
|
|||
if (!player->cards[it_redskull])
|
||||
player->message = GOTREDSKULL;
|
||||
P_GiveCard (player, it_redskull);
|
||||
sound = 3;
|
||||
if (!netgame)
|
||||
break;
|
||||
return;
|
||||
|
@ -461,7 +467,7 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
|
|||
if (!P_GivePower (player, pw_invulnerability))
|
||||
return;
|
||||
player->message = GOTINVUL;
|
||||
sound = sfx_getpow;
|
||||
sound = 1;
|
||||
break;
|
||||
|
||||
case SPR_PSTR:
|
||||
|
@ -470,35 +476,35 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
|
|||
player->message = GOTBERSERK;
|
||||
if (player->readyweapon != wp_fist)
|
||||
player->pendingweapon = wp_fist;
|
||||
sound = sfx_getpow;
|
||||
sound = 1;
|
||||
break;
|
||||
|
||||
case SPR_PINS:
|
||||
if (!P_GivePower (player, pw_invisibility))
|
||||
return;
|
||||
player->message = GOTINVIS;
|
||||
sound = sfx_getpow;
|
||||
sound = 1;
|
||||
break;
|
||||
|
||||
case SPR_SUIT:
|
||||
if (!P_GivePower (player, pw_ironfeet))
|
||||
return;
|
||||
player->message = GOTSUIT;
|
||||
sound = sfx_getpow;
|
||||
sound = 1;
|
||||
break;
|
||||
|
||||
case SPR_PMAP:
|
||||
if (!P_GivePower (player, pw_allmap))
|
||||
return;
|
||||
player->message = GOTMAP;
|
||||
sound = sfx_getpow;
|
||||
sound = 1;
|
||||
break;
|
||||
|
||||
case SPR_PVIS:
|
||||
if (!P_GivePower (player, pw_infrared))
|
||||
return;
|
||||
player->message = GOTVISOR;
|
||||
sound = sfx_getpow;
|
||||
sound = 1;
|
||||
break;
|
||||
|
||||
// ammo
|
||||
|
@ -575,49 +581,49 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
|
|||
if (!P_GiveWeapon (player, wp_bfg, false) )
|
||||
return;
|
||||
player->message = GOTBFG9000;
|
||||
sound = sfx_wpnup;
|
||||
sound = 2;
|
||||
break;
|
||||
|
||||
case SPR_MGUN:
|
||||
if (!P_GiveWeapon (player, wp_chaingun, special->flags&MF_DROPPED) )
|
||||
return;
|
||||
player->message = GOTCHAINGUN;
|
||||
sound = sfx_wpnup;
|
||||
sound = 2;
|
||||
break;
|
||||
|
||||
case SPR_CSAW:
|
||||
if (!P_GiveWeapon (player, wp_chainsaw, false) )
|
||||
return;
|
||||
player->message = GOTCHAINSAW;
|
||||
sound = sfx_wpnup;
|
||||
sound = 2;
|
||||
break;
|
||||
|
||||
case SPR_LAUN:
|
||||
if (!P_GiveWeapon (player, wp_missile, false) )
|
||||
return;
|
||||
player->message = GOTLAUNCHER;
|
||||
sound = sfx_wpnup;
|
||||
sound = 2;
|
||||
break;
|
||||
|
||||
case SPR_PLAS:
|
||||
if (!P_GiveWeapon (player, wp_plasma, false) )
|
||||
return;
|
||||
player->message = GOTPLASMA;
|
||||
sound = sfx_wpnup;
|
||||
sound = 2;
|
||||
break;
|
||||
|
||||
case SPR_SHOT:
|
||||
if (!P_GiveWeapon (player, wp_shotgun, special->flags&MF_DROPPED ) )
|
||||
return;
|
||||
player->message = GOTSHOTGUN;
|
||||
sound = sfx_wpnup;
|
||||
sound = 2;
|
||||
break;
|
||||
|
||||
case SPR_SGN2:
|
||||
if (!P_GiveWeapon (player, wp_supershotgun, special->flags&MF_DROPPED ) )
|
||||
return;
|
||||
player->message = GOTSHOTGUN2;
|
||||
sound = sfx_wpnup;
|
||||
sound = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -630,259 +636,329 @@ void P_TouchSpecialThing (mobj_t *special, mobj_t *toucher)
|
|||
}
|
||||
P_RemoveMobj (special);
|
||||
player->bonuscount += BONUSADD;
|
||||
if (player == &players[displayplayer]) { // [RH] Not consoleplayer
|
||||
if (sound == sfx_getpow)
|
||||
S_StartSound (ORIGIN_SURROUND3, sound);
|
||||
else
|
||||
S_StartSound (ORIGIN_AMBIENT, sound);
|
||||
if (player->mo == players[consoleplayer].camera) { // [RH] Use camera
|
||||
switch (sound) {
|
||||
case 0:
|
||||
case 3:
|
||||
S_StartSound (ORIGIN_AMBIENT, "misc/i_pkup", 78);
|
||||
break;
|
||||
case 1:
|
||||
S_StartSound (ORIGIN_SURROUND3, "misc/p_pkup", 78);
|
||||
break;
|
||||
case 2:
|
||||
S_StartSound (ORIGIN_AMBIENT, "misc/w_pkup", 78);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// [RH]
|
||||
// SexMessage: Replace parts of strings with gender-specific phrases
|
||||
//
|
||||
// The following expansions are performed:
|
||||
// %g -> he/she/it
|
||||
// %h -> him/her/it
|
||||
// %p -> his/her/its
|
||||
//
|
||||
void SexMessage (const char *from, char *to, int gender)
|
||||
{
|
||||
static const char *genderstuff[3][3] = {
|
||||
{ "he", "him", "his" },
|
||||
{ "she", "her", "her" },
|
||||
{ "it", "it", "its" }
|
||||
};
|
||||
static const int gendershift[3][3] = {
|
||||
{ 2, 3, 3 },
|
||||
{ 3, 3, 3 },
|
||||
{ 2, 2, 3 }
|
||||
};
|
||||
int gendermsg;
|
||||
|
||||
do {
|
||||
if (*from != '%') {
|
||||
*to++ = *from;
|
||||
} else {
|
||||
switch (from[1]) {
|
||||
case 'g': gendermsg = 0; break;
|
||||
case 'h': gendermsg = 1; break;
|
||||
case 'p': gendermsg = 2; break;
|
||||
default: gendermsg = -1; break;
|
||||
}
|
||||
if (gendermsg < 0) {
|
||||
*to++ = '%';
|
||||
} else {
|
||||
strcpy (to, genderstuff[gender][gendermsg]);
|
||||
to += gendershift[gender][gendermsg];
|
||||
from++;
|
||||
}
|
||||
}
|
||||
} while (*from++);
|
||||
}
|
||||
|
||||
// [RH]
|
||||
// ClientObituary: Show a message when a player dies
|
||||
//
|
||||
void ClientObituary (mobj_t *self, mobj_t *inflictor, mobj_t *attacker)
|
||||
{
|
||||
int mod;
|
||||
char *message;
|
||||
char *message2;
|
||||
BOOL friendly;
|
||||
int mod;
|
||||
char *message;
|
||||
char gendermessage[1024];
|
||||
BOOL friendly;
|
||||
int gender;
|
||||
|
||||
if (1) {
|
||||
friendly = MeansOfDeath & MOD_FRIENDLY_FIRE;
|
||||
mod = MeansOfDeath & ~MOD_FRIENDLY_FIRE;
|
||||
message = NULL;
|
||||
message2 = "";
|
||||
if (!self->player)
|
||||
return;
|
||||
|
||||
switch (mod) {
|
||||
case MOD_SUICIDE:
|
||||
message = "suicides";
|
||||
break;
|
||||
case MOD_FALLING:
|
||||
message = "fell too far";
|
||||
break;
|
||||
case MOD_CRUSH:
|
||||
message = "was squished";
|
||||
break;
|
||||
case MOD_EXIT:
|
||||
message = "tried to leave";
|
||||
break;
|
||||
case MOD_WATER:
|
||||
message = "has no gills";
|
||||
break;
|
||||
case MOD_SLIME:
|
||||
message = "mutated";
|
||||
break;
|
||||
case MOD_LAVA:
|
||||
message = "melted";
|
||||
break;
|
||||
case MOD_BARREL:
|
||||
message = "went boom";
|
||||
break;
|
||||
case MOD_SPLASH:
|
||||
message = "stood in the wrong spot";
|
||||
break;
|
||||
}
|
||||
gender = self->player->userinfo.gender;
|
||||
|
||||
if (attacker && !message) {
|
||||
if (attacker == self) {
|
||||
switch (mod) {
|
||||
case MOD_R_SPLASH:
|
||||
case MOD_ROCKET:
|
||||
message = "should have stood back";
|
||||
break;
|
||||
default:
|
||||
message = "killed himself";
|
||||
break;
|
||||
}
|
||||
} else if (!attacker->player) {
|
||||
switch (attacker->type) {
|
||||
case MT_STEALTHBABY:
|
||||
message = "thought he saw an arachnotron";
|
||||
break;
|
||||
case MT_STEALTHVILE:
|
||||
message = "thought he saw an archvile";
|
||||
break;
|
||||
case MT_STEALTHBRUISER:
|
||||
message = "thought he saw a Baron of Hell";
|
||||
break;
|
||||
case MT_STEALTHHEAD:
|
||||
message = "thought he saw a mancubus";
|
||||
break;
|
||||
case MT_STEALTHCHAINGUY:
|
||||
message = "thought he saw a chaingunner";
|
||||
break;
|
||||
case MT_STEALTHSERGEANT:
|
||||
message = "thought he saw a demon";
|
||||
break;
|
||||
case MT_STEALTHKNIGHT:
|
||||
message = "thought he saw a Hell Knight";
|
||||
break;
|
||||
case MT_STEALTHIMP:
|
||||
message = "thought he saw an imp";
|
||||
break;
|
||||
case MT_STEALTHFATSO:
|
||||
message = "thought he saw a mancubus";
|
||||
break;
|
||||
case MT_STEALTHUNDEAD:
|
||||
message = "thought he saw a revenant";
|
||||
break;
|
||||
case MT_STEALTHSHOTGUY:
|
||||
message = "thought he saw a sargeant";
|
||||
break;
|
||||
case MT_STEALTHZOMBIE:
|
||||
message = "thought he saw a zombieman";
|
||||
break;
|
||||
default:
|
||||
if (mod == MOD_HIT) {
|
||||
switch (attacker->type) {
|
||||
case MT_UNDEAD:
|
||||
message = "was punched by a revenant";
|
||||
break;
|
||||
case MT_TROOP:
|
||||
message = "was slashed by an imp";
|
||||
break;
|
||||
case MT_HEAD:
|
||||
message = "got too close to a mancubus";
|
||||
break;
|
||||
case MT_SERGEANT:
|
||||
message = "was bit by a demon";
|
||||
break;
|
||||
case MT_SHADOWS:
|
||||
message = "was eaten by a spectre";
|
||||
break;
|
||||
case MT_BRUISER:
|
||||
message = "was ripped open by a Baron of Hell";
|
||||
break;
|
||||
case MT_KNIGHT:
|
||||
message = "was gutted by a Hell Knight";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (attacker->type) {
|
||||
case MT_POSSESSED:
|
||||
message = "was killed by a zombieman";
|
||||
break;
|
||||
case MT_SHOTGUY:
|
||||
message = "was shot by a sargeant";
|
||||
break;
|
||||
case MT_VILE:
|
||||
message = "was incinerated by an archvile";
|
||||
break;
|
||||
case MT_UNDEAD:
|
||||
message = "couldn't evade a revenant's fireball";
|
||||
break;
|
||||
case MT_FATSO:
|
||||
message = "was squashed by a mancubus";
|
||||
break;
|
||||
case MT_CHAINGUY:
|
||||
message = "was perforated by a chaingunner";
|
||||
break;
|
||||
case MT_SKULL:
|
||||
message = "was spooked by a lost soul";
|
||||
break;
|
||||
case MT_TROOP:
|
||||
message = "was burned by an imp";
|
||||
break;
|
||||
case MT_HEAD:
|
||||
message = "was mesmerized by a cacodemon";
|
||||
break;
|
||||
case MT_BRUISER:
|
||||
message = "was bruised by a Baron of Hell";
|
||||
break;
|
||||
case MT_KNIGHT:
|
||||
message = "was splayed by a Hell Knight";
|
||||
break;
|
||||
case MT_SPIDER:
|
||||
message = "stood in awe of the spider mastermind";
|
||||
break;
|
||||
case MT_BABY:
|
||||
message = "let an arachnotron get him";
|
||||
break;
|
||||
case MT_CYBORG:
|
||||
message = "was splattered by a cyberdemon";
|
||||
break;
|
||||
case MT_WOLFSS:
|
||||
message = "becomes Hitler's personal slave";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (netgame && !deathmatch->value)
|
||||
MeansOfDeath |= MOD_FRIENDLY_FIRE;
|
||||
|
||||
if (message) {
|
||||
Printf ("%s %s.\n", self->player->userinfo->netname, message);
|
||||
return;
|
||||
}
|
||||
friendly = MeansOfDeath & MOD_FRIENDLY_FIRE;
|
||||
mod = MeansOfDeath & ~MOD_FRIENDLY_FIRE;
|
||||
message = NULL;
|
||||
|
||||
if (attacker && attacker->player) {
|
||||
switch (mod) {
|
||||
case MOD_SUICIDE:
|
||||
message = OB_SUICIDE;
|
||||
break;
|
||||
case MOD_FALLING:
|
||||
message = OB_FALLING;
|
||||
break;
|
||||
case MOD_CRUSH:
|
||||
message = OB_CRUSH;
|
||||
break;
|
||||
case MOD_EXIT:
|
||||
message = OB_EXIT;
|
||||
break;
|
||||
case MOD_WATER:
|
||||
message = OB_WATER;
|
||||
break;
|
||||
case MOD_SLIME:
|
||||
message = OB_SLIME;
|
||||
break;
|
||||
case MOD_LAVA:
|
||||
message = OB_LAVA;
|
||||
break;
|
||||
case MOD_BARREL:
|
||||
message = OB_BARREL;
|
||||
break;
|
||||
case MOD_SPLASH:
|
||||
message = OB_SPLASH;
|
||||
break;
|
||||
}
|
||||
|
||||
if (attacker && !message) {
|
||||
if (attacker == self) {
|
||||
switch (mod) {
|
||||
case MOD_FIST:
|
||||
message = "chewed on";
|
||||
message2 = "'s fist";
|
||||
break;
|
||||
case MOD_CHAINSAW:
|
||||
message = "was mowed over by";
|
||||
message2 = "'s chainsaw";
|
||||
break;
|
||||
case MOD_PISTOL:
|
||||
message = "was tickled by";
|
||||
break;
|
||||
case MOD_SHOTGUN:
|
||||
message = "chewed on";
|
||||
message2 = "'s boomstick";
|
||||
break;
|
||||
case MOD_SSHOTGUN:
|
||||
message = "was splattered by";
|
||||
message2 = "'s super shotgun";
|
||||
break;
|
||||
case MOD_CHAINGUN:
|
||||
message = "was mowed down by";
|
||||
case MOD_R_SPLASH:
|
||||
message = OB_R_SPLASH;
|
||||
break;
|
||||
case MOD_ROCKET:
|
||||
message = "rode";
|
||||
message2 = "'s rocket";
|
||||
message = OB_ROCKET;
|
||||
break;
|
||||
case MOD_R_SPLASH:
|
||||
message = "almost dodged";
|
||||
message2 = "'s rocket";
|
||||
break;
|
||||
case MOD_PLASMARIFLE:
|
||||
message = "was melted by";
|
||||
break;
|
||||
case MOD_BFG_BOOM:
|
||||
message = "was splintered by";
|
||||
message2 = "'s BFG";
|
||||
break;
|
||||
case MOD_BFG_SPLASH:
|
||||
message = "couldn't hide from";
|
||||
message2 = "'s BFG";
|
||||
break;
|
||||
case MOD_TELEFRAG:
|
||||
message = "was stepped on by";
|
||||
break;
|
||||
case MOD_FALLXFER:
|
||||
message = "was";
|
||||
message2 = "'s cushion";
|
||||
default:
|
||||
message = OB_KILLEDSELF;
|
||||
break;
|
||||
}
|
||||
} else if (!attacker->player) {
|
||||
switch (attacker->type) {
|
||||
case MT_STEALTHBABY:
|
||||
message = OB_STEALTHBABY;
|
||||
break;
|
||||
case MT_STEALTHVILE:
|
||||
message = OB_STEALTHVILE;
|
||||
break;
|
||||
case MT_STEALTHBRUISER:
|
||||
message = OB_STEALTHBARON;
|
||||
break;
|
||||
case MT_STEALTHHEAD:
|
||||
message = OB_STEALTHCACO;
|
||||
break;
|
||||
case MT_STEALTHCHAINGUY:
|
||||
message = OB_STEALTHCHAINGUY;
|
||||
break;
|
||||
case MT_STEALTHSERGEANT:
|
||||
message = OB_STEALTHDEMON;
|
||||
break;
|
||||
case MT_STEALTHKNIGHT:
|
||||
message = OB_STEALTHKNIGHT;
|
||||
break;
|
||||
case MT_STEALTHIMP:
|
||||
message = OB_STEALTHIMP;
|
||||
break;
|
||||
case MT_STEALTHFATSO:
|
||||
message = OB_STEALTHFATSO;
|
||||
break;
|
||||
case MT_STEALTHUNDEAD:
|
||||
message = OB_STEALTHUNDEAD;
|
||||
break;
|
||||
case MT_STEALTHSHOTGUY:
|
||||
message = OB_STEALTHSHOTGUY;
|
||||
break;
|
||||
case MT_STEALTHZOMBIE:
|
||||
message = OB_STEALTHZOMBIE;
|
||||
break;
|
||||
default:
|
||||
if (mod == MOD_HIT) {
|
||||
switch (attacker->type) {
|
||||
case MT_UNDEAD:
|
||||
message = OB_UNDEADHIT;
|
||||
break;
|
||||
case MT_TROOP:
|
||||
message = OB_IMPHIT;
|
||||
break;
|
||||
case MT_HEAD:
|
||||
message = OB_CACOHIT;
|
||||
break;
|
||||
case MT_SERGEANT:
|
||||
message = OB_DEMONHIT;
|
||||
break;
|
||||
case MT_SHADOWS:
|
||||
message = OB_SPECTREHIT;
|
||||
break;
|
||||
case MT_BRUISER:
|
||||
message = OB_BARONHIT;
|
||||
break;
|
||||
case MT_KNIGHT:
|
||||
message = OB_KNIGHTHIT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (attacker->type) {
|
||||
case MT_POSSESSED:
|
||||
message = OB_ZOMBIE;
|
||||
break;
|
||||
case MT_SHOTGUY:
|
||||
message = OB_SHOTGUY;
|
||||
break;
|
||||
case MT_VILE:
|
||||
message = OB_VILE;
|
||||
break;
|
||||
case MT_UNDEAD:
|
||||
message = OB_UNDEAD;
|
||||
break;
|
||||
case MT_FATSO:
|
||||
message = OB_FATSO;
|
||||
break;
|
||||
case MT_CHAINGUY:
|
||||
message = OB_CHAINGUY;
|
||||
break;
|
||||
case MT_SKULL:
|
||||
message = OB_SKULL;
|
||||
break;
|
||||
case MT_TROOP:
|
||||
message = OB_IMP;
|
||||
break;
|
||||
case MT_HEAD:
|
||||
message = OB_CACO;
|
||||
break;
|
||||
case MT_BRUISER:
|
||||
message = OB_BARON;
|
||||
break;
|
||||
case MT_KNIGHT:
|
||||
message = OB_KNIGHT;
|
||||
break;
|
||||
case MT_SPIDER:
|
||||
message = OB_SPIDER;
|
||||
break;
|
||||
case MT_BABY:
|
||||
message = OB_BABY;
|
||||
break;
|
||||
case MT_CYBORG:
|
||||
message = OB_CYBORG;
|
||||
break;
|
||||
case MT_WOLFSS:
|
||||
message = OB_WOLFSS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (message) {
|
||||
Printf ("%s %s %s%s\n", self->player->userinfo->netname, message,
|
||||
attacker->player->userinfo->netname, message2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Printf ("%s died.\n", self->player->userinfo->netname);
|
||||
if (message) {
|
||||
SexMessage (message, gendermessage, gender);
|
||||
Printf ("%s %s.\n", self->player->userinfo.netname, gendermessage);
|
||||
return;
|
||||
}
|
||||
|
||||
if (attacker && attacker->player) {
|
||||
if (friendly) {
|
||||
int rnum = P_Random (pr_obituary);
|
||||
|
||||
attacker->player->fragcount -= 2;
|
||||
attacker->player->frags[attacker->player-players]++;
|
||||
self = attacker;
|
||||
|
||||
if (rnum < 64)
|
||||
message = OB_FRIENDLY1;
|
||||
else if (rnum < 128)
|
||||
message = OB_FRIENDLY2;
|
||||
else if (rnum < 192)
|
||||
message = OB_FRIENDLY3;
|
||||
else
|
||||
message = OB_FRIENDLY4;
|
||||
} else {
|
||||
switch (mod) {
|
||||
case MOD_FIST:
|
||||
message = OB_MPFIST;
|
||||
break;
|
||||
case MOD_CHAINSAW:
|
||||
message = OB_MPCHAINSAW;
|
||||
break;
|
||||
case MOD_PISTOL:
|
||||
message = OB_MPPISTOL;
|
||||
break;
|
||||
case MOD_SHOTGUN:
|
||||
message = OB_MPSHOTGUN;
|
||||
break;
|
||||
case MOD_SSHOTGUN:
|
||||
message = OB_MPSSHOTGUN;
|
||||
break;
|
||||
case MOD_CHAINGUN:
|
||||
message = OB_MPCHAINGUN;
|
||||
break;
|
||||
case MOD_ROCKET:
|
||||
message = OB_MPROCKET;
|
||||
break;
|
||||
case MOD_R_SPLASH:
|
||||
message = OB_MPR_SPLASH;
|
||||
break;
|
||||
case MOD_PLASMARIFLE:
|
||||
message = OB_MPPLASMARIFLE;
|
||||
break;
|
||||
case MOD_BFG_BOOM:
|
||||
message = OB_MPBFG_BOOM;
|
||||
break;
|
||||
case MOD_BFG_SPLASH:
|
||||
message = OB_MPBFG_SPLASH;
|
||||
break;
|
||||
case MOD_TELEFRAG:
|
||||
message = OB_MPTELEFRAG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (message) {
|
||||
char work[256];
|
||||
|
||||
SexMessage (message, gendermessage, gender);
|
||||
sprintf (work, "%%s %s\n", gendermessage);
|
||||
Printf (work, self->player->userinfo.netname,
|
||||
attacker->player->userinfo.netname);
|
||||
return;
|
||||
}
|
||||
|
||||
SexMessage (OB_DEFAULT, gendermessage, gender);
|
||||
Printf ("%s %s.\n", self->player->userinfo.netname, gendermessage);
|
||||
}
|
||||
|
||||
|
||||
|
@ -904,6 +980,18 @@ void P_KillMobj (mobj_t *source, mobj_t *target, mobj_t *inflictor)
|
|||
target->flags |= MF_CORPSE|MF_DROPOFF;
|
||||
target->height >>= 2;
|
||||
|
||||
// [RH] If the thing has a special, execute and remove it
|
||||
// Note that the thing that killed it is considered
|
||||
// the activator of the script.
|
||||
if (target->special) {
|
||||
LineSpecials[target->special] (NULL, source, target->args[0],
|
||||
target->args[1], target->args[2],
|
||||
target->args[3], target->args[4]);
|
||||
target->special = 0;
|
||||
}
|
||||
// [RH] Also set the thing's tid to 0.
|
||||
target->tid = 0;
|
||||
|
||||
if (source && source->player)
|
||||
{
|
||||
// count for intermission
|
||||
|
@ -912,7 +1000,10 @@ void P_KillMobj (mobj_t *source, mobj_t *target, mobj_t *inflictor)
|
|||
level.killed_monsters++;
|
||||
}
|
||||
|
||||
if (target->player) {
|
||||
// Don't count any frags at level start, because they're just telefrags
|
||||
// resulting from insufficient deathmatch starts, and it wouldn't be
|
||||
// fair to count them toward a player's score.
|
||||
if (target->player && level.time) {
|
||||
source->player->frags[target->player-players]++;
|
||||
if (target->player == source->player) // [RH] Cumulative frag count
|
||||
source->player->fragcount--;
|
||||
|
@ -922,8 +1013,8 @@ void P_KillMobj (mobj_t *source, mobj_t *target, mobj_t *inflictor)
|
|||
// [RH] Implement fraglimit
|
||||
if (deathmatch->value && fraglimit->value &&
|
||||
(int)fraglimit->value == source->player->fragcount) {
|
||||
Printf ("%s got %d frags.\n", source->player->userinfo->netname, source->player->fragcount);
|
||||
G_ExitLevel ();
|
||||
Printf ("Fraglimit hit.\n");
|
||||
G_ExitLevel (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -973,10 +1064,8 @@ void P_KillMobj (mobj_t *source, mobj_t *target, mobj_t *inflictor)
|
|||
if (target->tics < 1)
|
||||
target->tics = 1;
|
||||
|
||||
// I_StartSound (&actor->r, actor->info->deathsound);
|
||||
|
||||
// [RH] Death messages
|
||||
if (target->player)
|
||||
if (target->player && level.time && !olddemo)
|
||||
ClientObituary (target, inflictor, source);
|
||||
|
||||
// Drop stuff.
|
||||
|
@ -1003,7 +1092,6 @@ void P_KillMobj (mobj_t *source, mobj_t *target, mobj_t *inflictor)
|
|||
|
||||
mo = P_SpawnMobj (target->x,target->y,0, item, ONFLOORZ);
|
||||
mo->flags |= MF_DROPPED; // special versions of items
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1052,7 +1140,6 @@ void P_DamageMobj (mobj_t *target, mobj_t *inflictor, mobj_t *source, int damage
|
|||
player = target->player;
|
||||
if (player && gameskill->value == 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,
|
||||
|
@ -1079,22 +1166,21 @@ void P_DamageMobj (mobj_t *target, mobj_t *inflictor, mobj_t *source, int damage
|
|||
ang += ANG180;
|
||||
thrust *= 4;
|
||||
}
|
||||
|
||||
|
||||
ang >>= ANGLETOFINESHIFT;
|
||||
target->momx += FixedMul (thrust, finecosine[ang]);
|
||||
target->momy += FixedMul (thrust, finesine[ang]);
|
||||
}
|
||||
|
||||
|
||||
// player specific
|
||||
if (player)
|
||||
{
|
||||
// end of game hell hack
|
||||
if (target->subsector->sector->special == 11
|
||||
if (target->subsector->sector->special & 255 == dDamage_End
|
||||
&& damage >= target->health)
|
||||
{
|
||||
damage = target->health - 1;
|
||||
}
|
||||
|
||||
|
||||
// Below certain threshold,
|
||||
// ignore damage in GOD mode, or with INVUL power.
|
||||
|
@ -1104,10 +1190,20 @@ void P_DamageMobj (mobj_t *target, mobj_t *inflictor, mobj_t *source, int damage
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// [RH] Avoid friendly fire if enabled
|
||||
if (teamplay->value && source && source->player &&
|
||||
source->player->userinfo.team[0] &&
|
||||
!stricmp (player->userinfo.team, source->player->userinfo.team)) {
|
||||
if (dmflags & DF_NO_FRIENDLY_FIRE)
|
||||
return;
|
||||
else
|
||||
MeansOfDeath |= MOD_FRIENDLY_FIRE;
|
||||
}
|
||||
|
||||
if (player->armortype)
|
||||
{
|
||||
if (player->armortype == deh_GreenAC)
|
||||
if (player->armortype == deh.GreenAC)
|
||||
saved = damage/3;
|
||||
else
|
||||
saved = damage/2;
|
||||
|
@ -1137,37 +1233,49 @@ void P_DamageMobj (mobj_t *target, mobj_t *inflictor, mobj_t *source, int damage
|
|||
I_Tactile (40,10,40+temp*2);
|
||||
}
|
||||
|
||||
// do the damage
|
||||
target->health -= damage;
|
||||
if (target->health <= 0)
|
||||
{
|
||||
P_KillMobj (source, target, inflictor);
|
||||
return;
|
||||
// do the damage
|
||||
// [RH] Only if not immune
|
||||
if (!(target->flags2 & (MF2_INVULNERABLE | MF2_INDESTRUCTABLE))) {
|
||||
target->health -= damage;
|
||||
if (target->health <= 0)
|
||||
{
|
||||
P_KillMobj (source, target, inflictor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( (P_Random (pr_damagemobj) < target->info->painchance)
|
||||
&& !(target->flags&MF_SKULLFLY) )
|
||||
{
|
||||
target->flags |= MF_JUSTHIT; // fight back!
|
||||
|
||||
P_SetMobjState (target, target->info->painstate);
|
||||
}
|
||||
|
||||
target->reactiontime = 0; // we're awake now...
|
||||
if (!(target->flags2 & MF2_DORMANT)) {
|
||||
// [RH] Only react if not dormant
|
||||
if ( (P_Random (pr_damagemobj) < target->info->painchance)
|
||||
&& !(target->flags&MF_SKULLFLY) )
|
||||
{
|
||||
target->flags |= MF_JUSTHIT; // fight back!
|
||||
|
||||
P_SetMobjState (target, target->info->painstate);
|
||||
}
|
||||
|
||||
target->reactiontime = 0; // we're awake now...
|
||||
|
||||
if ( (!target->threshold || target->type == MT_VILE)
|
||||
&& source && source != target
|
||||
&& source->type != MT_VILE)
|
||||
{
|
||||
// if not intent on another player,
|
||||
// chase after this one
|
||||
target->target = source;
|
||||
target->threshold = BASETHRESHOLD;
|
||||
if (target->state == &states[target->info->spawnstate]
|
||||
&& target->info->seestate != S_NULL)
|
||||
P_SetMobjState (target, target->info->seestate);
|
||||
if ( (!target->threshold || target->type == MT_VILE)
|
||||
&& source && source != target
|
||||
&& source->type != MT_VILE)
|
||||
{
|
||||
// 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
|
||||
|
||||
if (!target->lastenemy || !target->lastenemy->player ||
|
||||
target->lastenemy->health <= 0)
|
||||
target->lastenemy = target->target; // remember last enemy - killough
|
||||
|
||||
target->target = source;
|
||||
target->threshold = BASETHRESHOLD;
|
||||
if (target->state == &states[target->info->spawnstate]
|
||||
&& target->info->seestate != S_NULL)
|
||||
P_SetMobjState (target, target->info->seestate);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOL CheckCheatmode (void);
|
||||
|
|
530
code/P_lights.c
Normal file
530
code/P_lights.c
Normal file
|
@ -0,0 +1,530 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// $Log:$
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Handle Sector base lighting effects.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "z_zone.h"
|
||||
#include "m_random.h"
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
|
||||
#include "p_lnspec.h"
|
||||
|
||||
// State.
|
||||
#include "r_state.h"
|
||||
|
||||
// [RH] These functions only change the sector special in
|
||||
// demo compatibility mode.
|
||||
extern BOOL olddemo;
|
||||
|
||||
// [RH] Make sure the light level is in bounds.
|
||||
#define CLIPLIGHT(l) (((l) < 0) ? 0 : (((l) > 255) ? 255 : (l)))
|
||||
|
||||
//
|
||||
// FIRELIGHT FLICKER
|
||||
//
|
||||
|
||||
//
|
||||
// T_FireFlicker
|
||||
//
|
||||
void T_FireFlicker (fireflicker_t *flick)
|
||||
{
|
||||
int amount;
|
||||
|
||||
if (--flick->count)
|
||||
return;
|
||||
|
||||
amount = (P_Random (pr_fireflicker) & 3) << 4;
|
||||
|
||||
if (flick->sector->lightlevel - amount < flick->minlight)
|
||||
flick->sector->lightlevel = (short)flick->minlight;
|
||||
else
|
||||
flick->sector->lightlevel = (short)(flick->maxlight - amount);
|
||||
|
||||
flick->count = 4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// P_SpawnFireFlicker
|
||||
//
|
||||
void P_SpawnFireFlicker (sector_t *sector)
|
||||
{
|
||||
fireflicker_t *flick;
|
||||
|
||||
if (olddemo)
|
||||
sector->special &= 0xff00;
|
||||
|
||||
flick = Z_Malloc ( sizeof(*flick), PU_LEVSPEC, 0);
|
||||
|
||||
P_AddThinker (&flick->thinker);
|
||||
|
||||
flick->thinker.function.acp1 = (actionf_p1) T_FireFlicker;
|
||||
flick->sector = sector;
|
||||
flick->maxlight = sector->lightlevel;
|
||||
flick->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel)+16;
|
||||
flick->count = 4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// BROKEN LIGHT FLASHING
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// T_LightFlash
|
||||
// Do flashing lights.
|
||||
//
|
||||
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_lightflash) & flash->mintime) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
flash-> sector->lightlevel = flash->maxlight;
|
||||
flash->count = (P_Random (pr_lightflash) & flash->maxtime) + 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// P_SpawnLightFlash
|
||||
// [RH] Added min and max parameters
|
||||
//
|
||||
void P_SpawnLightFlash (sector_t *sector, int min, int max)
|
||||
{
|
||||
lightflash_t *flash;
|
||||
|
||||
if (olddemo)
|
||||
sector->special &= 0xff00;
|
||||
|
||||
flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
|
||||
|
||||
P_AddThinker (&flash->thinker);
|
||||
|
||||
flash->thinker.function.acp1 = (actionf_p1) T_LightFlash;
|
||||
flash->sector = sector;
|
||||
if (min < 0) {
|
||||
// If min is negative, find light levels like Doom.
|
||||
flash->maxlight = sector->lightlevel;
|
||||
flash->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel);
|
||||
} else {
|
||||
// Otherwise, use the ones provided.
|
||||
flash->maxlight = CLIPLIGHT(max);
|
||||
flash->minlight = CLIPLIGHT(min);
|
||||
}
|
||||
flash->maxtime = 64;
|
||||
flash->mintime = 7;
|
||||
flash->count = (P_Random (pr_spawnlightflash) & flash->maxtime) + 1;
|
||||
}
|
||||
|
||||
// [RH] New function to start light flashing on-demand.
|
||||
void EV_StartLightFlashing (int tag, int upper, int lower)
|
||||
{
|
||||
int secnum;
|
||||
|
||||
secnum = -1;
|
||||
while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
|
||||
{
|
||||
sector_t *sec = §ors[secnum];
|
||||
if (P_SectorActive (lighting_special, sec))
|
||||
continue;
|
||||
|
||||
P_SpawnLightFlash (sec, lower, upper);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// STROBE LIGHT FLASHING
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// T_StrobeFlash
|
||||
//
|
||||
void T_StrobeFlash (strobe_t *flash)
|
||||
{
|
||||
if (--flash->count)
|
||||
return;
|
||||
|
||||
if (flash->sector->lightlevel == flash->minlight)
|
||||
{
|
||||
flash-> sector->lightlevel = (short)flash->maxlight;
|
||||
flash->count = flash->brighttime;
|
||||
}
|
||||
else
|
||||
{
|
||||
flash-> sector->lightlevel = (short)flash->minlight;
|
||||
flash->count = flash->darktime;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// P_SpawnStrobeFlash
|
||||
// After the map has been loaded, scan each sector
|
||||
// for specials that spawn thinkers
|
||||
// [RH] brighttime is also adjustable
|
||||
//
|
||||
void P_SpawnStrobeFlash (sector_t *sector, int upper, int lower,
|
||||
int utics, int ltics, int inSync)
|
||||
{
|
||||
strobe_t *flash;
|
||||
|
||||
flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
|
||||
|
||||
P_AddThinker (&flash->thinker);
|
||||
|
||||
flash->sector = sector;
|
||||
flash->darktime = ltics;
|
||||
flash->brighttime = utics;
|
||||
flash->thinker.function.acp1 = (actionf_p1) T_StrobeFlash;
|
||||
|
||||
// [RH] If the upper light level is -1, we use Doom's mechanism
|
||||
// for setting this up. Otherwise, we use Hexen's.
|
||||
if (upper < 0) {
|
||||
flash->maxlight = sector->lightlevel;
|
||||
flash->minlight = P_FindMinSurroundingLight(sector, sector->lightlevel);
|
||||
|
||||
if (flash->minlight == flash->maxlight)
|
||||
flash->minlight = 0;
|
||||
|
||||
flash->count = inSync ? 1 : (P_Random (pr_spawnstrobeflash) & 7) + 1;
|
||||
} else {
|
||||
flash->maxlight = CLIPLIGHT(upper);
|
||||
flash->minlight = CLIPLIGHT(lower);
|
||||
flash->count = 1; // Hexen-style is always in sync.
|
||||
}
|
||||
if (olddemo)
|
||||
sector->special &= 0xff00;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Start strobing lights (usually from a trigger)
|
||||
// [RH] Made it more configurable.
|
||||
//
|
||||
void EV_StartLightStrobing (int tag, int upper, int lower, int utics, int ltics)
|
||||
{
|
||||
int secnum;
|
||||
|
||||
secnum = -1;
|
||||
while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
|
||||
{
|
||||
sector_t *sec = §ors[secnum];
|
||||
if (P_SectorActive (lighting_special, sec)) //jff 2/22/98
|
||||
continue;
|
||||
|
||||
P_SpawnStrobeFlash (sec, upper, lower, utics, ltics, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// TURN LINE'S TAG LIGHTS OFF
|
||||
// [RH] Takes a tag instead of a line
|
||||
//
|
||||
void EV_TurnTagLightsOff (int tag)
|
||||
{
|
||||
int i;
|
||||
int secnum;
|
||||
|
||||
// [RH] Don't do a linear search
|
||||
for (secnum = -1; (secnum = P_FindSectorFromTag (tag, secnum)) >= 0; )
|
||||
{
|
||||
sector_t *sector = sectors + secnum;
|
||||
int min = sector->lightlevel;
|
||||
|
||||
for (i = 0; i < sector->linecount; i++)
|
||||
{
|
||||
sector_t *tsec = getNextSector (sector->lines[i],sector);
|
||||
if (!tsec)
|
||||
continue;
|
||||
if (tsec->lightlevel < min)
|
||||
min = tsec->lightlevel;
|
||||
}
|
||||
sector->lightlevel = min;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// TURN LINE'S TAG LIGHTS ON
|
||||
// [RH] Takes a tag instead of a line
|
||||
//
|
||||
void EV_LightTurnOn (int tag, int bright)
|
||||
{
|
||||
int secnum = -1;
|
||||
|
||||
// [RH] Don't do a linear search
|
||||
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
|
||||
{
|
||||
sector_t *sector = sectors + secnum;
|
||||
|
||||
// bright = -1 means to search ([RH] Not 0)
|
||||
// for highest light level
|
||||
// surrounding sector
|
||||
if (bright < 0)
|
||||
{
|
||||
int j;
|
||||
|
||||
bright = 0;
|
||||
for (j = 0; j < sector->linecount; j++)
|
||||
{
|
||||
sector_t *temp = getNextSector (sector->lines[j], sector);
|
||||
|
||||
if (!temp)
|
||||
continue;
|
||||
|
||||
if (temp->lightlevel > bright)
|
||||
bright = temp->lightlevel;
|
||||
}
|
||||
}
|
||||
sector->lightlevel = CLIPLIGHT(bright);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// [RH] New function to adjust tagged sectors' light levels
|
||||
// by a relative amount. Light levels are clipped to
|
||||
// within the range 0-255 inclusive.
|
||||
//
|
||||
void EV_LightChange (int tag, int value)
|
||||
{
|
||||
int secnum = -1;
|
||||
|
||||
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) {
|
||||
int newlight = sectors[secnum].lightlevel + value;
|
||||
sectors[secnum].lightlevel = CLIPLIGHT(newlight);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Spawn glowing light
|
||||
//
|
||||
|
||||
void T_Glow (glow_t *g)
|
||||
{
|
||||
switch(g->direction)
|
||||
{
|
||||
case -1:
|
||||
// DOWN
|
||||
g->sector->lightlevel -= GLOWSPEED;
|
||||
if (g->sector->lightlevel <= g->minlight)
|
||||
{
|
||||
g->sector->lightlevel += GLOWSPEED;
|
||||
g->direction = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// UP
|
||||
g->sector->lightlevel += GLOWSPEED;
|
||||
if (g->sector->lightlevel >= g->maxlight)
|
||||
{
|
||||
g->sector->lightlevel -= GLOWSPEED;
|
||||
g->direction = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void P_SpawnGlowingLight (sector_t *sector)
|
||||
{
|
||||
glow_t *g;
|
||||
|
||||
g = Z_Malloc( sizeof(*g), PU_LEVSPEC, 0);
|
||||
|
||||
P_AddThinker(&g->thinker);
|
||||
|
||||
g->sector = sector;
|
||||
g->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel);
|
||||
g->maxlight = sector->lightlevel;
|
||||
g->thinker.function.acp1 = (actionf_p1) T_Glow;
|
||||
g->direction = -1;
|
||||
|
||||
if (olddemo)
|
||||
sector->special &= 0xff00;
|
||||
}
|
||||
|
||||
//
|
||||
// [RH] More glowing light, this time appropriate for Hexen-ish uses.
|
||||
//
|
||||
void T_Glow2 (glow2_t *g)
|
||||
{
|
||||
if (g->tics++ >= g->maxtics) {
|
||||
if (g->oneshot) {
|
||||
g->sector->lightlevel = g->end;
|
||||
P_RemoveThinker (&g->thinker);
|
||||
return;
|
||||
} else {
|
||||
int temp = g->start;
|
||||
g->start = g->end;
|
||||
g->end = temp;
|
||||
g->tics -= g->maxtics;
|
||||
}
|
||||
}
|
||||
|
||||
g->sector->lightlevel = ((g->end - g->start) * g->tics) / g->maxtics + g->start;
|
||||
}
|
||||
|
||||
|
||||
static void P_SpawnGlowingLight2 (sector_t *sector, int start, int end,
|
||||
int tics, BOOL oneshot)
|
||||
{
|
||||
glow2_t *g;
|
||||
|
||||
g = Z_Malloc( sizeof(*g), PU_LEVSPEC, 0);
|
||||
|
||||
P_AddThinker(&g->thinker);
|
||||
|
||||
g->sector = sector;
|
||||
g->start = CLIPLIGHT(start);
|
||||
g->end = CLIPLIGHT(end);
|
||||
g->maxtics = tics;
|
||||
g->tics = -1;
|
||||
g->oneshot = oneshot;
|
||||
g->thinker.function.acp1 = (actionf_p1) T_Glow2;
|
||||
}
|
||||
|
||||
void EV_StartLightGlowing (int tag, int upper, int lower, int tics)
|
||||
{
|
||||
int secnum;
|
||||
|
||||
if (upper < lower) {
|
||||
int temp = upper;
|
||||
upper = lower;
|
||||
lower = temp;
|
||||
}
|
||||
|
||||
secnum = -1;
|
||||
while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
|
||||
{
|
||||
sector_t *sec = §ors[secnum];
|
||||
if (P_SectorActive (lighting_special, sec))
|
||||
continue;
|
||||
|
||||
P_SpawnGlowingLight2 (sec, upper, lower, tics, false);
|
||||
}
|
||||
}
|
||||
|
||||
void EV_StartLightFading (int tag, int value, int tics)
|
||||
{
|
||||
int secnum;
|
||||
|
||||
secnum = -1;
|
||||
while ((secnum = P_FindSectorFromTag (tag,secnum)) >= 0)
|
||||
{
|
||||
sector_t *sec = §ors[secnum];
|
||||
if (P_SectorActive (lighting_special, sec))
|
||||
continue;
|
||||
|
||||
// No need to fade if lightlevel is already at desired value.
|
||||
if (sec->lightlevel == value)
|
||||
continue;
|
||||
|
||||
P_SpawnGlowingLight2 (sec, sec->lightlevel, value, tics, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// [RH] Phased lighting ala Hexen
|
||||
void T_PhasedLight (phased_t *l)
|
||||
{
|
||||
const int steps = 12;
|
||||
|
||||
if (l->phase < steps) {
|
||||
l->sector->lightlevel = ((255 - l->baselevel) * l->phase) / steps + l->baselevel;
|
||||
} else if (l->phase < 2*steps) {
|
||||
l->sector->lightlevel = ((255 - l->baselevel) * (2*steps - l->phase - 1) / steps
|
||||
+ l->baselevel);
|
||||
} else {
|
||||
l->sector->lightlevel = l->baselevel;
|
||||
}
|
||||
|
||||
if (l->phase-- == 0)
|
||||
l->phase = 63;
|
||||
}
|
||||
|
||||
static int phasehelper (sector_t *sector, int index, int light, sector_t *prev)
|
||||
{
|
||||
if (!sector) {
|
||||
return index;
|
||||
} else {
|
||||
phased_t *l = Z_Malloc (sizeof(*l), PU_LEVSPEC, 0);
|
||||
int numsteps;
|
||||
|
||||
l->sector = sector;
|
||||
l->baselevel = sector->lightlevel ? sector->lightlevel : light;
|
||||
numsteps = phasehelper (P_NextSpecialSector (sector,
|
||||
(sector->special & 0x00ff) == LightSequenceSpecial1 ?
|
||||
LightSequenceSpecial2 : LightSequenceSpecial1, prev),
|
||||
index + 1, l->baselevel, sector);
|
||||
l->phase = ((numsteps - index - 1) * 64) / numsteps;
|
||||
l->thinker.function.acp1 = (actionf_p1) T_PhasedLight;
|
||||
|
||||
P_AddThinker (&l->thinker);
|
||||
|
||||
sector->special &= 0xff00;
|
||||
|
||||
return numsteps;
|
||||
}
|
||||
}
|
||||
|
||||
void P_SpawnLightSequence (sector_t *sector)
|
||||
{
|
||||
phasehelper (sector, 0, 0, NULL);
|
||||
}
|
||||
|
||||
void P_SpawnLightPhased (sector_t *sector)
|
||||
{
|
||||
phased_t *l = Z_Malloc (sizeof(*l), PU_LEVSPEC, 0);
|
||||
|
||||
l->sector = sector;
|
||||
l->baselevel = 48;
|
||||
l->phase = 63 - (sector->lightlevel & 63);
|
||||
l->thinker.function.acp1 = (actionf_p1) T_PhasedLight;
|
||||
P_AddThinker (&l->thinker);
|
||||
|
||||
sector->special &= 0xff00;
|
||||
}
|
1362
code/P_lnspec.c
Normal file
1362
code/P_lnspec.c
Normal file
File diff suppressed because it is too large
Load diff
293
code/P_lnspec.h
Normal file
293
code/P_lnspec.h
Normal file
|
@ -0,0 +1,293 @@
|
|||
// p_lnspec.h: New line and sector specials (Using Hexen as a base.)
|
||||
|
||||
#ifndef __P_LNSPEC_H__
|
||||
#define __P_LNSPEC_H__
|
||||
|
||||
#include "doomtype.h"
|
||||
|
||||
typedef enum {
|
||||
Polyobj_StartLine = 1,
|
||||
Polyobj_RotateLeft = 2,
|
||||
Polyobj_RotateRight = 3,
|
||||
Polyobj_Move = 4,
|
||||
Polyobj_ExplicitLine = 5,
|
||||
Polyobj_MoveTimes8 = 6,
|
||||
Polyobj_DoorSwing = 7,
|
||||
Polyobj_DoorSlide = 8,
|
||||
|
||||
Door_Close = 10,
|
||||
Door_Open = 11,
|
||||
Door_Raise = 12,
|
||||
Door_LockedRaise = 13,
|
||||
|
||||
Floor_LowerByValue = 20,
|
||||
Floor_LowerToLowest = 21,
|
||||
Floor_LowerToNearest = 22,
|
||||
Floor_RaiseByValue = 23,
|
||||
Floor_RaiseToHighest = 24,
|
||||
Floor_RaiseToNearest = 25,
|
||||
|
||||
Stairs_BuildDown = 26,
|
||||
Stairs_BuildUp = 27,
|
||||
|
||||
Floor_RaiseAndCrush = 28,
|
||||
|
||||
Pillar_Build = 29,
|
||||
Pillar_Open = 30,
|
||||
|
||||
Stairs_BuildDownSync = 31,
|
||||
Stairs_BuildUpSync = 32,
|
||||
|
||||
Floor_RaiseByValueTimes8 = 35,
|
||||
Floor_LowerByValueTimes8 = 36,
|
||||
|
||||
Ceiling_LowerByValue = 40,
|
||||
Ceiling_RaiseByValue = 41,
|
||||
Ceiling_CrushAndRaise = 42,
|
||||
Ceiling_LowerAndCrush = 43,
|
||||
Ceiling_CrushStop = 44,
|
||||
Ceiling_CrushRaiseAndStay = 45,
|
||||
|
||||
Floor_CrushStop = 46,
|
||||
|
||||
Plat_PerpetualRaise = 60,
|
||||
Plat_Stop = 61,
|
||||
Plat_DownWaitUpStay = 62,
|
||||
Plat_DownByValue = 63,
|
||||
Plat_UpWaitDownStay = 64,
|
||||
Plat_UpByValue = 65,
|
||||
|
||||
Floor_LowerInstant = 66,
|
||||
Floor_RaiseInstant = 67,
|
||||
Floor_MoveToValueTimes8 = 68,
|
||||
|
||||
Ceiling_MoveToValueTimes8 = 69,
|
||||
|
||||
Teleport = 70,
|
||||
Teleport_NoFog = 71,
|
||||
|
||||
ThrustThing = 72,
|
||||
DamageThing = 73,
|
||||
|
||||
Teleport_NewMap = 74,
|
||||
Teleport_EndGame = 75,
|
||||
|
||||
ACS_Execute = 80,
|
||||
ACS_Suspend = 81,
|
||||
ACS_Terminate = 82,
|
||||
ACS_LockedExecute = 83,
|
||||
|
||||
Polyobj_OR_RotateLeft = 90,
|
||||
Polyobj_OR_RotateRight = 91,
|
||||
Polyobj_OR_Move = 92,
|
||||
Polyobj_OR_MoveTimes8 = 93,
|
||||
|
||||
Pillar_BuildAndCrush = 94,
|
||||
|
||||
FloorAndCeiling_LowerByValue = 95,
|
||||
FloorAndCeiling_RaiseByValue = 96,
|
||||
|
||||
Scroll_Texture_Left = 100,
|
||||
Scroll_Texture_Right = 101,
|
||||
Scroll_Texture_Up = 102,
|
||||
Scroll_Texture_Down = 103,
|
||||
|
||||
Light_ForceLightning = 109,
|
||||
Light_RaiseByValue = 110,
|
||||
Light_LowerByValue = 111,
|
||||
Light_ChangeToValue = 112,
|
||||
Light_Fade = 113,
|
||||
Light_Glow = 114,
|
||||
Light_Flicker = 115,
|
||||
Light_Strobe = 116,
|
||||
|
||||
Radius_Quake = 120, // Earthquake
|
||||
|
||||
Line_SetIdentification = 121,
|
||||
|
||||
UsePuzzleItem = 129,
|
||||
|
||||
Thing_Activate = 130,
|
||||
Thing_Deactivate = 131,
|
||||
Thing_Remove = 132,
|
||||
Thing_Destroy = 133,
|
||||
Thing_Projectile = 134,
|
||||
Thing_Spawn = 135,
|
||||
Thing_ProjectileGravity = 136,
|
||||
Thing_SpawnNoFog = 137,
|
||||
|
||||
Floor_Waggle = 138,
|
||||
|
||||
Sector_ChangeSound = 140,
|
||||
|
||||
// [RH] Begin new specials for ZDoom
|
||||
|
||||
Ceiling_LowerToHighestFloor = 192,
|
||||
Ceiling_LowerInstant = 193,
|
||||
Ceiling_RaiseInstant = 194,
|
||||
Ceiling_CrushRaiseAndStayA = 195,
|
||||
Ceiling_CrushAndRaiseA = 196,
|
||||
Ceiling_CrushAndRaiseSilentA = 197,
|
||||
Ceiling_RaiseByValueTimes8 = 198,
|
||||
Ceiling_LowerByValueTimes8 = 199,
|
||||
|
||||
Generic_Floor = 200,
|
||||
Generic_Ceiling = 201,
|
||||
Generic_Door = 202,
|
||||
Generic_Lift = 203,
|
||||
Generic_Stairs = 204,
|
||||
Generic_Crusher = 205,
|
||||
|
||||
Plat_DownWaitUpStayLip = 206,
|
||||
Plat_PerpetualRaiseLip = 207,
|
||||
|
||||
TranslucentLine = 208,
|
||||
Transfer_Heights = 209,
|
||||
Transfer_FloorLight = 210,
|
||||
Transfer_CeilingLight = 211,
|
||||
|
||||
Sector_SetColor = 212,
|
||||
Sector_SetFade = 213,
|
||||
Sector_SetDamage = 214,
|
||||
|
||||
Teleport_Line = 215,
|
||||
|
||||
Sector_SetGravity = 216,
|
||||
|
||||
Stairs_BuildUpDoom = 217,
|
||||
|
||||
Sector_SetWind = 218,
|
||||
Sector_SetFriction = 219,
|
||||
Sector_SetCurrent = 220,
|
||||
|
||||
Scroll_Texture_Both = 221,
|
||||
Scroll_Texture_Model = 222,
|
||||
Scroll_Floor = 223,
|
||||
Scroll_Ceiling = 224,
|
||||
Scroll_Texture_Offsets = 225,
|
||||
|
||||
ACS_ExecuteAlways = 226,
|
||||
|
||||
PointPush_SetForce = 227,
|
||||
|
||||
Plat_RaiseAndStayTx0 = 228,
|
||||
|
||||
Thing_SetGoal = 229,
|
||||
|
||||
Plat_UpByValueStayTx = 230,
|
||||
Plat_ToggleCeiling = 231,
|
||||
|
||||
Light_StrobeDoom = 232,
|
||||
Light_MinNeighbor = 233,
|
||||
Light_MaxNeighbor = 234,
|
||||
|
||||
Floor_TransferTrigger = 235,
|
||||
Floor_TransferNumeric = 236,
|
||||
|
||||
ChangeCamera = 237,
|
||||
|
||||
Floor_RaiseToLowestCeiling = 238,
|
||||
Floor_RaiseByValueTxTy = 239,
|
||||
Floor_RaiseByTexture = 240,
|
||||
Floor_LowerToLowestTxTy = 241,
|
||||
Floor_LowerToHighest = 242,
|
||||
|
||||
Exit_Normal = 243,
|
||||
Exit_Secret = 244,
|
||||
|
||||
Elevator_RaiseToNearest = 245,
|
||||
Elevator_MoveToFloor = 246,
|
||||
Elevator_LowerToNearest = 247,
|
||||
|
||||
HealThing = 248,
|
||||
Door_CloseWaitOpen = 249,
|
||||
|
||||
Floor_Donut = 250,
|
||||
|
||||
FloorAndCeiling_LowerRaise = 251,
|
||||
|
||||
Ceiling_RaiseToNearest = 252,
|
||||
Ceiling_LowerToLowest = 253,
|
||||
Ceiling_LowerToFloor = 254,
|
||||
Ceiling_CrushRaiseAndStaySilA = 255
|
||||
} linespecial_t;
|
||||
|
||||
typedef enum {
|
||||
Light_Phased = 1,
|
||||
LightSequenceStart = 2,
|
||||
LightSequenceSpecial1 = 3,
|
||||
LightSequenceSpecial2 = 4,
|
||||
|
||||
Stairs_Special1 = 26,
|
||||
Stairs_Special2 = 27,
|
||||
|
||||
// [RH] Equivalents for DOOM's sector specials
|
||||
dLight_Flicker = 65,
|
||||
dLight_StrobeFast = 66,
|
||||
dLight_StrobeSlow = 67,
|
||||
dLight_Strobe_Hurt = 68,
|
||||
dDamage_Hellslime = 69,
|
||||
dDamage_Nukage = 71,
|
||||
dLight_Glow = 72,
|
||||
dSector_DoorCloseIn30 = 74,
|
||||
dDamage_End = 75,
|
||||
dLight_StrobeSlowSync = 76,
|
||||
dLight_StrobeFastSync = 77,
|
||||
dSector_DoorRaiseIn5Mins = 78,
|
||||
dDamage_SuperHellslime = 80,
|
||||
dLight_FireFlicker = 81,
|
||||
|
||||
Light_IndoorLightning2 = 198,
|
||||
Light_IndoorLightning1 = 199,
|
||||
|
||||
Sky2 = 200,
|
||||
|
||||
Scroll_North_Slow = 201,
|
||||
Scroll_North_Medium = 202,
|
||||
Scroll_North_Fast = 203,
|
||||
Scroll_East_Slow = 204,
|
||||
Scroll_East_Medium = 205,
|
||||
Scroll_East_Fast = 206,
|
||||
Scroll_South_Slow = 207,
|
||||
Scroll_South_Medium = 208,
|
||||
Scroll_South_Fast = 209,
|
||||
Scroll_West_Slow = 210,
|
||||
Scroll_West_Medium = 211,
|
||||
Scroll_West_Fast = 212,
|
||||
Scroll_NorthWest_Slow = 213,
|
||||
Scroll_NorthWest_Medium = 214,
|
||||
Scroll_NorthWest_Fast = 215,
|
||||
Scroll_NorthEast_Slow = 216,
|
||||
Scroll_NorthEast_Medium = 217,
|
||||
Scroll_NorthEast_Fast = 218,
|
||||
Scroll_SouthEast_Slow = 219,
|
||||
Scroll_SouthEast_Medium = 220,
|
||||
Scroll_SouthEast_Fast = 221,
|
||||
Scroll_SouthWest_Slow = 222,
|
||||
Scroll_SouthWest_Medium = 223,
|
||||
Scroll_SouthWest_Fast = 224,
|
||||
} sectorspecial_t;
|
||||
|
||||
// [RH] Equivalents for BOOM's generalized sector types
|
||||
|
||||
#define DAMAGE_MASK 0x0300
|
||||
#define SECRET_MASK 0x0400
|
||||
#define FRICTION_MASK 0x0800
|
||||
#define PUSH_MASK 0x1000
|
||||
|
||||
struct line_s;
|
||||
struct mobj_s;
|
||||
|
||||
typedef BOOL (*lnSpecFunc)(struct line_s *line,
|
||||
struct mobj_s *activator,
|
||||
int arg1,
|
||||
int arg2,
|
||||
int arg3,
|
||||
int arg4,
|
||||
int arg5);
|
||||
|
||||
extern lnSpecFunc LineSpecials[256];
|
||||
|
||||
extern int TeleportSide;
|
||||
|
||||
#endif //__P_LNSPEC_H__
|
|
@ -91,7 +91,8 @@ void P_DropWeapon (player_t* player);
|
|||
//
|
||||
// P_USER
|
||||
//
|
||||
void P_PlayerThink (player_t* player);
|
||||
void P_FallingDamage (mobj_t *ent);
|
||||
void P_PlayerThink (player_t *player);
|
||||
|
||||
|
||||
//
|
||||
|
@ -109,7 +110,15 @@ extern int iquehead;
|
|||
extern int iquetail;
|
||||
|
||||
|
||||
void P_RespawnSpecials (void);
|
||||
// [RH] Functions to work with ThingIDs.
|
||||
void P_ClearTidHashes (void);
|
||||
void P_AddMobjToHash (mobj_t *mobj);
|
||||
void P_RemoveMobjFromHash (mobj_t *mobj);
|
||||
mobj_t *P_FindMobjByTid (mobj_t *mobj, int tid);
|
||||
mobj_t *P_FindGoal (mobj_t *mobj, int tid, int type);
|
||||
|
||||
|
||||
void P_RespawnSpecials (void);
|
||||
|
||||
mobj_t *P_SpawnMobj (fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, int onfloor);
|
||||
|
||||
|
@ -126,10 +135,28 @@ void P_SpawnPlayerMissile (mobj_t* source, mobjtype_t type);
|
|||
void ThrowGib (mobj_t *self, mobjtype_t gibtype, int damage);
|
||||
|
||||
|
||||
//
|
||||
// [RH] P_THINGS
|
||||
//
|
||||
extern int SpawnableThings[];
|
||||
extern const int NumSpawnableThings;
|
||||
|
||||
BOOL P_Thing_Spawn (int tid, int type, angle_t angle, BOOL fog);
|
||||
BOOL P_Thing_Projectile (int tid, int type, angle_t angle,
|
||||
fixed_t speed, fixed_t vspeed, BOOL gravity);
|
||||
BOOL P_ActivateMobj (mobj_t *mobj);
|
||||
BOOL P_DeactivateMobj (mobj_t *mobj);
|
||||
|
||||
|
||||
//
|
||||
// P_ENEMY
|
||||
//
|
||||
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;
|
||||
|
||||
// [RH] Andy Baker's stealth monsters
|
||||
void P_BecomeVisible (mobj_t *actor);
|
||||
|
@ -212,17 +239,18 @@ extern BOOL floatok;
|
|||
extern fixed_t tmfloorz;
|
||||
extern fixed_t tmceilingz;
|
||||
extern msecnode_t *sector_list; // phares 3/16/98
|
||||
extern BOOL oldshootactivation; // [RH]
|
||||
|
||||
extern line_t* ceilingline;
|
||||
|
||||
BOOL P_CheckPosition (mobj_t *thing, fixed_t x, fixed_t y);
|
||||
BOOL P_TryMove (mobj_t* thing, fixed_t x, fixed_t y);
|
||||
BOOL P_TryMove (mobj_t* thing, fixed_t x, fixed_t y, BOOL dropoff);
|
||||
BOOL P_TeleportMove (mobj_t* thing, fixed_t x, fixed_t y, fixed_t z, BOOL telefrag); // [RH] Added z and telefrag parameters
|
||||
void P_SlideMove (mobj_t* mo);
|
||||
BOOL P_CheckSight (const mobj_t* t1, const mobj_t* t2);
|
||||
BOOL P_CheckSight (const mobj_t* t1, const mobj_t* t2, BOOL ignoreInvisibility);
|
||||
void P_UseLines (player_t* player);
|
||||
|
||||
BOOL P_ChangeSector (sector_t* sector, BOOL crunch);
|
||||
BOOL P_ChangeSector (sector_t* sector, int crunch);
|
||||
|
||||
extern mobj_t* linetarget; // who got hit (or NULL)
|
||||
|
||||
|
@ -234,7 +262,7 @@ void P_LineAttack (mobj_t *t1, angle_t angle, fixed_t distance, fixed_t slope, i
|
|||
void P_RadiusAttack (mobj_t *spot, mobj_t *source, int damage, int mod);
|
||||
|
||||
//jff 3/19/98 P_CheckSector(): new routine to replace P_ChangeSector()
|
||||
BOOL P_CheckSector(sector_t *sector, BOOL crunch);
|
||||
BOOL P_CheckSector(sector_t *sector, int crunch);
|
||||
void P_DelSeclist(msecnode_t *); // phares 3/16/98
|
||||
void P_CreateSecNodeList(mobj_t*,fixed_t,fixed_t); // phares 3/14/98
|
||||
int P_GetMoveFactor(mobj_t* mo); // phares 3/6/98
|
||||
|
@ -306,7 +334,6 @@ void P_DamageMobj (mobj_t *target, mobj_t *inflictor, mobj_t *source, int damage
|
|||
#define MOD_EXIT 20
|
||||
#define MOD_SPLASH 21
|
||||
#define MOD_HIT 22
|
||||
#define MOD_FALLXFER 23
|
||||
#define MOD_FRIENDLY_FIRE 0x80000000
|
||||
|
||||
extern int MeansOfDeath;
|
||||
|
|
583
code/P_map.c
583
code/P_map.c
|
@ -41,22 +41,26 @@
|
|||
// State.
|
||||
#include "doomstat.h"
|
||||
#include "r_state.h"
|
||||
// Data.
|
||||
#include "sounds.h"
|
||||
|
||||
#include "z_zone.h"
|
||||
|
||||
fixed_t tmbbox[4];
|
||||
mobj_t* tmthing;
|
||||
int tmflags;
|
||||
fixed_t tmx;
|
||||
fixed_t tmy;
|
||||
fixed_t tmz; // [RH] Needed for third dimension of teleporters
|
||||
static mobj_t *tmthing;
|
||||
static int tmflags;
|
||||
static fixed_t tmx;
|
||||
static fixed_t tmy;
|
||||
static fixed_t tmz; // [RH] Needed for third dimension of teleporters
|
||||
static int pe_x; // Pain Elemental position for Lost Soul checks // phares
|
||||
static int pe_y; // Pain Elemental position for Lost Soul checks // phares
|
||||
static int ls_x; // Lost Soul position for Lost Soul checks // phares
|
||||
static int ls_y; // Lost Soul position for Lost Soul checks // phares
|
||||
|
||||
BOOL oldshootactivation; // [RH] True if no distinction is made between
|
||||
// projectile cross and projectile hit
|
||||
|
||||
// If "floatok" true, move would be ok
|
||||
// if within "tmfloorz - tmceilingz".
|
||||
BOOL floatok;
|
||||
BOOL floatok;
|
||||
|
||||
fixed_t tmfloorz;
|
||||
fixed_t tmceilingz;
|
||||
|
@ -68,7 +72,7 @@ line_t* ceilingline;
|
|||
|
||||
// keep track of special lines as they are hit,
|
||||
// but don't process them until the move is proven valid
|
||||
// [RH] MaxSpecialCross grows as needed in increments of 8
|
||||
// [RH] MaxSpecialCross grows as needed
|
||||
int MaxSpecialCross = 0;
|
||||
|
||||
line_t** spechit;
|
||||
|
@ -90,19 +94,18 @@ static BOOL StompAlwaysFrags;
|
|||
|
||||
BOOL PIT_StompThing (mobj_t* thing)
|
||||
{
|
||||
fixed_t blockdist;
|
||||
|
||||
if (!(thing->flags & MF_SHOOTABLE) )
|
||||
fixed_t blockdist;
|
||||
|
||||
if (!(thing->flags & MF_SHOOTABLE))
|
||||
return true;
|
||||
|
||||
|
||||
// don't clip against self
|
||||
if (thing == tmthing)
|
||||
return true;
|
||||
|
||||
|
||||
blockdist = thing->radius + tmthing->radius;
|
||||
|
||||
if ( abs(thing->x - tmx) >= blockdist
|
||||
|| abs(thing->y - tmy) >= blockdist )
|
||||
if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist)
|
||||
{
|
||||
// didn't hit it
|
||||
return true;
|
||||
|
@ -193,25 +196,117 @@ BOOL P_TeleportMove (mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, BOOL telefr
|
|||
thing->ceilingz = tmceilingz;
|
||||
thing->x = x;
|
||||
thing->y = y;
|
||||
thing->z = z;
|
||||
|
||||
P_SetThingPosition (thing);
|
||||
|
||||
thing->z = z;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// P_GetMoveFactor() returns the value by which the x,y // phares 3/19/98
|
||||
// movements are multiplied to add to player movement. // |
|
||||
// V
|
||||
int P_GetMoveFactor(mobj_t* mo)
|
||||
{
|
||||
int movefactor = ORIG_FRICTION_FACTOR;
|
||||
|
||||
// If the floor is icy or muddy, it's harder to get moving. This is where
|
||||
// the different friction factors are applied to 'trying to move'. In
|
||||
// p_mobj.c, the friction factors are applied as you coast and slow down.
|
||||
|
||||
int momentum, friction;
|
||||
|
||||
if (!olddemo && boom_friction->value &&
|
||||
!(mo->flags & (MF_NOGRAVITY | MF_NOCLIP)))
|
||||
{
|
||||
friction = mo->friction;
|
||||
if (friction == ORIG_FRICTION) // normal floor
|
||||
;
|
||||
else if (friction > ORIG_FRICTION) // ice
|
||||
{
|
||||
movefactor = mo->movefactor;
|
||||
mo->movefactor = ORIG_FRICTION_FACTOR; // reset
|
||||
}
|
||||
else // sludge
|
||||
{
|
||||
|
||||
// phares 3/11/98: you start off slowly, then increase as
|
||||
// you get better footing
|
||||
|
||||
momentum = (P_AproxDistance (mo->momx, mo->momy));
|
||||
movefactor = mo->movefactor;
|
||||
if (momentum > MORE_FRICTION_MOMENTUM<<2)
|
||||
movefactor <<= 3;
|
||||
|
||||
else if (momentum > MORE_FRICTION_MOMENTUM<<1)
|
||||
movefactor <<= 2;
|
||||
|
||||
else if (momentum > MORE_FRICTION_MOMENTUM)
|
||||
movefactor <<= 1;
|
||||
|
||||
mo->movefactor = ORIG_FRICTION_FACTOR; // reset
|
||||
}
|
||||
} // ^
|
||||
return (movefactor); // |
|
||||
} // phares 3/19/98
|
||||
|
||||
//
|
||||
// MOVEMENT ITERATOR FUNCTIONS
|
||||
//
|
||||
|
||||
// // phares
|
||||
// PIT_CrossLine // |
|
||||
// Checks to see if a PE->LS trajectory line crosses a blocking // V
|
||||
// line. Returns false if it does.
|
||||
//
|
||||
// tmbbox holds the bounding box of the trajectory. If that box
|
||||
// does not touch the bounding box of the line in question,
|
||||
// then the trajectory is not blocked. If the PE is on one side
|
||||
// of the line and the LS is on the other side, then the
|
||||
// trajectory is blocked.
|
||||
//
|
||||
// Currently this assumes an infinite line, which is not quite
|
||||
// correct. A more correct solution would be to check for an
|
||||
// intersection of the trajectory and the line, but that takes
|
||||
// longer and probably really isn't worth the effort.
|
||||
//
|
||||
|
||||
static // killough 3/26/98: make static
|
||||
BOOL PIT_CrossLine (line_t* ld)
|
||||
{
|
||||
if (!(ld->flags & ML_TWOSIDED) ||
|
||||
(ld->flags & (ML_BLOCKING|ML_BLOCKMONSTERS|ML_BLOCKEVERYTHING)))
|
||||
if (!(tmbbox[BOXLEFT] > ld->bbox[BOXRIGHT] ||
|
||||
tmbbox[BOXRIGHT] < ld->bbox[BOXLEFT] ||
|
||||
tmbbox[BOXTOP] < ld->bbox[BOXBOTTOM] ||
|
||||
tmbbox[BOXBOTTOM] > ld->bbox[BOXTOP]))
|
||||
if (P_PointOnLineSide(pe_x,pe_y,ld) != P_PointOnLineSide(ls_x,ls_y,ld))
|
||||
return(false); // line blocks trajectory // ^
|
||||
return(true); // line doesn't block trajectory // |
|
||||
} // phares
|
||||
|
||||
//
|
||||
// PIT_CheckLine
|
||||
// Adjusts tmfloorz and tmceilingz as lines are contacted
|
||||
//
|
||||
BOOL PIT_CheckLine (line_t* ld)
|
||||
|
||||
// [RH] Moved this out of PIT_CheckLine()
|
||||
static void AddSpecialLine (line_t *ld)
|
||||
{
|
||||
if (ld->special)
|
||||
{
|
||||
// [RH] Grow the spechit array as needed
|
||||
if (numspechit >= MaxSpecialCross) {
|
||||
MaxSpecialCross = MaxSpecialCross ? MaxSpecialCross * 2 : 8;
|
||||
spechit = Realloc (spechit, MaxSpecialCross * sizeof(*spechit));
|
||||
DPrintf ("MaxSpecialCross increased to %d\n", MaxSpecialCross);
|
||||
}
|
||||
spechit[numspechit++] = ld;
|
||||
}
|
||||
}
|
||||
|
||||
static // killough 3/26/98: make static
|
||||
BOOL PIT_CheckLine (line_t *ld)
|
||||
{
|
||||
if (tmbbox[BOXRIGHT] <= ld->bbox[BOXLEFT]
|
||||
|| tmbbox[BOXLEFT] >= ld->bbox[BOXRIGHT]
|
||||
|
@ -233,16 +328,22 @@ BOOL PIT_CheckLine (line_t* ld)
|
|||
// so two special lines that are only 8 pixels apart
|
||||
// could be crossed in either order.
|
||||
|
||||
if (!ld->backsector)
|
||||
if (!ld->backsector) {
|
||||
// [RH] Let somebody push it if they want to
|
||||
if ((ld->flags & ML_ACTIVATIONMASK) == ML_ACTIVATEPUSH)
|
||||
AddSpecialLine (ld);
|
||||
return false; // one sided line
|
||||
}
|
||||
|
||||
if (!(tmthing->flags & MF_MISSILE) )
|
||||
if (!(tmthing->flags & MF_MISSILE) || (ld->flags & ML_BLOCKEVERYTHING))
|
||||
{
|
||||
if ( ld->flags & ML_BLOCKING )
|
||||
return false; // explicitly blocking everything
|
||||
|
||||
if ( !tmthing->player && ld->flags & ML_BLOCKMONSTERS )
|
||||
return false; // block monsters only
|
||||
if ((ld->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING)) || // explicitly blocking everything
|
||||
(!tmthing->player && ld->flags & ML_BLOCKMONSTERS)) { // block monsters only
|
||||
// [RH] Add pushable lines to the special list
|
||||
if ((ld->flags & ML_ACTIVATIONMASK) == ML_ACTIVATEPUSH)
|
||||
AddSpecialLine (ld);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// set openrange, opentop, openbottom
|
||||
|
@ -262,17 +363,7 @@ BOOL PIT_CheckLine (line_t* ld)
|
|||
tmdropoffz = lowfloor;
|
||||
|
||||
// if contacted a special line, add it to the list
|
||||
if (ld->special)
|
||||
{
|
||||
// [RH] Grow the spechit array as needed
|
||||
if (numspechit >= MaxSpecialCross) {
|
||||
MaxSpecialCross += 8;
|
||||
spechit = Realloc (spechit, MaxSpecialCross * sizeof(line_t *));
|
||||
DPrintf ("MaxSpecialCross increased to %d\n", MaxSpecialCross);
|
||||
}
|
||||
spechit[numspechit] = ld;
|
||||
numspechit++;
|
||||
}
|
||||
AddSpecialLine (ld);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -280,23 +371,23 @@ BOOL PIT_CheckLine (line_t* ld)
|
|||
//
|
||||
// PIT_CheckThing
|
||||
//
|
||||
static // killough 3/26/98: make static
|
||||
BOOL PIT_CheckThing (mobj_t *thing)
|
||||
{
|
||||
fixed_t blockdist;
|
||||
BOOL solid;
|
||||
int damage;
|
||||
|
||||
if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_SHOOTABLE) ))
|
||||
return true;
|
||||
|
||||
// don't clip against self
|
||||
if (thing == tmthing)
|
||||
return true;
|
||||
|
||||
if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_SHOOTABLE)) )
|
||||
return true;
|
||||
|
||||
blockdist = thing->radius + tmthing->radius;
|
||||
|
||||
if ( abs(thing->x - tmx) >= blockdist
|
||||
|| abs(thing->y - tmy) >= blockdist )
|
||||
if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist)
|
||||
{
|
||||
// didn't hit it
|
||||
return true;
|
||||
|
@ -348,7 +439,7 @@ BOOL PIT_CheckThing (mobj_t *thing)
|
|||
return true;
|
||||
|
||||
// [RH] DeHackEd infighting is here.
|
||||
if (!deh_Infight && thing->type != MT_PLAYER)
|
||||
if (!deh.Infight && thing->type != MT_PLAYER)
|
||||
{
|
||||
// Explode, but do no damage.
|
||||
// Let players missile other players.
|
||||
|
@ -400,10 +491,77 @@ BOOL PIT_CheckThing (mobj_t *thing)
|
|||
}
|
||||
return !solid;
|
||||
}
|
||||
|
||||
return !(thing->flags & MF_SOLID);
|
||||
|
||||
// [RH] Allow step up on top of things up to 24 units (like stairs)
|
||||
// The movement code will automatically place the moving object
|
||||
// on top of the other one.
|
||||
if (!olddemo
|
||||
&& !(tmthing->z & MF2_JUMPING)
|
||||
&& tmthing->z < thing->z + thing->height
|
||||
&& thing->z + thing->height - tmthing->z <= 24 * FRACUNIT
|
||||
&& thing->z + thing->height + tmthing->height < thing->subsector->sector->ceilingheight
|
||||
) {
|
||||
tmthing->z = thing->z;
|
||||
tmthing->momz = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// killough 3/16/98: Allow non-solid moving objects to move through solid
|
||||
// ones, by allowing the moving thing (tmthing) to move if it's non-solid,
|
||||
// despite another solid thing being in the way.
|
||||
// killough 4/11/98: Treat no-clipping things as not blocking
|
||||
|
||||
return !((thing->flags & MF_SOLID && !(thing->flags & MF_NOCLIP))
|
||||
&& (tmthing->flags & MF_SOLID || olddemo));
|
||||
|
||||
// return !(thing->flags & MF_SOLID); // old code -- killough
|
||||
}
|
||||
|
||||
// This routine checks for Lost Souls trying to be spawned // phares
|
||||
// across 1-sided lines, impassible lines, or "monsters can't // |
|
||||
// cross" lines. Draw an imaginary line between the PE // V
|
||||
// and the new Lost Soul spawn spot. If that line crosses
|
||||
// a 'blocking' line, then disallow the spawn. Only search
|
||||
// lines in the blocks of the blockmap where the bounding box
|
||||
// of the trajectory line resides. Then check bounding box
|
||||
// of the trajectory vs. the bounding box of each blocking
|
||||
// line to see if the trajectory and the blocking line cross.
|
||||
// Then check the PE and LS to see if they're on different
|
||||
// sides of the blocking line. If so, return true, otherwise
|
||||
// false.
|
||||
|
||||
BOOL Check_Sides(mobj_t* actor, int x, int y)
|
||||
{
|
||||
int bx,by,xl,xh,yl,yh;
|
||||
|
||||
pe_x = actor->x;
|
||||
pe_y = actor->y;
|
||||
ls_x = x;
|
||||
ls_y = y;
|
||||
|
||||
// Here is the bounding box of the trajectory
|
||||
|
||||
tmbbox[BOXLEFT] = pe_x < x ? pe_x : x;
|
||||
tmbbox[BOXRIGHT] = pe_x > x ? pe_x : x;
|
||||
tmbbox[BOXTOP] = pe_y > y ? pe_y : y;
|
||||
tmbbox[BOXBOTTOM] = pe_y < y ? pe_y : y;
|
||||
|
||||
// Determine which blocks to look in for blocking lines
|
||||
|
||||
xl = (tmbbox[BOXLEFT] - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xh = (tmbbox[BOXRIGHT] - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
yl = (tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yh = (tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
|
||||
// xl->xh, yl->yh determine the mapblock set to search
|
||||
|
||||
validcount++; // prevents checking same line twice
|
||||
for (bx = xl ; bx <= xh ; bx++)
|
||||
for (by = yl ; by <= yh ; by++)
|
||||
if (!P_BlockLinesIterator(bx,by,PIT_CrossLine))
|
||||
return true; // ^
|
||||
return(false); // |
|
||||
} // phares
|
||||
|
||||
//
|
||||
// MOVEMENT CLIPPING
|
||||
|
@ -435,13 +593,10 @@ BOOL PIT_CheckThing (mobj_t *thing)
|
|||
//
|
||||
BOOL P_CheckPosition (mobj_t *thing, fixed_t x, fixed_t y)
|
||||
{
|
||||
int xl;
|
||||
int xh;
|
||||
int yl;
|
||||
int yh;
|
||||
int bx;
|
||||
int by;
|
||||
subsector_t* newsubsec;
|
||||
int xl, xh;
|
||||
int yl, yh;
|
||||
int bx, by;
|
||||
subsector_t *newsubsec;
|
||||
|
||||
tmthing = thing;
|
||||
tmflags = thing->flags;
|
||||
|
@ -505,7 +660,8 @@ BOOL P_CheckPosition (mobj_t *thing, fixed_t x, fixed_t y)
|
|||
// Attempt to move to a new position,
|
||||
// crossing special lines unless MF_TELEPORT is set.
|
||||
//
|
||||
BOOL P_TryMove (mobj_t *thing, fixed_t x, fixed_t y)
|
||||
BOOL P_TryMove (mobj_t *thing, fixed_t x, fixed_t y,
|
||||
BOOL dropoff) // killough 3/15/98: allow dropoff as option
|
||||
{
|
||||
fixed_t oldx;
|
||||
fixed_t oldy;
|
||||
|
@ -519,6 +675,13 @@ BOOL P_TryMove (mobj_t *thing, fixed_t x, fixed_t y)
|
|||
|
||||
if ( !(thing->flags & MF_NOCLIP) )
|
||||
{
|
||||
#ifdef CEILCARRY
|
||||
// killough 4/11/98: if the thing hangs from
|
||||
// a ceiling, don't worry about it fitting
|
||||
|
||||
if (!(thing->flags & MF_SPAWNCEILING) || demo_compatibility)
|
||||
#endif
|
||||
|
||||
if (tmceilingz - tmfloorz < thing->height)
|
||||
return false; // doesn't fit
|
||||
|
||||
|
@ -530,8 +693,12 @@ BOOL P_TryMove (mobj_t *thing, fixed_t x, fixed_t y)
|
|||
if ( !(thing->flags&MF_TELEPORT) && tmfloorz - thing->z > 24*FRACUNIT )
|
||||
return false; // too big a step up
|
||||
|
||||
if ( !(thing->flags&(MF_DROPOFF|MF_FLOAT)) && tmfloorz - tmdropoffz > 24*FRACUNIT )
|
||||
return false; // don't stand over a dropoff
|
||||
// killough 3/15/98: Allow certain objects to drop off
|
||||
|
||||
if (olddemo || !dropoff)
|
||||
if ( !(thing->flags&(MF_DROPOFF|MF_FLOAT))
|
||||
&& tmfloorz - tmdropoffz > 24*FRACUNIT )
|
||||
return false; // don't stand over a dropoff
|
||||
}
|
||||
|
||||
// the move is ok,
|
||||
|
@ -556,11 +723,8 @@ BOOL P_TryMove (mobj_t *thing, fixed_t x, fixed_t y)
|
|||
ld = spechit[numspechit];
|
||||
side = P_PointOnLineSide (thing->x, thing->y, ld);
|
||||
oldside = P_PointOnLineSide (oldx, oldy, ld);
|
||||
if (side != oldside)
|
||||
{
|
||||
if (ld->special)
|
||||
P_CrossSpecialLine (ld-lines, oldside, thing);
|
||||
}
|
||||
if (side != oldside && ld->special)
|
||||
P_CrossSpecialLine (ld-lines, oldside, thing);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -628,59 +792,111 @@ mobj_t* slidemo;
|
|||
fixed_t tmxmove;
|
||||
fixed_t tmymove;
|
||||
|
||||
extern mobj_t *onground;
|
||||
|
||||
|
||||
//
|
||||
// P_HitSlideLine
|
||||
// Adjusts the xmove / ymove
|
||||
// so that the next move will slide along the wall.
|
||||
// If the floor is icy, then you can bounce off a wall. // phares
|
||||
//
|
||||
void P_HitSlideLine (line_t* ld)
|
||||
{
|
||||
int side;
|
||||
int side;
|
||||
|
||||
angle_t lineangle;
|
||||
angle_t moveangle;
|
||||
angle_t deltaangle;
|
||||
angle_t lineangle;
|
||||
angle_t moveangle;
|
||||
angle_t deltaangle;
|
||||
|
||||
fixed_t movelen;
|
||||
fixed_t newlen;
|
||||
|
||||
|
||||
fixed_t movelen;
|
||||
fixed_t newlen;
|
||||
BOOL icyfloor; // is floor icy? // phares
|
||||
// |
|
||||
// Under icy conditions, if the angle of approach to the wall // V
|
||||
// is more than 45 degrees, then you'll bounce and lose half
|
||||
// your momentum. If less than 45 degrees, you'll slide along
|
||||
// the wall. 45 is arbitrary and is believable.
|
||||
|
||||
// Check for the special cases of horz or vert walls.
|
||||
|
||||
if (!olddemo && boom_friction->value && slidemo->player)
|
||||
// player must be on ground
|
||||
icyfloor = ((onground == (mobj_t *)-1) && (slidemo->friction > ORIG_FRICTION));
|
||||
else
|
||||
icyfloor = false;
|
||||
|
||||
if (ld->slopetype == ST_HORIZONTAL)
|
||||
{
|
||||
tmymove = 0;
|
||||
if (icyfloor && (abs(tmymove) > abs(tmxmove)))
|
||||
{
|
||||
tmxmove /= 2; // absorb half the momentum
|
||||
tmymove = -tmymove/2;
|
||||
S_StartSound (slidemo, "*grunt1", 78); // oooff!
|
||||
}
|
||||
else
|
||||
tmymove = 0; // no more movement in the Y direction
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (ld->slopetype == ST_VERTICAL)
|
||||
{
|
||||
tmxmove = 0;
|
||||
if (icyfloor && (abs(tmxmove) > abs(tmymove)))
|
||||
{
|
||||
tmxmove = -tmxmove/2; // absorb half the momentum
|
||||
tmymove /= 2;
|
||||
S_StartSound (slidemo, "*grunt1", 78); // oooff! // ^
|
||||
} // |
|
||||
else // phares
|
||||
tmxmove = 0; // no more movement in the X direction
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// The wall is angled. Bounce if the angle of approach is // phares
|
||||
// less than 45 degrees. // phares
|
||||
|
||||
side = P_PointOnLineSide (slidemo->x, slidemo->y, ld);
|
||||
|
||||
|
||||
lineangle = R_PointToAngle2 (0,0, ld->dx, ld->dy);
|
||||
|
||||
if (side == 1)
|
||||
lineangle += ANG180;
|
||||
|
||||
moveangle = R_PointToAngle2 (0,0, tmxmove, tmymove);
|
||||
deltaangle = moveangle-lineangle;
|
||||
|
||||
if (deltaangle > ANG180)
|
||||
deltaangle += ANG180;
|
||||
// I_Error ("SlideLine: ang>ANG180");
|
||||
// killough 3/2/98:
|
||||
// The moveangle+=10 breaks v1.9 demo compatibility in
|
||||
// some demos, so it needs demo_compatibility switch.
|
||||
|
||||
lineangle >>= ANGLETOFINESHIFT;
|
||||
deltaangle >>= ANGLETOFINESHIFT;
|
||||
|
||||
if (!olddemo)
|
||||
moveangle += 10; // prevents sudden path reversal due to // phares
|
||||
// rounding error // |
|
||||
deltaangle = moveangle-lineangle; // V
|
||||
movelen = P_AproxDistance (tmxmove, tmymove);
|
||||
newlen = FixedMul (movelen, finecosine[deltaangle]);
|
||||
if (icyfloor && (deltaangle > ANG45) && (deltaangle < ANG90+ANG45))
|
||||
{
|
||||
moveangle = lineangle - deltaangle;
|
||||
movelen /= 2; // absorb
|
||||
S_StartSound (slidemo, "*grunt1", 78); // oooff!
|
||||
moveangle >>= ANGLETOFINESHIFT;
|
||||
tmxmove = FixedMul (movelen, finecosine[moveangle]);
|
||||
tmymove = FixedMul (movelen, finesine[moveangle]);
|
||||
} // ^
|
||||
else // |
|
||||
{ // phares
|
||||
if (deltaangle > ANG180)
|
||||
deltaangle += ANG180;
|
||||
// I_Error ("SlideLine: ang>ANG180");
|
||||
|
||||
tmxmove = FixedMul (newlen, finecosine[lineangle]);
|
||||
tmymove = FixedMul (newlen, finesine[lineangle]);
|
||||
lineangle >>= ANGLETOFINESHIFT;
|
||||
deltaangle >>= ANGLETOFINESHIFT;
|
||||
|
||||
movelen = P_AproxDistance (tmxmove, tmymove);
|
||||
newlen = FixedMul (movelen, finecosine[deltaangle]);
|
||||
|
||||
tmxmove = FixedMul (newlen, finecosine[lineangle]);
|
||||
tmymove = FixedMul (newlen, finesine[lineangle]);
|
||||
} // phares
|
||||
}
|
||||
|
||||
|
||||
|
@ -801,8 +1017,17 @@ void P_SlideMove (mobj_t* mo)
|
|||
{
|
||||
// the move most have hit the middle, so stairstep
|
||||
stairstep:
|
||||
if (!P_TryMove (mo, mo->x, mo->y + mo->momy))
|
||||
P_TryMove (mo, mo->x + mo->momx, mo->y);
|
||||
// killough 3/15/98: Allow objects to drop off ledges
|
||||
|
||||
if (!P_TryMove (mo, mo->x, mo->y + mo->momy, true))
|
||||
|
||||
// phares 5/4/98: kill momentum if you can't move at all
|
||||
// This eliminates player bobbing if pressed against a wall
|
||||
// while on ice.
|
||||
|
||||
if (!P_TryMove (mo, mo->x + mo->momx, mo->y, true))
|
||||
if (!olddemo)
|
||||
mo->momx = mo->momy = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -813,7 +1038,9 @@ void P_SlideMove (mobj_t* mo)
|
|||
newx = FixedMul (mo->momx, bestslidefrac);
|
||||
newy = FixedMul (mo->momy, bestslidefrac);
|
||||
|
||||
if (!P_TryMove (mo, mo->x+newx, mo->y+newy))
|
||||
// killough 3/15/98: Allow objects to drop off ledges
|
||||
|
||||
if (!P_TryMove (mo, mo->x+newx, mo->y+newy, true))
|
||||
goto stairstep;
|
||||
}
|
||||
|
||||
|
@ -835,10 +1062,10 @@ void P_SlideMove (mobj_t* mo)
|
|||
mo->momx = tmxmove;
|
||||
mo->momy = tmymove;
|
||||
|
||||
if (!P_TryMove (mo, mo->x+tmxmove, mo->y+tmymove))
|
||||
{
|
||||
// killough 3/15/98: Allow objects to drop off ledges
|
||||
|
||||
if (!P_TryMove (mo, mo->x+tmxmove, mo->y+tmymove, true))
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -858,16 +1085,17 @@ fixed_t attackrange;
|
|||
fixed_t aimslope;
|
||||
|
||||
// slopes to top and bottom of target
|
||||
extern fixed_t topslope;
|
||||
extern fixed_t bottomslope;
|
||||
// killough 4/20/98: make static instead of using ones in p_sight.c
|
||||
|
||||
static fixed_t topslope;
|
||||
static fixed_t bottomslope;
|
||||
|
||||
|
||||
//
|
||||
// PTR_AimTraverse
|
||||
// Sets linetaget and aimslope when a target is aimed at.
|
||||
//
|
||||
BOOL
|
||||
PTR_AimTraverse (intercept_t* in)
|
||||
BOOL PTR_AimTraverse (intercept_t* in)
|
||||
{
|
||||
line_t* li;
|
||||
mobj_t* th;
|
||||
|
@ -970,10 +1198,10 @@ BOOL PTR_ShootTraverse (intercept_t* in)
|
|||
{
|
||||
li = in->d.line;
|
||||
|
||||
if (li->special)
|
||||
if (oldshootactivation && li->special)
|
||||
P_ShootSpecialLine (shootthing, li);
|
||||
|
||||
if ( !(li->flags & ML_TWOSIDED) )
|
||||
if ( !(li->flags & ML_TWOSIDED) || (li->flags & ML_BLOCKEVERYTHING))
|
||||
goto hitline;
|
||||
|
||||
// crosses a two sided line
|
||||
|
@ -990,21 +1218,27 @@ BOOL PTR_ShootTraverse (intercept_t* in)
|
|||
|
||||
if (li->frontsector->ceilingheight != li->backsector->ceilingheight)
|
||||
{
|
||||
slope = FixedDiv (opentop - shootz , dist);
|
||||
slope = FixedDiv (opentop - shootz, dist);
|
||||
if (slope < aimslope)
|
||||
goto hitline;
|
||||
}
|
||||
|
||||
// shot continues
|
||||
// [RH] Possibly trigger activation
|
||||
if (!oldshootactivation && li->special)
|
||||
P_ShotCrossSpecialLine (shootthing, li);
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
// hit line
|
||||
hitline:
|
||||
// [RH] Possibly trigger activation
|
||||
if (!oldshootactivation && li->special)
|
||||
P_ShootSpecialLine (shootthing, li);
|
||||
|
||||
// position a bit closer
|
||||
frac = in->frac - FixedDiv (4*FRACUNIT,attackrange);
|
||||
x = trace.x + FixedMul (trace.dx, frac);
|
||||
y = trace.y + FixedMul (trace.dy, frac);
|
||||
z = shootz + FixedMul (aimslope, FixedMul(frac, attackrange));
|
||||
|
||||
if (li->frontsector->ceilingpic == skyflatnum)
|
||||
|
@ -1015,11 +1249,42 @@ BOOL PTR_ShootTraverse (intercept_t* in)
|
|||
|
||||
// it's a sky hack wall
|
||||
if (li->backsector && li->backsector->ceilingpic == skyflatnum)
|
||||
return false;
|
||||
// fix bullet-eaters -- killough:
|
||||
// WARNING: Almost all demos will lose sync without this
|
||||
// demo_compatibility flag check!!! killough 1/18/98
|
||||
if (olddemo || li->backsector->ceilingheight < z)
|
||||
return false;
|
||||
}
|
||||
|
||||
// [RH] If the trace went below/above the floor/ceiling, make the puff
|
||||
// appear in the right place and not on a wall.
|
||||
{
|
||||
fixed_t ceilingheight, floorheight;
|
||||
|
||||
if (!li->backsector || !P_PointOnLineSide (trace.x, trace.y, li)) {
|
||||
ceilingheight = li->frontsector->ceilingheight;
|
||||
floorheight = li->frontsector->floorheight;
|
||||
} else {
|
||||
ceilingheight = li->backsector->ceilingheight;
|
||||
floorheight = li->backsector->floorheight;
|
||||
}
|
||||
|
||||
if (z < floorheight) {
|
||||
frac = FixedDiv (FixedMul (floorheight - shootz, frac), z - shootz);
|
||||
z = floorheight;
|
||||
} else if (z > ceilingheight) {
|
||||
// Puffs on the ceiling need to be lowered to compensate for the height of the puff
|
||||
ceilingheight -= mobjinfo[MT_PUFF].height;
|
||||
frac = FixedDiv (FixedMul (ceilingheight - shootz, frac), z - shootz);
|
||||
z = ceilingheight;
|
||||
}
|
||||
}
|
||||
|
||||
x = trace.x + FixedMul (trace.dx, frac);
|
||||
y = trace.y + FixedMul (trace.dy, frac);
|
||||
|
||||
// Spawn bullet puffs.
|
||||
P_SpawnPuff (x,y,z);
|
||||
P_SpawnPuff (x, y, z);
|
||||
|
||||
// don't go any farther
|
||||
return false;
|
||||
|
@ -1056,17 +1321,20 @@ BOOL PTR_ShootTraverse (intercept_t* in)
|
|||
|
||||
// Spawn bullet puffs or blod spots,
|
||||
// depending on target type.
|
||||
if (in->d.thing->flags & MF_NOBLOOD)
|
||||
if ((in->d.thing->flags & MF_NOBLOOD) || (in->d.thing->flags2 & MF2_INVULNERABLE))
|
||||
P_SpawnPuff (x,y,z);
|
||||
else
|
||||
P_SpawnBlood (x,y,z, la_damage);
|
||||
|
||||
if (la_damage) {
|
||||
// [RH] figure out means of death;
|
||||
// [RH] try and figure out means of death;
|
||||
int mod = MOD_UNKNOWN;
|
||||
|
||||
if (shootthing->player) {
|
||||
switch (shootthing->player->readyweapon) {
|
||||
case wp_fist:
|
||||
mod = MOD_FIST;
|
||||
break;
|
||||
case wp_pistol:
|
||||
mod = MOD_PISTOL;
|
||||
break;
|
||||
|
@ -1096,11 +1364,7 @@ BOOL PTR_ShootTraverse (intercept_t* in)
|
|||
//
|
||||
// P_AimLineAttack
|
||||
//
|
||||
fixed_t
|
||||
P_AimLineAttack
|
||||
( mobj_t* t1,
|
||||
angle_t angle,
|
||||
fixed_t distance )
|
||||
fixed_t P_AimLineAttack (mobj_t *t1, angle_t angle, fixed_t distance)
|
||||
{
|
||||
fixed_t x2;
|
||||
fixed_t y2;
|
||||
|
@ -1165,7 +1429,7 @@ void P_LineAttack (mobj_t *t1, angle_t angle, fixed_t distance,
|
|||
//
|
||||
mobj_t *usething;
|
||||
|
||||
BOOL PTR_UseTraverse (intercept_t* in)
|
||||
BOOL PTR_UseTraverse (intercept_t *in)
|
||||
{
|
||||
int side;
|
||||
|
||||
|
@ -1174,7 +1438,7 @@ BOOL PTR_UseTraverse (intercept_t* in)
|
|||
P_LineOpening (in->d.line);
|
||||
if (openrange <= 0)
|
||||
{
|
||||
S_StartSound (usething, sfx_noway);
|
||||
S_StartSound (usething, "*grunt1", 78);
|
||||
|
||||
// can't use through a wall
|
||||
return false;
|
||||
|
@ -1197,6 +1461,29 @@ BOOL PTR_UseTraverse (intercept_t* in)
|
|||
return (!olddemo && (in->d.line->flags & ML_PASSUSE)) ? true : false;
|
||||
}
|
||||
|
||||
// Returns false if a "oof" sound should be made because of a blocking
|
||||
// linedef. Makes 2s middles which are impassable, as well as 2s uppers
|
||||
// and lowers which block the player, cause the sound effect when the
|
||||
// player tries to activate them. Specials are excluded, although it is
|
||||
// assumed that all special linedefs within reach have been considered
|
||||
// and rejected already (see P_UseLines).
|
||||
//
|
||||
// by Lee Killough
|
||||
//
|
||||
|
||||
BOOL PTR_NoWayTraverse(intercept_t* in)
|
||||
{
|
||||
line_t *ld = in->d.line; // This linedef
|
||||
|
||||
return ld->special || !( // Ignore specials
|
||||
ld->flags & (ML_BLOCKING|ML_BLOCKEVERYTHING) || ( // Always blocking
|
||||
P_LineOpening(ld), // Find openings
|
||||
openrange <= 0 || // No opening
|
||||
openbottom > usething->z+24*FRACUNIT || // Too high it blocks
|
||||
opentop < usething->z+usething->height // Too low it blocks
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// P_UseLines
|
||||
|
@ -1218,8 +1505,16 @@ void P_UseLines (player_t* player)
|
|||
y1 = player->mo->y;
|
||||
x2 = x1 + (USERANGE>>FRACBITS)*finecosine[angle];
|
||||
y2 = y1 + (USERANGE>>FRACBITS)*finesine[angle];
|
||||
|
||||
P_PathTraverse ( x1, y1, x2, y2, PT_ADDLINES, PTR_UseTraverse );
|
||||
|
||||
// old code:
|
||||
//
|
||||
// P_PathTraverse ( x1, y1, x2, y2, PT_ADDLINES, PTR_UseTraverse );
|
||||
//
|
||||
// This added test makes the "oof" sound work on 2s lines -- killough:
|
||||
|
||||
if (P_PathTraverse ( x1, y1, x2, y2, PT_ADDLINES, PTR_UseTraverse ))
|
||||
if (!P_PathTraverse ( x1, y1, x2, y2, PT_ADDLINES, PTR_NoWayTraverse ))
|
||||
S_StartSound (usething, "*grunt1", 78);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1389,6 +1684,9 @@ void P_StandOnThing (mobj_t *thing, mobj_t *spot)
|
|||
thing->z = spot->z + spot->height;
|
||||
else
|
||||
thing->z = thing->floorz;
|
||||
|
||||
if (thing->flags2 & MF2_JUMPING)
|
||||
thing->flags2 &= ~MF2_JUMPING;
|
||||
}
|
||||
// [RH] Z-Check <-
|
||||
|
||||
|
@ -1411,6 +1709,19 @@ vec3_t bombvec;
|
|||
// [RH] Now it knows about vertical distances and
|
||||
// can thrust things vertically, too.
|
||||
//
|
||||
|
||||
// [RH] Damage scale to apply to thing that shot the missile.
|
||||
cvar_t *splashfactor;
|
||||
static float selfthrustscale;
|
||||
|
||||
void SplashFactorCallback (cvar_t *var) {
|
||||
if (var->value <= 0.0f) {
|
||||
SetCVarFloat (var, 1.0f);
|
||||
} else {
|
||||
selfthrustscale = 1.0f / var->value;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL PIT_RadiusAttack (mobj_t *thing)
|
||||
{
|
||||
if (!(thing->flags & MF_SHOOTABLE) )
|
||||
|
@ -1439,9 +1750,9 @@ BOOL PIT_RadiusAttack (mobj_t *thing)
|
|||
points = bombdamagefloat - len;
|
||||
}
|
||||
if (thing == bombsource)
|
||||
points = points * 0.5f;
|
||||
points = points * splashfactor->value;
|
||||
if (points > 0) {
|
||||
if (P_CheckSight (thing, bombspot)) {
|
||||
if (P_CheckSight (thing, bombspot, true)) {
|
||||
vec3_t dir;
|
||||
float thrust;
|
||||
fixed_t momx = thing->momx;
|
||||
|
@ -1449,11 +1760,16 @@ BOOL PIT_RadiusAttack (mobj_t *thing)
|
|||
|
||||
P_DamageMobj (thing, bombspot, bombsource, (int)points, bombmod);
|
||||
|
||||
thrust = points * 70000.0f / (float)thing->info->mass;
|
||||
thrust = points * 35000.0f / (float)thing->info->mass;
|
||||
VectorSubtract (thingvec, bombvec, dir);
|
||||
VectorScale (dir, thrust, dir);
|
||||
if (bombsource != thing)
|
||||
if (bombsource != thing) {
|
||||
dir[2] *= 0.5f;
|
||||
} else if (splashfactor->value) {
|
||||
dir[0] *= selfthrustscale;
|
||||
dir[1] *= selfthrustscale;
|
||||
dir[2] *= selfthrustscale;
|
||||
}
|
||||
thing->momx = momx + (fixed_t)(dir[0]);
|
||||
thing->momy = momy + (fixed_t)(dir[1]);
|
||||
thing->momz += (fixed_t)(dir[2]);
|
||||
|
@ -1477,7 +1793,7 @@ BOOL PIT_RadiusAttack (mobj_t *thing)
|
|||
if (dist < 0)
|
||||
dist = 0;
|
||||
|
||||
if ( P_CheckSight (thing, bombspot) )
|
||||
if ( P_CheckSight (thing, bombspot, true) )
|
||||
{
|
||||
// must be in direct path
|
||||
P_DamageMobj (thing, bombspot, bombsource, bombdamage - dist, bombmod);
|
||||
|
@ -1530,14 +1846,19 @@ void P_RadiusAttack (mobj_t *spot, mobj_t *source, int damage, int mod)
|
|||
// of all things that touch the sector.
|
||||
//
|
||||
// If anything doesn't fit anymore, true will be returned.
|
||||
// If crunch is true, they will take damage
|
||||
// as they are being crushed.
|
||||
// If Crunch is false, you should set the sector height back
|
||||
// the way it was and call P_ChangeSector again
|
||||
// to undo the changes.
|
||||
//
|
||||
BOOL crushchange;
|
||||
BOOL nofit;
|
||||
// [RH] If crushchange is non-negative, they will take the
|
||||
// specified amount of damage as they are being crushed.
|
||||
// If crushchange is negative, you should set the sector
|
||||
// height back the way it was and call P_ChangeSector
|
||||
// again to undo the changes.
|
||||
// Note that this is very different from the original
|
||||
// true/false usage of crushchange! If you want regular
|
||||
// DOOM crushing behavior set crushchange to 10 or -1
|
||||
// if no crushing is desired.
|
||||
//
|
||||
int crushchange;
|
||||
BOOL nofit;
|
||||
|
||||
|
||||
//
|
||||
|
@ -1585,9 +1906,9 @@ BOOL PIT_ChangeSector (mobj_t *thing)
|
|||
|
||||
nofit = true;
|
||||
|
||||
if (crushchange && !(level.time&3) )
|
||||
if ((crushchange >= 0) && !(level.time&3) )
|
||||
{
|
||||
P_DamageMobj(thing,NULL,NULL,10,MOD_CRUSH);
|
||||
P_DamageMobj (thing, NULL, NULL, crushchange, MOD_CRUSH);
|
||||
|
||||
// spray blood in a random direction
|
||||
mo = P_SpawnMobj (thing->x,
|
||||
|
@ -1609,14 +1930,18 @@ BOOL PIT_ChangeSector (mobj_t *thing)
|
|||
//
|
||||
// P_ChangeSector
|
||||
//
|
||||
BOOL P_ChangeSector (sector_t *sector, BOOL crunch)
|
||||
BOOL P_ChangeSector (sector_t *sector, int crunch)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
|
||||
nofit = false;
|
||||
crushchange = crunch;
|
||||
|
||||
|
||||
// ARRGGHHH!!!!
|
||||
// This is horrendously slow!!!
|
||||
// killough 3/14/98
|
||||
|
||||
// re-check heights for all things near the moving sector
|
||||
for (x=sector->blockbox[BOXLEFT] ; x<= sector->blockbox[BOXRIGHT] ; x++)
|
||||
for (y=sector->blockbox[BOXBOTTOM];y<= sector->blockbox[BOXTOP] ; y++)
|
||||
|
@ -1632,12 +1957,12 @@ BOOL P_ChangeSector (sector_t *sector, BOOL crunch)
|
|||
// sector. Both more accurate and faster.
|
||||
//
|
||||
|
||||
BOOL P_CheckSector (sector_t *sector, BOOL crunch)
|
||||
BOOL P_CheckSector (sector_t *sector, int crunch)
|
||||
{
|
||||
msecnode_t *n;
|
||||
|
||||
if (olddemo) // use the old routine for old demos though
|
||||
return P_ChangeSector(sector,crunch);
|
||||
return P_ChangeSector (sector, crunch);
|
||||
|
||||
nofit = false;
|
||||
crushchange = crunch;
|
||||
|
|
103
code/P_maputl.c
103
code/P_maputl.c
|
@ -67,14 +67,14 @@ int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line)
|
|||
|
||||
return line->dy < 0;
|
||||
}
|
||||
if (!line->dy)
|
||||
else if (!line->dy)
|
||||
{
|
||||
if (y <= line->v1->y)
|
||||
return line->dx < 0;
|
||||
|
||||
return line->dx > 0;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
fixed_t left = FixedMul ( line->dy>>FRACBITS , (x - line->v1->x) );
|
||||
fixed_t right = FixedMul ( (y - line->v1->y) , line->dx>>FRACBITS );
|
||||
|
@ -142,11 +142,6 @@ int P_BoxOnLineSide (const fixed_t *tmbox, const line_t *ld)
|
|||
//
|
||||
int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line)
|
||||
{
|
||||
fixed_t dx;
|
||||
fixed_t dy;
|
||||
fixed_t left;
|
||||
fixed_t right;
|
||||
|
||||
if (!line->dx)
|
||||
{
|
||||
if (x <= line->x)
|
||||
|
@ -154,31 +149,35 @@ int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line)
|
|||
|
||||
return line->dy < 0;
|
||||
}
|
||||
if (!line->dy)
|
||||
else if (!line->dy)
|
||||
{
|
||||
if (y <= line->y)
|
||||
return line->dx < 0;
|
||||
|
||||
return line->dx > 0;
|
||||
}
|
||||
|
||||
dx = (x - line->x);
|
||||
dy = (y - line->y);
|
||||
|
||||
// try to quickly decide by looking at sign bits
|
||||
if ( (line->dy ^ line->dx ^ dx ^ dy)&0x80000000 )
|
||||
else
|
||||
{
|
||||
if ( (line->dy ^ dx) & 0x80000000 )
|
||||
return 1; // (left is negative)
|
||||
return 0;
|
||||
fixed_t dx = (x - line->x);
|
||||
fixed_t dy = (y - line->y);
|
||||
|
||||
// try to quickly decide by looking at sign bits
|
||||
if ( (line->dy ^ line->dx ^ dx ^ dy)&0x80000000 )
|
||||
{
|
||||
if ( (line->dy ^ dx) & 0x80000000 )
|
||||
return 1; // (left is negative)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t left = FixedMul ( line->dy>>8, dx>>8 );
|
||||
fixed_t right = FixedMul ( dy>>8 , line->dx>>8 );
|
||||
|
||||
if (right < left)
|
||||
return 0; // front side
|
||||
return 1; // back side
|
||||
}
|
||||
}
|
||||
|
||||
left = FixedMul ( line->dy>>8, dx>>8 );
|
||||
right = FixedMul ( dy>>8 , line->dx>>8 );
|
||||
|
||||
if (right < left)
|
||||
return 0; // front side
|
||||
return 1; // back side
|
||||
}
|
||||
|
||||
|
||||
|
@ -198,10 +197,8 @@ void P_MakeDivline (const line_t *li, divline_t *dl)
|
|||
|
||||
//
|
||||
// P_InterceptVector
|
||||
// Returns the fractional intercept point
|
||||
// along the first divline.
|
||||
// This is only called by the addthings
|
||||
// and addlines traversers.
|
||||
// Returns the fractional intercept point along the first divline.
|
||||
// This is only called by the addthings and addlines traversers.
|
||||
//
|
||||
fixed_t P_InterceptVector (const divline_t *v2, const divline_t *v1)
|
||||
{
|
||||
|
@ -284,10 +281,9 @@ void P_LineOpening (const line_t *linedef)
|
|||
front = linedef->frontsector;
|
||||
back = linedef->backsector;
|
||||
|
||||
if (front->ceilingheight < back->ceilingheight)
|
||||
opentop = front->ceilingheight;
|
||||
else
|
||||
opentop = back->ceilingheight;
|
||||
opentop = (front->ceilingheight < back->ceilingheight) ?
|
||||
opentop = front->ceilingheight :
|
||||
back->ceilingheight;
|
||||
|
||||
if (front->floorheight > back->floorheight)
|
||||
{
|
||||
|
@ -313,14 +309,11 @@ void P_LineOpening (const line_t *linedef)
|
|||
// P_UnsetThingPosition
|
||||
// Unlinks a thing from block map and sectors.
|
||||
// On each position change, BLOCKMAP and other
|
||||
// lookups maintaining lists ot things inside
|
||||
// lookups maintaining lists of things inside
|
||||
// these structures need to be updated.
|
||||
//
|
||||
void P_UnsetThingPosition (mobj_t *thing)
|
||||
{
|
||||
int blockx;
|
||||
int blocky;
|
||||
|
||||
if (!(thing->flags & MF_NOSECTOR))
|
||||
{
|
||||
// inert things don't need to be in blockmap?
|
||||
|
@ -361,8 +354,8 @@ void P_UnsetThingPosition (mobj_t *thing)
|
|||
thing->bprev->bnext = thing->bnext;
|
||||
else
|
||||
{
|
||||
blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
int blockx = (thing->x - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
int blocky = (thing->y - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
|
||||
if (blockx>=0 && blockx < bmapwidth
|
||||
&& blocky>=0 && blocky <bmapheight)
|
||||
|
@ -476,7 +469,7 @@ BOOL P_BlockLinesIterator (int x, int y, BOOL(*func)(line_t*))
|
|||
{
|
||||
if (x<0 || y<0 || x>=bmapwidth || y>=bmapheight)
|
||||
return true;
|
||||
|
||||
else
|
||||
{
|
||||
int offset = *(blockmap+(y*bmapwidth+x));
|
||||
int *list = blockmaplump + offset;
|
||||
|
@ -490,13 +483,12 @@ BOOL P_BlockLinesIterator (int x, int y, BOOL(*func)(line_t*))
|
|||
{
|
||||
line_t *ld = &lines[*list];
|
||||
|
||||
if (ld->validcount == validcount)
|
||||
continue; // line has already been checked
|
||||
|
||||
ld->validcount = validcount;
|
||||
if (ld->validcount != validcount) {
|
||||
ld->validcount = validcount;
|
||||
|
||||
if ( !func(ld) )
|
||||
return false;
|
||||
if ( !func(ld) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true; // everything was checked
|
||||
|
@ -510,7 +502,7 @@ BOOL P_BlockThingsIterator (int x, int y, BOOL(*func)(mobj_t*))
|
|||
{
|
||||
if (x<0 || y<0 || x>=bmapwidth || y>=bmapheight)
|
||||
return true;
|
||||
|
||||
else
|
||||
{
|
||||
mobj_t *mobj;
|
||||
|
||||
|
@ -603,19 +595,19 @@ BOOL PIT_AddLineIntercepts (line_t *ld)
|
|||
//
|
||||
BOOL PIT_AddThingIntercepts (mobj_t* thing)
|
||||
{
|
||||
fixed_t x1;
|
||||
fixed_t y1;
|
||||
fixed_t x2;
|
||||
fixed_t y2;
|
||||
fixed_t x1;
|
||||
fixed_t y1;
|
||||
fixed_t x2;
|
||||
fixed_t y2;
|
||||
|
||||
int s1;
|
||||
int s2;
|
||||
int s1;
|
||||
int s2;
|
||||
|
||||
BOOL tracepositive;
|
||||
|
||||
divline_t dl;
|
||||
divline_t dl;
|
||||
|
||||
fixed_t frac;
|
||||
fixed_t frac;
|
||||
|
||||
tracepositive = (trace.dx ^ trace.dy)>0;
|
||||
|
||||
|
@ -834,8 +826,7 @@ BOOL P_PathTraverse (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2, int flags,
|
|||
return false; // early out
|
||||
}
|
||||
|
||||
if (mapx == xt2
|
||||
&& mapy == yt2)
|
||||
if (mapx == xt2 && mapy == yt2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
400
code/P_mobj.c
400
code/P_mobj.c
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
#include "sounds.h"
|
||||
#include "p_lnspec.h"
|
||||
|
||||
#include "st_stuff.h"
|
||||
#include "hu_stuff.h"
|
||||
|
@ -47,7 +47,6 @@ cvar_t *sv_friction;
|
|||
|
||||
|
||||
void G_PlayerReborn (int player);
|
||||
void P_SpawnMapThing (mapthing2_t *mthing);
|
||||
|
||||
|
||||
//
|
||||
|
@ -83,7 +82,8 @@ BOOL P_SetMobjState (mobj_t *mobj, statenum_t state)
|
|||
st = &states[state];
|
||||
mobj->state = st;
|
||||
mobj->tics = st->tics;
|
||||
mobj->sprite = st->sprite;
|
||||
if (!mobj->player) // [RH] Only change sprite if not a player
|
||||
mobj->sprite = st->sprite;
|
||||
mobj->frame = st->frame;
|
||||
|
||||
// Modified handling.
|
||||
|
@ -129,13 +129,16 @@ void P_ExplodeMissile (mobj_t* mo)
|
|||
mo->flags &= ~MF_MISSILE;
|
||||
|
||||
if (mo->info->deathsound)
|
||||
S_StartSound (mo, mo->info->deathsound);
|
||||
S_StartSound (mo, mo->info->deathsound, 70);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// P_XYMovement
|
||||
//
|
||||
extern int numspechit;
|
||||
extern line_t **spechit;
|
||||
|
||||
#define STOPSPEED 0x1000
|
||||
#define FRICTION 0xe800
|
||||
|
||||
|
@ -146,7 +149,9 @@ void P_XYMovement (mobj_t* mo)
|
|||
player_t* player;
|
||||
fixed_t xmove;
|
||||
fixed_t ymove;
|
||||
|
||||
fixed_t oldx,oldy; // phares 9/10/98: reducing bobbing/momentum on ice
|
||||
// when up against walls
|
||||
|
||||
if (!mo->momx && !mo->momy)
|
||||
{
|
||||
if (mo->flags & MF_SKULLFLY)
|
||||
|
@ -175,6 +180,9 @@ void P_XYMovement (mobj_t* mo)
|
|||
xmove = mo->momx;
|
||||
ymove = mo->momy;
|
||||
|
||||
oldx = mo->x; // phares 9/10/98: new code to reduce bobbing/momentum
|
||||
oldy = mo->y; // when on ice & up against wall. These will be compared
|
||||
// to your x,y values later to see if you were able to move
|
||||
do
|
||||
{
|
||||
if (xmove > MAXMOVE/2 || ymove > MAXMOVE/2)
|
||||
|
@ -191,15 +199,28 @@ void P_XYMovement (mobj_t* mo)
|
|||
xmove = ymove = 0;
|
||||
}
|
||||
|
||||
if (!P_TryMove (mo, ptryx, ptryy))
|
||||
// killough 3/15/98: Allow objects to drop off
|
||||
|
||||
if (!P_TryMove (mo, ptryx, ptryy, true))
|
||||
{
|
||||
// blocked move
|
||||
if (mo->player)
|
||||
{ // try to slide along it
|
||||
{
|
||||
// [RH] Activate any potential special lines
|
||||
while (numspechit-- > 0)
|
||||
P_PushSpecialLine (mo,
|
||||
P_PointOnLineSide (mo->x, mo->y, spechit[numspechit]),
|
||||
spechit[numspechit]);
|
||||
|
||||
// try to slide along it
|
||||
P_SlideMove (mo);
|
||||
}
|
||||
else if (mo->flags & MF_MISSILE)
|
||||
{
|
||||
// [RH] missiles can activate projectile hit lines, too
|
||||
if (!olddemo)
|
||||
while (numspechit > 0)
|
||||
P_ShootSpecialLine (mo, spechit[--numspechit]);
|
||||
// explode a missile
|
||||
if (ceilingline &&
|
||||
ceilingline->backsector &&
|
||||
|
@ -269,20 +290,42 @@ void P_XYMovement (mobj_t* mo)
|
|||
}
|
||||
else
|
||||
{
|
||||
mo->momx = FixedMul (mo->momx, FRICTION);
|
||||
mo->momy = FixedMul (mo->momy, FRICTION);
|
||||
// phares 3/17/98
|
||||
// Friction will have been adjusted by friction thinkers for icy
|
||||
// or muddy floors. Otherwise it was never touched and
|
||||
// remained set at ORIG_FRICTION
|
||||
|
||||
// phares 9/10/98: reduce bobbing/momentum when on ice & up against wall
|
||||
|
||||
if ((oldx == mo->x) && (oldy == mo->y)) // Did you go anywhere?
|
||||
{ // No. Use original friction. This allows you to not bob so much
|
||||
// if you're on ice, but keeps enough momentum around to break free
|
||||
// when you're mildly stuck in a wall.
|
||||
mo->momx = FixedMul(mo->momx,ORIG_FRICTION);
|
||||
mo->momy = FixedMul(mo->momy,ORIG_FRICTION);
|
||||
}
|
||||
else
|
||||
{ // Yes. Use stored friction.
|
||||
mo->momx = FixedMul(mo->momx,mo->friction);
|
||||
mo->momy = FixedMul(mo->momy,mo->friction);
|
||||
}
|
||||
mo->friction = ORIG_FRICTION; // reset to normal for next tic
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_ZMovement
|
||||
//
|
||||
void P_ZMovement (mobj_t* mo)
|
||||
void P_ZMovement (mobj_t *mo)
|
||||
{
|
||||
fixed_t dist;
|
||||
fixed_t delta;
|
||||
mobj_t *other;
|
||||
fixed_t movez;
|
||||
|
||||
if (mo->flags2 & MF2_NOADJUST)
|
||||
return;
|
||||
|
||||
// check for smooth step up
|
||||
if (mo->player && mo->z < mo->floorz)
|
||||
{
|
||||
|
@ -293,14 +336,13 @@ void P_ZMovement (mobj_t* mo)
|
|||
}
|
||||
|
||||
// adjust height
|
||||
mo->z += mo->momz;
|
||||
mo->z += (movez = mo->momz);
|
||||
|
||||
if ( mo->flags & MF_FLOAT
|
||||
&& mo->target)
|
||||
{
|
||||
// float down towards target if too close
|
||||
if ( !(mo->flags & MF_SKULLFLY)
|
||||
&& !(mo->flags & MF_INFLOAT) )
|
||||
if ( !(mo->flags & MF_SKULLFLY) && !(mo->flags & MF_INFLOAT) )
|
||||
{
|
||||
dist = P_AproxDistance (mo->x - mo->target->x,
|
||||
mo->y - mo->target->y);
|
||||
|
@ -323,7 +365,7 @@ void P_ZMovement (mobj_t* mo)
|
|||
other = NULL;
|
||||
} else {
|
||||
other = P_FindFloor (mo); // [RH] Z-Check
|
||||
if ((mo->flags & MF_MISSILE) && (other == mo->target) && (gametic < (signed)mo->targettic))
|
||||
if ((mo->flags & MF_MISSILE) && (other == mo->target) && mo->targettic)
|
||||
other = NULL;
|
||||
}
|
||||
|
||||
|
@ -342,48 +384,14 @@ void P_ZMovement (mobj_t* mo)
|
|||
if (mo->momz < 0)
|
||||
{
|
||||
if (mo->player
|
||||
&& mo->momz < (fixed_t)(sv_gravity->value * -655.36))
|
||||
&& mo->momz < (fixed_t)(sv_gravity->value * mo->subsector->sector->gravity * -655.36f))
|
||||
{
|
||||
// [RH] Andy Kempling's fall damage mod.
|
||||
// (adapted to work with ZDoom)
|
||||
// calculate the number of broken bones... (joke)
|
||||
// damage player according to the height fallen.
|
||||
//
|
||||
if (dmflags & (DF_YES_FALLING|DF_YES_FALLING_LOTS)) {
|
||||
fixed_t minvelocity;
|
||||
fixed_t damage;
|
||||
float divisor;
|
||||
|
||||
if (dmflags & DF_YES_FALLING_LOTS) {
|
||||
// Original values
|
||||
minvelocity = -741455*4/3;
|
||||
divisor = -26214400.0f;
|
||||
} else {
|
||||
// Not-quite-so-damaging values
|
||||
minvelocity = -741455*5/3;
|
||||
divisor = -39321600.0f;
|
||||
}
|
||||
|
||||
if (mo->momz < minvelocity) {
|
||||
damage = (fixed_t)((float)(mo->momz) * sv_gravity->value / divisor);
|
||||
if (other != (mobj_t *)-1) {
|
||||
// [RH] We landed on another thing. Give half the damage to it.
|
||||
damage >>= 1;
|
||||
P_DamageMobj (other, mo, mo, damage, MOD_FALLXFER);
|
||||
}
|
||||
if (mo->player) {
|
||||
// Monsters don't take falling damage
|
||||
P_DamageMobj(mo, mo, mo, damage, MOD_FALLING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Squat down.
|
||||
// Decrease viewheight for a moment
|
||||
// after hitting the ground (hard),
|
||||
// and utter appropriate sound.
|
||||
mo->player->deltaviewheight = mo->momz>>3;
|
||||
S_StartSound (mo, sfx_oof);
|
||||
S_StartSound (mo, "*land1", 96);
|
||||
}
|
||||
mo->momz = 0;
|
||||
}
|
||||
|
@ -401,15 +409,14 @@ void P_ZMovement (mobj_t* mo)
|
|||
P_ExplodeMissile (mo);
|
||||
return;
|
||||
}
|
||||
|
||||
P_StandOnThing (mo, other);
|
||||
}
|
||||
else if (! (mo->flags & MF_NOGRAVITY) )
|
||||
{
|
||||
if (mo->momz == 0)
|
||||
mo->momz = (fixed_t)(sv_gravity->value * -163.84);
|
||||
mo->momz = (fixed_t)(sv_gravity->value * mo->subsector->sector->gravity * -163.84);
|
||||
else
|
||||
mo->momz -= (fixed_t)(sv_gravity->value * 81.92);
|
||||
mo->momz -= (fixed_t)(sv_gravity->value * mo->subsector->sector->gravity * 81.92);
|
||||
}
|
||||
|
||||
if (olddemo) {
|
||||
|
@ -419,7 +426,7 @@ void P_ZMovement (mobj_t* mo)
|
|||
other = NULL;
|
||||
} else {
|
||||
other = P_FindCeiling (mo); // [RH] Z-Check
|
||||
if ((mo->flags & MF_MISSILE) && (other == mo->target) && (gametic < (signed)mo->targettic))
|
||||
if ((mo->flags & MF_MISSILE) && (other == mo->target) && mo->targettic)
|
||||
other = NULL;
|
||||
}
|
||||
|
||||
|
@ -464,7 +471,7 @@ void P_ZMovement (mobj_t* mo)
|
|||
//
|
||||
// P_NightmareRespawn
|
||||
//
|
||||
void P_NightmareRespawn (mobj_t* mobj)
|
||||
void P_NightmareRespawn (mobj_t *mobj)
|
||||
{
|
||||
fixed_t x;
|
||||
fixed_t y;
|
||||
|
@ -488,7 +495,7 @@ void P_NightmareRespawn (mobj_t* mobj)
|
|||
mobj->y,
|
||||
0, MT_TFOG, ONFLOORZ);
|
||||
// initiate teleport sound
|
||||
S_StartSound (mo, sfx_telept);
|
||||
S_StartSound (mo, "misc/teleport", 32);
|
||||
|
||||
ss = R_PointInSubsector (x,y);
|
||||
|
||||
|
@ -500,7 +507,7 @@ void P_NightmareRespawn (mobj_t* mobj)
|
|||
|
||||
mo = P_SpawnMobj (x, y, z, MT_TFOG, onfloor);
|
||||
|
||||
S_StartSound (mo, sfx_telept);
|
||||
S_StartSound (mo, "misc/teleport", 32);
|
||||
|
||||
// spawn the new monster
|
||||
mthing = &mobj->spawnpoint;
|
||||
|
@ -521,15 +528,134 @@ void P_NightmareRespawn (mobj_t* mobj)
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// [RH] Some new functions to work with Thing IDs. ------->
|
||||
//
|
||||
static mobj_t *tidhash[128];
|
||||
#define TIDHASH(i) ((i)&127)
|
||||
|
||||
//
|
||||
// P_ClearTidHashes
|
||||
//
|
||||
// Clears the tid hashtable.
|
||||
//
|
||||
void P_ClearTidHashes (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 128; i++)
|
||||
tidhash[i] = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// P_AddMobjToHash
|
||||
//
|
||||
// Inserts an mobj into the correct chain based on its tid.
|
||||
// If its tid is 0, this function does nothing.
|
||||
//
|
||||
void P_AddMobjToHash (mobj_t *mobj)
|
||||
{
|
||||
if (mobj->tid == 0) {
|
||||
mobj->inext = mobj->iprev = NULL;
|
||||
return;
|
||||
} else {
|
||||
int hash = TIDHASH(mobj->tid);
|
||||
|
||||
mobj->inext = tidhash[hash];
|
||||
mobj->iprev = NULL;
|
||||
tidhash[hash] = mobj;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_RemoveMobjFromHash
|
||||
//
|
||||
// Removes an mobj from its hash chain.
|
||||
//
|
||||
void P_RemoveMobjFromHash (mobj_t *mobj)
|
||||
{
|
||||
if (mobj->tid == 0)
|
||||
return;
|
||||
else {
|
||||
if (mobj->iprev == NULL) {
|
||||
// First mobj in the chain (probably)
|
||||
int hash = TIDHASH(mobj->tid);
|
||||
|
||||
if (tidhash[hash] == mobj)
|
||||
tidhash[hash] = mobj->inext;
|
||||
if (mobj->inext) {
|
||||
mobj->inext->iprev = NULL;
|
||||
mobj->inext = NULL;
|
||||
}
|
||||
} else {
|
||||
// Not the first mobj in the chain
|
||||
mobj->iprev->inext = mobj->inext;
|
||||
if (mobj->inext) {
|
||||
mobj->inext->iprev = mobj->iprev;
|
||||
mobj->inext = NULL;
|
||||
}
|
||||
mobj->iprev = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_FindMobjByTid
|
||||
//
|
||||
// Returns the next mobj with the tid after the one given,
|
||||
// or the first with that tid if no mobj is passed. Returns
|
||||
// NULL if there are no more.
|
||||
//
|
||||
mobj_t *P_FindMobjByTid (mobj_t *mobj, int tid)
|
||||
{
|
||||
// Mobjs without tid are never stored.
|
||||
if (tid == 0)
|
||||
return NULL;
|
||||
|
||||
if (!mobj)
|
||||
mobj = tidhash[TIDHASH(tid)];
|
||||
else
|
||||
mobj = mobj->inext;
|
||||
|
||||
while (mobj && mobj->tid != tid)
|
||||
mobj = mobj->inext;
|
||||
|
||||
return mobj;
|
||||
}
|
||||
|
||||
//
|
||||
// P_FindGoal
|
||||
//
|
||||
// Like P_FindMobjByTid except it also matcheds on type.
|
||||
//
|
||||
mobj_t *P_FindGoal (mobj_t *mobj, int tid, int kind)
|
||||
{
|
||||
mobj_t *goal;
|
||||
|
||||
do {
|
||||
goal = P_FindMobjByTid (mobj, tid);
|
||||
} while (goal && goal->type != kind);
|
||||
|
||||
return goal;
|
||||
}
|
||||
|
||||
// <------- [RH] End new functions
|
||||
|
||||
|
||||
//
|
||||
// P_MobjThinker
|
||||
//
|
||||
void P_MobjThinker (mobj_t* mobj)
|
||||
void P_MobjThinker (mobj_t *mobj)
|
||||
{
|
||||
if (mobj == (mobj_t *)0x0131E0D8) {
|
||||
int foo = 50;
|
||||
}
|
||||
// [RH] Decrement targettic
|
||||
if (mobj->targettic)
|
||||
mobj->targettic--;
|
||||
|
||||
// momentum movement
|
||||
if (mobj->momx
|
||||
|| mobj->momy
|
||||
|| (mobj->flags&MF_SKULLFLY) )
|
||||
if (mobj->momx || mobj->momy || (mobj->flags&MF_SKULLFLY) )
|
||||
{
|
||||
P_XYMovement (mobj);
|
||||
|
||||
|
@ -537,8 +663,7 @@ void P_MobjThinker (mobj_t* mobj)
|
|||
if (mobj->thinker.function.acv == (actionf_v) (-1))
|
||||
return; // mobj was removed
|
||||
}
|
||||
if ( (mobj->z != mobj->floorz)
|
||||
|| mobj->momz )
|
||||
if ( (mobj->z != mobj->floorz) || mobj->momz )
|
||||
{
|
||||
P_ZMovement (mobj);
|
||||
|
||||
|
@ -547,6 +672,9 @@ void P_MobjThinker (mobj_t* mobj)
|
|||
return; // mobj was removed
|
||||
}
|
||||
|
||||
// [RH] Dormant things do no state changes
|
||||
if (mobj->flags2 & MF2_DORMANT)
|
||||
return;
|
||||
|
||||
// cycle through states,
|
||||
// calling action functions at transitions
|
||||
|
@ -581,7 +709,6 @@ void P_MobjThinker (mobj_t* mobj)
|
|||
|
||||
P_NightmareRespawn (mobj);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -609,6 +736,10 @@ mobj_t *P_SpawnMobj (fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, int onflo
|
|||
mobj->height = info->height;
|
||||
mobj->flags = info->flags;
|
||||
mobj->health = info->spawnhealth;
|
||||
if (type == MT_BRIDGE) // [RH] Floating bridge never adjusts its Z-position
|
||||
mobj->flags2 |= MF2_NOADJUST;
|
||||
if (mobj->flags & MF_STEALTH) // [RH] Stealth monsters start out invisible
|
||||
mobj->flags2 |= MF2_INVISIBLE;
|
||||
|
||||
if (gameskill->value != sk_nightmare)
|
||||
mobj->reactiontime = info->reactiontime;
|
||||
|
@ -637,13 +768,10 @@ mobj_t *P_SpawnMobj (fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, int onflo
|
|||
else
|
||||
mobj->z = z;
|
||||
|
||||
mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
|
||||
|
||||
P_AddThinker (&mobj->thinker);
|
||||
mobj->friction = ORIG_FRICTION; // phares 3/17/98
|
||||
|
||||
// [RH] If it's an ambient sound, activate it
|
||||
if (type >= MT_AMBIENT0 && type <= MT_AMBIENT63)
|
||||
S_ActivateAmbient (mobj, type - MT_AMBIENT0);
|
||||
mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
|
||||
P_AddThinker (&mobj->thinker);
|
||||
|
||||
return mobj;
|
||||
}
|
||||
|
@ -677,6 +805,9 @@ void P_RemoveMobj (mobj_t* mobj)
|
|||
// unlink from sector and block lists
|
||||
P_UnsetThingPosition (mobj);
|
||||
|
||||
// [RH] Unlink from tid chain
|
||||
P_RemoveMobjFromHash (mobj);
|
||||
|
||||
// Delete all nodes on the current sector_list phares 3/16/98
|
||||
|
||||
if (sector_list)
|
||||
|
@ -744,7 +875,7 @@ void P_RespawnSpecials (void)
|
|||
// spawn a teleport fog at the new spot
|
||||
ss = R_PointInSubsector (x,y);
|
||||
mo = P_SpawnMobj (x, y, z, MT_IFOG, onfloor);
|
||||
S_StartSound (mo, sfx_itmbk);
|
||||
S_StartSound (mo, "misc/spawn", 100);
|
||||
|
||||
// spawn it
|
||||
mo = P_SpawnMobj (x,y,z, i, onfloor);
|
||||
|
@ -766,50 +897,39 @@ void P_RespawnSpecials (void)
|
|||
//
|
||||
void P_SpawnPlayer (mapthing2_t *mthing)
|
||||
{
|
||||
int playernum;
|
||||
player_t *p;
|
||||
fixed_t x;
|
||||
fixed_t y;
|
||||
fixed_t z;
|
||||
|
||||
mobj_t *mobj;
|
||||
|
||||
int i;
|
||||
|
||||
// not playing?
|
||||
// [RH] Things 4001-? are also multiplayer starts.
|
||||
if (mthing->type > 4000) {
|
||||
if (!playeringame[mthing->type - 4001 + 4])
|
||||
return;
|
||||
else {
|
||||
p = &players[mthing->type - 4001 + 4];
|
||||
if (p->playerstate == PST_REBORN)
|
||||
G_PlayerReborn (mthing->type - 4001 + 4);
|
||||
}
|
||||
} else {
|
||||
if (!playeringame[mthing->type-1])
|
||||
return;
|
||||
else {
|
||||
p = &players[mthing->type-1];
|
||||
if (p->playerstate == PST_REBORN)
|
||||
G_PlayerReborn (mthing->type - 1);
|
||||
}
|
||||
}
|
||||
// [RH] Things 4001-? are also multiplayer starts. Just like 1-4.
|
||||
// To make things simpler, figure out which player is being
|
||||
// spawned here.
|
||||
playernum = (mthing->type > 4000) ? mthing->type - 4001 + 4 : mthing->type - 1;
|
||||
|
||||
x = mthing->x << FRACBITS;
|
||||
y = mthing->y << FRACBITS;
|
||||
z = mthing->z << FRACBITS;
|
||||
mobj = P_SpawnMobj (x,y,z, MT_PLAYER, ONFLOORZ);
|
||||
// not playing?
|
||||
if (playernum >= MAXPLAYERS || !playeringame[playernum])
|
||||
return;
|
||||
|
||||
p = &players[playernum];
|
||||
if (p->playerstate == PST_REBORN)
|
||||
G_PlayerReborn (playernum);
|
||||
|
||||
mobj = P_SpawnMobj (mthing->x << FRACBITS, mthing->y << FRACBITS, 0, MT_PLAYER, ONFLOORZ);
|
||||
|
||||
// set color translations for player sprites
|
||||
// [RH] Different now: MF_TRANSLATION is not used.
|
||||
mobj->palette = (struct palette_s *)(translationtables + (mthing->type-1)*256);
|
||||
mobj->palette = (struct palette_s *)(translationtables + 256*playernum);
|
||||
|
||||
mobj->angle = ANG45 * (mthing->angle/45);
|
||||
mobj->pitch = mobj->roll = 0;
|
||||
mobj->player = p;
|
||||
mobj->health = p->health;
|
||||
|
||||
p->mo = mobj;
|
||||
// [RH] Set player sprite based on skin
|
||||
mobj->sprite = skins[p->userinfo.skin].sprite;
|
||||
|
||||
p->camera = p->mo = mobj; // [RH]
|
||||
p->playerstate = PST_LIVE;
|
||||
p->refire = 0;
|
||||
p->message = NULL;
|
||||
|
@ -827,14 +947,17 @@ void P_SpawnPlayer (mapthing2_t *mthing)
|
|||
for (i=0 ; i<NUMCARDS ; i++)
|
||||
p->cards[i] = true;
|
||||
|
||||
if (consoleplayer ==
|
||||
(mthing->type > 4000 ? mthing->type - 4001 + 4 : mthing->type - 1))
|
||||
if (consoleplayer == playernum)
|
||||
{
|
||||
// wake up the status bar
|
||||
ST_Start ();
|
||||
// wake up the heads up text
|
||||
HU_Start ();
|
||||
}
|
||||
|
||||
// [RH] If someone is in the way, kill them
|
||||
if (!olddemo)
|
||||
P_TeleportMove (mobj, mobj->x, mobj->y, mobj->z, true);
|
||||
}
|
||||
|
||||
|
||||
|
@ -843,7 +966,8 @@ void P_SpawnPlayer (mapthing2_t *mthing)
|
|||
// The fields of the mapthing should
|
||||
// already be in host byte order.
|
||||
//
|
||||
void P_SpawnMapThing (mapthing2_t *mthing)
|
||||
// [RH] position is used to weed out unwanted start spots
|
||||
void P_SpawnMapThing (mapthing2_t *mthing, int position)
|
||||
{
|
||||
int i;
|
||||
int bit;
|
||||
|
@ -858,7 +982,7 @@ void P_SpawnMapThing (mapthing2_t *mthing)
|
|||
{
|
||||
if (deathmatch_p == &deathmatchstarts[MaxDeathmatchStarts]) {
|
||||
// [RH] Get more deathmatchstarts
|
||||
MaxDeathmatchStarts += 8;
|
||||
MaxDeathmatchStarts *= 2;
|
||||
deathmatchstarts = Realloc (deathmatchstarts, MaxDeathmatchStarts * sizeof(mapthing2_t));
|
||||
deathmatch_p = &deathmatchstarts[MaxDeathmatchStarts - 8];
|
||||
}
|
||||
|
@ -870,6 +994,10 @@ void P_SpawnMapThing (mapthing2_t *mthing)
|
|||
// check for players specially
|
||||
if (mthing->type <= 4 && mthing->type > 0)
|
||||
{
|
||||
// [RH] Only spawn spots that match position.
|
||||
if (mthing->args[0] != position)
|
||||
return;
|
||||
|
||||
// save spots for respawning in network games
|
||||
playerstarts[mthing->type-1] = *mthing;
|
||||
if (!deathmatch->value)
|
||||
|
@ -878,6 +1006,11 @@ void P_SpawnMapThing (mapthing2_t *mthing)
|
|||
return;
|
||||
} else if (mthing->type >= 4001 && mthing->type <= 4001 + MAXPLAYERS - 4) {
|
||||
// [RH] Multiplayer starts for players 5-?
|
||||
|
||||
// [RH] Only spawn spots that match position.
|
||||
if (mthing->args[0] != position)
|
||||
return;
|
||||
|
||||
playerstarts[mthing->type - 4001 + 4] = *mthing;
|
||||
if (!deathmatch->value)
|
||||
P_SpawnPlayer (mthing);
|
||||
|
@ -892,8 +1025,10 @@ void P_SpawnMapThing (mapthing2_t *mthing)
|
|||
if (!(mthing->flags & MTF_COOPERATIVE))
|
||||
return;
|
||||
}
|
||||
} else if (!(mthing->flags & MTF_SINGLE))
|
||||
return;
|
||||
} else {
|
||||
if (!(mthing->flags & MTF_SINGLE))
|
||||
return;
|
||||
}
|
||||
|
||||
// check for apropriate skill level
|
||||
if (gameskill->value == sk_baby)
|
||||
|
@ -906,10 +1041,18 @@ void P_SpawnMapThing (mapthing2_t *mthing)
|
|||
if (!(mthing->flags & bit) )
|
||||
return;
|
||||
|
||||
// find which type to spawn
|
||||
for (i=0 ; i< NUMMOBJTYPES ; i++)
|
||||
if (mthing->type == mobjinfo[i].doomednum)
|
||||
break;
|
||||
// [RH] Determine if it is an old ambient thing, and if so,
|
||||
// map it to MT_AMBIENT with the proper parameter.
|
||||
if (mthing->type >= 14001 && mthing->type <= 14064) {
|
||||
mthing->args[0] = mthing->type - 14000;
|
||||
mthing->type = 14065;
|
||||
i = MT_AMBIENT;
|
||||
} else {
|
||||
// find which type to spawn
|
||||
for (i=0 ; i< NUMMOBJTYPES ; i++)
|
||||
if (mthing->type == mobjinfo[i].doomednum)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i==NUMMOBJTYPES) {
|
||||
// [RH] Don't die if the map tries to spawn an unknown thing
|
||||
|
@ -994,6 +1137,14 @@ void P_SpawnMapThing (mapthing2_t *mthing)
|
|||
mobj = P_SpawnMobj (x,y,z, i, onfloor);
|
||||
mobj->spawnpoint = *mthing;
|
||||
|
||||
// [RH] Set the thing's special
|
||||
mobj->special = mthing->special;
|
||||
memcpy (mobj->args, mthing->args, sizeof(mobj->args));
|
||||
|
||||
// [RH] If it's an ambient sound, activate it
|
||||
if (i == MT_AMBIENT)
|
||||
S_ActivateAmbient (mobj, mobj->args[0]);
|
||||
|
||||
if (mobj->tics > 0)
|
||||
mobj->tics = 1 + (P_Random (pr_spawnmapthing) % mobj->tics);
|
||||
if (mobj->flags & MF_COUNTKILL)
|
||||
|
@ -1004,6 +1155,14 @@ void P_SpawnMapThing (mapthing2_t *mthing)
|
|||
mobj->angle = ANG45 * (mthing->angle/45);
|
||||
if (mthing->flags & MTF_AMBUSH)
|
||||
mobj->flags |= MF_AMBUSH;
|
||||
|
||||
// [RH] Add ThingID to mobj and link it in with the others
|
||||
mobj->tid = mthing->thingid;
|
||||
P_AddMobjToHash (mobj);
|
||||
|
||||
// [RH] Go dormant as needed
|
||||
if (mthing->flags & MTF_DORMANT)
|
||||
P_DeactivateMobj (mobj);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1043,8 +1202,7 @@ void P_SpawnPuff (fixed_t x, fixed_t y, fixed_t z)
|
|||
//
|
||||
// P_SpawnBlood
|
||||
//
|
||||
void
|
||||
P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, int damage)
|
||||
void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, int damage)
|
||||
{
|
||||
mobj_t *th;
|
||||
int t;
|
||||
|
@ -1077,8 +1235,9 @@ void P_CheckMissileSpawn (mobj_t* th)
|
|||
if (th->tics < 1)
|
||||
th->tics = 1;
|
||||
|
||||
// Give the missile time to get away from the shooter
|
||||
th->targettic = gametic + 10;
|
||||
// [RH] Give the missile time to get away from the shooter
|
||||
if (!olddemo)
|
||||
th->targettic = 10;
|
||||
|
||||
// move a little forward so an angle can
|
||||
// be computed if it immediately explodes
|
||||
|
@ -1086,9 +1245,10 @@ void P_CheckMissileSpawn (mobj_t* th)
|
|||
th->y += th->momy>>1;
|
||||
th->z += th->momz>>1;
|
||||
|
||||
if (!P_TryMove (th, th->x, th->y)) {
|
||||
// killough 3/15/98: no dropoff (really = don't care for missiles)
|
||||
|
||||
if (!P_TryMove (th, th->x, th->y, false))
|
||||
P_ExplodeMissile (th);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1106,7 +1266,7 @@ mobj_t *P_SpawnMissile (mobj_t *source, mobj_t *dest, mobjtype_t type)
|
|||
source->z + 4*8*FRACUNIT, type, 0);
|
||||
|
||||
if (th->info->seesound)
|
||||
S_StartSound (th, th->info->seesound);
|
||||
S_StartSound (th, th->info->seesound, 70);
|
||||
|
||||
th->target = source; // where it came from
|
||||
an = R_PointToAngle2 (source->x, source->y, dest->x, dest->y);
|
||||
|
@ -1178,7 +1338,7 @@ void P_SpawnPlayerMissile (mobj_t *source, mobjtype_t type)
|
|||
|
||||
if (linetarget && source->player)
|
||||
if (!(dmflags & DF_NO_FREELOOK)
|
||||
&& abs(slope - pitchslope) > source->player->userinfo->aimdist) {
|
||||
&& abs(slope - pitchslope) > source->player->userinfo.aimdist) {
|
||||
an = source->angle;
|
||||
slope = pitchslope;
|
||||
}
|
||||
|
@ -1190,7 +1350,7 @@ void P_SpawnPlayerMissile (mobj_t *source, mobjtype_t type)
|
|||
th = P_SpawnMobj (x,y,z, type, 0);
|
||||
|
||||
if (th->info->seesound)
|
||||
S_StartSound (th, th->info->seesound);
|
||||
S_StartSound (th, th->info->seesound, 70);
|
||||
|
||||
th->target = source;
|
||||
th->angle = an;
|
||||
|
|
|
@ -207,6 +207,40 @@ typedef enum
|
|||
MF_TRANSLUC50 = 0x40000000,
|
||||
MF_TRANSLUC75 = 0x60000000,
|
||||
|
||||
// [RH] These are all based on Hexen's. Very few are used.
|
||||
MF2_LOWGRAVITY = 0x00000001,
|
||||
MF2_BLOWN = 0x00000002,
|
||||
MF2_BOUNCES = 0x00000004,
|
||||
MF2_PROJECTILEPUSH = 0x00000008,
|
||||
MF2_DROPUP = 0x00000010,
|
||||
MF2_INLIQUID = 0x00000020,
|
||||
MF2_STARTONFLOOR = 0x00000040,
|
||||
MF2_NOTELEPORT = 0x00000080,
|
||||
MF2_PIERCING = 0x00000100,
|
||||
MF2_PUSHABLE = 0x00000200,
|
||||
MF2_DONTHURTPLAYERS = 0x00000400,
|
||||
MF2_NOADJUST = 0x00000800,
|
||||
MF2_POTSOMETHING = 0x00001000,
|
||||
MF2_PARTICLE = 0x00002000,
|
||||
MF2_DORMANT = 0x00004000,
|
||||
MF2_BOSS = 0x00008000,
|
||||
MF2_XDEATHONLY = 0x00010000,
|
||||
MF2_DOESNOTPUSH = 0x00020000,
|
||||
MF2_TELEFRAGS = 0x00040000,
|
||||
MF2_BOB = 0x00080000,
|
||||
MF2_INVISIBLE = 0x00100000,
|
||||
MF2_ACTIVATEIMPACT = 0x00200000,
|
||||
MF2_JUMPING = 0x00400000,
|
||||
MF2_ACTIVATEMCROSS = 0x00800000,
|
||||
MF2_ACTIVATEPCROSS = 0x01000000,
|
||||
MF2_PASSPROJECTILES = 0x02000000,
|
||||
MF2_STALKERSOMETHING= 0x04000000,
|
||||
MF2_INVULNERABLE = 0x08000000,
|
||||
MF2_INDESTRUCTABLE = 0x10000000,
|
||||
MF2_ICYDEATH = 0x20000000,
|
||||
MF2_HOMINGSOMETHING = 0x40000000,
|
||||
MF2_REFLECTIVE = 0x80000000
|
||||
|
||||
} mobjflag_t;
|
||||
|
||||
|
||||
|
@ -221,6 +255,10 @@ typedef struct mobj_s
|
|||
fixed_t y;
|
||||
fixed_t z;
|
||||
|
||||
int tid; // [RH] Thing ID
|
||||
struct mobj_s* inext; // [RH] links to other mobjs whose
|
||||
struct mobj_s* iprev; // tid hash to the same value.
|
||||
|
||||
// More list: links in sector (if needed)
|
||||
struct mobj_s* snext;
|
||||
struct mobj_s* sprev;
|
||||
|
@ -261,6 +299,7 @@ typedef struct mobj_s
|
|||
int tics; // state tic counter
|
||||
state_t* state;
|
||||
int flags;
|
||||
int flags2; // [RH] more flags
|
||||
int health;
|
||||
|
||||
// Movement direction, movement generation (zig-zagging).
|
||||
|
@ -273,7 +312,7 @@ typedef struct mobj_s
|
|||
|
||||
// Reaction time: if non 0, don't attack yet.
|
||||
// Used by player to freeze a bit after teleporting.
|
||||
int reactiontime;
|
||||
int reactiontime;
|
||||
|
||||
// If >0, the target will be chased
|
||||
// no matter what (even if shot)
|
||||
|
@ -292,11 +331,14 @@ typedef struct mobj_s
|
|||
// Thing being chased/attacked for tracers.
|
||||
struct mobj_s* tracer;
|
||||
|
||||
// [RH] Andy Baker's stealth monsters
|
||||
BOOL invisible;
|
||||
// new field: last known enemy -- killough 2/15/98
|
||||
struct mobj_s* lastenemy;
|
||||
|
||||
// [RH] The goal this monster is moving toward (if target is NULL)
|
||||
struct mobj_s* goal;
|
||||
|
||||
// [RH] Z-Check
|
||||
// Gametic when a missile will be able to impact
|
||||
// Time until a missile will be able to impact
|
||||
// whoever shot it. Used to prevent the missile
|
||||
// from blowing up in the shooter's face before
|
||||
// it gets anywhere.
|
||||
|
@ -308,8 +350,16 @@ typedef struct mobj_s
|
|||
// than a full-fledged palette.
|
||||
struct palette_s *palette;
|
||||
|
||||
// a linked list of sectors where this object appears
|
||||
struct msecnode_s *touching_sectorlist; // phares 3/14/98
|
||||
// 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
|
||||
|
||||
// [RH] Thing special
|
||||
byte special;
|
||||
byte args[5];
|
||||
|
||||
} mobj_t;
|
||||
|
||||
|
|
399
code/P_plats.c
Normal file
399
code/P_plats.c
Normal file
|
@ -0,0 +1,399 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// $Log:$
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Plats (i.e. elevator platforms) code, raising/lowering.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
#include "m_alloc.h"
|
||||
|
||||
#include "i_system.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_random.h"
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
|
||||
#include "s_sound.h"
|
||||
|
||||
// State.
|
||||
#include "doomstat.h"
|
||||
#include "r_state.h"
|
||||
|
||||
|
||||
// [RH] Active plats are now linked together in a list instead of
|
||||
// stored in an array. Similar to what Lee Killough did with
|
||||
// BOOM except I link the plats themselves together.
|
||||
plat_t *activeplats;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Move a plat up and down
|
||||
//
|
||||
void T_PlatRaise(plat_t* plat)
|
||||
{
|
||||
result_e res;
|
||||
|
||||
switch (plat->status)
|
||||
{
|
||||
case up:
|
||||
res = T_MovePlane(plat->sector,
|
||||
plat->speed,
|
||||
plat->high,
|
||||
plat->crush,0,1);
|
||||
|
||||
if (plat->type == platUpByValueStay
|
||||
|| plat->type == platRaiseAndStay)
|
||||
{
|
||||
if (!(level.time&7))
|
||||
S_StartSound((mobj_t *)&plat->sector->soundorg, "plats/pt1_mid", 119);
|
||||
}
|
||||
|
||||
|
||||
if (res == crushed && (!plat->crush))
|
||||
{
|
||||
plat->count = plat->wait;
|
||||
plat->status = down;
|
||||
S_StartSound((mobj_t *)&plat->sector->soundorg, "plats/pt1_strt", 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (res == pastdest)
|
||||
{
|
||||
if (plat->type != platToggle) {
|
||||
plat->count = plat->wait;
|
||||
plat->status = waiting;
|
||||
S_StartSound((mobj_t *)&plat->sector->soundorg, "plats/pt1_stop", 100);
|
||||
|
||||
switch(plat->type)
|
||||
{
|
||||
case platDownWaitUpStay:
|
||||
case platRaiseAndStay:
|
||||
case platUpByValueStay:
|
||||
case platDownToNearestFloor:
|
||||
case platDownToLowestCeiling:
|
||||
P_RemoveActivePlat(plat);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
plat->oldstatus = plat->status;//jff 3/14/98 after action wait
|
||||
plat->status = in_stasis; //for reactivation of toggle
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case down:
|
||||
res = T_MovePlane (plat->sector, plat->speed, plat->low, -1, 0, -1);
|
||||
|
||||
if (res == pastdest)
|
||||
{
|
||||
// if not an instant toggle, start waiting, make plat stop sound
|
||||
if (plat->type != platToggle) //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, "plats/pt1_stop", 100);
|
||||
|
||||
switch (plat->type) {
|
||||
case platUpWaitDownStay:
|
||||
case platUpByValue:
|
||||
P_RemoveActivePlat (plat);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} 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 it's a pure raise type
|
||||
if (!olddemo)
|
||||
{
|
||||
switch (plat->type)
|
||||
{
|
||||
case platUpByValueStay:
|
||||
case platRaiseAndStay:
|
||||
P_RemoveActivePlat(plat);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case waiting:
|
||||
if (!--plat->count)
|
||||
{
|
||||
if (plat->sector->floorheight == plat->low)
|
||||
plat->status = up;
|
||||
else
|
||||
plat->status = down;
|
||||
S_StartSound((mobj_t *)&plat->sector->soundorg, "plats/pt1_strt", 100);
|
||||
}
|
||||
break;
|
||||
|
||||
case in_stasis:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Do Platforms
|
||||
// [RH] Changed amount to height and added delay,
|
||||
// lip, change, tag, and speed parameters.
|
||||
//
|
||||
BOOL EV_DoPlat (int tag, line_t *line, plattype_e type, int height,
|
||||
int speed, int delay, int lip, int change)
|
||||
{
|
||||
plat_t* plat;
|
||||
int secnum;
|
||||
sector_t *sec;
|
||||
int rtn = false;
|
||||
BOOL manual = false;
|
||||
|
||||
// [RH] If tag is zero, use the sector on the back side
|
||||
// of the activating line (if any).
|
||||
if (!tag && !olddemo) {
|
||||
if (!line || !(sec = line->backsector))
|
||||
return false;
|
||||
secnum = sec - sectors;
|
||||
manual = true;
|
||||
goto manual_plat;
|
||||
}
|
||||
|
||||
// Activate all <type> plats that are in_stasis
|
||||
switch (type)
|
||||
{
|
||||
case platToggle:
|
||||
rtn = true;
|
||||
case platPerpetualRaise:
|
||||
P_ActivateInStasis (tag);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
secnum = -1;
|
||||
while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
|
||||
manual_plat:
|
||||
if (P_SectorActive (floor_special, sec)) //jff 2/23/98 multiple thinkers
|
||||
continue;
|
||||
|
||||
// Find lowest & highest floors around sector
|
||||
rtn = true;
|
||||
plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0);
|
||||
P_AddThinker(&plat->thinker);
|
||||
|
||||
plat->type = type;
|
||||
plat->sector = sec;
|
||||
plat->sector->floordata = plat; //jff 2/23/98 multiple thinkers
|
||||
plat->thinker.function.acp1 = (actionf_p1) T_PlatRaise;
|
||||
plat->crush = -1;
|
||||
plat->tag = tag;
|
||||
plat->speed = speed;
|
||||
plat->wait = delay;
|
||||
|
||||
//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;
|
||||
|
||||
if (change) {
|
||||
if (line)
|
||||
sec->floorpic = sides[line->sidenum[0]].sector->floorpic;
|
||||
if (change == 1)
|
||||
sec->special = 0; // Stop damage and other stuff, if any
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case platRaiseAndStay:
|
||||
plat->high = P_FindNextHighestFloor (sec, sec->floorheight);
|
||||
plat->status = up;
|
||||
S_StartSound ((mobj_t *)&sec->soundorg, "plats/pt1_mid", 119);
|
||||
break;
|
||||
|
||||
case platUpByValue:
|
||||
case platUpByValueStay:
|
||||
plat->high = sec->floorheight + height;
|
||||
plat->status = up;
|
||||
S_StartSound ((mobj_t *)&sec->soundorg, "plats/pt1_mid", 119);
|
||||
break;
|
||||
|
||||
case platDownByValue:
|
||||
plat->low = sec->floorheight - height;
|
||||
plat->status = down;
|
||||
S_StartSound ((mobj_t *)&sec->soundorg, "plats/pt1_mid", 119);
|
||||
break;
|
||||
|
||||
case platDownWaitUpStay:
|
||||
plat->low = P_FindLowestFloorSurrounding (sec) + lip*FRACUNIT;
|
||||
|
||||
if (plat->low > sec->floorheight)
|
||||
plat->low = sec->floorheight;
|
||||
|
||||
plat->high = sec->floorheight;
|
||||
plat->status = down;
|
||||
S_StartSound ((mobj_t *)&sec->soundorg, "plats/pt1_strt", 100);
|
||||
break;
|
||||
|
||||
case platUpWaitDownStay:
|
||||
plat->high = P_FindHighestFloorSurrounding (sec);
|
||||
|
||||
if (plat->high < sec->floorheight)
|
||||
plat->high = sec->floorheight;
|
||||
|
||||
plat->status = up;
|
||||
S_StartSound ((mobj_t *)&sec->soundorg, "plats/pt1_strt", 100);
|
||||
break;
|
||||
|
||||
case platPerpetualRaise:
|
||||
plat->low = P_FindLowestFloorSurrounding (sec) + lip*FRACUNIT;
|
||||
|
||||
if (plat->low > sec->floorheight)
|
||||
plat->low = sec->floorheight;
|
||||
|
||||
plat->high = P_FindHighestFloorSurrounding (sec);
|
||||
|
||||
if (plat->high < sec->floorheight)
|
||||
plat->high = sec->floorheight;
|
||||
|
||||
plat->status = P_Random (pr_doplat) & 1;
|
||||
|
||||
S_StartSound((mobj_t *)&sec->soundorg, "plats/pt1_strt", 100);
|
||||
break;
|
||||
|
||||
case platToggle: //jff 3/14/98 add new type to support instant toggle
|
||||
plat->crush = 10; //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;
|
||||
|
||||
case platDownToNearestFloor:
|
||||
plat->low = P_FindNextLowestFloor (sec, sec->floorheight) + lip*FRACUNIT;
|
||||
plat->status = down;
|
||||
plat->high = sec->floorheight;
|
||||
S_StartSound((mobj_t *)&sec->soundorg, "plats/pt1_strt", 100);
|
||||
break;
|
||||
|
||||
case platDownToLowestCeiling:
|
||||
plat->low = P_FindLowestCeilingSurrounding(sec);
|
||||
plat->high = sec->floorheight;
|
||||
|
||||
if (plat->low > sec->floorheight)
|
||||
plat->low = sec->floorheight;
|
||||
|
||||
plat->status = down;
|
||||
S_StartSound((mobj_t *)&sec->soundorg, "plats/pt1_strt", 100);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
P_AddActivePlat (plat);
|
||||
if (manual)
|
||||
return rtn;
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
|
||||
// [RH] Rewritten to use list
|
||||
void P_ActivateInStasis (int tag)
|
||||
{
|
||||
plat_t *scan = activeplats;
|
||||
|
||||
while (scan) {
|
||||
if (scan->tag == tag && scan->status == in_stasis) {
|
||||
if (scan->type == platToggle) //jff 3/14/98 reactivate toggle type
|
||||
scan->status = scan->oldstatus == up ? down : up;
|
||||
else
|
||||
scan->status = scan->oldstatus;
|
||||
scan->thinker.function.acp1 = (actionf_p1) T_PlatRaise;
|
||||
}
|
||||
scan = scan->next;
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] Passed a tag instead of a line and rewritten to use list
|
||||
void EV_StopPlat (int tag)
|
||||
{
|
||||
plat_t *scan = activeplats;
|
||||
|
||||
while (scan) {
|
||||
if (scan->status != in_stasis && scan->tag == tag) {
|
||||
scan->oldstatus = scan->status;
|
||||
scan->status = in_stasis;
|
||||
scan->thinker.function.acv = (actionf_v)NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] Rewritten to use list
|
||||
void P_AddActivePlat (plat_t *plat)
|
||||
{
|
||||
if (activeplats)
|
||||
activeplats->prev = plat;
|
||||
plat->next = activeplats;
|
||||
plat->prev = NULL;
|
||||
activeplats = plat;
|
||||
}
|
||||
|
||||
// [RH] Rewritten to use list
|
||||
void P_RemoveActivePlat (plat_t *plat)
|
||||
{
|
||||
plat_t *scan = activeplats;
|
||||
|
||||
while (scan) {
|
||||
if (scan == plat) {
|
||||
scan->sector->floordata = NULL;
|
||||
if (scan == activeplats) {
|
||||
activeplats = scan->next;
|
||||
} else {
|
||||
if (scan->prev)
|
||||
scan->prev->next = scan->next;
|
||||
if (scan->next)
|
||||
scan->next->prev = scan->prev;
|
||||
}
|
||||
P_RemoveThinker (&scan->thinker);
|
||||
break;
|
||||
}
|
||||
scan = scan->next;
|
||||
}
|
||||
}
|
||||
|
|
@ -37,9 +37,6 @@
|
|||
// State.
|
||||
#include "doomstat.h"
|
||||
|
||||
// Data.
|
||||
#include "sounds.h"
|
||||
|
||||
#include "p_pspr.h"
|
||||
|
||||
#define LOWERSPEED FRACUNIT*6
|
||||
|
@ -137,7 +134,7 @@ void P_BringUpWeapon (player_t *player)
|
|||
player->pendingweapon = player->readyweapon;
|
||||
|
||||
if (player->pendingweapon == wp_chainsaw)
|
||||
S_StartSound (player->mo, sfx_sawup);
|
||||
S_StartSound (player->mo, "weapons/sawup", 64);
|
||||
|
||||
newstate = weaponinfo[player->pendingweapon].upstate;
|
||||
|
||||
|
@ -161,7 +158,7 @@ BOOL P_CheckAmmo (player_t *player)
|
|||
|
||||
// Minimal amount for one shot varies.
|
||||
if (player->readyweapon == wp_bfg)
|
||||
count = deh_BFGCells;
|
||||
count = deh.BFGCells;
|
||||
else if (player->readyweapon == wp_supershotgun)
|
||||
count = 2; // Double barrel.
|
||||
else
|
||||
|
@ -287,7 +284,7 @@ void A_WeaponReady (player_t *player, pspdef_t *psp)
|
|||
if (player->readyweapon == wp_chainsaw
|
||||
&& psp->state == &states[S_SAW])
|
||||
{
|
||||
S_StartSound (player->mo, sfx_sawidl);
|
||||
S_StartSound (player->mo, "weapons/sawidle", 118);
|
||||
}
|
||||
|
||||
// check for change
|
||||
|
@ -463,7 +460,7 @@ void A_Punch (player_t *player, pspdef_t *psp)
|
|||
// turn to face target
|
||||
if (linetarget)
|
||||
{
|
||||
S_StartSound (player->mo, sfx_punch);
|
||||
S_StartSound (player->mo, "*fist", 64);
|
||||
player->mo->angle = R_PointToAngle2 (player->mo->x,
|
||||
player->mo->y,
|
||||
linetarget->x,
|
||||
|
@ -493,10 +490,10 @@ void A_Saw (player_t *player, pspdef_t *psp)
|
|||
|
||||
if (!linetarget)
|
||||
{
|
||||
S_StartSound (player->mo, sfx_sawful);
|
||||
S_StartSound (player->mo, "weapons/sawfull", 64);
|
||||
return;
|
||||
}
|
||||
S_StartSound (player->mo, sfx_sawhit);
|
||||
S_StartSound (player->mo, "weapons/sawhit", 64);
|
||||
|
||||
// turn to face target
|
||||
angle = R_PointToAngle2 (player->mo->x, player->mo->y,
|
||||
|
@ -534,11 +531,24 @@ void A_FireMissile (player_t *player, pspdef_t *psp)
|
|||
//
|
||||
// A_FireBFG
|
||||
//
|
||||
cvar_t *nobfgaim;
|
||||
|
||||
void A_FireBFG (player_t *player, pspdef_t *psp)
|
||||
{
|
||||
// [RH] bfg can be forced to not use freeaim
|
||||
fixed_t storedpitch = player->mo->pitch;
|
||||
int storedaimdist = player->userinfo.aimdist;
|
||||
|
||||
if (!(dmflags & DF_INFINITE_AMMO))
|
||||
player->ammo[weaponinfo[player->readyweapon].ammo] -= deh_BFGCells;
|
||||
player->ammo[weaponinfo[player->readyweapon].ammo] -= deh.BFGCells;
|
||||
|
||||
if (nobfgaim->value) {
|
||||
player->mo->pitch = 0;
|
||||
player->userinfo.aimdist = 81920000;
|
||||
}
|
||||
P_SpawnPlayerMissile (player->mo, MT_BFG);
|
||||
player->mo->pitch = storedpitch;
|
||||
player->userinfo.aimdist = storedaimdist;
|
||||
}
|
||||
|
||||
|
||||
|
@ -596,7 +606,7 @@ void P_BulletSlope (mobj_t *mo)
|
|||
}
|
||||
if (linetarget && mo->player)
|
||||
if (!(dmflags & DF_NO_FREELOOK)
|
||||
&& abs(bulletslope - pitchslope) > mo->player->userinfo->aimdist) {
|
||||
&& abs(bulletslope - pitchslope) > mo->player->userinfo.aimdist) {
|
||||
bulletslope = pitchslope;
|
||||
an = mo->angle;
|
||||
}
|
||||
|
@ -626,12 +636,9 @@ void P_GunShot (mobj_t *mo, BOOL accurate)
|
|||
//
|
||||
// A_FirePistol
|
||||
//
|
||||
void
|
||||
A_FirePistol
|
||||
( player_t* player,
|
||||
pspdef_t* psp )
|
||||
void A_FirePistol (player_t *player, pspdef_t *psp)
|
||||
{
|
||||
S_StartSound (player->mo, sfx_pistol);
|
||||
S_StartSound (player->mo, "weapons/pistol", 64);
|
||||
|
||||
P_SetMobjState (player->mo, S_PLAY_ATK2);
|
||||
if (!(dmflags & DF_INFINITE_AMMO))
|
||||
|
@ -649,14 +656,11 @@ A_FirePistol
|
|||
//
|
||||
// A_FireShotgun
|
||||
//
|
||||
void
|
||||
A_FireShotgun
|
||||
( player_t* player,
|
||||
pspdef_t* psp )
|
||||
void A_FireShotgun (player_t *player, pspdef_t *psp)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
S_StartSound (player->mo, sfx_shotgn);
|
||||
S_StartSound (player->mo, "weapons/shotgf", 64);
|
||||
P_SetMobjState (player->mo, S_PLAY_ATK2);
|
||||
|
||||
if (!(dmflags & DF_INFINITE_AMMO))
|
||||
|
@ -677,10 +681,7 @@ A_FireShotgun
|
|||
//
|
||||
// A_FireShotgun2
|
||||
//
|
||||
void
|
||||
A_FireShotgun2
|
||||
( player_t* player,
|
||||
pspdef_t* psp )
|
||||
void A_FireShotgun2 (player_t *player, pspdef_t *psp)
|
||||
{
|
||||
int i;
|
||||
angle_t angle;
|
||||
|
@ -688,7 +689,7 @@ A_FireShotgun2
|
|||
int t;
|
||||
|
||||
|
||||
S_StartSound (player->mo, sfx_dshtgn);
|
||||
S_StartSound (player->mo, "weapons/sshotf", 64);
|
||||
P_SetMobjState (player->mo, S_PLAY_ATK2);
|
||||
|
||||
if (!(dmflags & DF_INFINITE_AMMO))
|
||||
|
@ -718,12 +719,9 @@ A_FireShotgun2
|
|||
//
|
||||
// A_FireCGun
|
||||
//
|
||||
void
|
||||
A_FireCGun
|
||||
( player_t* player,
|
||||
pspdef_t* psp )
|
||||
void A_FireCGun (player_t *player, pspdef_t *psp)
|
||||
{
|
||||
S_StartSound (player->mo, sfx_pistol);
|
||||
S_StartSound (player->mo, "weapons/chngun", 64);
|
||||
|
||||
if (!player->ammo[weaponinfo[player->readyweapon].ammo])
|
||||
return;
|
||||
|
@ -768,14 +766,14 @@ void A_Light2 (player_t *player, pspdef_t *psp)
|
|||
// A_BFGSpray
|
||||
// Spawn a BFG explosion on every monster in view
|
||||
//
|
||||
void A_BFGSpray (mobj_t* mo)
|
||||
void A_BFGSpray (mobj_t *mo)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int damage;
|
||||
angle_t an;
|
||||
|
||||
// [RH] Needed for The New Breed
|
||||
// [RH] Don't crash if no target
|
||||
if (!mo->target)
|
||||
return;
|
||||
|
||||
|
@ -809,12 +807,9 @@ void A_BFGSpray (mobj_t* mo)
|
|||
//
|
||||
// A_BFGsound
|
||||
//
|
||||
void
|
||||
A_BFGsound
|
||||
( player_t* player,
|
||||
pspdef_t* psp )
|
||||
void A_BFGsound (player_t *player, pspdef_t *psp)
|
||||
{
|
||||
S_StartSound (player->mo, sfx_bfg);
|
||||
S_StartSound (player->mo, "weapons/bfgf", 64);
|
||||
}
|
||||
|
||||
|
||||
|
|
829
code/P_saveg.c
829
code/P_saveg.c
File diff suppressed because it is too large
Load diff
|
@ -32,15 +32,24 @@ void P_UnArchivePlayers (void);
|
|||
void P_ArchiveWorld (void);
|
||||
void P_UnArchiveWorld (void);
|
||||
void P_ArchiveThinkers (void);
|
||||
void P_UnArchiveThinkers (void);
|
||||
void P_UnArchiveThinkers (BOOL keepPlayers); // [RH] added parameter
|
||||
void P_ArchiveSpecials (void);
|
||||
void P_UnArchiveSpecials (void);
|
||||
void P_ArchiveRNGState (void); // [RH]
|
||||
void P_UnArchiveRNGState (void); // [RH]
|
||||
void P_ArchiveLevelLocals (void); // [RH]
|
||||
void P_UnArchiveLevelLocals (void); // [RH]
|
||||
void P_ArchiveScripts (void); // [RH]
|
||||
void P_UnArchiveScripts (void); // [RH]
|
||||
void P_ArchiveACSDefereds (void); // [RH]
|
||||
void P_UnArchiveACSDefereds (void); // [RH]
|
||||
|
||||
extern byte *save_p;
|
||||
extern byte *save_p, *savebuffer;
|
||||
extern size_t savegamesize;
|
||||
void CheckSaveGame (size_t); // killough
|
||||
|
||||
|
||||
// Pads save_p to a 4-byte boundary
|
||||
// so that the load/save works on SGI&Gecko.
|
||||
#define PADSAVEP() save_p += (4 - ((int) save_p & 3)) & 3
|
||||
|
||||
|
||||
#endif
|
||||
|
|
879
code/P_setup.c
879
code/P_setup.c
File diff suppressed because it is too large
Load diff
360
code/P_sight.c
360
code/P_sight.c
|
@ -27,6 +27,7 @@
|
|||
#include "i_system.h"
|
||||
#include "p_local.h"
|
||||
#include "m_random.h"
|
||||
#include "m_bbox.h"
|
||||
|
||||
// State.
|
||||
#include "r_state.h"
|
||||
|
@ -34,63 +35,41 @@
|
|||
//
|
||||
// P_CheckSight
|
||||
//
|
||||
fixed_t sightzstart; // eye z of looker
|
||||
fixed_t topslope;
|
||||
fixed_t bottomslope; // slopes to top and bottom of target
|
||||
// killough 4/19/98:
|
||||
// Convert LOS info to struct for reentrancy and efficiency of data locality
|
||||
|
||||
divline_t strace; // from t1 to t2
|
||||
fixed_t t2x;
|
||||
fixed_t t2y;
|
||||
|
||||
int sightcounts[2];
|
||||
typedef struct {
|
||||
fixed_t sightzstart; // eye z of looker
|
||||
fixed_t t2x, t2y;
|
||||
divline_t strace; // from t1 to t2
|
||||
fixed_t topslope, bottomslope; // slopes to top and bottom of target
|
||||
fixed_t bbox[4];
|
||||
} los_t;
|
||||
|
||||
|
||||
//
|
||||
// P_DivlineSide
|
||||
// Returns side 0 (front), 1 (back), or 2 (on).
|
||||
//
|
||||
int P_DivlineSide (const fixed_t x, const fixed_t y, const divline_t *node)
|
||||
static int P_DivlineSide (const fixed_t x, const fixed_t y, const divline_t *node)
|
||||
{
|
||||
fixed_t dx;
|
||||
fixed_t dy;
|
||||
fixed_t left;
|
||||
fixed_t right;
|
||||
|
||||
if (!node->dx)
|
||||
{
|
||||
if (x==node->x)
|
||||
return 2;
|
||||
|
||||
if (x <= node->x)
|
||||
return node->dy > 0;
|
||||
|
||||
return node->dy < 0;
|
||||
return (x==node->x) ? 2 : ((x < node->x) ? node->dy > 0 : node->dy < 0);
|
||||
}
|
||||
|
||||
if (!node->dy)
|
||||
else if (!node->dy)
|
||||
{
|
||||
return (y==node->y) ? 2 : ((y < node->y) ? node->dx < 0 : node->dx > 0);
|
||||
// ^^^^^^^^^^^^
|
||||
// [RH] Original code was (x==node->y), but that's obviously not right.
|
||||
if (y==node->y)
|
||||
return 2;
|
||||
|
||||
if (y <= node->y)
|
||||
return node->dx < 0;
|
||||
|
||||
return node->dx > 0;
|
||||
}
|
||||
|
||||
dx = (x - node->x);
|
||||
dy = (y - node->y);
|
||||
else
|
||||
{
|
||||
fixed_t left = (node->dy>>FRACBITS) * ((x - node->x)>>FRACBITS);
|
||||
fixed_t right = ((y - node->y)>>FRACBITS) * (node->dx>>FRACBITS);
|
||||
|
||||
left = (node->dy>>FRACBITS) * (dx>>FRACBITS);
|
||||
right = (dy>>FRACBITS) * (node->dx>>FRACBITS);
|
||||
|
||||
if (right < left)
|
||||
return 0; // front side
|
||||
|
||||
if (left == right)
|
||||
return 2;
|
||||
return 1; // back side
|
||||
return (right < left) ? 0 : ((left == right) ? 2 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -100,23 +79,15 @@ int P_DivlineSide (const fixed_t x, const fixed_t y, const divline_t *node)
|
|||
// along the first divline.
|
||||
// This is only called by the addthings and addlines traversers.
|
||||
//
|
||||
fixed_t P_InterceptVector2 (const divline_t *v2, const divline_t *v1)
|
||||
//
|
||||
// killough 4/19/98: made static, cleaned up
|
||||
|
||||
static fixed_t P_InterceptVector2(const divline_t *v2, const divline_t *v1)
|
||||
{
|
||||
fixed_t frac;
|
||||
fixed_t num;
|
||||
fixed_t den;
|
||||
|
||||
den = FixedMul (v1->dy>>8,v2->dx) - FixedMul(v1->dx>>8,v2->dy);
|
||||
|
||||
if (den == 0)
|
||||
return 0;
|
||||
// I_Error ("P_InterceptVector: parallel");
|
||||
|
||||
num = FixedMul ( (v1->x - v2->x)>>8 ,v1->dy) +
|
||||
FixedMul ( (v2->y - v1->y)>>8 , v1->dx);
|
||||
frac = FixedDiv (num , den);
|
||||
|
||||
return frac;
|
||||
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;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -124,122 +95,103 @@ fixed_t P_InterceptVector2 (const divline_t *v2, const divline_t *v1)
|
|||
// Returns true
|
||||
// if strace crosses the given subsector successfully.
|
||||
//
|
||||
BOOL P_CrossSubsector (const int num)
|
||||
//
|
||||
// killough 4/19/98: made static and cleaned up
|
||||
|
||||
static BOOL P_CrossSubsector(int num, register los_t *los)
|
||||
{
|
||||
seg_t* seg;
|
||||
line_t* line;
|
||||
int s1;
|
||||
int s2;
|
||||
int count;
|
||||
subsector_t* sub;
|
||||
sector_t* front;
|
||||
sector_t* back;
|
||||
fixed_t opentop;
|
||||
fixed_t openbottom;
|
||||
divline_t divl;
|
||||
vertex_t* v1;
|
||||
vertex_t* v2;
|
||||
fixed_t frac;
|
||||
fixed_t slope;
|
||||
|
||||
seg_t *seg = segs + subsectors[num].firstline;
|
||||
int count;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (num>=numsubsectors)
|
||||
I_Error ("P_CrossSubsector: ss %i with numss = %i",
|
||||
num,
|
||||
numsubsectors);
|
||||
if (num >= numsubsectors)
|
||||
I_Error("P_CrossSubsector: ss %i with numss = %i", num, numsubsectors);
|
||||
#endif
|
||||
|
||||
sub = &subsectors[num];
|
||||
|
||||
// check lines
|
||||
count = sub->numlines;
|
||||
seg = &segs[sub->firstline];
|
||||
|
||||
for ( ; count ; seg++, count--)
|
||||
for (count = subsectors[num].numlines; --count >= 0; seg++) // check lines
|
||||
{
|
||||
line = seg->linedef;
|
||||
line_t *line = seg->linedef;
|
||||
divline_t divl;
|
||||
fixed_t opentop, openbottom;
|
||||
const sector_t *front, *back;
|
||||
const vertex_t *v1,*v2;
|
||||
fixed_t frac;
|
||||
|
||||
// allready checked other side?
|
||||
// already checked other side?
|
||||
if (line->validcount == validcount)
|
||||
continue;
|
||||
|
||||
|
||||
line->validcount = validcount;
|
||||
|
||||
|
||||
// OPTIMIZE: killough 4/20/98: Added quick bounding-box rejection test
|
||||
|
||||
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;
|
||||
|
||||
v1 = line->v1;
|
||||
v2 = line->v2;
|
||||
s1 = P_DivlineSide (v1->x,v1->y, &strace);
|
||||
s2 = P_DivlineSide (v2->x, v2->y, &strace);
|
||||
|
||||
// line isn't crossed?
|
||||
if (s1 == s2)
|
||||
if (P_DivlineSide(v1->x, v1->y, &los->strace) ==
|
||||
P_DivlineSide(v2->x, v2->y, &los->strace))
|
||||
continue;
|
||||
|
||||
divl.x = v1->x;
|
||||
divl.y = v1->y;
|
||||
// [RH] This is already calculated. Why calculate it again?
|
||||
divl.dx = line->dx;
|
||||
divl.dy = line->dy;
|
||||
/* divl.dx = v2->x - v1->x;
|
||||
divl.dy = v2->y - v1->y; */
|
||||
s1 = P_DivlineSide (strace.x, strace.y, &divl);
|
||||
s2 = P_DivlineSide (t2x, t2y, &divl);
|
||||
|
||||
divl.dx = v2->x - (divl.x = v1->x);
|
||||
divl.dy = v2->y - (divl.y = v1->y);
|
||||
|
||||
// line isn't crossed?
|
||||
if (s1 == s2)
|
||||
continue;
|
||||
if (P_DivlineSide(los->strace.x, los->strace.y, &divl) ==
|
||||
P_DivlineSide(los->t2x, los->t2y, &divl))
|
||||
continue;
|
||||
|
||||
// stop because it is not two sided anyway
|
||||
// might do this after updating validcount?
|
||||
if ( !(line->flags & ML_TWOSIDED) )
|
||||
if (!(line->flags & ML_TWOSIDED) || (line->flags & ML_BLOCKEVERYTHING))
|
||||
return false;
|
||||
|
||||
// crosses a two sided line
|
||||
front = seg->frontsector;
|
||||
back = seg->backsector;
|
||||
|
||||
// crosses a two sided line
|
||||
// no wall to block sight with?
|
||||
if (front->floorheight == back->floorheight
|
||||
&& front->ceilingheight == back->ceilingheight)
|
||||
continue;
|
||||
if ((front = seg->frontsector)->floorheight ==
|
||||
(back = seg->backsector)->floorheight &&
|
||||
front->ceilingheight == back->ceilingheight)
|
||||
continue;
|
||||
|
||||
// possible occluder
|
||||
// because of ceiling height differences
|
||||
if (front->ceilingheight < back->ceilingheight)
|
||||
opentop = front->ceilingheight;
|
||||
else
|
||||
opentop = back->ceilingheight;
|
||||
opentop = front->ceilingheight < back->ceilingheight ?
|
||||
front->ceilingheight : back->ceilingheight ;
|
||||
|
||||
// because of floor height differences
|
||||
if (front->floorheight > back->floorheight)
|
||||
openbottom = front->floorheight;
|
||||
else
|
||||
openbottom = back->floorheight;
|
||||
|
||||
openbottom = front->floorheight > back->floorheight ?
|
||||
front->floorheight : back->floorheight ;
|
||||
|
||||
// quick test for totally closed doors
|
||||
if (openbottom >= opentop)
|
||||
if (openbottom >= opentop)
|
||||
return false; // stop
|
||||
|
||||
frac = P_InterceptVector2 (&strace, &divl);
|
||||
|
||||
frac = P_InterceptVector2(&los->strace, &divl);
|
||||
|
||||
if (front->floorheight != back->floorheight)
|
||||
{
|
||||
slope = FixedDiv (openbottom - sightzstart , frac);
|
||||
if (slope > bottomslope)
|
||||
bottomslope = slope;
|
||||
}
|
||||
|
||||
if (front->ceilingheight != back->ceilingheight)
|
||||
{
|
||||
slope = FixedDiv (opentop - sightzstart , frac);
|
||||
if (slope < topslope)
|
||||
topslope = slope;
|
||||
fixed_t slope = FixedDiv(openbottom - los->sightzstart , frac);
|
||||
if (slope > los->bottomslope)
|
||||
los->bottomslope = slope;
|
||||
}
|
||||
|
||||
if (topslope <= bottomslope)
|
||||
return false; // stop
|
||||
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;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -249,39 +201,24 @@ BOOL P_CrossSubsector (const int num)
|
|||
// Returns true
|
||||
// if strace crosses the given node successfully.
|
||||
//
|
||||
BOOL P_CrossBSPNode (const int bspnum)
|
||||
// killough 4/20/98: rewritten to remove tail recursion, clean up, and optimize
|
||||
|
||||
static BOOL P_CrossBSPNode(int bspnum, register los_t *los)
|
||||
{
|
||||
node_t* bsp;
|
||||
int side;
|
||||
|
||||
if (bspnum & NF_SUBSECTOR)
|
||||
while (!(bspnum & NF_SUBSECTOR))
|
||||
{
|
||||
if (bspnum == -1)
|
||||
return P_CrossSubsector (0);
|
||||
else
|
||||
return P_CrossSubsector (bspnum&(~NF_SUBSECTOR));
|
||||
register const node_t *bsp = nodes + bspnum;
|
||||
int side = P_DivlineSide(los->strace.x,los->strace.y,(divline_t *)bsp)&1;
|
||||
if (side == P_DivlineSide(los->t2x, los->t2y, (divline_t *) bsp))
|
||||
bspnum = bsp->children[side]; // doesn't touch the other side
|
||||
else { // the partition plane is crossed here
|
||||
if (!P_CrossBSPNode(bsp->children[side], los))
|
||||
return 0; // cross the starting side
|
||||
else
|
||||
bspnum = bsp->children[side^1]; // cross the ending side
|
||||
}
|
||||
}
|
||||
|
||||
bsp = &nodes[bspnum];
|
||||
|
||||
// decide which side the start point is on
|
||||
side = P_DivlineSide (strace.x, strace.y, (divline_t *)bsp);
|
||||
if (side == 2)
|
||||
side = 0; // an "on" should cross both sides
|
||||
|
||||
// cross the starting side
|
||||
if (!P_CrossBSPNode (bsp->children[side]) )
|
||||
return false;
|
||||
|
||||
// the partition plane is crossed here
|
||||
if (side == P_DivlineSide (t2x, t2y,(divline_t *)bsp))
|
||||
{
|
||||
// the line doesn't touch the other side
|
||||
return true;
|
||||
}
|
||||
|
||||
// cross the ending side
|
||||
return P_CrossBSPNode (bsp->children[side^1]);
|
||||
return P_CrossSubsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR, los);
|
||||
}
|
||||
|
||||
|
||||
|
@ -291,57 +228,64 @@ BOOL P_CrossBSPNode (const int bspnum)
|
|||
// if a straight line between t1 and t2 is unobstructed.
|
||||
// Uses REJECT.
|
||||
//
|
||||
BOOL P_CheckSight (const mobj_t *t1, const mobj_t *t2)
|
||||
// killough 4/20/98: cleaned up, made to use new LOS struct
|
||||
|
||||
BOOL P_CheckSight (const mobj_t *t1, const mobj_t *t2, BOOL ignoreInvisibility)
|
||||
{
|
||||
int s1;
|
||||
int s2;
|
||||
int pnum;
|
||||
int bytenum;
|
||||
int bitnum;
|
||||
const sector_t *s1 = t1->subsector->sector;
|
||||
const sector_t *s2 = t2->subsector->sector;
|
||||
int pnum = (s1-sectors)*numsectors + (s2-sectors);
|
||||
los_t los;
|
||||
|
||||
// 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;
|
||||
|
||||
// [RH] Andy Baker's stealth monsters
|
||||
// Cannot see an invisible object
|
||||
if (t2->invisible)
|
||||
{
|
||||
if (P_Random (pr_checksight) > 50) // small chance of an attack being made anyway
|
||||
return false;
|
||||
}
|
||||
if (!ignoreInvisibility && (t2->flags2 & MF2_INVISIBLE)
|
||||
&& P_Random (pr_checksight) > 50) //^^^^^^^^ small chance of an attack being made anyway
|
||||
return false;
|
||||
|
||||
// First check for trivial rejection.
|
||||
// killough 4/19/98: make fake floors and ceilings block monster view
|
||||
|
||||
// Determine subsector entries in REJECT table.
|
||||
s1 = (t1->subsector->sector - sectors);
|
||||
s2 = (t2->subsector->sector - sectors);
|
||||
pnum = s1*numsectors + s2;
|
||||
bytenum = pnum>>3;
|
||||
bitnum = 1 << (pnum&7);
|
||||
|
||||
// Check in REJECT table.
|
||||
if (rejectmatrix[bytenum]&bitnum)
|
||||
{
|
||||
sightcounts[0]++;
|
||||
|
||||
// can't possibly be connected
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
|
||||
// An unobstructed LOS is possible.
|
||||
// Now look from eyes of t1 to any part of t2.
|
||||
sightcounts[1]++;
|
||||
|
||||
validcount++;
|
||||
|
||||
sightzstart = t1->z + t1->height - (t1->height>>2);
|
||||
topslope = (t2->z+t2->height) - sightzstart;
|
||||
bottomslope = (t2->z) - sightzstart;
|
||||
|
||||
strace.x = t1->x;
|
||||
strace.y = t1->y;
|
||||
t2x = t2->x;
|
||||
t2y = t2->y;
|
||||
strace.dx = t2->x - t1->x;
|
||||
strace.dy = t2->y - t1->y;
|
||||
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;
|
||||
|
||||
// the head node is the last node output
|
||||
return P_CrossBSPNode (numnodes-1);
|
||||
return P_CrossBSPNode (numnodes-1, &los);
|
||||
}
|
||||
|
|
2348
code/P_spec.c
2348
code/P_spec.c
File diff suppressed because it is too large
Load diff
520
code/P_spec.h
520
code/P_spec.h
|
@ -56,6 +56,54 @@ typedef struct {
|
|||
} type; // Type of scroll effect
|
||||
} scroll_t;
|
||||
|
||||
// phares 3/12/98: added new model of friction for ice/sludge effects
|
||||
|
||||
typedef struct {
|
||||
thinker_t thinker; // Thinker structure for friction
|
||||
int friction; // friction value (E800 = normal)
|
||||
int movefactor; // inertia factor when adding to momentum
|
||||
int affectee; // Number of affected sector
|
||||
} friction_t;
|
||||
|
||||
// phares 3/20/98: added new model of Pushers for push/pull effects
|
||||
|
||||
typedef struct {
|
||||
thinker_t thinker; // Thinker structure for Pusher
|
||||
enum
|
||||
{
|
||||
p_push,
|
||||
p_pull,
|
||||
p_wind,
|
||||
p_current,
|
||||
} type;
|
||||
mobj_t* source; // Point source if point pusher
|
||||
int x_mag; // X Strength
|
||||
int y_mag; // Y Strength
|
||||
int magnitude; // Vector strength for point pusher
|
||||
int radius; // Effective radius for point pusher
|
||||
int x; // X of point source if point pusher
|
||||
int y; // Y of point source if point pusher
|
||||
int affectee; // Number of affected sector
|
||||
} pusher_t;
|
||||
|
||||
// [RH] Types of keys used by locked doors and scripts
|
||||
typedef enum
|
||||
{
|
||||
NoKey,
|
||||
RCard,
|
||||
BCard,
|
||||
YCard,
|
||||
RSkull,
|
||||
BSkull,
|
||||
YSkull,
|
||||
|
||||
AnyKey = 100,
|
||||
AllKeys = 101,
|
||||
|
||||
CardIsSkull = 128
|
||||
} keytype_t;
|
||||
|
||||
BOOL P_CheckKeys (player_t *p, keytype_t lock, BOOL remote);
|
||||
|
||||
// Define values for map objects
|
||||
#define MO_TELEPORTMAN 14
|
||||
|
@ -77,10 +125,10 @@ void P_UpdateSpecials (void);
|
|||
|
||||
// when needed
|
||||
BOOL P_UseSpecialLine (mobj_t *thing, line_t *line, int side);
|
||||
|
||||
void P_ShootSpecialLine (mobj_t *thing, line_t *line);
|
||||
|
||||
void P_ShotCrossSpecialLine (mobj_t *thing, line_t *line); // [RH]
|
||||
void P_CrossSpecialLine (int linenum, int side, mobj_t *thing);
|
||||
BOOL P_PushSpecialLine (mobj_t *thing, int side, line_t *line); // [RH]
|
||||
|
||||
void P_PlayerInSpecialSector (player_t *player);
|
||||
|
||||
|
@ -96,23 +144,35 @@ fixed_t P_FindHighestFloorSurrounding (sector_t *sec);
|
|||
fixed_t P_FindNextHighestFloor (sector_t *sec, int currentheight);
|
||||
fixed_t P_FindNextLowestFloor (sector_t* sec, int currentheight);
|
||||
|
||||
fixed_t P_FindLowestCeilingSurrounding (sector_t *sec);
|
||||
fixed_t P_FindHighestCeilingSurrounding (sector_t *sec);
|
||||
fixed_t P_FindLowestCeilingSurrounding (sector_t *sec); // jff 2/04/98
|
||||
fixed_t P_FindHighestCeilingSurrounding (sector_t *sec); // jff 2/04/98
|
||||
|
||||
int P_FindSectorFromLineTag (line_t *line, int start);
|
||||
fixed_t P_FindNextLowestCeiling (sector_t *sec, int currentheight); // jff 2/04/98
|
||||
fixed_t P_FindNextHighestCeiling (sector_t *sec, int currentheight); // jff 2/04/98
|
||||
|
||||
fixed_t P_FindShortestTextureAround (int secnum); // jff 2/04/98
|
||||
fixed_t P_FindShortestUpperAround (int secnum); // jff 2/04/98
|
||||
|
||||
sector_t* P_FindModelFloorSector (fixed_t floordestheight, int secnum); //jff 02/04/98
|
||||
sector_t* P_FindModelCeilingSector (fixed_t ceildestheight, int secnum); //jff 02/04/98
|
||||
|
||||
int P_FindSectorFromTag (int tag, int start);
|
||||
int P_FindLineFromID (int id, int start);
|
||||
|
||||
int P_FindMinSurroundingLight (sector_t *sector, int max);
|
||||
|
||||
sector_t *getNextSector (line_t *line, sector_t *sec);
|
||||
|
||||
sector_t *P_NextSpecialSector (sector_t *sec, int type, sector_t *back2); // [RH]
|
||||
|
||||
void T_Scroll (scroll_t *); // killough 3/7/98: scroll effect thinker
|
||||
void T_Friction (friction_t *); // phares 3/12/98: friction thinker
|
||||
void T_Pusher (pusher_t *); // phares 3/20/98: Push thinker
|
||||
|
||||
|
||||
//
|
||||
// SPECIAL
|
||||
//
|
||||
int EV_DoDonut (line_t *line);
|
||||
int EV_DoDonut (int tag, fixed_t pillarspeed, fixed_t slimespeed);
|
||||
|
||||
|
||||
|
||||
|
@ -166,29 +226,58 @@ typedef struct
|
|||
int direction;
|
||||
} glow_t;
|
||||
|
||||
// [RH] Glow from Light_Glow and Light_Fade specials
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
int start;
|
||||
int end;
|
||||
int maxtics;
|
||||
int tics;
|
||||
BOOL oneshot;
|
||||
} glow2_t;
|
||||
|
||||
#define GLOWSPEED ((TICRATE*8)/35)
|
||||
#define STROBEBRIGHT (TICRATE/7)
|
||||
#define FASTDARK ((TICRATE*3)/7)
|
||||
// [RH] Phased light thinker
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
byte baselevel;
|
||||
byte phase;
|
||||
} phased_t;
|
||||
|
||||
#define GLOWSPEED 8
|
||||
#define STROBEBRIGHT 5
|
||||
#define FASTDARK 15
|
||||
#define SLOWDARK TICRATE
|
||||
|
||||
void T_FireFlicker (fireflicker_t *flick);
|
||||
void P_SpawnFireFlicker (sector_t *sector);
|
||||
void T_LightFlash (lightflash_t *flash);
|
||||
void P_SpawnLightFlash (sector_t *sector);
|
||||
void P_SpawnLightFlash (sector_t *sector, int min, int max);
|
||||
void T_StrobeFlash (strobe_t *flash);
|
||||
|
||||
void P_SpawnStrobeFlash (sector_t *sector, int fastOrSlow, int inSync);
|
||||
void P_SpawnStrobeFlash (sector_t *sector, int upper, int lower,
|
||||
int utics, int ltics, int inSync);
|
||||
|
||||
void EV_StartLightStrobing(line_t *line);
|
||||
void EV_TurnTagLightsOff(line_t *line);
|
||||
|
||||
void EV_LightTurnOn (line_t *line, int bright);
|
||||
void EV_StartLightFlashing (int tag, int upper, int lower);
|
||||
void EV_StartLightStrobing (int tag, int upper, int lower,
|
||||
int utics, int ltics);
|
||||
void EV_TurnTagLightsOff (int tag);
|
||||
void EV_LightTurnOn (int tag, int bright);
|
||||
void EV_LightChange (int tag, int value);
|
||||
|
||||
void T_Glow (glow_t *g);
|
||||
void P_SpawnGlowingLight (sector_t *sector);
|
||||
|
||||
void T_Glow2 (glow2_t *g);
|
||||
void EV_StartLightGlowing (int tag, int upper, int lower, int tics);
|
||||
void EV_StartLightFading (int tag, int value, int tics);
|
||||
|
||||
void T_PhasedLight (phased_t *l);
|
||||
void P_SpawnLightSequence (sector_t *sector);
|
||||
void P_SpawnLightPhased (sector_t *sector);
|
||||
|
||||
|
||||
//
|
||||
|
@ -212,8 +301,9 @@ typedef enum
|
|||
} bwhere_e;
|
||||
|
||||
|
||||
typedef struct
|
||||
typedef struct button_s
|
||||
{
|
||||
struct button_s *next; // [RH] make buttons a singly-linked list
|
||||
line_t* line;
|
||||
bwhere_e where;
|
||||
int btexture;
|
||||
|
@ -225,13 +315,10 @@ typedef struct
|
|||
|
||||
|
||||
|
||||
// 4 players, 4 buttons each at once, max.
|
||||
#define MAXBUTTONS (MAXPLAYERS*4)
|
||||
|
||||
// 1 second, in ticks.
|
||||
#define BUTTONTIME TICRATE
|
||||
|
||||
extern button_t buttonlist[MAXBUTTONS];
|
||||
extern button_t *buttonlist;
|
||||
|
||||
void P_ChangeSwitchTexture (line_t *line, int useAgain);
|
||||
|
||||
|
@ -254,19 +341,29 @@ typedef enum
|
|||
|
||||
typedef enum
|
||||
{
|
||||
perpetualRaise,
|
||||
downWaitUpStay,
|
||||
raiseAndChange,
|
||||
raiseToNearestAndChange,
|
||||
blazeDWUS
|
||||
// [RH] Changed these
|
||||
platPerpetualRaise,
|
||||
platDownWaitUpStay,
|
||||
platUpWaitDownStay,
|
||||
platDownByValue,
|
||||
platUpByValue,
|
||||
platUpByValueStay,
|
||||
platRaiseAndStay,
|
||||
platToggle,
|
||||
platDownToNearestFloor,
|
||||
platDownToLowestCeiling
|
||||
|
||||
} plattype_e;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
typedef struct plat_s
|
||||
{
|
||||
thinker_t thinker;
|
||||
|
||||
// [RH] Added next and prev links
|
||||
struct plat_s *next, *prev;
|
||||
|
||||
sector_t* sector;
|
||||
fixed_t speed;
|
||||
fixed_t low;
|
||||
|
@ -283,40 +380,62 @@ typedef struct
|
|||
|
||||
|
||||
|
||||
#define PLATWAIT 3
|
||||
#define PLATSPEED FRACUNIT
|
||||
|
||||
extern int MaxPlats;
|
||||
extern plat_t **activeplats;
|
||||
extern plat_t *activeplats;
|
||||
|
||||
void T_PlatRaise(plat_t *plat);
|
||||
|
||||
int EV_DoPlat (line_t *line, plattype_e type, int amount);
|
||||
BOOL EV_DoPlat (int tag, line_t *line, plattype_e type, int height,
|
||||
int speed, int delay, int lip, int change);
|
||||
|
||||
void P_AddActivePlat (plat_t *plat);
|
||||
void P_RemoveActivePlat (plat_t *plat);
|
||||
void EV_StopPlat (line_t *line);
|
||||
void EV_StopPlat (int tag);
|
||||
void P_ActivateInStasis (int tag);
|
||||
|
||||
|
||||
//
|
||||
// [RH]
|
||||
// P_PILLAR
|
||||
//
|
||||
typedef enum
|
||||
{
|
||||
pillarBuild,
|
||||
pillarOpen
|
||||
|
||||
} pillar_e;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
pillar_e type;
|
||||
fixed_t floorspeed;
|
||||
fixed_t ceilingspeed;
|
||||
fixed_t floortarget;
|
||||
fixed_t ceilingtarget;
|
||||
int crush;
|
||||
|
||||
} pillar_t;
|
||||
|
||||
BOOL EV_DoPillar (pillar_e type, int tag, fixed_t speed, fixed_t height,
|
||||
fixed_t height2, int crush);
|
||||
|
||||
void T_Pillar (pillar_t *pillar);
|
||||
|
||||
//
|
||||
// P_DOORS
|
||||
//
|
||||
typedef enum
|
||||
{
|
||||
normal,
|
||||
close30ThenOpen,
|
||||
close,
|
||||
open,
|
||||
raiseIn5Mins,
|
||||
blazeRaise,
|
||||
blazeOpen,
|
||||
blazeClose
|
||||
// [RH] Changed for new specials
|
||||
doorClose,
|
||||
doorOpen,
|
||||
doorRaise,
|
||||
doorRaiseIn5Mins,
|
||||
doorCloseWaitOpen,
|
||||
|
||||
} vldoor_e;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
|
@ -337,133 +456,78 @@ typedef struct
|
|||
} vldoor_t;
|
||||
|
||||
|
||||
|
||||
#define VDOORSPEED (FRACUNIT*2)
|
||||
#define VDOORWAIT ((TICRATE*30)/7)
|
||||
|
||||
void EV_VerticalDoor (line_t *line, mobj_t *thing);
|
||||
|
||||
int EV_DoDoor (line_t *line, vldoor_e type);
|
||||
|
||||
int EV_DoLockedDoor (line_t *line, vldoor_e type, mobj_t *thing);
|
||||
BOOL EV_DoDoor (vldoor_e type, line_t *line, mobj_t *thing,
|
||||
int tag, int speed, int delay, keytype_t lock);
|
||||
|
||||
void T_VerticalDoor (vldoor_t *door);
|
||||
void P_SpawnDoorCloseIn30 (sector_t *sec);
|
||||
|
||||
void P_SpawnDoorRaiseIn5Mins (sector_t *sec, int secnum);
|
||||
|
||||
|
||||
|
||||
#if 0 // UNUSED
|
||||
//
|
||||
// Sliding doors...
|
||||
//
|
||||
typedef enum
|
||||
{
|
||||
sd_opening,
|
||||
sd_waiting,
|
||||
sd_closing
|
||||
|
||||
} sd_e;
|
||||
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
sdt_openOnly,
|
||||
sdt_closeOnly,
|
||||
sdt_openAndClose
|
||||
|
||||
} sdt_e;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sdt_e type;
|
||||
line_t* line;
|
||||
int frame;
|
||||
int whichDoorIndex;
|
||||
int timer;
|
||||
sector_t* frontsector;
|
||||
sector_t* backsector;
|
||||
sd_e status;
|
||||
|
||||
} slidedoor_t;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char frontFrame1[9];
|
||||
char frontFrame2[9];
|
||||
char frontFrame3[9];
|
||||
char frontFrame4[9];
|
||||
char backFrame1[9];
|
||||
char backFrame2[9];
|
||||
char backFrame3[9];
|
||||
char backFrame4[9];
|
||||
|
||||
} slidename_t;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int frontFrames[4];
|
||||
int backFrames[4];
|
||||
|
||||
} slideframe_t;
|
||||
|
||||
|
||||
|
||||
// how many frames of animation
|
||||
#define SNUMFRAMES 4
|
||||
|
||||
#define SDOORWAIT (3*TICRATE)
|
||||
#define SWAITTICS 4
|
||||
|
||||
// how many diff. types of anims
|
||||
#define MAXSLIDEDOORS 5
|
||||
|
||||
void P_InitSlidingDoorFrames(void);
|
||||
|
||||
void EV_SlidingDoor (line_t *line, mobj_t *thing);
|
||||
#endif
|
||||
void P_SpawnDoorRaiseIn5Mins (sector_t *sec);
|
||||
|
||||
|
||||
|
||||
//
|
||||
// P_CEILNG
|
||||
//
|
||||
|
||||
// [RH] Changed these
|
||||
typedef enum
|
||||
{
|
||||
lowerToFloor,
|
||||
raiseToHighest,
|
||||
lowerAndCrush,
|
||||
crushAndRaise,
|
||||
fastCrushAndRaise,
|
||||
silentCrushAndRaise
|
||||
ceilLowerByValue,
|
||||
ceilRaiseByValue,
|
||||
ceilMoveToValue,
|
||||
ceilLowerToHighestFloor,
|
||||
ceilLowerInstant,
|
||||
ceilRaiseInstant,
|
||||
ceilCrushAndRaise,
|
||||
ceilLowerAndCrush,
|
||||
ceilCrushRaiseAndStay,
|
||||
ceilRaiseToNearest,
|
||||
ceilLowerToLowest,
|
||||
ceilLowerToFloor,
|
||||
|
||||
// The following are only used by Generic_Ceiling
|
||||
ceilRaiseToHighest,
|
||||
ceilLowerToHighest,
|
||||
ceilRaiseToLowest,
|
||||
ceilLowerToNearest,
|
||||
ceilRaiseToHighestFloor,
|
||||
ceilRaiseToFloor,
|
||||
ceilRaiseByTexture,
|
||||
ceilLowerByTexture,
|
||||
|
||||
genCeilingChg0,
|
||||
genCeilingChgT,
|
||||
genCeilingChg
|
||||
|
||||
} ceiling_e;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
typedef struct ceiling_s
|
||||
{
|
||||
thinker_t thinker;
|
||||
|
||||
// [RH] Added next and prev links
|
||||
struct ceiling_s *next, *prev;
|
||||
|
||||
ceiling_e type;
|
||||
sector_t* sector;
|
||||
fixed_t bottomheight;
|
||||
fixed_t topheight;
|
||||
fixed_t speed;
|
||||
BOOL crush;
|
||||
fixed_t speed1; // [RH] dnspeed of crushers
|
||||
fixed_t speed2; // [RH] upspeed of crushers
|
||||
int crush;
|
||||
int silent; // [RH] 1=noise at stops, 2=no noise at all
|
||||
|
||||
// 1 = up, 0 = waiting, -1 = down
|
||||
int direction;
|
||||
|
||||
// [RH] Need these for BOOM-ish transfering ceilings
|
||||
int texture;
|
||||
int newspecial;
|
||||
|
||||
// ID
|
||||
int tag;
|
||||
int olddirection;
|
||||
|
@ -474,48 +538,74 @@ typedef struct
|
|||
|
||||
|
||||
|
||||
#define CEILSPEED FRACUNIT
|
||||
#define CEILWAIT ((TICRATE*30)/7)
|
||||
extern ceiling_t *activeceilings;
|
||||
|
||||
extern int MaxCeilings;
|
||||
extern ceiling_t **activeceilings;
|
||||
|
||||
int EV_DoCeiling (line_t *line, ceiling_e type);
|
||||
BOOL EV_DoCeiling (ceiling_e type, line_t *line,
|
||||
int tag, fixed_t speed, fixed_t speed2, fixed_t height,
|
||||
int crush, int silent, int change);
|
||||
|
||||
void T_MoveCeiling (ceiling_t *ceiling);
|
||||
void P_AddActiveCeiling(ceiling_t *c);
|
||||
void P_RemoveActiveCeiling(ceiling_t *c);
|
||||
int EV_CeilingCrushStop(line_t *line);
|
||||
void P_ActivateInStasisCeiling(line_t *line);
|
||||
void P_AddActiveCeiling (ceiling_t *c);
|
||||
void P_RemoveActiveCeiling (ceiling_t *c);
|
||||
BOOL EV_CeilingCrushStop (int tag);
|
||||
void P_ActivateInStasisCeiling(int tag);
|
||||
|
||||
|
||||
//
|
||||
// P_FLOOR
|
||||
//
|
||||
// [RH] Changed these enums
|
||||
typedef enum
|
||||
{
|
||||
lowerFloor, // lower floor to highest surrounding floor
|
||||
lowerFloorToLowest, // lower floor to lowest surrounding floor
|
||||
turboLower, // lower floor to highest surrounding floor VERY FAST
|
||||
raiseFloor, // raise floor to lowest surrounding CEILING
|
||||
raiseFloorToNearest, // raise floor to next highest surrounding floor
|
||||
raiseToTexture, // raise floor to shortest height texture around it
|
||||
lowerAndChange, // lower floor to lowest surrounding floor and change floorpic
|
||||
floorLowerToLowest,
|
||||
floorLowerToNearest,
|
||||
floorLowerToHighest,
|
||||
floorLowerByValue,
|
||||
floorRaiseByValue,
|
||||
floorRaiseToHighest,
|
||||
floorRaiseToNearest,
|
||||
floorRaiseAndCrush,
|
||||
floorCrushStop,
|
||||
floorLowerInstant,
|
||||
floorRaiseInstant,
|
||||
floorMoveToValue,
|
||||
floorRaiseToLowestCeiling,
|
||||
floorRaiseByTexture,
|
||||
|
||||
raiseFloor24,
|
||||
raiseFloor24AndChange,
|
||||
raiseFloorCrush,
|
||||
floorLowerAndChange,
|
||||
floorRaiseAndChange,
|
||||
|
||||
raiseFloorTurbo, // raise to next highest floor, turbo-speed
|
||||
floorRaiseToLowest,
|
||||
floorRaiseToCeiling,
|
||||
floorLowerToLowestCeiling,
|
||||
floorLowerByTexture,
|
||||
floorLowerToCeiling,
|
||||
|
||||
donutRaise,
|
||||
raiseFloor512
|
||||
|
||||
|
||||
buildStair,
|
||||
waitStair,
|
||||
resetStair,
|
||||
|
||||
// Not to be used as parameters to EV_DoFloor()
|
||||
genFloorChg0,
|
||||
genFloorChgT,
|
||||
genFloorChg
|
||||
|
||||
} floor_e;
|
||||
|
||||
//jff 3/15/98 pure texture/type change for better generalized support
|
||||
typedef enum
|
||||
{
|
||||
build8, // slowly build by 8
|
||||
turbo16 // quickly build by 16
|
||||
trigChangeOnly,
|
||||
numChangeOnly,
|
||||
} change_e;
|
||||
|
||||
// [RH] Changed to use Hexen-ish specials
|
||||
typedef enum
|
||||
{
|
||||
buildUp,
|
||||
buildDown
|
||||
|
||||
} stair_e;
|
||||
|
||||
|
@ -524,36 +614,56 @@ typedef enum
|
|||
elevateUp,
|
||||
elevateDown,
|
||||
elevateCurrent,
|
||||
// [RH] For FloorAndCeiling_Raise/Lower
|
||||
elevateRaise,
|
||||
elevateLower
|
||||
} elevator_e;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
floor_e type;
|
||||
BOOL crush;
|
||||
int crush;
|
||||
sector_t* sector;
|
||||
int direction;
|
||||
int newspecial;
|
||||
short newspecial;
|
||||
short texture;
|
||||
fixed_t floordestheight;
|
||||
fixed_t speed;
|
||||
|
||||
// [RH] New parameters use to reset and delayed stairs
|
||||
int resetcount;
|
||||
int orgheight;
|
||||
int delay;
|
||||
int pausetime;
|
||||
int steptime;
|
||||
int persteptime;
|
||||
|
||||
} floormove_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
elevator_e type;
|
||||
sector_t* sector;
|
||||
int direction;
|
||||
fixed_t floordestheight;
|
||||
fixed_t ceilingdestheight;
|
||||
fixed_t speed;
|
||||
thinker_t thinker;
|
||||
elevator_e type;
|
||||
sector_t* sector;
|
||||
int direction;
|
||||
fixed_t floordestheight;
|
||||
fixed_t ceilingdestheight;
|
||||
fixed_t speed;
|
||||
} elevator_t;
|
||||
|
||||
typedef struct {
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
int x;
|
||||
int amp;
|
||||
int freq;
|
||||
int timetodie;
|
||||
fixed_t baseline;
|
||||
int stage;
|
||||
int ampfactor;
|
||||
} waggle_t;
|
||||
|
||||
#define ELEVATORSPEED (FRACUNIT*4)
|
||||
#define FLOORSPEED FRACUNIT
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -564,25 +674,65 @@ typedef enum
|
|||
} result_e;
|
||||
|
||||
result_e T_MovePlane (sector_t *sector, fixed_t speed, fixed_t dest,
|
||||
BOOL crush, int floorOrCeiling, int direction);
|
||||
int crush, int floorOrCeiling, int direction);
|
||||
|
||||
int EV_DoElevator (line_t *line, ceiling_e type);
|
||||
BOOL EV_DoElevator (line_t *line, ceiling_e type, fixed_t speed, fixed_t height, int tag);
|
||||
|
||||
int EV_BuildStairs (line_t *line, stair_e type);
|
||||
BOOL EV_BuildStairs (int tag, stair_e type, line_t *line,
|
||||
fixed_t stairsize, fixed_t speed, int delay, int reset, int igntxt,
|
||||
int usespecials);
|
||||
|
||||
int EV_DoFloor (line_t *line, floor_e floortype);
|
||||
BOOL EV_DoFloor (floor_e floortype, line_t *line, int tag,
|
||||
fixed_t speed, fixed_t height, int crush, int change);
|
||||
BOOL EV_FloorCrushStop (int tag);
|
||||
BOOL EV_DoChange (line_t *line, change_e changetype, int tag);
|
||||
BOOL EV_DoFloorWaggle (int tag, fixed_t amplitude, fixed_t speed, int delay, int count);
|
||||
|
||||
void T_Waggle (waggle_t *w);
|
||||
void T_MoveFloor (floormove_t *floor);
|
||||
|
||||
void T_MoveElevator (elevator_t *elevator);
|
||||
|
||||
|
||||
//
|
||||
// P_TELEPT
|
||||
//
|
||||
int EV_Teleport (line_t *line, int side, mobj_t *thing);
|
||||
BOOL EV_Teleport (int tid, int side, mobj_t *thing);
|
||||
BOOL EV_SilentTeleport (int tid, line_t *line, int side, mobj_t *thing);
|
||||
BOOL EV_SilentLineTeleport (line_t *line, int side, mobj_t *thing, int id,
|
||||
BOOL reverse);
|
||||
|
||||
|
||||
int P_SectorActive (special_e t, sector_t *s); // [RH] from BOOM
|
||||
|
||||
|
||||
//
|
||||
// [RH] ACS (see also p_acs.h)
|
||||
//
|
||||
|
||||
void P_ClearScripts (void);
|
||||
|
||||
BOOL P_StartScript (mobj_t *who, line_t *where, int script, char *map, int lineSide,
|
||||
int arg0, int arg1, int arg2, int always);
|
||||
void P_SuspendScript (int script, char *map);
|
||||
void P_TerminateScript (int script, char *map);
|
||||
void P_StartOpenScripts (void);
|
||||
void P_DoDeferedScripts (void);
|
||||
|
||||
//
|
||||
// [RH] p_quake.c
|
||||
//
|
||||
typedef struct quake_s {
|
||||
struct quake_s *next;
|
||||
mobj_t *quakespot;
|
||||
fixed_t tremorbox[4];
|
||||
fixed_t damagebox[4];
|
||||
int intensity;
|
||||
int countdown;
|
||||
} quake_t;
|
||||
|
||||
extern quake_t *ActiveQuakes;
|
||||
|
||||
void P_RunQuakes (void);
|
||||
BOOL P_StartQuake (int tid, int intensity, int duration, int damrad, int tremrad);
|
||||
|
||||
#endif
|
||||
|
|
526
code/P_switch.c
526
code/P_switch.c
|
@ -15,8 +15,6 @@
|
|||
// for more details.
|
||||
//
|
||||
//
|
||||
// $Log:$
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Switches, buttons. Two-state animation. Exits.
|
||||
//
|
||||
|
@ -27,14 +25,12 @@
|
|||
#include "i_system.h"
|
||||
#include "doomdef.h"
|
||||
#include "p_local.h"
|
||||
#include "p_lnspec.h"
|
||||
|
||||
#include "g_game.h"
|
||||
|
||||
#include "s_sound.h"
|
||||
|
||||
// Data.
|
||||
#include "sounds.h"
|
||||
|
||||
// State.
|
||||
#include "doomstat.h"
|
||||
#include "r_state.h"
|
||||
|
@ -49,7 +45,7 @@
|
|||
static int *switchlist;
|
||||
static int numswitches;
|
||||
|
||||
button_t buttonlist[MAXBUTTONS];
|
||||
button_t *buttonlist; // [RH] remove limit on number of buttons
|
||||
|
||||
//
|
||||
// P_InitSwitchList
|
||||
|
@ -100,58 +96,44 @@ void P_InitSwitchList(void)
|
|||
Z_Free (alphSwitchList);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Start a button counting down till it turns off.
|
||||
// [RH] Rewritten to remove MAXBUTTONS limit and use temporary soundorgs.
|
||||
//
|
||||
void P_StartButton (line_t *line, bwhere_e w, int texture, int time)
|
||||
void P_StartButton (line_t *line, bwhere_e w, int texture, int time, mobj_t *soundorg)
|
||||
{
|
||||
int i;
|
||||
button_t *button;
|
||||
|
||||
// See if button is already pressed
|
||||
for (i = 0;i < MAXBUTTONS;i++)
|
||||
{
|
||||
if (buttonlist[i].btimer
|
||||
&& buttonlist[i].line == line)
|
||||
{
|
||||
|
||||
button = buttonlist;
|
||||
while (button) {
|
||||
if (button->line == line)
|
||||
return;
|
||||
}
|
||||
button = button->next;
|
||||
}
|
||||
|
||||
button = Z_Malloc (sizeof(*button), PU_LEVEL, 0);
|
||||
|
||||
|
||||
for (i = 0;i < MAXBUTTONS;i++)
|
||||
{
|
||||
if (!buttonlist[i].btimer)
|
||||
{
|
||||
buttonlist[i].line = line;
|
||||
buttonlist[i].where = w;
|
||||
buttonlist[i].btexture = texture;
|
||||
buttonlist[i].btimer = time;
|
||||
buttonlist[i].soundorg = (mobj_t *)&line->frontsector->soundorg;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
I_Error("P_StartButton: no button slots left!");
|
||||
button->line = line;
|
||||
button->where = w;
|
||||
button->btexture = texture;
|
||||
button->btimer = time;
|
||||
button->soundorg = soundorg;
|
||||
button->next = buttonlist;
|
||||
buttonlist = button;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Function that changes wall texture.
|
||||
// Tell it if switch is ok to use again (1=yes, it's a button).
|
||||
//
|
||||
void P_ChangeSwitchTexture (line_t *line, int useAgain)
|
||||
{
|
||||
int texTop;
|
||||
int texMid;
|
||||
int texBot;
|
||||
int i;
|
||||
int sound;
|
||||
int texTop;
|
||||
int texMid;
|
||||
int texBot;
|
||||
int i;
|
||||
char *sound;
|
||||
|
||||
if (!useAgain)
|
||||
line->special = 0;
|
||||
|
@ -160,58 +142,53 @@ void P_ChangeSwitchTexture (line_t *line, int useAgain)
|
|||
texMid = sides[line->sidenum[0]].midtexture;
|
||||
texBot = sides[line->sidenum[0]].bottomtexture;
|
||||
|
||||
sound = sfx_swtchn;
|
||||
|
||||
// EXIT SWITCH?
|
||||
if (line->special == 11)
|
||||
sound = sfx_swtchx;
|
||||
if (line->special == Exit_Normal ||
|
||||
line->special == Exit_Secret ||
|
||||
line->special == Teleport_NewMap ||
|
||||
line->special == Teleport_EndGame)
|
||||
sound = "switches/exitbutn";
|
||||
else
|
||||
sound = "switches/normbutn";
|
||||
|
||||
for (i = 0;i < numswitches*2;i++)
|
||||
for (i = 0; i < numswitches*2; i++)
|
||||
{
|
||||
if (switchlist[i] == texTop)
|
||||
{
|
||||
S_StartSound(buttonlist->soundorg,sound);
|
||||
sides[line->sidenum[0]].toptexture = (short)switchlist[i^1];
|
||||
// [RH] Rewritten slightly to be more compact
|
||||
short *texture = NULL;
|
||||
bwhere_e where;
|
||||
|
||||
if (useAgain)
|
||||
P_StartButton(line,top,switchlist[i],BUTTONTIME);
|
||||
|
||||
return;
|
||||
if (switchlist[i] == texTop) {
|
||||
texture = &sides[line->sidenum[0]].toptexture;
|
||||
where = top;
|
||||
} else if (switchlist[i] == texMid) {
|
||||
texture = &sides[line->sidenum[0]].midtexture;
|
||||
where = middle;
|
||||
} else if (switchlist[i] == texBot) {
|
||||
texture = &sides[line->sidenum[0]].bottomtexture;
|
||||
where = bottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (switchlist[i] == texMid)
|
||||
{
|
||||
S_StartSound(buttonlist->soundorg,sound);
|
||||
sides[line->sidenum[0]].midtexture = (short)switchlist[i^1];
|
||||
|
||||
if (useAgain)
|
||||
P_StartButton(line, middle,switchlist[i],BUTTONTIME);
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (switchlist[i] == texBot)
|
||||
{
|
||||
S_StartSound(buttonlist->soundorg,sound);
|
||||
sides[line->sidenum[0]].bottomtexture = (short)switchlist[i^1];
|
||||
|
||||
if (useAgain)
|
||||
P_StartButton(line, bottom,switchlist[i],BUTTONTIME);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (texture) {
|
||||
// [RH] The original code played the sound at buttonlist->soundorg.
|
||||
// I spawn a temporary mobj on the button's line to play the
|
||||
// sound. It automatically removes itself after 60 seconds.
|
||||
mobj_t *soundorg = P_SpawnMobj (
|
||||
line->v1->x + (line->dx >> 1),
|
||||
line->v1->y + (line->dy >> 1),
|
||||
0, // z doesn't matter
|
||||
MT_SWITCHTEMP,
|
||||
0);
|
||||
S_StartSound (soundorg, sound, 78);
|
||||
*texture = (short)switchlist[i^1];
|
||||
if (useAgain)
|
||||
P_StartButton (line, where, switchlist[i], BUTTONTIME, soundorg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// P_UseSpecialLine
|
||||
// Called when a thing uses a special line.
|
||||
|
@ -219,381 +196,34 @@ void P_ChangeSwitchTexture (line_t *line, int useAgain)
|
|||
//
|
||||
BOOL P_UseSpecialLine (mobj_t *thing, line_t *line, int side)
|
||||
{
|
||||
BOOL result;
|
||||
|
||||
// Err...
|
||||
// Use the back sides of VERY SPECIAL lines...
|
||||
if (side)
|
||||
{
|
||||
switch(line->special)
|
||||
{
|
||||
case 124:
|
||||
// Sliding door open&close
|
||||
// UNUSED?
|
||||
break;
|
||||
// [RH] Line needs to be setup for use activation
|
||||
if ((line->flags & ML_ACTIVATIONMASK) != ML_ACTIVATEUSE)
|
||||
return false;
|
||||
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Switches that other things can activate.
|
||||
if (!thing->player)
|
||||
{
|
||||
// never open secret doors
|
||||
// [RH] Don't let monsters activate the special unless the line says they can.
|
||||
// (Some lines automatically imply ML_MONSTERSCANACTIVATE)
|
||||
if (!thing->player) {
|
||||
if (line->flags & ML_SECRET)
|
||||
return false; // monsters never activate secrets
|
||||
if (!(line->flags & ML_MONSTERSCANACTIVATE) &&
|
||||
(line->special != Door_Raise || line->args[0] != 0) &&
|
||||
line->special != Teleport &&
|
||||
line->special != Teleport_NoFog)
|
||||
return false;
|
||||
|
||||
switch(line->special)
|
||||
{
|
||||
case 1: // MANUAL DOOR RAISE
|
||||
case 32: // MANUAL BLUE
|
||||
case 33: // MANUAL RED
|
||||
case 34: // MANUAL YELLOW
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] Use LineSpecials[] dispatcher table.
|
||||
result = LineSpecials[line->special] (line, thing, line->args[0],
|
||||
line->args[1], line->args[2],
|
||||
line->args[3], line->args[4]);
|
||||
|
||||
// do something
|
||||
switch (line->special)
|
||||
{
|
||||
// MANUALS
|
||||
case 1: // Vertical Door
|
||||
case 26: // Blue Door/Locked
|
||||
case 27: // Yellow Door /Locked
|
||||
case 28: // Red Door /Locked
|
||||
// [RH] It's possible for a script to render the line unusable even if it has the
|
||||
// repeatable flag set by calling clearlinespecial().
|
||||
if (result)
|
||||
P_ChangeSwitchTexture (line, (line->flags & ML_REPEATABLE) && line->special);
|
||||
|
||||
case 31: // Manual door open
|
||||
case 32: // Blue locked door open
|
||||
case 33: // Red locked door open
|
||||
case 34: // Yellow locked door open
|
||||
|
||||
case 117: // Blazing door raise
|
||||
case 118: // Blazing door open
|
||||
EV_VerticalDoor (line, thing);
|
||||
break;
|
||||
|
||||
//UNUSED - Door Slide Open&Close
|
||||
// case 124:
|
||||
// EV_SlidingDoor (line, thing);
|
||||
// break;
|
||||
|
||||
// SWITCHES
|
||||
case 7:
|
||||
// Build Stairs
|
||||
if (EV_BuildStairs(line,build8))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
// Change Donut
|
||||
if (EV_DoDonut(line))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
// Exit level
|
||||
if (CheckIfExitIsGood (thing)) {
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
G_ExitLevel ();
|
||||
}
|
||||
break;
|
||||
|
||||
case 14:
|
||||
// Raise Floor 32 and change texture
|
||||
if (EV_DoPlat(line,raiseAndChange,32))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 15:
|
||||
// Raise Floor 24 and change texture
|
||||
if (EV_DoPlat(line,raiseAndChange,24))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 18:
|
||||
// Raise Floor to next highest floor
|
||||
if (EV_DoFloor(line, raiseFloorToNearest))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 20:
|
||||
// Raise Plat next highest floor and change texture
|
||||
if (EV_DoPlat(line,raiseToNearestAndChange,0))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 21:
|
||||
// PlatDownWaitUpStay
|
||||
if (EV_DoPlat(line,downWaitUpStay,0))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 23:
|
||||
// Lower Floor to Lowest
|
||||
if (EV_DoFloor(line,lowerFloorToLowest))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 29:
|
||||
// Raise Door
|
||||
if (EV_DoDoor(line,normal))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 41:
|
||||
// Lower Ceiling to Floor
|
||||
if (EV_DoCeiling(line,lowerToFloor))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 71:
|
||||
// Turbo Lower Floor
|
||||
if (EV_DoFloor(line,turboLower))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 49:
|
||||
// Ceiling Crush And Raise
|
||||
if (EV_DoCeiling(line,crushAndRaise))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 50:
|
||||
// Close Door
|
||||
if (EV_DoDoor(line,close))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 51:
|
||||
// Secret EXIT
|
||||
if (CheckIfExitIsGood (thing)) {
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
G_SecretExitLevel ();
|
||||
}
|
||||
break;
|
||||
|
||||
case 55:
|
||||
// Raise Floor Crush
|
||||
if (EV_DoFloor(line,raiseFloorCrush))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 101:
|
||||
// Raise Floor
|
||||
if (EV_DoFloor(line,raiseFloor))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 102:
|
||||
// Lower Floor to Surrounding floor height
|
||||
if (EV_DoFloor(line,lowerFloor))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 103:
|
||||
// Open Door
|
||||
if (EV_DoDoor(line,open))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 111:
|
||||
// Blazing Door Raise (faster than TURBO!)
|
||||
if (EV_DoDoor (line,blazeRaise))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 112:
|
||||
// Blazing Door Open (faster than TURBO!)
|
||||
if (EV_DoDoor (line,blazeOpen))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 113:
|
||||
// Blazing Door Close (faster than TURBO!)
|
||||
if (EV_DoDoor (line,blazeClose))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 122:
|
||||
// Blazing PlatDownWaitUpStay
|
||||
if (EV_DoPlat(line,blazeDWUS,0))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 127:
|
||||
// Build Stairs Turbo 16
|
||||
if (EV_BuildStairs(line,turbo16))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 131:
|
||||
// Raise Floor Turbo
|
||||
if (EV_DoFloor(line,raiseFloorTurbo))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 133:
|
||||
// BlzOpenDoor BLUE
|
||||
case 135:
|
||||
// BlzOpenDoor RED
|
||||
case 137:
|
||||
// BlzOpenDoor YELLOW
|
||||
if (EV_DoLockedDoor (line,blazeOpen,thing))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
case 140:
|
||||
// Raise Floor 512
|
||||
if (EV_DoFloor(line,raiseFloor512))
|
||||
P_ChangeSwitchTexture(line,0);
|
||||
break;
|
||||
|
||||
// BUTTONS
|
||||
case 42:
|
||||
// Close Door
|
||||
if (EV_DoDoor(line,close))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 43:
|
||||
// Lower Ceiling to Floor
|
||||
if (EV_DoCeiling(line,lowerToFloor))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 45:
|
||||
// Lower Floor to Surrounding floor height
|
||||
if (EV_DoFloor(line,lowerFloor))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 60:
|
||||
// Lower Floor to Lowest
|
||||
if (EV_DoFloor(line,lowerFloorToLowest))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 61:
|
||||
// Open Door
|
||||
if (EV_DoDoor(line,open))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 62:
|
||||
// PlatDownWaitUpStay
|
||||
if (EV_DoPlat(line,downWaitUpStay,1))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 63:
|
||||
// Raise Door
|
||||
if (EV_DoDoor(line,normal))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 64:
|
||||
// Raise Floor to ceiling
|
||||
if (EV_DoFloor(line,raiseFloor))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 66:
|
||||
// Raise Floor 24 and change texture
|
||||
if (EV_DoPlat(line,raiseAndChange,24))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 67:
|
||||
// Raise Floor 32 and change texture
|
||||
if (EV_DoPlat(line,raiseAndChange,32))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 65:
|
||||
// Raise Floor Crush
|
||||
if (EV_DoFloor(line,raiseFloorCrush))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 68:
|
||||
// Raise Plat to next highest floor and change texture
|
||||
if (EV_DoPlat(line,raiseToNearestAndChange,0))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 69:
|
||||
// Raise Floor to next highest floor
|
||||
if (EV_DoFloor(line, raiseFloorToNearest))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 70:
|
||||
// Turbo Lower Floor
|
||||
if (EV_DoFloor(line,turboLower))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 114:
|
||||
// Blazing Door Raise (faster than TURBO!)
|
||||
if (EV_DoDoor (line,blazeRaise))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 115:
|
||||
// Blazing Door Open (faster than TURBO!)
|
||||
if (EV_DoDoor (line,blazeOpen))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 116:
|
||||
// Blazing Door Close (faster than TURBO!)
|
||||
if (EV_DoDoor (line,blazeClose))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 123:
|
||||
// Blazing PlatDownWaitUpStay
|
||||
if (EV_DoPlat(line,blazeDWUS,0))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 132:
|
||||
// Raise Floor Turbo
|
||||
if (EV_DoFloor(line,raiseFloorTurbo))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 99:
|
||||
// BlzOpenDoor BLUE
|
||||
case 134:
|
||||
// BlzOpenDoor RED
|
||||
case 136:
|
||||
// BlzOpenDoor YELLOW
|
||||
if (EV_DoLockedDoor (line,blazeOpen,thing))
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 138:
|
||||
// Light Turn On
|
||||
EV_LightTurnOn(line,255);
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
case 139:
|
||||
// Light Turn Off
|
||||
EV_LightTurnOn(line,35);
|
||||
P_ChangeSwitchTexture(line,1);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,10 +25,13 @@
|
|||
|
||||
#include "z_zone.h"
|
||||
#include "p_local.h"
|
||||
#include "p_acs.h"
|
||||
#include "c_consol.h"
|
||||
|
||||
#include "doomstat.h"
|
||||
|
||||
extern int ConsoleState;
|
||||
extern constate_e ConsoleState;
|
||||
extern gamestate_t wipegamestate;
|
||||
|
||||
//
|
||||
// THINKERS
|
||||
|
@ -41,7 +44,7 @@ extern int ConsoleState;
|
|||
|
||||
|
||||
// Both the head and tail of the thinker list.
|
||||
thinker_t thinkercap;
|
||||
thinker_t thinkercap;
|
||||
|
||||
|
||||
//
|
||||
|
@ -49,7 +52,7 @@ thinker_t thinkercap;
|
|||
//
|
||||
void P_InitThinkers (void)
|
||||
{
|
||||
thinkercap.prev = thinkercap.next = &thinkercap;
|
||||
thinkercap.prev = thinkercap.next = &thinkercap;
|
||||
}
|
||||
|
||||
|
||||
|
@ -130,7 +133,7 @@ void P_RunThinkers (void)
|
|||
|
||||
void P_Ticker (void)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
// run the tic
|
||||
if (paused)
|
||||
|
@ -138,23 +141,36 @@ void P_Ticker (void)
|
|||
|
||||
// pause if in menu or console and at least one tic has been run
|
||||
if ( !netgame
|
||||
&& (menuactive || ConsoleState == 1 || ConsoleState == 2)
|
||||
&& (menuactive || ConsoleState == c_down || ConsoleState == c_falling)
|
||||
&& !demoplayback
|
||||
&& !demorecording
|
||||
&& players[consoleplayer].viewz != 1)
|
||||
&& players[consoleplayer].viewz != 1
|
||||
&& wipegamestate == gamestate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
||||
for (i = 0; i<MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
P_PlayerThink (&players[i]);
|
||||
|
||||
P_RunThinkers ();
|
||||
P_RunScripts (); // [RH] Execute any active scripts
|
||||
P_RunQuakes (); // [RH] Shake the earth a little
|
||||
P_UpdateSpecials ();
|
||||
P_RespawnSpecials ();
|
||||
|
||||
// [RH] Apply falling damage
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i]) {
|
||||
P_FallingDamage (players[i].mo);
|
||||
|
||||
players[i].oldvelocity[0] = players[i].mo->momx;
|
||||
players[i].oldvelocity[1] = players[i].mo->momy;
|
||||
players[i].oldvelocity[2] = players[i].mo->momz;
|
||||
}
|
||||
|
||||
// for par times
|
||||
level.time++;
|
||||
}
|
||||
|
|
224
code/P_user.c
224
code/P_user.c
|
@ -28,10 +28,9 @@
|
|||
|
||||
#include "doomdef.h"
|
||||
#include "d_event.h"
|
||||
|
||||
#include "p_local.h"
|
||||
|
||||
#include "doomstat.h"
|
||||
#include "s_sound.h"
|
||||
|
||||
|
||||
|
||||
|
@ -80,14 +79,20 @@ void P_CalcHeight (player_t* player)
|
|||
// OPTIMIZE: tablify angle
|
||||
// Note: a LUT allows for effects
|
||||
// like a ramp with low health.
|
||||
player->bob =
|
||||
FixedMul (player->mo->momx, player->mo->momx)
|
||||
+ FixedMul (player->mo->momy,player->mo->momy);
|
||||
|
||||
player->bob = FixedMul(player->mo->momx,player->mo->momx)
|
||||
+ FixedMul(player->mo->momy,player->mo->momy);
|
||||
player->bob >>= 2;
|
||||
|
||||
if (player->bob>MAXBOB)
|
||||
player->bob = MAXBOB;
|
||||
// phares 9/9/98: If player is standing on ice, reduce his bobbing.
|
||||
|
||||
if (player->mo->friction > ORIG_FRICTION) // ice?
|
||||
{
|
||||
if (player->bob > (MAXBOB>>2))
|
||||
player->bob = MAXBOB>>2;
|
||||
}
|
||||
else // ^
|
||||
if (player->bob > MAXBOB) // |
|
||||
player->bob = MAXBOB; // phares 2/26/98
|
||||
|
||||
if ((player->cheats & CF_NOMOMENTUM) || !onground)
|
||||
{
|
||||
|
@ -96,7 +101,11 @@ void P_CalcHeight (player_t* player)
|
|||
if (player->viewz > player->mo->ceilingz-4*FRACUNIT)
|
||||
player->viewz = player->mo->ceilingz-4*FRACUNIT;
|
||||
|
||||
player->viewz = player->mo->z + player->viewheight;
|
||||
// The following line was in the Id source and appears // phares 2/25/98
|
||||
// to be a bug. player->viewz is checked in a similar
|
||||
// manner at a different exit below.
|
||||
|
||||
// player->viewz = player->mo->z + player->viewheight;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -143,26 +152,33 @@ void P_CalcHeight (player_t* player)
|
|||
void P_MovePlayer (player_t *player)
|
||||
{
|
||||
ticcmd_t *cmd = &player->cmd;
|
||||
|
||||
int movefactor; // movement factor // phares
|
||||
fixed_t forwardmove;
|
||||
fixed_t sidemove;
|
||||
|
||||
player->mo->angle += (cmd->ucmd.yaw<<16);
|
||||
|
||||
// [RH] allow very limited movement if not on ground.
|
||||
onground = P_FindFloor (player->mo);
|
||||
|
||||
if (onground) {
|
||||
if (cmd->ucmd.forwardmove)
|
||||
P_Thrust (player, player->mo->angle, cmd->ucmd.forwardmove*8);
|
||||
|
||||
if (cmd->ucmd.sidemove)
|
||||
P_Thrust (player, player->mo->angle-ANG90, cmd->ucmd.sidemove*8);
|
||||
} else if (!olddemo) {
|
||||
if (cmd->ucmd.forwardmove)
|
||||
P_Thrust (player, player->mo->angle, cmd->ucmd.forwardmove/8);
|
||||
|
||||
if (cmd->ucmd.sidemove)
|
||||
P_Thrust (player, player->mo->angle-ANG90, cmd->ucmd.sidemove/8);
|
||||
movefactor = P_GetMoveFactor (player->mo);
|
||||
if (!onground) {
|
||||
if (!olddemo) {
|
||||
// [RH] allow very limited movement if not on ground.
|
||||
movefactor >>= 8;
|
||||
} else {
|
||||
movefactor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
forwardmove = (cmd->ucmd.forwardmove * movefactor) >> 8;
|
||||
sidemove = (cmd->ucmd.sidemove * movefactor) >> 8;
|
||||
|
||||
if (forwardmove)
|
||||
P_Thrust (player, player->mo->angle, forwardmove);
|
||||
|
||||
if (sidemove)
|
||||
P_Thrust (player, player->mo->angle-ANG90, sidemove);
|
||||
|
||||
if ( (cmd->ucmd.forwardmove || cmd->ucmd.sidemove)
|
||||
&& player->mo->state == &states[S_PLAY] )
|
||||
{
|
||||
|
@ -170,6 +186,60 @@ void P_MovePlayer (player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
// [RH] (Adapted from Q2)
|
||||
// P_FallingDamage
|
||||
//
|
||||
void P_FallingDamage (mobj_t *ent)
|
||||
{
|
||||
mobj_t *groundentity;
|
||||
float delta;
|
||||
int damage;
|
||||
|
||||
if (!ent->player)
|
||||
return; // not a player
|
||||
|
||||
if (ent->flags & MF_NOCLIP)
|
||||
return;
|
||||
|
||||
groundentity = P_FindFloor (ent);
|
||||
|
||||
if ((ent->player->oldvelocity[2] < 0) && (ent->momz > ent->player->oldvelocity[2]) && (!groundentity))
|
||||
{
|
||||
delta = (float)ent->player->oldvelocity[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!groundentity)
|
||||
return;
|
||||
delta = (float)(ent->momz - ent->player->oldvelocity[2]);
|
||||
}
|
||||
delta = delta*delta * 2.03904313e-11f;
|
||||
|
||||
if (delta < 1)
|
||||
return;
|
||||
|
||||
if (delta < 15)
|
||||
{
|
||||
//ent->s.event = EV_FOOTSTEP;
|
||||
return;
|
||||
}
|
||||
|
||||
if (delta > 30)
|
||||
{
|
||||
damage = (int)((delta-30)/2);
|
||||
if (damage < 1)
|
||||
damage = 1;
|
||||
|
||||
if (dmflags & DF_YES_FALLING)
|
||||
P_DamageMobj (ent, NULL, NULL, damage, MOD_FALLING);
|
||||
}
|
||||
else
|
||||
{
|
||||
//ent->s.event = EV_FALLSHORT;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
@ -237,11 +307,13 @@ void P_DeathThink (player_t* player)
|
|||
//
|
||||
// P_PlayerThink
|
||||
//
|
||||
void P_PlayerThink (player_t* player)
|
||||
void P_PlayerThink (player_t *player)
|
||||
{
|
||||
ticcmd_t* cmd;
|
||||
weapontype_t newweapon;
|
||||
|
||||
ticcmd_t *cmd;
|
||||
weapontype_t newweapon;
|
||||
|
||||
player->xviewshift = 0; // [RH] Make sure view is in right place
|
||||
|
||||
// fixme: do this in the cheat code
|
||||
if (player->cheats & CF_NOCLIP)
|
||||
player->mo->flags |= MF_NOCLIP;
|
||||
|
@ -299,7 +371,7 @@ void P_PlayerThink (player_t* player)
|
|||
|
||||
P_CalcHeight (player);
|
||||
|
||||
if (player->mo->subsector->sector->special)
|
||||
if (player->mo->subsector->sector->special || player->mo->subsector->sector->damage)
|
||||
P_PlayerInSpecialSector (player);
|
||||
|
||||
// Check for weapon change.
|
||||
|
@ -307,45 +379,64 @@ void P_PlayerThink (player_t* player)
|
|||
// A special event has no other buttons.
|
||||
if (cmd->ucmd.buttons & BT_SPECIAL)
|
||||
cmd->ucmd.buttons = 0;
|
||||
|
||||
if (cmd->ucmd.buttons & BT_CHANGE)
|
||||
|
||||
if ((cmd->ucmd.buttons & BT_CHANGE) || cmd->ucmd.impulse >= 50)
|
||||
{
|
||||
// The actual changing of the weapon is done
|
||||
// when the weapon psprite can do it
|
||||
// (read: not in the middle of an attack).
|
||||
newweapon = (cmd->ucmd.buttons&BT_WEAPONMASK)>>BT_WEAPONSHIFT;
|
||||
|
||||
if (newweapon == wp_fist
|
||||
&& player->weaponowned[wp_chainsaw]
|
||||
&& !(player->readyweapon == wp_chainsaw
|
||||
&& player->powers[pw_strength]))
|
||||
{
|
||||
newweapon = wp_chainsaw;
|
||||
}
|
||||
|
||||
if ( (gamemode == commercial)
|
||||
&& newweapon == wp_shotgun
|
||||
&& player->weaponowned[wp_supershotgun]
|
||||
&& player->readyweapon != wp_supershotgun)
|
||||
{
|
||||
newweapon = wp_supershotgun;
|
||||
}
|
||||
|
||||
|
||||
if (player->weaponowned[newweapon]
|
||||
&& newweapon != player->readyweapon)
|
||||
{
|
||||
// Do not go to plasma or BFG in shareware,
|
||||
// even if cheated.
|
||||
if ((newweapon != wp_plasma
|
||||
&& newweapon != wp_bfg)
|
||||
|| (gamemode != shareware) )
|
||||
// [RH] Support direct weapon changes
|
||||
if (cmd->ucmd.impulse) {
|
||||
newweapon = cmd->ucmd.impulse - 50;
|
||||
} else {
|
||||
// The actual changing of the weapon is done
|
||||
// when the weapon psprite can do it
|
||||
// (read: not in the middle of an attack).
|
||||
newweapon = (cmd->ucmd.buttons&BT_WEAPONMASK)>>BT_WEAPONSHIFT;
|
||||
|
||||
if (newweapon == wp_fist
|
||||
&& player->weaponowned[wp_chainsaw]
|
||||
&& !(player->readyweapon == wp_chainsaw
|
||||
&& player->powers[pw_strength]))
|
||||
{
|
||||
player->pendingweapon = newweapon;
|
||||
newweapon = wp_chainsaw;
|
||||
}
|
||||
|
||||
if ( (gamemode == commercial)
|
||||
&& newweapon == wp_shotgun
|
||||
&& player->weaponowned[wp_supershotgun]
|
||||
&& player->readyweapon != wp_supershotgun)
|
||||
{
|
||||
newweapon = wp_supershotgun;
|
||||
}
|
||||
}
|
||||
|
||||
if (newweapon >= 0 && newweapon < NUMWEAPONS) {
|
||||
if (player->weaponowned[newweapon]
|
||||
&& newweapon != player->readyweapon)
|
||||
{
|
||||
// Do not go to plasma or BFG in shareware,
|
||||
// even if cheated.
|
||||
if ((newweapon != wp_plasma
|
||||
&& newweapon != wp_bfg)
|
||||
|| (gamemode != shareware) )
|
||||
{
|
||||
player->pendingweapon = newweapon;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] check for jump
|
||||
if ((cmd->ucmd.buttons & BT_JUMP) == BT_JUMP) {
|
||||
if (!player->jumpdown && !(dmflags & DF_NO_JUMP)) {
|
||||
// only jump if we are on the ground
|
||||
if (P_FindFloor (player->mo)) {
|
||||
player->mo->momz += 8 * FRACUNIT;
|
||||
player->mo->flags2 |= MF2_JUMPING;
|
||||
S_StartSound (player->mo, "*jump1", 100);
|
||||
}
|
||||
player->jumpdown = true;
|
||||
}
|
||||
} else player->jumpdown = false;
|
||||
|
||||
// check for use
|
||||
if (cmd->ucmd.buttons & BT_USE)
|
||||
{
|
||||
|
@ -358,16 +449,6 @@ void P_PlayerThink (player_t* player)
|
|||
else
|
||||
player->usedown = false;
|
||||
|
||||
// [RH] check for jump
|
||||
if ((cmd->ucmd.buttons & BT_JUMP) == BT_JUMP) {
|
||||
if (!player->jumpdown && !(dmflags & DF_NO_JUMP)) {
|
||||
// only jump if we are on the ground
|
||||
if (P_FindFloor (player->mo))
|
||||
player->mo->momz += 8 * FRACUNIT;
|
||||
player->jumpdown = true;
|
||||
}
|
||||
} else player->jumpdown = false;
|
||||
|
||||
// cycle psprites
|
||||
P_MovePsprites (player);
|
||||
|
||||
|
@ -421,4 +502,3 @@ void P_PlayerThink (player_t* player)
|
|||
player->fixedcolormap = 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
613
code/P_xlat.c
Normal file
613
code/P_xlat.c
Normal file
|
@ -0,0 +1,613 @@
|
|||
// p_xlat.c: Translate old linedefs to new linedefs
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "p_lnspec.h"
|
||||
#include "doomdata.h"
|
||||
#include "r_data.h"
|
||||
#include "m_swap.h"
|
||||
#include "p_spec.h"
|
||||
#include "p_local.h"
|
||||
|
||||
// Speeds for ceilings/crushers (x/8 units per tic)
|
||||
// (Hexen crushers go up at half the speed that they go down)
|
||||
#define C_SLOW 8
|
||||
#define C_NORMAL 16
|
||||
#define C_FAST 32
|
||||
#define C_TURBO 64
|
||||
|
||||
#define CEILWAIT 150
|
||||
|
||||
// Speeds for floors (x/8 units per tic)
|
||||
#define F_SLOW 8
|
||||
#define F_NORMAL 16
|
||||
#define F_FAST 32
|
||||
#define F_TURBO 64
|
||||
|
||||
// Speeds for doors (x/8 units per tic)
|
||||
#define D_SLOW 16
|
||||
#define D_NORMAL 32
|
||||
#define D_FAST 64
|
||||
#define D_TURBO 128
|
||||
|
||||
#define VDOORWAIT 150
|
||||
|
||||
// Speeds for stairs (x/8 units per tic)
|
||||
#define S_SLOW 2
|
||||
#define S_NORMAL 4
|
||||
#define S_FAST 16
|
||||
#define S_TURBO 32
|
||||
|
||||
// Speeds for plats (Hexen plats stop 8 units above the floor)
|
||||
#define P_SLOW 8
|
||||
#define P_NORMAL 16
|
||||
#define P_FAST 32
|
||||
#define P_TURBO 64
|
||||
|
||||
#define PLATWAIT 105
|
||||
|
||||
#define ELEVATORSPEED 32
|
||||
|
||||
// Speeds for donut slime and pillar (x/8 units per tic)
|
||||
#define DORATE 4
|
||||
|
||||
// Texture scrollers operate at a rate of x/64 units per tic.
|
||||
#define SCROLL_UNIT 64
|
||||
|
||||
|
||||
//Define masks, shifts, for fields in generalized linedef types
|
||||
// (from BOOM's p_psec.h file)
|
||||
|
||||
#define GenFloorBase 0x6000
|
||||
#define GenCeilingBase 0x4000
|
||||
#define GenDoorBase 0x3c00
|
||||
#define GenLockedBase 0x3800
|
||||
#define GenLiftBase 0x3400
|
||||
#define GenStairsBase 0x3000
|
||||
#define GenCrusherBase 0x2F80
|
||||
|
||||
// define names for the TriggerType field of the general linedefs
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WalkOnce,
|
||||
WalkMany,
|
||||
SwitchOnce,
|
||||
SwitchMany,
|
||||
GunOnce,
|
||||
GunMany,
|
||||
PushOnce,
|
||||
PushMany,
|
||||
} triggertype_e;
|
||||
|
||||
|
||||
// Line special translation structure
|
||||
typedef struct {
|
||||
byte flags;
|
||||
byte newspecial;
|
||||
byte args[5];
|
||||
} xlat_t;
|
||||
|
||||
#define TAG 123 // Special value that gets replaced with the line tag
|
||||
|
||||
#define WALK (ML_ACTIVATECROSS>>8)
|
||||
#define USE (ML_ACTIVATEUSE>>8)
|
||||
#define SHOOT (ML_ACTIVATEPROJECTILEHIT>>8)
|
||||
#define MONST (ML_MONSTERSCANACTIVATE>>8)
|
||||
#define MONWALK (ML_ACTIVATEMONSTERCROSS>>8)
|
||||
#define REP (ML_REPEATABLE>>8)
|
||||
|
||||
static const xlat_t SpecialTranslation[] = {
|
||||
/* 0 */ { 0 },
|
||||
/* 1 */ { USE|MONST|REP, Door_Raise, { 0, D_SLOW, VDOORWAIT } },
|
||||
/* 2 */ { WALK, Door_Open, { TAG, D_SLOW } },
|
||||
/* 3 */ { WALK, Door_Close, { TAG, D_SLOW } },
|
||||
/* 4 */ { WALK|MONST, Door_Raise, { TAG, D_SLOW, VDOORWAIT } },
|
||||
/* 5 */ { WALK, Floor_RaiseToLowestCeiling, { TAG, F_SLOW } },
|
||||
/* 6 */ { WALK, Ceiling_CrushAndRaiseA, { TAG, C_NORMAL, C_NORMAL, 10 } },
|
||||
/* 7 */ { USE, Stairs_BuildUpDoom, { TAG, S_SLOW, 8 } },
|
||||
/* 8 */ { WALK, Stairs_BuildUpDoom, { TAG, S_SLOW, 8 } },
|
||||
/* 9 */ { USE, Floor_Donut, { TAG, DORATE, DORATE } },
|
||||
/* 10 */ { WALK|MONST, Plat_DownWaitUpStayLip, { TAG, P_FAST, PLATWAIT, 0 } },
|
||||
/* 11 */ { USE, Exit_Normal, { 0 } },
|
||||
/* 12 */ { WALK, Light_MaxNeighbor, { TAG } },
|
||||
/* 13 */ { WALK, Light_ChangeToValue, { TAG, 255 } },
|
||||
/* 14 */ { USE, Plat_UpByValueStayTx, { TAG, P_SLOW/2, 4 } },
|
||||
/* 15 */ { USE, Plat_UpByValueStayTx, { TAG, P_SLOW/2, 3 } },
|
||||
/* 16 */ { WALK, Door_CloseWaitOpen, { TAG, D_SLOW, 240 } },
|
||||
/* 17 */ { WALK, Light_StrobeDoom, { TAG, 5, 35 } },
|
||||
/* 18 */ { USE, Floor_RaiseToNearest, { TAG, F_SLOW } },
|
||||
/* 19 */ { WALK, Floor_LowerToHighest, { TAG, F_SLOW, 128 } },
|
||||
/* 20 */ { USE, Plat_RaiseAndStayTx0, { TAG, P_SLOW/2 } },
|
||||
/* 21 */ { USE, Plat_DownWaitUpStayLip, { TAG, P_FAST, PLATWAIT } },
|
||||
/* 22 */ { WALK, Plat_RaiseAndStayTx0, { TAG, P_SLOW/2 } },
|
||||
/* 23 */ { USE, Floor_LowerToLowest, { TAG, F_SLOW } },
|
||||
/* 24 */ { SHOOT, Floor_RaiseToLowestCeiling, { TAG, F_SLOW } },
|
||||
/* 25 */ { WALK, Ceiling_CrushAndRaiseA, { TAG, C_SLOW, C_SLOW, 10 } },
|
||||
/* 26 */ { USE|REP, Door_LockedRaise, { TAG, D_SLOW, VDOORWAIT, BCard | CardIsSkull } },
|
||||
/* 27 */ { USE|REP, Door_LockedRaise, { TAG, D_SLOW, VDOORWAIT, YCard | CardIsSkull } },
|
||||
/* 28 */ { USE|REP, Door_LockedRaise, { TAG, D_SLOW, VDOORWAIT, RCard | CardIsSkull } },
|
||||
/* 29 */ { USE, Door_Raise, { TAG, D_SLOW, VDOORWAIT } },
|
||||
/* 30 */ { WALK, Floor_RaiseByTexture, { TAG, F_SLOW } },
|
||||
/* 31 */ { USE, Door_Open, { 0, D_SLOW } },
|
||||
/* 32 */ { USE|MONST, Door_LockedRaise, { 0, D_SLOW, 0, BCard | CardIsSkull } },
|
||||
/* 33 */ { USE|MONST, Door_LockedRaise, { 0, D_SLOW, 0, RCard | CardIsSkull } },
|
||||
/* 34 */ { USE|MONST, Door_LockedRaise, { 0, D_SLOW, 0, YCard | CardIsSkull } },
|
||||
/* 35 */ { WALK, Light_ChangeToValue, { TAG, 35 } },
|
||||
/* 36 */ { WALK, Floor_LowerToHighest, { TAG, F_FAST, 136 } },
|
||||
/* 37 */ { WALK, Floor_LowerToLowestTxTy, { TAG, F_SLOW } },
|
||||
/* 38 */ { WALK, Floor_LowerToLowest, { TAG, F_SLOW } },
|
||||
/* 39 */ { WALK|MONST, Teleport, { TAG } },
|
||||
/* 40 */ { WALK, Generic_Ceiling, { TAG, C_SLOW, 0, 1, 8 } },
|
||||
/* 41 */ { USE, Ceiling_LowerToFloor, { TAG, C_SLOW } },
|
||||
/* 42 */ { USE|REP, Door_Close, { TAG, D_SLOW } },
|
||||
/* 43 */ { USE|REP, Ceiling_LowerToFloor, { TAG, C_SLOW } },
|
||||
/* 44 */ { WALK, Ceiling_LowerAndCrush, { TAG, C_SLOW, 0 } },
|
||||
/* 45 */ { USE|REP, Floor_LowerToHighest, { TAG, F_SLOW, 128 } },
|
||||
/* 46 */ { SHOOT|REP|MONST,Door_Open, { TAG, D_SLOW } },
|
||||
/* 47 */ { SHOOT, Plat_RaiseAndStayTx0, { TAG, P_SLOW/2 } },
|
||||
/* 48 */ { 0, Scroll_Texture_Left, { SCROLL_UNIT } },
|
||||
/* 49 */ { USE, Ceiling_CrushAndRaiseA, { TAG, C_SLOW, C_SLOW, 10 } },
|
||||
/* 50 */ { USE, Door_Close, { TAG, D_SLOW } },
|
||||
/* 51 */ { USE, Exit_Secret, { 0 } },
|
||||
/* 52 */ { WALK, Exit_Normal, { 0 } },
|
||||
/* 53 */ { WALK, Plat_PerpetualRaiseLip, { TAG, P_SLOW, PLATWAIT, 0 } },
|
||||
/* 54 */ { WALK, Plat_Stop, { TAG } },
|
||||
/* 55 */ { USE, Floor_RaiseAndCrush, { TAG, F_SLOW, 10 } },
|
||||
/* 56 */ { WALK, Floor_RaiseAndCrush, { TAG, F_SLOW, 10 } },
|
||||
/* 57 */ { WALK, Ceiling_CrushStop, { TAG } },
|
||||
/* 58 */ { WALK, Floor_RaiseByValue, { TAG, F_SLOW, 24 } },
|
||||
/* 59 */ { WALK, Floor_RaiseByValueTxTy, { TAG, F_SLOW, 24 } },
|
||||
/* 60 */ { USE|REP, Floor_LowerToLowest, { TAG, F_SLOW } },
|
||||
/* 61 */ { USE|REP, Door_Open, { TAG, D_SLOW } },
|
||||
/* 62 */ { USE|REP, Plat_DownWaitUpStayLip, { TAG, P_FAST, PLATWAIT, 0 } },
|
||||
/* 63 */ { USE|REP, Door_Raise, { TAG, D_SLOW, VDOORWAIT } },
|
||||
/* 64 */ { USE|REP, Floor_RaiseToLowestCeiling, { TAG, F_SLOW } },
|
||||
/* 65 */ { USE|REP, Floor_RaiseAndCrush, { TAG, F_SLOW, 10 } },
|
||||
/* 66 */ { USE|REP, Plat_UpByValueStayTx, { TAG, P_SLOW/2, 3 } },
|
||||
/* 67 */ { USE|REP, Plat_UpByValueStayTx, { TAG, P_SLOW/2, 4 } },
|
||||
/* 68 */ { USE|REP, Plat_RaiseAndStayTx0, { TAG, P_SLOW/2 } },
|
||||
/* 69 */ { USE|REP, Floor_RaiseToNearest, { TAG, F_SLOW } },
|
||||
/* 70 */ { USE|REP, Floor_LowerToHighest, { TAG, F_FAST, 136 } },
|
||||
/* 71 */ { USE, Floor_LowerToHighest, { TAG, F_FAST, 136 } },
|
||||
/* 72 */ { WALK|REP, Ceiling_LowerAndCrush, { TAG, C_SLOW, 0 } },
|
||||
/* 73 */ { WALK|REP, Ceiling_CrushAndRaiseA, { TAG, C_SLOW, C_SLOW, 10 } },
|
||||
/* 74 */ { WALK|REP, Ceiling_CrushStop, { TAG } },
|
||||
/* 75 */ { WALK|REP, Door_Close, { TAG, D_SLOW } },
|
||||
/* 76 */ { WALK|REP, Door_CloseWaitOpen, { TAG, D_SLOW, 240 } },
|
||||
/* 77 */ { WALK|REP, Ceiling_CrushAndRaiseA, { TAG, C_NORMAL, C_NORMAL, 10 } },
|
||||
/* 78 */ { USE|REP, Floor_TransferNumeric, { TAG } }, // <- BOOM special
|
||||
/* 79 */ { WALK|REP, Light_ChangeToValue, { TAG, 35 } },
|
||||
/* 80 */ { WALK|REP, Light_MaxNeighbor, { TAG } },
|
||||
/* 81 */ { WALK|REP, Light_ChangeToValue, { TAG, 255 } },
|
||||
/* 82 */ { WALK|REP, Floor_LowerToLowest, { TAG, F_SLOW } },
|
||||
/* 83 */ { WALK|REP, Floor_LowerToHighest, { TAG, F_SLOW, 128 } },
|
||||
/* 84 */ { WALK|REP, Floor_LowerToLowestTxTy, { TAG, F_SLOW } },
|
||||
/* 85 */ { 0, Scroll_Texture_Right, { SCROLL_UNIT } }, // <- BOOM special
|
||||
/* 86 */ { WALK|REP, Door_Open, { TAG, D_SLOW } },
|
||||
/* 87 */ { WALK|REP, Plat_PerpetualRaiseLip, { TAG, P_SLOW, PLATWAIT, 0 } },
|
||||
/* 88 */ { WALK|REP|MONST, Plat_DownWaitUpStayLip, { TAG, P_FAST, PLATWAIT, 0 } },
|
||||
/* 89 */ { WALK|REP, Plat_Stop, { TAG } },
|
||||
/* 90 */ { WALK|REP, Door_Raise, { TAG, D_SLOW, VDOORWAIT } },
|
||||
/* 91 */ { WALK|REP, Floor_RaiseToLowestCeiling, { TAG, F_SLOW } },
|
||||
/* 92 */ { WALK|REP, Floor_RaiseByValue, { TAG, F_SLOW, 24 } },
|
||||
/* 93 */ { WALK|REP, Floor_RaiseByValueTxTy, { TAG, F_SLOW, 24 } },
|
||||
/* 94 */ { WALK|REP, Floor_RaiseAndCrush, { TAG, F_SLOW, 10 } },
|
||||
/* 95 */ { WALK|REP, Plat_RaiseAndStayTx0, { TAG, P_SLOW/2 } },
|
||||
/* 96 */ { WALK|REP, Floor_RaiseByTexture, { TAG, F_SLOW } },
|
||||
/* 97 */ { WALK|REP|MONST, Teleport, { TAG } },
|
||||
/* 98 */ { WALK|REP, Floor_LowerToHighest, { TAG, F_FAST, 136 } },
|
||||
/* 99 */ { USE|REP, Door_LockedRaise, { TAG, D_FAST, 0, BCard | CardIsSkull } },
|
||||
/* 100 */ { WALK, Stairs_BuildUpDoom, { TAG, S_TURBO, 16, 0, 0 } },
|
||||
/* 101 */ { USE, Floor_RaiseToLowestCeiling, { TAG, F_SLOW } },
|
||||
/* 102 */ { USE, Floor_LowerToHighest, { TAG, F_SLOW, 128 } },
|
||||
/* 103 */ { USE, Door_Open, { TAG, D_SLOW } },
|
||||
/* 104 */ { WALK, Light_MinNeighbor, { TAG } },
|
||||
/* 105 */ { WALK|REP, Door_Raise, { TAG, D_FAST, VDOORWAIT } },
|
||||
/* 106 */ { WALK|REP, Door_Open, { TAG, D_FAST } },
|
||||
/* 107 */ { WALK|REP, Door_Close, { TAG, D_FAST } },
|
||||
/* 108 */ { WALK, Door_Raise, { TAG, D_FAST, VDOORWAIT } },
|
||||
/* 109 */ { WALK, Door_Open, { TAG, D_FAST } },
|
||||
/* 110 */ { WALK, Door_Close, { TAG, D_FAST } },
|
||||
/* 111 */ { USE, Door_Raise, { TAG, D_FAST, VDOORWAIT } },
|
||||
/* 112 */ { USE, Door_Open, { TAG, D_FAST } },
|
||||
/* 113 */ { USE, Door_Close, { TAG, D_FAST } },
|
||||
/* 114 */ { USE|REP, Door_Raise, { TAG, D_FAST, VDOORWAIT } },
|
||||
/* 115 */ { USE|REP, Door_Open, { TAG, D_FAST } },
|
||||
/* 116 */ { USE|REP, Door_Close, { TAG, D_FAST } },
|
||||
/* 117 */ { USE|REP, Door_Raise, { 0, D_FAST, VDOORWAIT } },
|
||||
/* 118 */ { USE, Door_Open, { 0, D_FAST } },
|
||||
/* 119 */ { WALK, Floor_RaiseToNearest, { TAG, F_SLOW } },
|
||||
/* 120 */ { WALK|REP, Plat_DownWaitUpStayLip, { TAG, P_TURBO, PLATWAIT, 0 } },
|
||||
/* 121 */ { WALK, Plat_DownWaitUpStayLip, { TAG, P_TURBO, PLATWAIT, 0 } },
|
||||
/* 122 */ { USE, Plat_DownWaitUpStayLip, { TAG, P_TURBO, PLATWAIT, 0 } },
|
||||
/* 123 */ { USE|REP, Plat_DownWaitUpStayLip, { TAG, P_TURBO, PLATWAIT, 0 } },
|
||||
/* 124 */ { WALK, Exit_Secret, { 0 } },
|
||||
/* 125 */ { MONWALK, Teleport, { TAG } },
|
||||
/* 126 */ { MONWALK|REP, Teleport, { TAG } },
|
||||
/* 127 */ { USE, Stairs_BuildUpDoom, { TAG, S_TURBO, 16, 0, 0 } },
|
||||
/* 128 */ { WALK|REP, Floor_RaiseToNearest, { TAG, F_SLOW } },
|
||||
/* 129 */ { WALK|REP, Floor_RaiseToNearest, { TAG, F_FAST } },
|
||||
/* 130 */ { WALK, Floor_RaiseToNearest, { TAG, F_FAST } },
|
||||
/* 131 */ { USE, Floor_RaiseToNearest, { TAG, F_FAST } },
|
||||
/* 132 */ { USE|REP, Floor_RaiseToNearest, { TAG, F_FAST } },
|
||||
/* 133 */ { USE, Door_LockedRaise, { TAG, D_FAST, 0, BCard | CardIsSkull } },
|
||||
/* 134 */ { USE|REP, Door_LockedRaise, { TAG, D_FAST, 0, BCard | CardIsSkull } },
|
||||
/* 135 */ { USE, Door_LockedRaise, { TAG, D_FAST, 0, RCard | CardIsSkull } },
|
||||
/* 136 */ { USE|REP, Door_LockedRaise, { TAG, D_FAST, 0, YCard | CardIsSkull } },
|
||||
/* 137 */ { USE, Door_LockedRaise, { TAG, D_FAST, 0, YCard | CardIsSkull } },
|
||||
/* 138 */ { USE|REP, Light_ChangeToValue, { TAG, 255 } },
|
||||
/* 139 */ { USE|REP, Light_ChangeToValue, { TAG, 35 } },
|
||||
/* 140 */ { USE, Floor_RaiseByValueTimes8, { TAG, F_SLOW, 64 } },
|
||||
/* 141 */ { WALK, Ceiling_CrushAndRaiseSilentA,{ TAG, C_SLOW, C_SLOW, 10 } },
|
||||
|
||||
/****** The following are all new to BOOM ******/
|
||||
|
||||
/* 142 */ { WALK, Floor_RaiseByValueTimes8, { TAG, F_SLOW, 64 } },
|
||||
/* 143 */ { WALK, Plat_UpByValueStayTx, { TAG, P_SLOW/2, 3 } },
|
||||
/* 144 */ { WALK, Plat_UpByValueStayTx, { TAG, P_SLOW/2, 4 } },
|
||||
/* 145 */ { WALK, Ceiling_LowerToFloor, { TAG, C_SLOW } },
|
||||
/* 146 */ { WALK, Floor_Donut, { TAG, DORATE, DORATE } },
|
||||
/* 147 */ { WALK|REP, Floor_RaiseByValueTimes8, { TAG, F_SLOW, 64 } },
|
||||
/* 148 */ { WALK|REP, Plat_UpByValueStayTx, { TAG, P_SLOW/2, 3 } },
|
||||
/* 149 */ { WALK|REP, Plat_UpByValueStayTx, { TAG, P_SLOW/2, 4 } },
|
||||
/* 150 */ { WALK|REP, Ceiling_CrushAndRaiseSilentA,{ TAG, C_SLOW, C_SLOW, 10 } },
|
||||
/* 151 */ { WALK|REP, FloorAndCeiling_LowerRaise, { TAG, F_SLOW, C_SLOW } },
|
||||
/* 152 */ { WALK|REP, Ceiling_LowerToFloor, { TAG, C_SLOW } },
|
||||
/* 153 */ { WALK, Floor_TransferTrigger, { TAG } },
|
||||
/* 154 */ { WALK|REP, Floor_TransferTrigger, { TAG } },
|
||||
/* 155 */ { WALK|REP, Floor_Donut, { TAG, DORATE, DORATE } },
|
||||
/* 156 */ { WALK|REP, Light_StrobeDoom, { TAG, 5, 35 } },
|
||||
/* 157 */ { WALK|REP, Light_MinNeighbor, { TAG } },
|
||||
/* 158 */ { USE, Floor_RaiseByTexture, { TAG, F_SLOW } },
|
||||
/* 159 */ { USE, Floor_LowerToLowestTxTy, { TAG, F_SLOW } },
|
||||
/* 160 */ { USE, Floor_RaiseByValueTxTy, { TAG, F_SLOW, 24 } },
|
||||
/* 161 */ { USE, Floor_RaiseByValue, { TAG, F_SLOW, 24 } },
|
||||
/* 162 */ { USE, Plat_PerpetualRaiseLip, { TAG, P_SLOW, PLATWAIT, 0 } },
|
||||
/* 163 */ { USE, Plat_Stop, { TAG } },
|
||||
/* 164 */ { USE, Ceiling_CrushAndRaiseA, { TAG, C_NORMAL, C_NORMAL, 10 } },
|
||||
/* 165 */ { USE, Ceiling_CrushAndRaiseSilentA,{ TAG, C_SLOW, C_SLOW, 10 } },
|
||||
/* 166 */ { USE, FloorAndCeiling_LowerRaise, { TAG, F_SLOW, C_SLOW } },
|
||||
/* 167 */ { USE, Ceiling_LowerAndCrush, { TAG, C_SLOW, 0 } },
|
||||
/* 168 */ { USE, Ceiling_CrushStop, { TAG } },
|
||||
/* 169 */ { USE, Light_MaxNeighbor, { TAG } },
|
||||
/* 170 */ { USE, Light_ChangeToValue, { TAG, 35 } },
|
||||
/* 171 */ { USE, Light_ChangeToValue, { TAG, 255 } },
|
||||
/* 172 */ { USE, Light_StrobeDoom, { TAG, 5, 35 } },
|
||||
/* 173 */ { USE, Light_MinNeighbor, { TAG } },
|
||||
/* 174 */ { USE|MONST, Teleport, { TAG } },
|
||||
/* 175 */ { USE, Door_CloseWaitOpen, { TAG, F_SLOW, 240 } },
|
||||
/* 176 */ { USE|REP, Floor_RaiseByTexture, { TAG, F_SLOW } },
|
||||
/* 177 */ { USE|REP, Floor_LowerToLowestTxTy, { TAG, F_SLOW } },
|
||||
/* 178 */ { USE|REP, Floor_RaiseByValueTimes8, { TAG, F_SLOW, 64 } },
|
||||
/* 179 */ { USE|REP, Floor_RaiseByValueTxTy, { TAG, F_SLOW, 24 } },
|
||||
/* 180 */ { USE|REP, Floor_RaiseByValue, { TAG, F_SLOW, 24 } },
|
||||
/* 181 */ { USE|REP, Plat_PerpetualRaiseLip, { TAG, P_SLOW, PLATWAIT, 0 } },
|
||||
/* 182 */ { USE|REP, Plat_Stop, { TAG } },
|
||||
/* 183 */ { USE|REP, Ceiling_CrushAndRaiseA, { TAG, C_NORMAL, C_NORMAL, 10 } },
|
||||
/* 184 */ { USE|REP, Ceiling_CrushAndRaiseA, { TAG, C_SLOW, C_SLOW, 10 } },
|
||||
/* 185 */ { USE|REP, Ceiling_CrushAndRaiseSilentA,{ TAG, C_SLOW, C_SLOW, 10 } },
|
||||
/* 186 */ { USE|REP, FloorAndCeiling_LowerRaise, { TAG, F_SLOW, C_SLOW } },
|
||||
/* 187 */ { USE|REP, Ceiling_LowerAndCrush, { TAG, C_SLOW, 0 } },
|
||||
/* 188 */ { USE|REP, Ceiling_CrushStop, { TAG } },
|
||||
/* 189 */ { USE, Floor_TransferTrigger, { TAG } },
|
||||
/* 190 */ { USE|REP, Floor_TransferTrigger, { TAG } },
|
||||
/* 191 */ { USE|REP, Floor_Donut, { TAG, DORATE, DORATE } },
|
||||
/* 192 */ { USE|REP, Light_MaxNeighbor, { TAG } },
|
||||
/* 193 */ { USE|REP, Light_StrobeDoom, { TAG, 5, 35 } },
|
||||
/* 194 */ { USE|REP, Light_MinNeighbor, { TAG } },
|
||||
/* 195 */ { USE|REP|MONST, Teleport, { TAG } },
|
||||
/* 196 */ { USE|REP, Door_CloseWaitOpen, { TAG, D_SLOW, 240 } },
|
||||
/* 197 */ { SHOOT, Exit_Normal, { 0 } },
|
||||
/* 198 */ { SHOOT, Exit_Secret, { 0 } },
|
||||
/* 199 */ { WALK, Ceiling_LowerToLowest, { TAG, C_SLOW } },
|
||||
/* 200 */ { WALK, Ceiling_LowerToHighestFloor, { TAG, C_SLOW } },
|
||||
/* 201 */ { WALK|REP, Ceiling_LowerToLowest, { TAG, C_SLOW } },
|
||||
/* 202 */ { WALK|REP, Ceiling_LowerToHighestFloor, { TAG, C_SLOW } },
|
||||
/* 203 */ { USE, Ceiling_LowerToLowest, { TAG, C_SLOW } },
|
||||
/* 204 */ { USE, Ceiling_LowerToHighestFloor, { TAG, C_SLOW } },
|
||||
/* 205 */ { USE|REP, Ceiling_LowerToLowest, { TAG, C_SLOW } },
|
||||
/* 206 */ { USE|REP, Ceiling_LowerToHighestFloor, { TAG, C_SLOW } },
|
||||
/* 207 */ { WALK|MONST, Teleport_NoFog, { TAG } },
|
||||
/* 208 */ { WALK|REP|MONST, Teleport_NoFog, { TAG } },
|
||||
/* 209 */ { USE|MONST, Teleport_NoFog, { TAG } },
|
||||
/* 210 */ { USE|REP|MONST, Teleport_NoFog, { TAG } },
|
||||
/* 211 */ { USE|REP, Plat_ToggleCeiling, { TAG } },
|
||||
/* 212 */ { WALK|REP, Plat_ToggleCeiling, { TAG } },
|
||||
/* 213 */ { 0, Transfer_FloorLight, { TAG } },
|
||||
/* 214 */ { 0, Scroll_Ceiling, { TAG, 6, 0, 0, 0 } },
|
||||
/* 215 */ { 0, Scroll_Floor, { TAG, 6, 0, 0, 0 } },
|
||||
/* 216 */ { 0, Scroll_Floor, { TAG, 6, 1, 0, 0 } },
|
||||
/* 217 */ { 0, Scroll_Floor, { TAG, 6, 2, 0, 0 } },
|
||||
/* 218 */ { 0, Scroll_Texture_Model, { TAG, 2 } },
|
||||
/* 219 */ { WALK, Floor_LowerToNearest, { TAG, F_SLOW } },
|
||||
/* 220 */ { WALK|REP, Floor_LowerToNearest, { TAG, F_SLOW } },
|
||||
/* 221 */ { USE, Floor_LowerToNearest, { TAG, F_SLOW } },
|
||||
/* 222 */ { USE|REP, Floor_LowerToNearest, { TAG, F_SLOW } },
|
||||
/* 223 */ { 0, Sector_SetFriction, { TAG, 0 } },
|
||||
/* 224 */ { 0, Sector_SetWind, { TAG, 0, 0, 1 } },
|
||||
/* 225 */ { 0, Sector_SetCurrent, { TAG, 0, 0, 1 } },
|
||||
/* 226 */ { 0, PointPush_SetForce, { TAG, 0, 0, 1 } },
|
||||
/* 227 */ { WALK, Elevator_RaiseToNearest, { TAG, ELEVATORSPEED } },
|
||||
/* 228 */ { WALK|REP, Elevator_RaiseToNearest, { TAG, ELEVATORSPEED } },
|
||||
/* 229 */ { USE, Elevator_RaiseToNearest, { TAG, ELEVATORSPEED } },
|
||||
/* 230 */ { USE|REP, Elevator_RaiseToNearest, { TAG, ELEVATORSPEED } },
|
||||
/* 231 */ { WALK, Elevator_LowerToNearest, { TAG, ELEVATORSPEED } },
|
||||
/* 232 */ { WALK|REP, Elevator_LowerToNearest, { TAG, ELEVATORSPEED } },
|
||||
/* 233 */ { USE, Elevator_LowerToNearest, { TAG, ELEVATORSPEED } },
|
||||
/* 234 */ { USE|REP, Elevator_LowerToNearest, { TAG, ELEVATORSPEED } },
|
||||
/* 235 */ { WALK, Elevator_MoveToFloor, { TAG, ELEVATORSPEED } },
|
||||
/* 236 */ { WALK|REP, Elevator_MoveToFloor, { TAG, ELEVATORSPEED } },
|
||||
/* 237 */ { USE, Elevator_MoveToFloor, { TAG, ELEVATORSPEED } },
|
||||
/* 238 */ { USE|REP, Elevator_MoveToFloor, { TAG, ELEVATORSPEED } },
|
||||
/* 239 */ { WALK, Floor_TransferNumeric, { TAG } },
|
||||
/* 240 */ { WALK|REP, Floor_TransferNumeric, { TAG } },
|
||||
/* 241 */ { USE, Floor_TransferNumeric, { TAG } },
|
||||
/* 242 */ { 0, Transfer_Heights, { TAG } },
|
||||
/* 243 */ { WALK|MONST, Teleport_Line, { TAG, TAG, 0 } },
|
||||
/* 244 */ { WALK|REP|MONST, Teleport_Line, { TAG, TAG, 0 } },
|
||||
/* 245 */ { 0, Scroll_Ceiling, { TAG, 5, 0, 0, 0 } },
|
||||
/* 246 */ { 0, Scroll_Floor, { TAG, 5, 0, 0, 0 } },
|
||||
/* 247 */ { 0, Scroll_Floor, { TAG, 5, 1, 0, 0 } },
|
||||
/* 248 */ { 0, Scroll_Floor, { TAG, 5, 2, 0, 0 } },
|
||||
/* 249 */ { 0, Scroll_Texture_Model, { TAG, 1 } },
|
||||
/* 250 */ { 0, Scroll_Ceiling, { TAG, 4, 0, 0, 0 } },
|
||||
/* 251 */ { 0, Scroll_Floor, { TAG, 4, 0, 0, 0 } },
|
||||
/* 252 */ { 0, Scroll_Floor, { TAG, 4, 1, 0, 0 } },
|
||||
/* 253 */ { 0, Scroll_Floor, { TAG, 4, 2, 0, 0 } },
|
||||
/* 254 */ { 0, Scroll_Texture_Model, { TAG, 0 } },
|
||||
/* 255 */ { 0, Scroll_Texture_Offsets },
|
||||
/* 256 */ { WALK|REP, Stairs_BuildUpDoom, { TAG, S_SLOW, 8, 0, 0 } },
|
||||
/* 257 */ { WALK|REP, Stairs_BuildUpDoom, { TAG, S_TURBO, 16, 0, 0 } },
|
||||
/* 258 */ { USE|REP, Stairs_BuildUpDoom, { TAG, S_SLOW, 8, 0, 0 } },
|
||||
/* 259 */ { USE|REP, Stairs_BuildUpDoom, { TAG, S_TURBO, 16, 0, 0 } },
|
||||
/* 260 */ { 0, TranslucentLine, { TAG, 128 } },
|
||||
/* 261 */ { 0, Transfer_CeilingLight, { TAG } },
|
||||
/* 262 */ { WALK|MONST, Teleport_Line, { TAG, TAG, 1 } },
|
||||
/* 263 */ { WALK|REP|MONST, Teleport_Line, { TAG, TAG, 1 } },
|
||||
/* 264 */ { MONWALK, Teleport_Line, { TAG, TAG, 1 } },
|
||||
/* 265 */ { MONWALK|REP, Teleport_Line, { TAG, TAG, 1 } },
|
||||
/* 266 */ { MONWALK, Teleport_Line, { TAG, TAG, 0 } },
|
||||
/* 267 */ { MONWALK|REP, Teleport_Line, { TAG, TAG, 0 } },
|
||||
/* 268 */ { MONWALK, Teleport_NoFog, { TAG } },
|
||||
/* 269 */ { MONWALK|REP, Teleport_NoFog, { TAG } }
|
||||
};
|
||||
#define NUM_SPECIALS 269
|
||||
|
||||
void P_TranslateLineDef (line_t *ld, maplinedef_t *mld)
|
||||
{
|
||||
short special = SHORT(mld->special);
|
||||
short tag = SHORT(mld->tag);
|
||||
short flags = SHORT(mld->flags);
|
||||
int i;
|
||||
|
||||
if (flags & ML_PASSUSEORG) // Remap ML_PASSUSE flag from BOOM.
|
||||
flags = (flags & ~ML_PASSUSEORG) | ML_PASSUSE;
|
||||
|
||||
flags = flags & 0x41ff; // Ignore flags unknown in DOOM.
|
||||
|
||||
if (special <= NUM_SPECIALS) {
|
||||
// This is a regular special; translate thru LUT
|
||||
flags = flags | (SpecialTranslation[special].flags << 8);
|
||||
ld->special = SpecialTranslation[special].newspecial;
|
||||
for (i = 0; i < 5; i++)
|
||||
ld->args[i] = SpecialTranslation[special].args[i] == TAG ? tag :
|
||||
SpecialTranslation[special].args[i];
|
||||
} else if (special <= GenCrusherBase) {
|
||||
// This is an unknown special. Just zero it.
|
||||
ld->special = 0;
|
||||
memset (ld->args, 0, sizeof(ld->args));
|
||||
} else {
|
||||
// Anything else is a BOOM generalized linedef type
|
||||
switch (special & 0x0007) {
|
||||
case WalkMany:
|
||||
flags |= ML_REPEATABLE;
|
||||
case WalkOnce:
|
||||
flags |= ML_ACTIVATECROSS;
|
||||
break;
|
||||
|
||||
case SwitchMany:
|
||||
case PushMany:
|
||||
flags |= ML_REPEATABLE;
|
||||
case SwitchOnce:
|
||||
case PushOnce:
|
||||
flags |= ML_ACTIVATEUSE;
|
||||
break;
|
||||
|
||||
case GunMany:
|
||||
flags |= ML_REPEATABLE;
|
||||
case GunOnce:
|
||||
flags |= ML_ACTIVATEPROJECTILEHIT;
|
||||
break;
|
||||
}
|
||||
|
||||
// We treat push triggers like switch triggers with zero tags.
|
||||
if ((special & 0x0007) == PushMany ||
|
||||
(special & 0x0007) == PushOnce)
|
||||
ld->args[0] = 0;
|
||||
else
|
||||
ld->args[0] = tag;
|
||||
|
||||
if (special <= GenStairsBase) {
|
||||
// Generalized crusher (tag, dnspeed, upspeed, silent, damage)
|
||||
ld->special = Generic_Crusher;
|
||||
if (special & 0x0020)
|
||||
flags |= ML_MONSTERSCANACTIVATE;
|
||||
switch (special & 0x0018) {
|
||||
case 0x0000: ld->args[1] = C_SLOW; break;
|
||||
case 0x0008: ld->args[1] = C_NORMAL; break;
|
||||
case 0x0010: ld->args[1] = C_FAST; break;
|
||||
case 0x0018: ld->args[1] = C_TURBO; break;
|
||||
}
|
||||
ld->args[2] = ld->args[1];
|
||||
ld->args[3] = (special & 0x0040) >> 6;
|
||||
ld->args[4] = 10;
|
||||
} else if (special <= GenLiftBase) {
|
||||
// Generalized stairs (tag, speed, step, dir/igntxt, reset)
|
||||
ld->special = Generic_Stairs;
|
||||
if (special & 0x0020)
|
||||
flags |= ML_MONSTERSCANACTIVATE;
|
||||
switch (special & 0x0018) {
|
||||
case 0x0000: ld->args[1] = S_SLOW; break;
|
||||
case 0x0008: ld->args[1] = S_NORMAL; break;
|
||||
case 0x0010: ld->args[1] = S_FAST; break;
|
||||
case 0x0018: ld->args[1] = S_TURBO; break;
|
||||
}
|
||||
switch (special & 0x00c0) {
|
||||
case 0x0000: ld->args[2] = 4; break;
|
||||
case 0x0040: ld->args[2] = 8; break;
|
||||
case 0x0080: ld->args[2] = 16; break;
|
||||
case 0x00c0: ld->args[2] = 24; break;
|
||||
}
|
||||
ld->args[3] = (special & 0x0300) >> 8;
|
||||
ld->args[4] = 0;
|
||||
} else if (special <= GenLockedBase) {
|
||||
// Generalized lift (tag, speed, delay, target, height)
|
||||
ld->special = Generic_Lift;
|
||||
if (special & 0x0020)
|
||||
flags |= ML_MONSTERSCANACTIVATE;
|
||||
switch (special & 0x0018) {
|
||||
case 0x0000: ld->args[1] = P_SLOW*2; break;
|
||||
case 0x0008: ld->args[1] = P_NORMAL*2; break;
|
||||
case 0x0010: ld->args[1] = P_FAST*2; break;
|
||||
case 0x0018: ld->args[1] = P_TURBO*2; break;
|
||||
}
|
||||
switch (special & 0x00c0) {
|
||||
case 0x0000: ld->args[2] = 8; break;
|
||||
case 0x0040: ld->args[2] = 24; break;
|
||||
case 0x0080: ld->args[2] = 40; break;
|
||||
case 0x00c0: ld->args[2] = 80; break;
|
||||
}
|
||||
ld->args[3] = ((special & 0x0300) >> 8) + 1;
|
||||
ld->args[4] = 0;
|
||||
} else if (special <= GenDoorBase) {
|
||||
// Generalized locked door (tag, speed, kind, delay, lock)
|
||||
ld->special = Generic_Door;
|
||||
if (special & 0x0080)
|
||||
flags |= ML_MONSTERSCANACTIVATE;
|
||||
switch (special & 0x0018) {
|
||||
case 0x0000: ld->args[1] = D_SLOW; break;
|
||||
case 0x0008: ld->args[1] = D_NORMAL; break;
|
||||
case 0x0010: ld->args[1] = D_FAST; break;
|
||||
case 0x0018: ld->args[1] = D_TURBO; break;
|
||||
}
|
||||
ld->args[2] = (special & 0x0020) >> 5;
|
||||
ld->args[3] = 0;
|
||||
ld->args[4] = (special & 0x01c0) >> 6;
|
||||
if (ld->args[4] == 0)
|
||||
ld->args[4] = AnyKey;
|
||||
else if (ld->args[4] == 7)
|
||||
ld->args[4] = AllKeys;
|
||||
ld->args[4] |= (special & 0x0200) >> 2;
|
||||
} else if (special <= GenCeilingBase) {
|
||||
// Generalized door (tag, speed, kind, delay, lock)
|
||||
ld->special = Generic_Door;
|
||||
switch (special & 0x0018) {
|
||||
case 0x0000: ld->args[1] = D_SLOW; break;
|
||||
case 0x0008: ld->args[1] = D_NORMAL; break;
|
||||
case 0x0010: ld->args[1] = D_FAST; break;
|
||||
case 0x0018: ld->args[1] = D_TURBO; break;
|
||||
}
|
||||
ld->args[2] = (special & 0x0060) >> 5;
|
||||
switch (special & 0x0300) {
|
||||
case 0x0000: ld->args[3] = 8; break;
|
||||
case 0x0100: ld->args[3] = 32; break;
|
||||
case 0x0200: ld->args[3] = 72; break;
|
||||
case 0x0300: ld->args[3] = 240; break;
|
||||
}
|
||||
ld->args[4] = 0;
|
||||
} else {
|
||||
// Generalized ceiling (tag, speed, height, target, change/model/direct/crush)
|
||||
// Generalized floor (tag, speed, height, target, change/model/direct/crush)
|
||||
if (special <= GenFloorBase)
|
||||
ld->special = Generic_Ceiling;
|
||||
else
|
||||
ld->special = Generic_Floor;
|
||||
|
||||
switch (special & 0x0018) {
|
||||
case 0x0000: ld->args[1] = F_SLOW; break;
|
||||
case 0x0008: ld->args[1] = F_NORMAL; break;
|
||||
case 0x0010: ld->args[1] = F_FAST; break;
|
||||
case 0x0018: ld->args[1] = F_TURBO; break;
|
||||
}
|
||||
ld->args[3] = ((special & 0x0380) >> 7) + 1;
|
||||
if (ld->args[3] >= 7) {
|
||||
ld->args[2] = 24 + (ld->args[3] - 7) * 8;
|
||||
ld->args[3] = 0;
|
||||
} else {
|
||||
ld->args[2] = 0;
|
||||
}
|
||||
ld->args[4] = ((special & 0x0c00) >> 10) |
|
||||
((special & 0x0060) >> 2) |
|
||||
((special & 0x1000) >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
ld->flags = flags;
|
||||
|
||||
// For purposes of maintaining BOOM compatibility, each
|
||||
// line also needs to have its ID set to the same as its tag.
|
||||
// An external conversion program would need to do this more
|
||||
// intelligently.
|
||||
|
||||
ld->id = tag;
|
||||
}
|
||||
|
||||
// The teleport specials that use things as destinations also require
|
||||
// that their TIDs be set to the tags of their containing sectors. We
|
||||
// do that after the rest of the level has been loaded.
|
||||
|
||||
void P_TranslateTeleportThings (void)
|
||||
{
|
||||
int i, j;
|
||||
thinker_t *thinker;
|
||||
mobj_t *m;
|
||||
|
||||
for (i = 0; i < numlines; i++) {
|
||||
if (lines[i].special == Teleport ||
|
||||
lines[i].special == Teleport_NoFog) {
|
||||
// The sector tag hash table hasn't been set up yet,
|
||||
// so we need to use this linear search.
|
||||
for (j = 0; j < numsectors; j++) {
|
||||
if (sectors[j].tag == lines[i].args[0]) {
|
||||
thinker = thinkercap.next;
|
||||
for (thinker = thinkercap.next;
|
||||
thinker != &thinkercap;
|
||||
thinker = thinker->next)
|
||||
{
|
||||
// not a mobj
|
||||
if (thinker->function.acp1 != (actionf_p1)P_MobjThinker)
|
||||
continue;
|
||||
|
||||
m = (mobj_t *)thinker;
|
||||
|
||||
// not a teleportman
|
||||
if (m->type != MT_TELEPORTMAN && m->type != MT_TELEPORTMAN2)
|
||||
continue;
|
||||
|
||||
// wrong sector
|
||||
if (m->subsector->sector - sectors != j)
|
||||
continue;
|
||||
|
||||
// It's a teleportman, so set it's tid to match
|
||||
// the sector's tag.
|
||||
m->tid = lines[i].args[0];
|
||||
P_AddMobjToHash (m);
|
||||
|
||||
// We only bother with the first teleportman
|
||||
break;
|
||||
}
|
||||
if (thinker != &thinkercap)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int P_TranslateSectorSpecial (int special)
|
||||
{
|
||||
// This supports phased lighting with specials 21-24
|
||||
return (special == 9) ? SECRET_MASK :
|
||||
((special & 0xfe0) << 3) |
|
||||
((special & 0x01f) + (((special & 0x1f) < 21) ? 64 : -20));
|
||||
}
|
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
/* Hacked for DOOM Win32 port by Petteri Kangaslampi <pekangas@sci.fi> */
|
||||
// [RH] And then further to not use any intermediate files
|
||||
|
||||
//#define MSDOG
|
||||
|
||||
|
@ -63,14 +64,14 @@ char tmp[MAXPATH] ;
|
|||
|
||||
size_t fwrite2(const int2 *ptr, size_t size, FILE *file)
|
||||
{
|
||||
int4 rev = 0, work;
|
||||
int4 rev = 0;
|
||||
int i;
|
||||
|
||||
for( i = 0 ; (size_t)i < size ; i++ ) {
|
||||
// VC++ didn't like this magic (but only for the release build!)
|
||||
// rev = (rev << 8) + (((*ptr) >> (i*8)) & 0xFF) ;
|
||||
int4 work = (*ptr) >> (i << 3);
|
||||
rev <<= 8;
|
||||
work = (*ptr) >> (i << 3);
|
||||
rev |= (work & 0xFF);
|
||||
}
|
||||
|
||||
|
@ -629,54 +630,3 @@ int convert( const char *mus, const char *mid, int nodisplay, int div,
|
|||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
int CheckParm( char *check, int argc, char *argv[] )
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = 1 ; i<argc ; i++ )
|
||||
#ifdef MSDOG
|
||||
if( !stricmp( check, argv[i] ) )
|
||||
#else
|
||||
if( !strcmp( check, argv[i] ) )
|
||||
#endif
|
||||
return i ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void PrintHeader( void )
|
||||
{
|
||||
/* Print( "===============================================================================\n"
|
||||
" Quick MUS->MID v2.0 ! (C) 1995,96 Sebastien Bacquet\n"
|
||||
" E-mail : bacquet@iie.cnam.fr\n"
|
||||
"===============================================================================\n" ) ;*/
|
||||
}
|
||||
|
||||
|
||||
void PrintSyntax( void )
|
||||
{
|
||||
PrintHeader() ;
|
||||
Printf(
|
||||
#ifdef MSDOG
|
||||
"\nSyntax : QMUS2MID musfile1[.mus] {musfile2[.mus] ... | "
|
||||
"midifile.mid} [options]\n"
|
||||
" Wildcards are accepted.\n"
|
||||
" Options are :\n"
|
||||
" -query : Query before processing\n"
|
||||
" -ow : OK, overwrite (without query)\n"
|
||||
#else
|
||||
"\nSyntax : QMUS2MID musfile midifile [options]\n"
|
||||
" Options are :\n"
|
||||
#endif
|
||||
" -noow : Don't overwrite !\n"
|
||||
" -nodisp : Display nothing ! (except errors)\n"
|
||||
" -nocomp : Don't compress !\n"
|
||||
" -size ### : Set the track buffer size to ### (in KB). "
|
||||
"Default = 64 KB\n"
|
||||
" -t ### : Ticks per quarter note. Default = 89\n"
|
||||
) ;
|
||||
}
|
||||
|
||||
|
||||
|
|
21
code/R_bsp.c
21
code/R_bsp.c
|
@ -38,6 +38,7 @@
|
|||
// State.
|
||||
#include "doomstat.h"
|
||||
#include "r_state.h"
|
||||
#include "v_palett.h"
|
||||
|
||||
//#include "r_local.h"
|
||||
|
||||
|
@ -302,7 +303,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec,
|
|||
if (sec->heightsec != -1)
|
||||
{
|
||||
const sector_t *s = §ors[sec->heightsec];
|
||||
int heightsec = viewplayer->mo->subsector->sector->heightsec;
|
||||
int heightsec = camera->subsector->sector->heightsec;
|
||||
int underwater = heightsec!=-1 && viewz<=sectors[heightsec].floorheight;
|
||||
|
||||
// Replace sector being drawn, with a copy to be hacked
|
||||
|
@ -320,7 +321,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec,
|
|||
tempsec->floor_xoffs = s->floor_xoffs;
|
||||
tempsec->floor_yoffs = s->floor_yoffs;
|
||||
|
||||
if (underwater)
|
||||
if (underwater) {
|
||||
if (s->ceilingpic == skyflatnum)
|
||||
{
|
||||
tempsec->floorheight = tempsec->ceilingheight+1;
|
||||
|
@ -334,6 +335,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec,
|
|||
tempsec->ceiling_xoffs = s->ceiling_xoffs;
|
||||
tempsec->ceiling_yoffs = s->ceiling_yoffs;
|
||||
}
|
||||
}
|
||||
|
||||
tempsec->lightlevel = s->lightlevel;
|
||||
|
||||
|
@ -480,9 +482,9 @@ void R_AddLine (seg_t* line)
|
|||
// Identical floor and ceiling on both sides,
|
||||
// identical light levels on both sides,
|
||||
// and no middle texture.
|
||||
if (backsector->ceilingpic == frontsector->ceilingpic
|
||||
if (backsector->lightlevel == frontsector->lightlevel
|
||||
&& backsector->floorpic == frontsector->floorpic
|
||||
&& backsector->lightlevel == frontsector->lightlevel
|
||||
&& backsector->ceilingpic == frontsector->ceilingpic
|
||||
&& curline->sidedef->midtexture == 0
|
||||
|
||||
// killough 3/7/98: Take flats offsets into account:
|
||||
|
@ -494,6 +496,9 @@ void R_AddLine (seg_t* line)
|
|||
// killough 4/16/98: consider altered lighting
|
||||
&& backsector->floorlightsec == frontsector->floorlightsec
|
||||
&& backsector->ceilinglightsec == frontsector->ceilinglightsec
|
||||
|
||||
// [RH] Also consider colormaps
|
||||
&& backsector->colormap == frontsector->colormap
|
||||
)
|
||||
{
|
||||
return;
|
||||
|
@ -655,7 +660,7 @@ void R_Subsector (int num)
|
|||
sector_t tempsec; // killough 3/7/98: deep water hack
|
||||
int floorlightlevel; // killough 3/16/98: set floor lightlevel
|
||||
int ceilinglightlevel; // killough 4/11/98
|
||||
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (num>=numsubsectors)
|
||||
I_Error ("R_Subsector: ss %i with numss = %i", num, numsubsectors);
|
||||
|
@ -666,6 +671,8 @@ void R_Subsector (int num)
|
|||
count = sub->numlines;
|
||||
line = &segs[sub->firstline];
|
||||
|
||||
basecolormap = frontsector->colormap->maps; // [RH] set basecolormap
|
||||
|
||||
// killough 3/8/98, 4/4/98: Deep water / fake ceiling effect
|
||||
frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel,
|
||||
&ceilinglightlevel, false); // killough 4/11/98
|
||||
|
@ -694,7 +701,9 @@ void R_Subsector (int num)
|
|||
frontsector->ceiling_yoffs
|
||||
) : NULL;
|
||||
|
||||
R_AddSprites (frontsector);
|
||||
// [RH] Fix BOOM bug where things in deep water sectors with
|
||||
// several subsectors caused massive slowdown.
|
||||
R_AddSprites (sub->sector);
|
||||
|
||||
while (count--)
|
||||
{
|
||||
|
|
149
code/R_data.c
149
code/R_data.c
|
@ -154,13 +154,6 @@ static byte** texturecomposite;
|
|||
int* flattranslation;
|
||||
int* texturetranslation;
|
||||
|
||||
// needed for pre rendering
|
||||
fixed_t* spritewidth;
|
||||
fixed_t* spriteoffset;
|
||||
fixed_t* spritetopoffset;
|
||||
|
||||
//lighttable_t *colormaps;
|
||||
|
||||
|
||||
//
|
||||
// MAPTEXTURE_T CACHING
|
||||
|
@ -502,21 +495,8 @@ void R_InitTextures (void)
|
|||
#undef ALLOC
|
||||
|
||||
totalwidth = 0;
|
||||
|
||||
// Really complex printing shit...
|
||||
{
|
||||
int temp3 = (((W_GetNumForName ("S_END") - 1) -
|
||||
W_GetNumForName ("S_START") + 127) >> 7) +
|
||||
((numtextures+127) >> 8);
|
||||
|
||||
Printf("[");
|
||||
for (i = temp3; i > 0; i--)
|
||||
Printf(" ");
|
||||
Printf(" ]");
|
||||
for (i = temp3; i > 0; i--)
|
||||
Printf("\x8");
|
||||
Printf("\x8\x8\x8\x8\x8\x8\x8\x8\x8\x8");
|
||||
}
|
||||
// [RH] Removed the complex printing shit
|
||||
|
||||
for (i = 0; i < numtextures; i++, directory++)
|
||||
{
|
||||
|
@ -534,7 +514,7 @@ void R_InitTextures (void)
|
|||
offset = LONG(*directory);
|
||||
|
||||
if (offset > maxoff)
|
||||
I_Error ("R_InitTextures: bad texture directory");
|
||||
I_FatalError ("R_InitTextures: bad texture directory");
|
||||
|
||||
mtexture = (maptexture_t *) ( (byte *)maptex + offset);
|
||||
|
||||
|
@ -589,7 +569,7 @@ void R_InitTextures (void)
|
|||
Z_Free (maptex2);
|
||||
|
||||
if (errors)
|
||||
I_Error ("%d errors in R_InitTextures.", errors);
|
||||
I_FatalError ("%d errors in R_InitTextures.", errors);
|
||||
|
||||
// [RH] Setup hash chains. Go from back to front so that if
|
||||
// duplicates are found, the first one gets used instead
|
||||
|
@ -609,7 +589,7 @@ void R_InitTextures (void)
|
|||
R_GenerateLookup (i, &errors);
|
||||
|
||||
if (errors)
|
||||
I_Error ("%d errors encountered during texture generation.", errors);
|
||||
I_FatalError ("%d errors encountered during texture generation.", errors);
|
||||
|
||||
// Create translation table for global animation.
|
||||
texturetranslation = Z_Malloc ((numtextures+1)*sizeof(*texturetranslation), PU_STATIC, 0);
|
||||
|
@ -648,51 +628,112 @@ void R_InitFlats (void)
|
|||
//
|
||||
void R_InitSpriteLumps (void)
|
||||
{
|
||||
int i;
|
||||
patch_t *patch;
|
||||
|
||||
firstspritelump = W_GetNumForName ("S_START") + 1;
|
||||
lastspritelump = W_GetNumForName ("S_END") - 1;
|
||||
|
||||
numspritelumps = lastspritelump - firstspritelump + 1;
|
||||
spritewidth = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
|
||||
spriteoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
|
||||
spritetopoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
|
||||
|
||||
for (i = 0; i < numspritelumps; i++)
|
||||
{
|
||||
if (!(i&127))
|
||||
Printf (".");
|
||||
|
||||
patch = W_CacheLumpNum (firstspritelump+i, PU_CACHE);
|
||||
spritewidth[i] = SHORT(patch->width)<<FRACBITS;
|
||||
spriteoffset[i] = SHORT(patch->leftoffset)<<FRACBITS;
|
||||
spritetopoffset[i] = SHORT(patch->topoffset)<<FRACBITS;
|
||||
}
|
||||
numspritelumps = lastspritelump - firstspritelump + 1;
|
||||
|
||||
// [RH] Rather than maintaining separate spritewidth, spriteoffset,
|
||||
// and spritetopoffset arrays, this data has now been moved into
|
||||
// the sprite frame definition and gets initialized by
|
||||
// R_InstallSpriteLump(), so there really isn't anything to do here.
|
||||
}
|
||||
|
||||
|
||||
static struct {
|
||||
char name[8];
|
||||
unsigned int blend;
|
||||
} *fakecmaps;
|
||||
size_t numfakecmaps;
|
||||
int firstfakecmap;
|
||||
byte *realcolormaps;
|
||||
int lastusedcolormap;
|
||||
|
||||
void R_SetDefaultColormap (const char *name)
|
||||
{
|
||||
if (strnicmp (fakecmaps[0].name, name, 8)) {
|
||||
byte *data = W_CacheLumpName (name, PU_CACHE);
|
||||
|
||||
memcpy (realcolormaps, data, (NUMCOLORMAPS+1)*256);
|
||||
uppercopy (fakecmaps[0].name, name);
|
||||
fakecmaps[0].blend = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// R_InitColormaps
|
||||
//
|
||||
void R_InitColormaps (void)
|
||||
{
|
||||
// [RH] This is all done dynamically in v_palette.c
|
||||
#if 0
|
||||
int lump, length;
|
||||
// [RH] Try and convert BOOM colormaps into blending values.
|
||||
// This is a really rough hack, but it's better than
|
||||
// not doing anything with them at all (right?)
|
||||
int lastfakecmap = W_CheckNumForName ("C_END");
|
||||
firstfakecmap = W_CheckNumForName ("C_START");
|
||||
|
||||
// Load in the light tables,
|
||||
// 256 byte align tables.
|
||||
lump = W_GetNumForName("COLORMAP");
|
||||
length = W_LumpLength (lump) + 255;
|
||||
colormaps = Z_Malloc (length, PU_STATIC, 0);
|
||||
colormaps = (byte *)( ((int)colormaps + 255)&~0xff);
|
||||
W_ReadLump (lump,colormaps);
|
||||
#endif
|
||||
if (firstfakecmap == -1 || lastfakecmap == -1)
|
||||
numfakecmaps = 1;
|
||||
else
|
||||
numfakecmaps = lastfakecmap - firstfakecmap;
|
||||
realcolormaps = Z_Malloc (256*(NUMCOLORMAPS+1)*numfakecmaps+255,PU_STATIC,0);
|
||||
realcolormaps = (byte *)((int)(realcolormaps + 255) & ~255);
|
||||
fakecmaps = Z_Malloc (sizeof(*fakecmaps) * numfakecmaps, PU_STATIC, 0);
|
||||
|
||||
fakecmaps[0].name[0] = 0;
|
||||
R_SetDefaultColormap ("COLORMAP");
|
||||
|
||||
if (numfakecmaps > 1)
|
||||
{
|
||||
int i;
|
||||
size_t j;
|
||||
palette_t *pal = GetDefaultPalette ();
|
||||
|
||||
for (i = ++firstfakecmap, j = 1; j < numfakecmaps; i++, j++) {
|
||||
if (W_LumpLength (i) >= (NUMCOLORMAPS+1)*256) {
|
||||
int k, r, g, b;
|
||||
byte *map = W_CacheLumpNum (i, PU_CACHE);
|
||||
|
||||
memcpy (realcolormaps+(NUMCOLORMAPS+1)*256*j,
|
||||
map, (NUMCOLORMAPS+1)*256);
|
||||
|
||||
r = RPART(pal->basecolors[*map]);
|
||||
g = GPART(pal->basecolors[*map]);
|
||||
b = BPART(pal->basecolors[*map]);
|
||||
|
||||
W_GetLumpName (fakecmaps[j].name, i);
|
||||
for (k = 1; k < 256; k++) {
|
||||
r = (r + RPART(pal->basecolors[map[k]])) >> 1;
|
||||
g = (g + GPART(pal->basecolors[map[k]])) >> 1;
|
||||
b = (b + BPART(pal->basecolors[map[k]])) >> 1;
|
||||
}
|
||||
fakecmaps[j].blend = MAKEARGB (255, r, g, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] Returns an index into realcolormaps. Multiply it by
|
||||
// 256*(NUMCOLORMAPS+1) to find the start of the colormap to use.
|
||||
// WATERMAP is an exception and returns a blending value instead.
|
||||
int R_ColormapNumForName (const char *name)
|
||||
{
|
||||
int lump, blend = 0;
|
||||
|
||||
if (strnicmp (name, "COLORMAP", 8)) { // COLORMAP always returns 0
|
||||
if (-1 != (lump = (W_CheckNumForName)(name, ns_colormaps)) )
|
||||
blend = lump - firstfakecmap + 1;
|
||||
else if (!strnicmp (name, "WATERMAP", 8))
|
||||
blend = MAKEARGB (128,0,0x4f,0xa5);
|
||||
}
|
||||
|
||||
return blend;
|
||||
}
|
||||
|
||||
unsigned int R_BlendForColormap (int map)
|
||||
{
|
||||
return APART(map) ? map :
|
||||
(unsigned)map < numfakecmaps ? fakecmaps[map].blend : 0;
|
||||
}
|
||||
|
||||
//
|
||||
// R_InitData
|
||||
|
@ -882,7 +923,7 @@ void R_PrecacheLevel (void)
|
|||
int k;
|
||||
|
||||
for (k = 7; k >= 0; k--)
|
||||
W_CacheLumpNum(firstspritelump + sflumps[k], PU_CACHE);
|
||||
W_CacheLumpNum(sflumps[k], PU_CACHE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
|
||||
|
||||
|
||||
// Silhouette, needed for clipping Segs (mainly)
|
||||
// and sprites representing things.
|
||||
#define SIL_NONE 0
|
||||
|
@ -90,10 +91,13 @@ struct degenmobj_s
|
|||
|
||||
};
|
||||
typedef struct degenmobj_s degenmobj_t;
|
||||
|
||||
//
|
||||
// The SECTORS record, at runtime.
|
||||
// Stores things/mobjs.
|
||||
//
|
||||
struct dyncolormap_s;
|
||||
|
||||
struct sector_s
|
||||
{
|
||||
fixed_t floorheight;
|
||||
|
@ -103,6 +107,7 @@ struct sector_s
|
|||
short lightlevel;
|
||||
short special;
|
||||
short tag;
|
||||
int nexttag,firsttag; // killough 1/30/98: improves searches for tags.
|
||||
|
||||
int soundtraversed; // 0 = untraversed, 1,2 = sndlines -1
|
||||
mobj_t* soundtarget; // thing that made a sound (or null)
|
||||
|
@ -131,6 +136,10 @@ struct sector_s
|
|||
// killough 4/11/98: support for lightlevels coming from another sector
|
||||
int floorlightsec, ceilinglightsec;
|
||||
|
||||
unsigned int bottommap, midmap, topmap; // killough 4/4/98: dynamic colormaps
|
||||
// [RH] these can also be blend values if
|
||||
// the alpha mask is non-zero
|
||||
|
||||
// list of mobjs that are at least partially in the sector
|
||||
// thinglist is a subset of touching_thinglist
|
||||
struct msecnode_s *touching_thinglist; // phares 3/14/98
|
||||
|
@ -138,6 +147,10 @@ struct sector_s
|
|||
int linecount;
|
||||
struct line_s **lines; // [linecount] size
|
||||
|
||||
float gravity; // [RH] Sector gravity (1.0 is normal)
|
||||
short damage; // [RH] Damage to do while standing on floor
|
||||
short mod; // [RH] Means-of-death for applied damage
|
||||
struct dyncolormap_s *colormap; // [RH] Per-sector colormap
|
||||
};
|
||||
typedef struct sector_s sector_t;
|
||||
|
||||
|
@ -161,6 +174,9 @@ struct side_s
|
|||
short bottomtexture;
|
||||
short midtexture;
|
||||
|
||||
// [RH] Bah. Had to add this for BOOM
|
||||
byte special;
|
||||
|
||||
// Sector the SideDef is facing.
|
||||
sector_t* sector;
|
||||
|
||||
|
@ -194,9 +210,13 @@ struct line_s
|
|||
|
||||
// Animation related.
|
||||
short flags;
|
||||
short special;
|
||||
short tag;
|
||||
byte args[5]; // [RH] Hexen-style arguments
|
||||
byte special; // [RH] Only one byte per special.
|
||||
byte lucency; // <--- Translucency (0-255/255=opaque)
|
||||
short id; // <--- Same as tag or set with Line_SetIdentification.
|
||||
short args[5]; // <--- Hexen-style arguments
|
||||
// Note that these are shorts in order to support
|
||||
// the tag parameter from DOOM.
|
||||
int firstid, nextid;
|
||||
|
||||
// Visual appearance: SideDefs.
|
||||
// sidenum[1] will be -1 if one sided
|
||||
|
@ -216,9 +236,6 @@ struct line_s
|
|||
|
||||
// if == validcount, already checked
|
||||
int validcount;
|
||||
|
||||
// thinker_t for reversable actions
|
||||
void* specialdata;
|
||||
};
|
||||
typedef struct line_s line_t;
|
||||
|
||||
|
@ -377,7 +394,6 @@ struct drawseg_s
|
|||
short* sprtopclip;
|
||||
short* sprbottomclip;
|
||||
short* maskedtexturecol;
|
||||
|
||||
};
|
||||
typedef struct drawseg_s drawseg_t;
|
||||
|
||||
|
@ -430,8 +446,7 @@ struct vissprite_s
|
|||
fixed_t texturemid;
|
||||
int patch;
|
||||
|
||||
// for color translation and shadow draw,
|
||||
// maxbright frames as well
|
||||
// for color translation and maxbright frames as well
|
||||
lighttable_t* colormap;
|
||||
|
||||
int mobjflags;
|
||||
|
@ -471,13 +486,18 @@ struct spriteframe_s
|
|||
// Lump to use for view angles 0-7.
|
||||
short lump[8];
|
||||
|
||||
// [RH] Move some data out of spritewidth, spriteoffset,
|
||||
// and spritetopoffset arrays.
|
||||
fixed_t width[8];
|
||||
fixed_t topoffset[8];
|
||||
fixed_t offset[8];
|
||||
|
||||
// Flip bit (1 = flip) to use for view angles 0-7.
|
||||
byte flip[8];
|
||||
|
||||
};
|
||||
typedef struct spriteframe_s spriteframe_t;
|
||||
|
||||
|
||||
//
|
||||
// A sprite definition:
|
||||
// a number of animation frames.
|
||||
|
@ -490,28 +510,36 @@ struct spritedef_s
|
|||
};
|
||||
typedef struct spritedef_s spritedef_t;
|
||||
|
||||
//
|
||||
// [RH] Internal "skin" definition.
|
||||
//
|
||||
struct playerskin_s
|
||||
{
|
||||
char name[17]; // 16 chars + NULL
|
||||
char face[3];
|
||||
int sprite;
|
||||
int namespc; // namespace for this skin
|
||||
int gender; // This skin's gender (not used)
|
||||
};
|
||||
typedef struct playerskin_s playerskin_t;
|
||||
|
||||
//
|
||||
// Now what is a visplane, anyway?
|
||||
// The infamous visplane
|
||||
//
|
||||
struct visplane_s
|
||||
{
|
||||
fixed_t height;
|
||||
int picnum;
|
||||
int lightlevel;
|
||||
fixed_t xoffs;
|
||||
fixed_t yoffs;
|
||||
int minx;
|
||||
int maxx;
|
||||
|
||||
// leave pads for [minx-1]/[maxx+1]
|
||||
|
||||
// Here lies the rub for all
|
||||
// dynamic resize/change of resolution.
|
||||
struct visplane_s *next; // Next visplane in hash chain -- killough
|
||||
|
||||
// These actually point one short past the memory
|
||||
// area allocated (for padding)
|
||||
unsigned short *top, *bottom;
|
||||
fixed_t height;
|
||||
int picnum;
|
||||
int lightlevel;
|
||||
fixed_t xoffs, yoffs; // killough 2/28/98: Support scrolling flats
|
||||
int minx, maxx;
|
||||
byte *colormap; // [RH] Support multiple colormaps
|
||||
|
||||
unsigned short *bottom; // [RH] bottom and top arrays are dynamically
|
||||
unsigned short pad; // allocated immediately after the
|
||||
unsigned short top[3]; // visplane.
|
||||
};
|
||||
typedef struct visplane_s visplane_t;
|
||||
|
||||
|
|
|
@ -254,7 +254,7 @@ void R_DrawFuzzColumnP_C (void)
|
|||
if (count < 0)
|
||||
return;
|
||||
|
||||
map = DefaultPalette->colormaps + 6*256;
|
||||
map = DefaultPalette->maps.colormaps + 6*256;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (dc_x >= screens[0].width
|
||||
|
@ -494,6 +494,8 @@ void R_DrawSpanP (void)
|
|||
/* */
|
||||
/****************************************/
|
||||
|
||||
#define dc_shademap ((unsigned int *)dc_colormap)
|
||||
|
||||
void R_DrawColumnD_C (void)
|
||||
{
|
||||
int count;
|
||||
|
@ -523,7 +525,7 @@ void R_DrawColumnD_C (void)
|
|||
|
||||
do
|
||||
{
|
||||
*dest = V_Palette[dc_colormap[dc_source[(frac>>FRACBITS)&dc_mask]]];
|
||||
*dest = dc_shademap[dc_source[(frac>>FRACBITS)&dc_mask]];
|
||||
|
||||
dest += dc_pitch >> 2;
|
||||
frac += fracstep;
|
||||
|
@ -608,7 +610,7 @@ void R_DrawTranslucentColumnD_C (void)
|
|||
do
|
||||
{
|
||||
*dest = ((*dest >> 1) & 0x7f7f7f) +
|
||||
((V_Palette[dc_colormap[dc_source[(frac>>FRACBITS)&dc_mask]]] >> 1) & 0x7f7f7f);
|
||||
((dc_shademap[dc_source[(frac>>FRACBITS)&dc_mask]] >> 1) & 0x7f7f7f);
|
||||
dest += dc_pitch >> 2;
|
||||
|
||||
frac += fracstep;
|
||||
|
@ -646,7 +648,7 @@ void R_DrawTranslatedColumnD_C (void)
|
|||
// Here we do an additional index re-mapping.
|
||||
do
|
||||
{
|
||||
*dest = V_Palette[dc_colormap[dc_translation[dc_source[(frac>>FRACBITS) & dc_mask]]]];
|
||||
*dest = dc_shademap[dc_translation[dc_source[(frac>>FRACBITS) & dc_mask]]];
|
||||
dest += dc_pitch >> 2;
|
||||
|
||||
frac += fracstep;
|
||||
|
@ -686,7 +688,7 @@ void R_DrawSpanD (void)
|
|||
|
||||
// Lookup pixel from flat texture tile,
|
||||
// re-index using light/colormap.
|
||||
*dest = V_Palette[ds_colormap[ds_source[spot]]];
|
||||
*dest = ((unsigned int *)ds_colormap)[ds_source[spot]];
|
||||
dest += ds_colsize >> 2;
|
||||
|
||||
// Next step in u,v.
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
extern int dc_pitch; // [RH] Distance between rows
|
||||
|
||||
extern lighttable_t* dc_colormap;
|
||||
extern unsigned int* dc_shademap; // [RH] For high/true color modes
|
||||
extern int dc_x;
|
||||
extern int dc_yl;
|
||||
extern int dc_yh;
|
||||
|
|
378
code/R_main.c
378
code/R_main.c
|
@ -50,7 +50,7 @@ cvar_t *r_viewsize;
|
|||
extern int dmflags;
|
||||
|
||||
// Fineangles in the SCREENWIDTH wide window.
|
||||
#define FIELDOFVIEW 2048
|
||||
#define FIELDOFVIEW 2048
|
||||
|
||||
|
||||
|
||||
|
@ -59,9 +59,10 @@ int viewangleoffset;
|
|||
// increment every time a check is made
|
||||
int validcount = 1;
|
||||
|
||||
lighttable_t* basecolormap; // [RH] colormap currently drawing with
|
||||
|
||||
lighttable_t* fixedcolormap;
|
||||
extern lighttable_t** walllights;
|
||||
extern int* walllights; // [RH] changed from lighttable_t** to int*
|
||||
|
||||
int centerx;
|
||||
int centery;
|
||||
|
@ -89,7 +90,7 @@ angle_t viewangle;
|
|||
fixed_t viewcos;
|
||||
fixed_t viewsin;
|
||||
|
||||
player_t* viewplayer;
|
||||
mobj_t* camera; // [RH] camera to draw from. doesn't have to be a player
|
||||
|
||||
//
|
||||
// precalculated math tables
|
||||
|
@ -117,13 +118,15 @@ angle_t *xtoviewangle;
|
|||
// fixed_t finesine[5*FINEANGLES/4];
|
||||
fixed_t* finecosine = &finesine[FINEANGLES/4];
|
||||
|
||||
// [RH] Changed these from lighttable_t* to int.
|
||||
int scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
|
||||
int scalelightfixed[MAXLIGHTSCALE];
|
||||
int zlight[LIGHTLEVELS][MAXLIGHTZ];
|
||||
|
||||
lighttable_t* scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
|
||||
lighttable_t* scalelightfixed[MAXLIGHTSCALE];
|
||||
lighttable_t* zlight[LIGHTLEVELS][MAXLIGHTZ];
|
||||
int lightscalexmul; // [RH] used to keep hires modes dark enough
|
||||
int lightscaleymul;
|
||||
|
||||
// bumped light from gun blasts
|
||||
int extralight;
|
||||
int extralight; // bumped light from gun blasts
|
||||
|
||||
extern BOOL DrawNewHUD; // [RH] Defined in d_main.c.
|
||||
|
||||
|
@ -144,11 +147,7 @@ void (*spanfunc) (void);
|
|||
// Expand a given bbox
|
||||
// so that it encloses a given point.
|
||||
//
|
||||
void
|
||||
R_AddPointToBox
|
||||
( int x,
|
||||
int y,
|
||||
fixed_t* box )
|
||||
void R_AddPointToBox (int x, int y, fixed_t *box)
|
||||
{
|
||||
if (x< box[BOXLEFT])
|
||||
box[BOXLEFT] = x;
|
||||
|
@ -163,123 +162,87 @@ R_AddPointToBox
|
|||
|
||||
//
|
||||
// R_PointOnSide
|
||||
// Traverse BSP (sub) tree,
|
||||
// check point against partition plane.
|
||||
// Traverse BSP (sub) tree, check point against partition plane.
|
||||
// Returns side 0 (front) or 1 (back).
|
||||
// [RH] Re-arranged slightly.
|
||||
//
|
||||
int
|
||||
R_PointOnSide
|
||||
( fixed_t x,
|
||||
fixed_t y,
|
||||
node_t* node )
|
||||
int R_PointOnSide (fixed_t x, fixed_t y, node_t *node)
|
||||
{
|
||||
fixed_t dx;
|
||||
fixed_t dy;
|
||||
fixed_t left;
|
||||
fixed_t right;
|
||||
|
||||
if (!node->dx)
|
||||
{
|
||||
if (x <= node->x)
|
||||
return node->dy > 0;
|
||||
|
||||
return node->dy < 0;
|
||||
return (x <= node->x) ? (node->dy > 0) : (node->dy < 0);
|
||||
}
|
||||
if (!node->dy)
|
||||
else if (!node->dy)
|
||||
{
|
||||
if (y <= node->y)
|
||||
return node->dx < 0;
|
||||
|
||||
return node->dx > 0;
|
||||
return (y <= node->y) ? (node->dx < 0) : (node->dx > 0);
|
||||
}
|
||||
|
||||
dx = (x - node->x);
|
||||
dy = (y - node->y);
|
||||
|
||||
// Try to quickly decide by looking at sign bits.
|
||||
if ( (node->dy ^ node->dx ^ dx ^ dy)&0x80000000 )
|
||||
else
|
||||
{
|
||||
if ( (node->dy ^ dx) & 0x80000000 )
|
||||
fixed_t dx = (x - node->x);
|
||||
fixed_t dy = (y - node->y);
|
||||
|
||||
// Try to quickly decide by looking at sign bits.
|
||||
if ( (node->dy ^ node->dx ^ dx ^ dy)&0x80000000 )
|
||||
{
|
||||
// (left is negative)
|
||||
return 1;
|
||||
if ( (node->dy ^ dx) & 0x80000000 )
|
||||
{
|
||||
// (left is negative)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
left = FixedMul ( node->dy>>FRACBITS , dx );
|
||||
right = FixedMul ( dy , node->dx>>FRACBITS );
|
||||
|
||||
if (right < left)
|
||||
{
|
||||
// front side
|
||||
return 0;
|
||||
if (FixedMul (dy, node->dx>>FRACBITS) < FixedMul (node->dy>>FRACBITS, dx))
|
||||
{
|
||||
// front side
|
||||
return 0;
|
||||
}
|
||||
// back side
|
||||
return 1;
|
||||
}
|
||||
// back side
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
R_PointOnSegSide
|
||||
( fixed_t x,
|
||||
fixed_t y,
|
||||
seg_t* line )
|
||||
// [RH] Rearranged this slightly, too.
|
||||
int R_PointOnSegSide (fixed_t x, fixed_t y, seg_t *line)
|
||||
{
|
||||
fixed_t lx;
|
||||
fixed_t ly;
|
||||
fixed_t ldx;
|
||||
fixed_t ldy;
|
||||
fixed_t dx;
|
||||
fixed_t dy;
|
||||
fixed_t left;
|
||||
fixed_t right;
|
||||
|
||||
lx = line->v1->x;
|
||||
ly = line->v1->y;
|
||||
|
||||
ldx = line->v2->x - lx;
|
||||
ldy = line->v2->y - ly;
|
||||
|
||||
fixed_t lx = line->v1->x;
|
||||
fixed_t ly = line->v1->y;
|
||||
|
||||
fixed_t ldx = line->v2->x - lx;
|
||||
fixed_t ldy = line->v2->y - ly;
|
||||
|
||||
if (!ldx)
|
||||
{
|
||||
if (x <= lx)
|
||||
return ldy > 0;
|
||||
|
||||
return ldy < 0;
|
||||
return (x <= lx) ? (ldy > 0) : (ldy < 0);
|
||||
}
|
||||
if (!ldy)
|
||||
else if (!ldy)
|
||||
{
|
||||
if (y <= ly)
|
||||
return ldx < 0;
|
||||
|
||||
return ldx > 0;
|
||||
return (y <= ly) ? (ldx < 0) : (ldx > 0);
|
||||
}
|
||||
|
||||
dx = (x - lx);
|
||||
dy = (y - ly);
|
||||
|
||||
// Try to quickly decide by looking at sign bits.
|
||||
if ( (ldy ^ ldx ^ dx ^ dy)&0x80000000 )
|
||||
else
|
||||
{
|
||||
if ( (ldy ^ dx) & 0x80000000 )
|
||||
{
|
||||
// (left is negative)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
fixed_t dx = (x - lx);
|
||||
fixed_t dy = (y - ly);
|
||||
|
||||
left = FixedMul ( ldy>>FRACBITS , dx );
|
||||
right = FixedMul ( dy , ldx>>FRACBITS );
|
||||
|
||||
if (right < left)
|
||||
{
|
||||
// front side
|
||||
return 0;
|
||||
// Try to quickly decide by looking at sign bits.
|
||||
if ( (ldy ^ ldx ^ dx ^ dy)&0x80000000 )
|
||||
{
|
||||
if ( (ldy ^ dx) & 0x80000000 )
|
||||
{
|
||||
// (left is negative)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (FixedMul (dy, ldx>>FRACBITS) < FixedMul (ldy>>FRACBITS, dx))
|
||||
{
|
||||
// front side
|
||||
return 0;
|
||||
}
|
||||
// back side
|
||||
return 1;
|
||||
}
|
||||
// back side
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -293,10 +256,6 @@ R_PointOnSegSide
|
|||
// tantoangle[] table.
|
||||
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
angle_t R_PointToAngle (fixed_t x, fixed_t y)
|
||||
{
|
||||
x -= viewx;
|
||||
|
@ -379,12 +338,7 @@ angle_t R_PointToAngle (fixed_t x, fixed_t y)
|
|||
}
|
||||
|
||||
|
||||
angle_t
|
||||
R_PointToAngle2
|
||||
( fixed_t x1,
|
||||
fixed_t y1,
|
||||
fixed_t x2,
|
||||
fixed_t y2 )
|
||||
angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2)
|
||||
{
|
||||
viewx = x1;
|
||||
viewy = y1;
|
||||
|
@ -398,7 +352,10 @@ R_PointToAngle2
|
|||
//
|
||||
void R_InitPointToAngle (void)
|
||||
{
|
||||
// UNUSED - now getting from tables.c [or are we? -RH]
|
||||
// UNUSED - now getting from tables.c
|
||||
// [RH] Actually, if you define CALC_TABLES, the game will use the FPU
|
||||
// to calculate these tables at runtime so that a little space
|
||||
// can be saved on disk.
|
||||
#ifdef CALC_TABLES
|
||||
double i, f;
|
||||
//
|
||||
|
@ -480,7 +437,9 @@ fixed_t R_ScaleFromGlobalAngle (angle_t visangle)
|
|||
//
|
||||
void R_InitTables (void)
|
||||
{
|
||||
// UNUSED: now getting from tables.c [or are we? -RH]
|
||||
// UNUSED: now getting from tables.c
|
||||
// [RH] As with R_InitPointToAngle, you can #define CALC_TABLES
|
||||
// to generate these tables at runtime.
|
||||
#ifdef CALC_TABLES
|
||||
int i;
|
||||
double a;
|
||||
|
@ -512,10 +471,10 @@ void R_InitTables (void)
|
|||
//
|
||||
void R_InitTextureMapping (void)
|
||||
{
|
||||
int i;
|
||||
int x;
|
||||
int t;
|
||||
fixed_t focallength;
|
||||
int i;
|
||||
int x;
|
||||
int t;
|
||||
fixed_t focallength;
|
||||
|
||||
// Use tangent table to generate viewangletox:
|
||||
// viewangletox will give the next greatest x
|
||||
|
@ -526,7 +485,7 @@ void R_InitTextureMapping (void)
|
|||
focallength = FixedDiv (centerxfrac,
|
||||
finetangent[FINEANGLES/4+FIELDOFVIEW/2] );
|
||||
|
||||
for (i=0 ; i<FINEANGLES/2 ; i++)
|
||||
for (i = 0; i < FINEANGLES/2; i++)
|
||||
{
|
||||
if (finetangent[i] > FRACUNIT*2)
|
||||
t = -1;
|
||||
|
@ -548,7 +507,7 @@ void R_InitTextureMapping (void)
|
|||
// Scan viewangletox[] to generate xtoviewangle[]:
|
||||
// xtoviewangle will give the smallest view angle
|
||||
// that maps to x.
|
||||
for (x=0;x<=viewwidth;x++)
|
||||
for (x = 0; x <= viewwidth; x++)
|
||||
{
|
||||
i = 0;
|
||||
while (viewangletox[i]>x)
|
||||
|
@ -557,7 +516,7 @@ void R_InitTextureMapping (void)
|
|||
}
|
||||
|
||||
// Take out the fencepost cases from viewangletox.
|
||||
for (i=0 ; i<FINEANGLES/2 ; i++)
|
||||
for (i = 0; i < FINEANGLES/2; i++)
|
||||
{
|
||||
t = FixedMul (finetangent[i], focallength);
|
||||
t = centerx - t;
|
||||
|
@ -577,37 +536,43 @@ void R_InitTextureMapping (void)
|
|||
// R_InitLightTables
|
||||
// Only inits the zlight table,
|
||||
// because the scalelight table changes with view size.
|
||||
// [RH] This now setups indices into a colormap rather than pointers into the
|
||||
// colormap, because the colormap can vary by sector, but the indices
|
||||
// into it don't.
|
||||
//
|
||||
#define DISTMAP 2
|
||||
#define DISTMAP 2
|
||||
|
||||
void R_InitLightTables (void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int level;
|
||||
int startmap;
|
||||
int scale;
|
||||
|
||||
int i;
|
||||
int j;
|
||||
int level;
|
||||
int startmap;
|
||||
int scale;
|
||||
int lightmapsize = 8 + (screens[0].is8bit ? 0 : 2);
|
||||
|
||||
// Calculate the light levels to use
|
||||
// for each level / distance combination.
|
||||
for (i=0 ; i< LIGHTLEVELS ; i++)
|
||||
for (i = 0; i < LIGHTLEVELS; i++)
|
||||
{
|
||||
startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
|
||||
for (j=0 ; j<MAXLIGHTZ ; j++)
|
||||
{
|
||||
scale = FixedDiv ((screens[0].width/2*FRACUNIT), (j+1)<<LIGHTZSHIFT);
|
||||
scale >>= LIGHTSCALESHIFT;
|
||||
scale = FixedDiv ((160*FRACUNIT), (j+1)<<LIGHTZSHIFT);
|
||||
scale >>= LIGHTSCALESHIFT-LIGHTSCALEMULBITS;
|
||||
level = startmap - scale/DISTMAP;
|
||||
|
||||
if (level < 0)
|
||||
level = 0;
|
||||
|
||||
if (level >= NUMCOLORMAPS)
|
||||
else if (level >= NUMCOLORMAPS)
|
||||
level = NUMCOLORMAPS-1;
|
||||
|
||||
zlight[i][j] = DefaultPalette->maps.colormaps + level*256;
|
||||
zlight[i][j] = level << lightmapsize;
|
||||
}
|
||||
}
|
||||
|
||||
lightscalexmul = 320 * (1<<LIGHTSCALEMULBITS) / screens[0].width;
|
||||
lightscaleymul = 200 * (1<<LIGHTSCALEMULBITS) / screens[0].height;
|
||||
}
|
||||
|
||||
|
||||
|
@ -618,9 +583,9 @@ void R_InitLightTables (void)
|
|||
// because it might be in the middle of a refresh.
|
||||
// The change will take effect next refresh.
|
||||
//
|
||||
BOOL setsizeneeded;
|
||||
int setblocks;
|
||||
int setdetail = -1;
|
||||
BOOL setsizeneeded;
|
||||
int setblocks;
|
||||
int setdetail = -1;
|
||||
|
||||
|
||||
void R_SetViewSize (int blocks)
|
||||
|
@ -667,6 +632,7 @@ void R_ExecuteSetViewSize (void)
|
|||
int startmap;
|
||||
int aspectx;
|
||||
int virtheight, virtwidth;
|
||||
int lightmapsize = 8 + (screens[0].is8bit ? 0 : 2);
|
||||
|
||||
setsizeneeded = false;
|
||||
|
||||
|
@ -685,7 +651,8 @@ void R_ExecuteSetViewSize (void)
|
|||
realviewwidth = screens[0].width;
|
||||
realviewheight = ST_Y;
|
||||
freelookviewheight = screens[0].height;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
realviewwidth = ((setblocks*screens[0].width)/10) & (~(15>>(screens[0].is8bit ? 0 : 2)));
|
||||
realviewheight = ((setblocks*ST_Y)/10)&~7;
|
||||
|
@ -717,7 +684,7 @@ void R_ExecuteSetViewSize (void)
|
|||
virtwidth = screens[0].width >> detailxshift;
|
||||
virtheight = screens[0].height >> detailyshift;
|
||||
|
||||
// [RH] aspect ratio stuff (based Doom Legacy's)
|
||||
// [RH] aspect ratio stuff (based on Doom Legacy's)
|
||||
aspectx = ((virtheight * centerx * 320) / 200) / virtwidth * FRACUNIT;
|
||||
|
||||
projection = centerxfrac;
|
||||
|
@ -768,8 +735,8 @@ void R_ExecuteSetViewSize (void)
|
|||
distscale[i] = FixedDiv (FRACUNIT,cosadj);
|
||||
}
|
||||
|
||||
// Calculate the light levels to use
|
||||
// for each level / scale combination.
|
||||
// Calculate the light levels to use for each level / scale combination.
|
||||
// [RH] This just stores indices into the colormap rather than pointers into it.
|
||||
for (i=0 ; i< LIGHTLEVELS ; i++)
|
||||
{
|
||||
startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
|
||||
|
@ -779,13 +746,15 @@ void R_ExecuteSetViewSize (void)
|
|||
|
||||
if (level < 0)
|
||||
level = 0;
|
||||
|
||||
if (level >= NUMCOLORMAPS)
|
||||
else if (level >= NUMCOLORMAPS)
|
||||
level = NUMCOLORMAPS-1;
|
||||
|
||||
scalelight[i][j] = DefaultPalette->maps.colormaps + level*256;
|
||||
scalelight[i][j] = level << lightmapsize;
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] Initialize z-light tables here
|
||||
R_InitLightTables ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -820,29 +789,14 @@ void R_Init (void)
|
|||
R_DetailCallback (r_detail);
|
||||
|
||||
R_InitData ();
|
||||
Printf (".");
|
||||
// Printf ("\nR_InitData");
|
||||
R_InitPointToAngle ();
|
||||
Printf (".");
|
||||
// Printf ("\nR_InitPointToAngle");
|
||||
R_InitTables ();
|
||||
// viewwidth / viewheight are set by the defaults
|
||||
Printf (".");
|
||||
// Printf ("\nR_InitTables");
|
||||
|
||||
R_SetViewSize ((int)screenblocks->value);
|
||||
R_InitPlanes ();
|
||||
Printf (".");
|
||||
// Printf ("\nR_InitPlanes");
|
||||
R_InitLightTables ();
|
||||
Printf (".");
|
||||
// Printf ("\nR_InitLightTables");
|
||||
// R_InitSkyMap ();
|
||||
Printf (".");
|
||||
// Printf ("\nR_InitSkyMap");
|
||||
R_InitTranslationTables ();
|
||||
Printf (".");
|
||||
// Printf ("\nR_InitTranslationsTables");
|
||||
|
||||
framecount = 0;
|
||||
}
|
||||
|
@ -851,10 +805,7 @@ void R_Init (void)
|
|||
//
|
||||
// R_PointInSubsector
|
||||
//
|
||||
subsector_t*
|
||||
R_PointInSubsector
|
||||
( fixed_t x,
|
||||
fixed_t y )
|
||||
subsector_t *R_PointInSubsector (fixed_t x, fixed_t y)
|
||||
{
|
||||
node_t* node;
|
||||
int side;
|
||||
|
@ -881,38 +832,79 @@ R_PointInSubsector
|
|||
//
|
||||
// R_SetupFrame
|
||||
//
|
||||
void R_SetupFrame (player_t* player)
|
||||
extern dyncolormap_t NormalLight;
|
||||
|
||||
void R_SetupFrame (player_t *player)
|
||||
{
|
||||
int i;
|
||||
static unsigned int oldblend = ~0;
|
||||
unsigned int newblend;
|
||||
int dy;
|
||||
|
||||
viewplayer = player;
|
||||
viewx = player->mo->x;
|
||||
viewy = player->mo->y;
|
||||
viewangle = player->mo->angle + viewangleoffset;
|
||||
extralight = player->extralight;
|
||||
|
||||
viewz = player->viewz;
|
||||
camera = player->camera; // [RH] Use camera instead of viewplayer
|
||||
viewx = camera->x;
|
||||
viewy = camera->y;
|
||||
viewangle = camera->angle + viewangleoffset;
|
||||
extralight = camera == player->mo ? player->extralight : 0;
|
||||
viewz = camera->player ? camera->player->viewz : camera->z;
|
||||
|
||||
viewsin = finesine[viewangle>>ANGLETOFINESHIFT];
|
||||
viewcos = finecosine[viewangle>>ANGLETOFINESHIFT];
|
||||
|
||||
if (player->fixedcolormap)
|
||||
// killough 3/20/98, 4/4/98: select colormap based on player status
|
||||
// [RH] Can also select a blend
|
||||
|
||||
if (camera->subsector->sector->heightsec != -1)
|
||||
{
|
||||
fixedcolormap =
|
||||
DefaultPalette->maps.colormaps
|
||||
+ player->fixedcolormap*256*sizeof(lighttable_t);
|
||||
const sector_t *s = camera->subsector->sector->heightsec + sectors;
|
||||
newblend = viewz < s->floorheight ? s->bottommap : viewz > s->ceilingheight ?
|
||||
s->topmap : s->midmap;
|
||||
if (!screens[0].is8bit)
|
||||
newblend = R_BlendForColormap (newblend);
|
||||
else if (APART(newblend) == 0 && newblend >= numfakecmaps)
|
||||
newblend = 0;
|
||||
} else {
|
||||
newblend = 0;
|
||||
}
|
||||
|
||||
// [RH] Don't override testblend unless entering a sector with a
|
||||
// blend different from the previous sector's. Same goes with
|
||||
// NormalLight's maps pointer.
|
||||
if (oldblend != newblend) {
|
||||
oldblend = newblend;
|
||||
if (APART(newblend)) {
|
||||
BaseBlendR = RPART(newblend);
|
||||
BaseBlendG = GPART(newblend);
|
||||
BaseBlendB = BPART(newblend);
|
||||
BaseBlendA = APART(newblend) / 255.0f;
|
||||
NormalLight.maps = realcolormaps;
|
||||
} else {
|
||||
NormalLight.maps = realcolormaps + (NUMCOLORMAPS+1)*256*newblend;
|
||||
BaseBlendR = BaseBlendG = BaseBlendB = 0;
|
||||
BaseBlendA = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
if (camera == player->mo && player->fixedcolormap)
|
||||
{
|
||||
if (screens[0].is8bit)
|
||||
fixedcolormap =
|
||||
DefaultPalette->maps.colormaps
|
||||
+ player->fixedcolormap*256;
|
||||
else
|
||||
fixedcolormap = (lighttable_t *)
|
||||
(DefaultPalette->maps.shades
|
||||
+ player->fixedcolormap*256);
|
||||
|
||||
walllights = scalelightfixed;
|
||||
|
||||
for (i=0 ; i<MAXLIGHTSCALE ; i++)
|
||||
scalelightfixed[i] = fixedcolormap;
|
||||
// [RH] scalelightfixed is an int* now, not a lighttable_t**
|
||||
memset (scalelightfixed, 0, MAXLIGHTSCALE*sizeof(*scalelightfixed));
|
||||
}
|
||||
else
|
||||
fixedcolormap = 0;
|
||||
fixedcolormap = NULL;
|
||||
|
||||
// [RH] freelook stuff
|
||||
dy = FixedMul (freelookviewheight << (FRACBITS/2), player->mo->pitch) >> 9;
|
||||
dy = FixedMul (freelookviewheight << (FRACBITS/2), camera->pitch) >> 9;
|
||||
yslope = yslopetab + (freelookviewheight >> 1) + dy + freediff;
|
||||
centery = (viewheight >> 1) - dy;
|
||||
centeryfrac = centery << FRACBITS;
|
||||
|
@ -927,8 +919,16 @@ void R_SetupFrame (player_t* player)
|
|||
//
|
||||
// R_RenderView
|
||||
//
|
||||
void R_RenderPlayerView (player_t* player)
|
||||
{
|
||||
void R_RenderPlayerView (player_t *player)
|
||||
{
|
||||
angle_t an;
|
||||
|
||||
// [RH] Shift view for earthquakes
|
||||
if (player->xviewshift) {
|
||||
an = (player->mo->angle-ANG90) >> ANGLETOFINESHIFT;
|
||||
player->mo->x += finecosine[an]*player->xviewshift;
|
||||
player->mo->y += finesine[an]*player->xviewshift;
|
||||
}
|
||||
R_SetupFrame (player);
|
||||
|
||||
// Clear buffers.
|
||||
|
@ -958,6 +958,12 @@ void R_RenderPlayerView (player_t* player)
|
|||
|
||||
// [RH] Apply detail mode doubling
|
||||
R_DetailDouble ();
|
||||
|
||||
// [RH] Undo view shift
|
||||
if (player->xviewshift) {
|
||||
player->mo->x -= finecosine[an]*player->xviewshift;
|
||||
player->mo->y -= finesine[an]*player->xviewshift;
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] Do all multires stuff. Called from V_SetResolution()
|
||||
|
|
|
@ -50,7 +50,7 @@ extern fixed_t projection;
|
|||
extern fixed_t projectiony; // [RH] fix aspect ratio (from doom3)
|
||||
extern fixed_t skytopfrac; // [RH] virtual top of the sky (for freelooking)
|
||||
|
||||
|
||||
extern byte* basecolormap; // [RH] Colormap for sector currently being drawn
|
||||
|
||||
extern int validcount;
|
||||
|
||||
|
@ -70,17 +70,22 @@ extern int loopcount;
|
|||
#define LIGHTSEGSHIFT 4
|
||||
|
||||
#define MAXLIGHTSCALE 48
|
||||
#define LIGHTSCALESHIFT 12
|
||||
#define LIGHTSCALEMULBITS 8 // [RH] for hires lighting fix
|
||||
#define LIGHTSCALESHIFT (12+LIGHTSCALEMULBITS)
|
||||
#define MAXLIGHTZ 128
|
||||
#define LIGHTZSHIFT 20
|
||||
|
||||
extern lighttable_t* scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
|
||||
extern lighttable_t* scalelightfixed[MAXLIGHTSCALE];
|
||||
extern lighttable_t* zlight[LIGHTLEVELS][MAXLIGHTZ];
|
||||
// [RH] Changed from lighttable_t* to int.
|
||||
extern int scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
|
||||
extern int scalelightfixed[MAXLIGHTSCALE];
|
||||
extern int zlight[LIGHTLEVELS][MAXLIGHTZ];
|
||||
|
||||
extern int extralight;
|
||||
extern lighttable_t* fixedcolormap;
|
||||
|
||||
extern int lightscalexmul; // [RH] for hires lighting fix
|
||||
extern int lightscaleymul;
|
||||
|
||||
|
||||
// Number of diminishing brightness levels.
|
||||
// There a 0-31, i.e. 32 LUT in the COLORMAP lump.
|
||||
|
@ -130,11 +135,6 @@ R_PointToAngle2
|
|||
fixed_t x2,
|
||||
fixed_t y2 );
|
||||
|
||||
fixed_t
|
||||
R_PointToDist
|
||||
( fixed_t x,
|
||||
fixed_t y );
|
||||
|
||||
|
||||
fixed_t R_ScaleFromGlobalAngle (angle_t visangle);
|
||||
|
||||
|
|
390
code/R_plane.c
390
code/R_plane.c
|
@ -21,6 +21,17 @@
|
|||
// while maintaining a per column clipping list only.
|
||||
// Moreover, the sky areas have to be determined.
|
||||
//
|
||||
// MAXVISPLANES is no longer a limit on the number of visplanes,
|
||||
// but a limit on the number of hash slots; larger numbers mean
|
||||
// better performance usually but after a point they are wasted,
|
||||
// and memory and time overheads creep in.
|
||||
//
|
||||
// For more information on visplanes, see:
|
||||
//
|
||||
// http://classicgaming.com/doom/editing/
|
||||
//
|
||||
// Lee Killough
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
@ -43,18 +54,26 @@
|
|||
planefunction_t floorfunc;
|
||||
planefunction_t ceilingfunc;
|
||||
|
||||
// Here comes the obnoxious "visplane".
|
||||
#define MAXVISPLANES 128 /* must be a power of 2 */
|
||||
|
||||
static visplane_t *visplanes[MAXVISPLANES]; // killough
|
||||
static visplane_t *freetail; // killough
|
||||
static visplane_t **freehead = &freetail; // killough
|
||||
|
||||
visplane_t *floorplane;
|
||||
visplane_t *ceilingplane;
|
||||
|
||||
// killough -- hash function for visplanes
|
||||
// Empirically verified to be fairly uniform:
|
||||
|
||||
#define visplane_hash(picnum,lightlevel,height) \
|
||||
((unsigned)((picnum)*3+(lightlevel)+(height)*7) & (MAXVISPLANES-1))
|
||||
|
||||
//
|
||||
// opening
|
||||
//
|
||||
|
||||
// Here comes the obnoxious "visplane".
|
||||
int MaxVisPlanes;
|
||||
visplane_t *visplanes;
|
||||
visplane_t *lastvisplane;
|
||||
visplane_t *floorplane;
|
||||
visplane_t *ceilingplane;
|
||||
|
||||
// ?
|
||||
size_t maxopenings;
|
||||
short *openings;
|
||||
short *lastopening;
|
||||
|
@ -78,7 +97,7 @@ int *spanstop;
|
|||
//
|
||||
// texture mapping
|
||||
//
|
||||
lighttable_t** planezlight;
|
||||
int* planezlight; // [RH] Changed from lighttable_t** to int*
|
||||
fixed_t planeheight;
|
||||
|
||||
fixed_t *yslopetab; // [RH] Added for freelook. ylook points into it
|
||||
|
@ -94,52 +113,12 @@ fixed_t *cachedxstep;
|
|||
fixed_t *cachedystep;
|
||||
|
||||
|
||||
static void PrepVisPlanes (int min)
|
||||
{
|
||||
int i;
|
||||
unsigned short *stuff;
|
||||
|
||||
for (i = min; i < MaxVisPlanes; i++) {
|
||||
stuff = (unsigned short *)Calloc (screens[0].width * 2 + 4, sizeof(unsigned short));
|
||||
visplanes[i].top = stuff + 1;
|
||||
visplanes[i].bottom = stuff + screens[0].width + 3;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// R_InitPlanes
|
||||
// Only at game startup.
|
||||
// [RH] This function is actually used now.
|
||||
//
|
||||
void R_InitPlanes (void)
|
||||
{
|
||||
MaxVisPlanes = 128; // Default. Increased as needed.
|
||||
visplanes = (visplane_t *)Calloc (MaxVisPlanes, sizeof(visplane_t));
|
||||
PrepVisPlanes (0);
|
||||
}
|
||||
|
||||
static void GetMoreVisPlanes (visplane_t **toupdate)
|
||||
{
|
||||
int oldMax;
|
||||
visplane_t *old = visplanes;
|
||||
|
||||
oldMax = MaxVisPlanes;
|
||||
MaxVisPlanes += 32;
|
||||
visplanes = (visplane_t *)Realloc (visplanes, (MaxVisPlanes) * sizeof(visplane_t));
|
||||
|
||||
DPrintf ("MaxVisPlanes increased to %d\n", MaxVisPlanes);
|
||||
|
||||
PrepVisPlanes (oldMax);
|
||||
|
||||
if (visplanes == old)
|
||||
return;
|
||||
|
||||
*toupdate = &visplanes[*toupdate - old];
|
||||
lastvisplane = &visplanes[lastvisplane - old];
|
||||
if (floorplane)
|
||||
floorplane = &visplanes[floorplane - old];
|
||||
if (ceilingplane)
|
||||
ceilingplane = &visplanes[ceilingplane - old];
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -154,6 +133,7 @@ static void GetMoreVisPlanes (visplane_t **toupdate)
|
|||
// viewy
|
||||
// xoffs
|
||||
// yoffs
|
||||
// basecolormap // [RH]
|
||||
//
|
||||
// BASIC PRIMITIVE
|
||||
//
|
||||
|
@ -200,17 +180,16 @@ void R_MapPlane (int y, int x1, int x2)
|
|||
{
|
||||
index = distance >> LIGHTZSHIFT;
|
||||
|
||||
if (index >= MAXLIGHTZ )
|
||||
if (index >= MAXLIGHTZ)
|
||||
index = MAXLIGHTZ-1;
|
||||
|
||||
ds_colormap = planezlight[index];
|
||||
ds_colormap = planezlight[index] + basecolormap; // [RH] add basecolormap
|
||||
}
|
||||
|
||||
ds_y = y;
|
||||
ds_x1 = x1;
|
||||
ds_x2 = x2;
|
||||
|
||||
// high or low detail
|
||||
spanfunc ();
|
||||
}
|
||||
|
||||
|
@ -225,27 +204,47 @@ void R_ClearPlanes (void)
|
|||
angle_t angle;
|
||||
|
||||
// opening / clipping determination
|
||||
for (i=0 ; i<viewwidth ; i++)
|
||||
for (i = 0; i < viewwidth ; i++)
|
||||
{
|
||||
floorclip[i] = (short)viewheight;
|
||||
ceilingclip[i] = -1;
|
||||
}
|
||||
|
||||
lastvisplane = visplanes;
|
||||
for (i = 0; i < MAXVISPLANES; i++) // new code -- killough
|
||||
for (*freehead = visplanes[i], visplanes[i] = NULL; *freehead; )
|
||||
freehead = &(*freehead)->next;
|
||||
|
||||
lastopening = openings;
|
||||
|
||||
// texture calculation
|
||||
memset (cachedheight, 0, sizeof(fixed_t) * screens[0].height);
|
||||
memset (cachedheight, 0, sizeof(*cachedheight) * screens[0].height);
|
||||
|
||||
// left to right mapping
|
||||
angle = (viewangle-ANG90)>>ANGLETOFINESHIFT;
|
||||
angle = (viewangle - ANG90)>>ANGLETOFINESHIFT;
|
||||
|
||||
// scale will be unit scale at SCREENWIDTH/2 distance
|
||||
basexscale = FixedDiv (finecosine[angle],centerxfrac);
|
||||
baseyscale = -FixedDiv (finesine[angle],centerxfrac);
|
||||
}
|
||||
|
||||
// New function, by Lee Killough
|
||||
// [RH] top and bottom buffers get allocated immediately
|
||||
// after the visplane.
|
||||
|
||||
static visplane_t *new_visplane(unsigned hash)
|
||||
{
|
||||
visplane_t *check = freetail;
|
||||
|
||||
if (!check) {
|
||||
check = Calloc (1, sizeof(*check) + sizeof(*check->top)*(screens[0].width*2));
|
||||
check->bottom = &check->top[screens[0].width+2];
|
||||
} else
|
||||
if (!(freetail = freetail->next))
|
||||
freehead = &freetail;
|
||||
check->next = visplanes[hash];
|
||||
visplanes[hash] = check;
|
||||
return check;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
@ -257,40 +256,35 @@ visplane_t *R_FindPlane (fixed_t height, int picnum, int lightlevel,
|
|||
fixed_t xoffs, fixed_t yoffs)
|
||||
{
|
||||
visplane_t *check;
|
||||
unsigned hash; // killough
|
||||
|
||||
if (picnum == skyflatnum)
|
||||
height = lightlevel = 0; // all skys map together
|
||||
|
||||
for (check=visplanes; check<lastvisplane; check++)
|
||||
{
|
||||
if (height == check->height
|
||||
&& picnum == check->picnum
|
||||
&& lightlevel == check->lightlevel
|
||||
&& xoffs == check->xoffs
|
||||
&& yoffs == check->yoffs
|
||||
)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
// New visplane algorithm uses hash table -- killough
|
||||
hash = visplane_hash (picnum, lightlevel, height);
|
||||
|
||||
if (check < lastvisplane)
|
||||
return check;
|
||||
|
||||
if (lastvisplane - visplanes == MaxVisPlanes)
|
||||
GetMoreVisPlanes (&check);
|
||||
|
||||
lastvisplane++;
|
||||
for (check = visplanes[hash]; check; check = check->next) // killough
|
||||
if (height == check->height &&
|
||||
picnum == check->picnum &&
|
||||
lightlevel == check->lightlevel &&
|
||||
xoffs == check->xoffs && // killough 2/28/98: Add offset checks
|
||||
yoffs == check->yoffs &&
|
||||
basecolormap == check->colormap) // [RH] Add colormap check
|
||||
return check;
|
||||
|
||||
check = new_visplane (hash); // killough
|
||||
|
||||
check->height = height;
|
||||
check->picnum = picnum;
|
||||
check->lightlevel = lightlevel;
|
||||
check->xoffs = xoffs; // killough 2/28/98: Save offsets
|
||||
check->xoffs = xoffs; // killough 2/28/98: Save offsets
|
||||
check->yoffs = yoffs;
|
||||
check->colormap = basecolormap; // [RH] Save colormap
|
||||
check->minx = screens[0].width;
|
||||
check->maxx = -1;
|
||||
|
||||
memset (check->top,0xff,sizeof(short) * screens[0].width);
|
||||
memset (check->top, 0xff, sizeof(*check->top) * screens[0].width);
|
||||
|
||||
return check;
|
||||
}
|
||||
|
@ -329,37 +323,30 @@ visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop)
|
|||
intrh = stop;
|
||||
}
|
||||
|
||||
for (x=intrl ; x<= intrh ; x++)
|
||||
if (pl->top[x] != 0xffff)
|
||||
break;
|
||||
for (x=intrl ; x <= intrh && pl->top[x] == 0xffff; x++)
|
||||
;
|
||||
|
||||
if (x > intrh)
|
||||
{
|
||||
pl->minx = unionl;
|
||||
pl->maxx = unionh;
|
||||
|
||||
// use the same one
|
||||
return pl;
|
||||
}
|
||||
|
||||
// [RH] Need to make sure we actually have this lastvisplane
|
||||
if (lastvisplane - visplanes == MaxVisPlanes)
|
||||
GetMoreVisPlanes (&pl);
|
||||
else
|
||||
{
|
||||
unsigned hash = visplane_hash (pl->picnum, pl->lightlevel, pl->height);
|
||||
visplane_t *new_pl = new_visplane (hash);
|
||||
|
||||
// make a new visplane
|
||||
lastvisplane->height = pl->height;
|
||||
lastvisplane->picnum = pl->picnum;
|
||||
lastvisplane->lightlevel = pl->lightlevel;
|
||||
lastvisplane->xoffs = pl->xoffs; // killough 2/28/98
|
||||
lastvisplane->yoffs = pl->yoffs;
|
||||
|
||||
pl = lastvisplane++;
|
||||
|
||||
pl->minx = start;
|
||||
pl->maxx = stop;
|
||||
|
||||
memset (pl->top,0xff,sizeof(short) * screens[0].width);
|
||||
|
||||
new_pl->height = pl->height;
|
||||
new_pl->picnum = pl->picnum;
|
||||
new_pl->lightlevel = pl->lightlevel;
|
||||
new_pl->xoffs = pl->xoffs; // killough 2/28/98
|
||||
new_pl->yoffs = pl->yoffs;
|
||||
new_pl->colormap = pl->colormap; // [RH] Copy colormap
|
||||
pl = new_pl;
|
||||
pl->minx = start;
|
||||
pl->maxx = stop;
|
||||
memset (pl->top, 0xff, sizeof(*pl->top) * screens[0].width);
|
||||
}
|
||||
return pl;
|
||||
}
|
||||
|
||||
|
@ -369,37 +356,20 @@ visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop)
|
|||
//
|
||||
void R_MakeSpans (int x, int t1, int b1, int t2, int b2)
|
||||
{
|
||||
//if (t1 != 0xffff)
|
||||
while (t1 < t2 && t1<=b1)
|
||||
{
|
||||
R_MapPlane (t1,spanstart[t1],x-1);
|
||||
t1++;
|
||||
}
|
||||
//if (b1 != 0xffff)
|
||||
while (b1 > b2 && b1>=t1)
|
||||
{
|
||||
R_MapPlane (b1,spanstart[b1],x-1);
|
||||
b1--;
|
||||
}
|
||||
|
||||
//if (t2 != 0xffff)
|
||||
while (t2 < t1 && t2<=b2)
|
||||
{
|
||||
spanstart[t2] = x;
|
||||
t2++;
|
||||
}
|
||||
//if (b2 != 0xffff)
|
||||
while (b2 > b1 && b2>=t2)
|
||||
{
|
||||
spanstart[b2] = x;
|
||||
b2--;
|
||||
}
|
||||
for (; t1 < t2 && t1 <= b1; t1++)
|
||||
R_MapPlane(t1, spanstart[t1], x-1);
|
||||
for (; b1 > b2 && b1 >= t1; b1--)
|
||||
R_MapPlane(b1, spanstart[b1] ,x-1);
|
||||
while (t2 < t1 && t2 <= b2)
|
||||
spanstart[t2++] = x;
|
||||
while (b2 > b1 && b2 >= t2)
|
||||
spanstart[b2--] = x;
|
||||
}
|
||||
|
||||
// [RH] This was separated from R_DrawPlanes() on 11.5.1998.
|
||||
// Also added support for columns with holes since double skies
|
||||
// opens up that possibility (modified from R_DrawMaskedColumn).
|
||||
// One implication of this is that the sky will always wrap
|
||||
// One implication of this is that the sky should always wrap
|
||||
// properly, provided that it is tall enough.
|
||||
|
||||
static void R_DrawMaskedSky (int skytexture, int skypos, fixed_t scale, fixed_t height, visplane_t *pl)
|
||||
|
@ -492,77 +462,78 @@ static void R_DrawSky (int skytexture, int skypos, visplane_t *pl)
|
|||
//
|
||||
void R_DrawPlanes (void)
|
||||
{
|
||||
visplane_t* pl;
|
||||
int light;
|
||||
int x;
|
||||
int stop;
|
||||
visplane_t *pl;
|
||||
int i;
|
||||
|
||||
for (pl = visplanes ; pl < lastvisplane ; pl++)
|
||||
{
|
||||
if (pl->minx > pl->maxx)
|
||||
continue;
|
||||
|
||||
// sky flat
|
||||
if (pl->picnum == skyflatnum)
|
||||
for (i = 0; i < MAXVISPLANES; i++)
|
||||
for (pl = visplanes[i]; pl; pl = pl->next)
|
||||
{
|
||||
// Sky is allways drawn full bright,
|
||||
// i.e. colormaps[0] is used.
|
||||
// Because of this hack, sky is not affected
|
||||
// by INVUL inverse mapping.
|
||||
dc_colormap = DefaultPalette->maps.colormaps;
|
||||
if (pl->minx > pl->maxx)
|
||||
continue;
|
||||
|
||||
// sky flat
|
||||
if (pl->picnum == skyflatnum)
|
||||
{
|
||||
// Sky is allways drawn full bright,
|
||||
// i.e. colormaps[0] is used.
|
||||
// Because of this hack, sky is not affected
|
||||
// by INVUL inverse mapping.
|
||||
dc_colormap = DefaultPalette->maps.colormaps;
|
||||
|
||||
if (level.flags & LEVEL_DOUBLESKY) {
|
||||
dc_iscale = sky2iscale >> sky2stretch;
|
||||
dc_texturemid = sky2texturemid;
|
||||
if (textureheight[sky2texture] == (128<<FRACBITS))
|
||||
R_DrawSky (sky2texture, sky2pos, pl);
|
||||
if (level.flags & LEVEL_DOUBLESKY) {
|
||||
dc_iscale = sky2iscale >> sky2stretch;
|
||||
dc_texturemid = sky2texturemid;
|
||||
if (textureheight[sky2texture] == (128<<FRACBITS))
|
||||
R_DrawSky (sky2texture, sky2pos, pl);
|
||||
else
|
||||
R_DrawMaskedSky (sky2texture, sky2pos, sky2scale, sky2height, pl);
|
||||
}
|
||||
|
||||
dc_iscale = sky1iscale >> sky1stretch;
|
||||
dc_texturemid = sky1texturemid;
|
||||
if ((level.flags & LEVEL_DOUBLESKY) || (textureheight[sky1texture] != (128<<FRACBITS)))
|
||||
R_DrawMaskedSky (sky1texture, sky1pos, sky1scale, sky1height, pl);
|
||||
else
|
||||
R_DrawMaskedSky (sky2texture, sky2pos, sky2scale, sky2height, pl);
|
||||
R_DrawSky (sky1texture, sky1pos, pl);
|
||||
}
|
||||
|
||||
dc_iscale = sky1iscale >> sky1stretch;
|
||||
dc_texturemid = sky1texturemid;
|
||||
if ((level.flags & LEVEL_DOUBLESKY) || (textureheight[sky1texture] != (128<<FRACBITS)))
|
||||
R_DrawMaskedSky (sky1texture, sky1pos, sky1scale, sky1height, pl);
|
||||
else
|
||||
R_DrawSky (sky1texture, sky1pos, pl);
|
||||
{
|
||||
// regular flat
|
||||
int light, stop, x;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// regular flat
|
||||
ds_source = W_CacheLumpNum(firstflat +
|
||||
flattranslation[pl->picnum],
|
||||
PU_STATIC);
|
||||
|
||||
xoffs = pl->xoffs; // killough 2/28/98: Add offsets
|
||||
yoffs = pl->yoffs;
|
||||
planeheight = abs(pl->height-viewz);
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT)+extralight;
|
||||
|
||||
if (light >= LIGHTLEVELS)
|
||||
light = LIGHTLEVELS-1;
|
||||
|
||||
if (light < 0)
|
||||
light = 0;
|
||||
|
||||
planezlight = zlight[light];
|
||||
|
||||
pl->top[pl->maxx+1] = 0xffff;
|
||||
pl->top[pl->minx-1] = 0xffff;
|
||||
ds_source = W_CacheLumpNum(firstflat +
|
||||
flattranslation[pl->picnum],
|
||||
PU_STATIC);
|
||||
|
||||
stop = pl->maxx + 1;
|
||||
xoffs = pl->xoffs; // killough 2/28/98: Add offsets
|
||||
yoffs = pl->yoffs;
|
||||
basecolormap = pl->colormap; // [RH] set basecolormap
|
||||
planeheight = abs(pl->height-viewz);
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT) + extralight;
|
||||
|
||||
for (x=pl->minx ; x<= stop ; x++)
|
||||
{
|
||||
R_MakeSpans(x,pl->top[x-1],
|
||||
pl->bottom[x-1],
|
||||
pl->top[x],
|
||||
pl->bottom[x]);
|
||||
if (light >= LIGHTLEVELS)
|
||||
light = LIGHTLEVELS-1;
|
||||
else if (light < 0)
|
||||
light = 0;
|
||||
|
||||
planezlight = zlight[light];
|
||||
|
||||
pl->top[pl->maxx+1] = 0xffff;
|
||||
pl->top[pl->minx-1] = 0xffff;
|
||||
|
||||
stop = pl->maxx + 1;
|
||||
|
||||
for (x = pl->minx; x <= stop; x++)
|
||||
{
|
||||
R_MakeSpans(x,pl->top[x-1],
|
||||
pl->bottom[x-1],
|
||||
pl->top[x],
|
||||
pl->bottom[x]);
|
||||
}
|
||||
|
||||
Z_ChangeTag (ds_source, PU_CACHE);
|
||||
}
|
||||
}
|
||||
|
||||
Z_ChangeTag (ds_source, PU_CACHE);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL R_PlaneInitData (void)
|
||||
|
@ -577,26 +548,41 @@ BOOL R_PlaneInitData (void)
|
|||
if (cachedxstep) free (cachedxstep);
|
||||
if (cachedystep) free (cachedystep);
|
||||
|
||||
floorclip = Calloc (screens[0].width, sizeof(short));
|
||||
ceilingclip = Calloc (screens[0].width, sizeof(short));
|
||||
floorclip = Calloc (screens[0].width, sizeof(*floorclip));
|
||||
ceilingclip = Calloc (screens[0].width, sizeof(*ceilingclip));
|
||||
|
||||
spanstart = Calloc (screens[0].height, sizeof(int));
|
||||
spanstop = Calloc (screens[0].height, sizeof(int));
|
||||
spanstart = Calloc (screens[0].height, sizeof(*spanstart));
|
||||
spanstop = Calloc (screens[0].height, sizeof(*spanstop));
|
||||
|
||||
yslopetab = Calloc ((screens[0].height<<1)+(screens[0].height>>1), sizeof(fixed_t));
|
||||
distscale = Calloc (screens[0].width, sizeof(fixed_t));
|
||||
cachedheight = Calloc (screens[0].height, sizeof(fixed_t));
|
||||
cacheddistance = Calloc (screens[0].height, sizeof(fixed_t));
|
||||
cachedxstep = Calloc (screens[0].height, sizeof(fixed_t));
|
||||
cachedystep = Calloc (screens[0].height, sizeof(fixed_t));
|
||||
yslopetab = Calloc ((screens[0].height<<1)+(screens[0].height>>1), sizeof(*yslopetab));
|
||||
distscale = Calloc (screens[0].width, sizeof(*distscale));
|
||||
cachedheight = Calloc (screens[0].height, sizeof(*cachedheight));
|
||||
cacheddistance = Calloc (screens[0].height, sizeof(*cacheddistance));
|
||||
cachedxstep = Calloc (screens[0].height, sizeof(*cachedxstep));
|
||||
cachedystep = Calloc (screens[0].height, sizeof(*cachedystep));
|
||||
|
||||
if (visplanes) {
|
||||
// Free all visplanes and let them be re-allocated as needed.
|
||||
{
|
||||
int i;
|
||||
visplane_t *pl = freetail;
|
||||
|
||||
for (i = 0; i < MaxVisPlanes; i++)
|
||||
free (visplanes[i].top - 1);
|
||||
while (pl) {
|
||||
visplane_t *next = pl->next;
|
||||
free (pl);
|
||||
pl = next;
|
||||
}
|
||||
freetail = NULL;
|
||||
freehead = &freetail;
|
||||
|
||||
PrepVisPlanes (0);
|
||||
for (i = 0; i < MAXVISPLANES; i++) {
|
||||
pl = visplanes[i];
|
||||
visplanes[i] = NULL;
|
||||
while (pl) {
|
||||
visplane_t *next = pl->next;
|
||||
free (pl);
|
||||
pl = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -68,7 +68,7 @@ R_FindPlane
|
|||
int picnum,
|
||||
int lightlevel,
|
||||
fixed_t xoffs, // killough 2/28/98: add x-y offsets
|
||||
fixed_t yoffs);
|
||||
fixed_t yoffs );
|
||||
|
||||
visplane_t*
|
||||
R_CheckPlane
|
||||
|
|
118
code/R_segs.c
118
code/R_segs.c
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "m_alloc.h"
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "i_system.h"
|
||||
|
||||
|
@ -54,7 +55,7 @@ static int midtexture;
|
|||
angle_t rw_normalangle; // angle to line origin
|
||||
int rw_angle1;
|
||||
fixed_t rw_distance;
|
||||
lighttable_t** walllights;
|
||||
int* walllights; // [RH] Changed from lighttable_t** to int*
|
||||
|
||||
//
|
||||
// regular wall
|
||||
|
@ -104,11 +105,24 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
|||
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
|
||||
curline = ds->curline;
|
||||
|
||||
// killough 4/11/98: draw translucent 2s normal textures
|
||||
// [RH] modified because we don't use user-definable
|
||||
// translucency maps
|
||||
colfunc = basecolfunc;
|
||||
if (curline->linedef->lucency < 240)
|
||||
{
|
||||
colfunc = lucentcolfunc;
|
||||
dc_transmap = TransTable + ((curline->linedef->lucency << 10) & 0x30000);
|
||||
}
|
||||
// killough 4/11/98: end translucent 2s normal code
|
||||
|
||||
frontsector = curline->frontsector;
|
||||
backsector = curline->backsector;
|
||||
|
||||
texnum = texturetranslation[curline->sidedef->midtexture];
|
||||
|
||||
|
||||
basecolormap = frontsector->colormap->maps; // [RH] Set basecolormap
|
||||
|
||||
// killough 4/13/98: get correct lightlevel for 2s normal textures
|
||||
lightnum = (R_FakeFlat(frontsector, &tempsec, NULL, NULL, false)
|
||||
->lightlevel >> LIGHTSEGSHIFT)+extralight;
|
||||
|
@ -154,12 +168,12 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
|||
// calculate lighting
|
||||
if (!fixedcolormap)
|
||||
{
|
||||
unsigned index = spryscale>>LIGHTSCALESHIFT;
|
||||
unsigned index = (spryscale*lightscalexmul)>>LIGHTSCALESHIFT; // [RH]
|
||||
|
||||
if (index >= MAXLIGHTSCALE)
|
||||
index = MAXLIGHTSCALE-1;
|
||||
|
||||
dc_colormap = walllights[index];
|
||||
dc_colormap = walllights[index] + basecolormap; // [RH] add basecolormap
|
||||
}
|
||||
|
||||
// killough 3/2/98:
|
||||
|
@ -175,7 +189,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
|||
{
|
||||
__int64 t = ((__int64) centeryfrac << FRACBITS) -
|
||||
(__int64) dc_texturemid * spryscale;
|
||||
// [RH] This doesn't work properly as-is with freelook
|
||||
// [RH] This doesn't work properly as-is with freelook. Probably just me.
|
||||
// if (t + (__int64) textureheight[texnum] * spryscale < 0 ||
|
||||
// t > (__int64) screens[0].height << FRACBITS*2)
|
||||
// continue; // skip if the texture is out of screen's range
|
||||
|
@ -219,17 +233,13 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
|||
|
||||
void R_RenderSegLoop (void)
|
||||
{
|
||||
angle_t angle;
|
||||
unsigned index;
|
||||
int yl;
|
||||
int yh;
|
||||
int mid;
|
||||
fixed_t texturecolumn;
|
||||
int top;
|
||||
int bottom;
|
||||
int yl;
|
||||
int yh;
|
||||
fixed_t texturecolumn;
|
||||
|
||||
if (fixedcolormap)
|
||||
dc_colormap = fixedcolormap;
|
||||
|
||||
//texturecolumn = 0; // shut up compiler warning
|
||||
|
||||
for ( ; rw_x < rw_stopx ; rw_x++)
|
||||
{
|
||||
// mark floor / ceiling areas
|
||||
|
@ -241,8 +251,8 @@ void R_RenderSegLoop (void)
|
|||
|
||||
if (markceiling)
|
||||
{
|
||||
top = ceilingclip[rw_x]+1;
|
||||
bottom = yl-1;
|
||||
int top = ceilingclip[rw_x]+1;
|
||||
int bottom = yl-1;
|
||||
|
||||
if (bottom >= floorclip[rw_x])
|
||||
bottom = floorclip[rw_x]-1;
|
||||
|
@ -261,8 +271,8 @@ void R_RenderSegLoop (void)
|
|||
|
||||
if (markfloor)
|
||||
{
|
||||
top = yh+1;
|
||||
bottom = floorclip[rw_x]-1;
|
||||
int top = yh+1;
|
||||
int bottom = floorclip[rw_x]-1;
|
||||
if (top <= ceilingclip[rw_x])
|
||||
top = ceilingclip[rw_x]+1;
|
||||
if (top <= bottom)
|
||||
|
@ -276,16 +286,19 @@ void R_RenderSegLoop (void)
|
|||
if (segtextured)
|
||||
{
|
||||
// calculate texture offset
|
||||
angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
|
||||
texturecolumn = rw_offset-FixedMul(finetangent[angle],rw_distance);
|
||||
texturecolumn = rw_offset-FixedMul(finetangent[(rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT],rw_distance);
|
||||
texturecolumn >>= FRACBITS;
|
||||
// calculate lighting
|
||||
index = rw_scale>>LIGHTSCALESHIFT;
|
||||
|
||||
if (index >= MAXLIGHTSCALE )
|
||||
index = MAXLIGHTSCALE-1;
|
||||
if (!fixedcolormap) {
|
||||
// calculate lighting
|
||||
unsigned index = (rw_scale*lightscalexmul)>>LIGHTSCALESHIFT;
|
||||
|
||||
if (index >= MAXLIGHTSCALE)
|
||||
index = MAXLIGHTSCALE-1;
|
||||
|
||||
dc_colormap = walllights[index] + basecolormap; // [RH] add basecolormap
|
||||
}
|
||||
|
||||
dc_colormap = walllights[index];
|
||||
dc_x = rw_x;
|
||||
dc_iscale = 0xffffffffu / (unsigned)rw_scale;
|
||||
}
|
||||
|
@ -308,7 +321,7 @@ void R_RenderSegLoop (void)
|
|||
if (toptexture)
|
||||
{
|
||||
// top wall
|
||||
mid = pixhigh>>HEIGHTBITS;
|
||||
int mid = pixhigh>>HEIGHTBITS;
|
||||
pixhigh += pixhighstep;
|
||||
|
||||
if (mid >= floorclip[rw_x])
|
||||
|
@ -336,7 +349,7 @@ void R_RenderSegLoop (void)
|
|||
if (bottomtexture)
|
||||
{
|
||||
// bottom wall
|
||||
mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS;
|
||||
int mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS;
|
||||
pixlow += pixlowstep;
|
||||
|
||||
// no space above wall?
|
||||
|
@ -411,7 +424,7 @@ void R_StoreWallRange (int start, int stop)
|
|||
angle_t distangle, offsetangle;
|
||||
fixed_t vtop;
|
||||
int lightnum;
|
||||
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (start >=viewwidth || start > stop)
|
||||
I_Error ("Bad R_RenderWallRange: %i to %i", start , stop);
|
||||
|
@ -419,11 +432,11 @@ void R_StoreWallRange (int start, int stop)
|
|||
|
||||
// don't overflow and crash
|
||||
if (ds_p == &drawsegs[MaxDrawSegs]) {
|
||||
unsigned pos = ds_p - drawsegs;
|
||||
// [RH] Grab some more drawsegs
|
||||
MaxDrawSegs = MaxDrawSegs ? MaxDrawSegs*2 : 32;
|
||||
drawsegs = Realloc (drawsegs, MaxDrawSegs * sizeof(drawseg_t));
|
||||
ds_p = drawsegs + pos;
|
||||
size_t newdrawsegs = MaxDrawSegs ? MaxDrawSegs*2 : 32;
|
||||
drawsegs = Realloc (drawsegs, newdrawsegs * sizeof(drawseg_t));
|
||||
ds_p = drawsegs + MaxDrawSegs;
|
||||
MaxDrawSegs = newdrawsegs;
|
||||
DPrintf ("MaxDrawSegs increased to %d\n", MaxDrawSegs);
|
||||
}
|
||||
|
||||
|
@ -441,18 +454,18 @@ void R_StoreWallRange (int start, int stop)
|
|||
offsetangle = ANG90;
|
||||
|
||||
distangle = ANG90 - offsetangle;
|
||||
hyp = R_PointToDist (curline->v1->x, curline->v1->y);
|
||||
hyp = (viewx == curline->v1->x && viewy == curline->v1->y) ?
|
||||
0 : R_PointToDist (curline->v1->x, curline->v1->y);
|
||||
sineval = finesine[distangle>>ANGLETOFINESHIFT];
|
||||
rw_distance = FixedMul (hyp, sineval);
|
||||
|
||||
|
||||
|
||||
ds_p->x1 = rw_x = start;
|
||||
ds_p->x2 = stop;
|
||||
ds_p->curline = curline;
|
||||
rw_stopx = stop+1;
|
||||
|
||||
|
||||
{ // killough 1/6/98, 2/1/98: remove limit on openings
|
||||
size_t pos = lastopening - openings;
|
||||
ptrdiff_t pos = lastopening - openings;
|
||||
size_t need = (rw_stopx - start)*4 + pos;
|
||||
|
||||
if (need > maxopenings)
|
||||
|
@ -464,7 +477,7 @@ void R_StoreWallRange (int start, int stop)
|
|||
do
|
||||
maxopenings = maxopenings ? maxopenings*2 : 16384;
|
||||
while (need > maxopenings);
|
||||
openings = Realloc(openings, maxopenings * sizeof(*openings));
|
||||
openings = Realloc (openings, maxopenings * sizeof(*openings));
|
||||
lastopening = openings + pos;
|
||||
DPrintf ("MaxOpenings increased to %u\n", maxopenings);
|
||||
|
||||
|
@ -485,7 +498,7 @@ void R_StoreWallRange (int start, int stop)
|
|||
ds_p->scale1 = rw_scale =
|
||||
R_ScaleFromGlobalAngle (viewangle + xtoviewangle[start]);
|
||||
|
||||
if (stop > start )
|
||||
if (stop > start)
|
||||
{
|
||||
ds_p->scale2 = R_ScaleFromGlobalAngle (viewangle + xtoviewangle[stop]);
|
||||
ds_p->scalestep = rw_scalestep =
|
||||
|
@ -612,16 +625,14 @@ void R_StoreWallRange (int start, int stop)
|
|||
worldlow = backsector->floorheight - viewz;
|
||||
|
||||
// hack to allow height changes in outdoor areas
|
||||
if (frontsector->ceilingpic == skyflatnum
|
||||
&& backsector->ceilingpic == skyflatnum)
|
||||
if (frontsector->ceilingpic == skyflatnum && backsector->ceilingpic == skyflatnum)
|
||||
{
|
||||
worldtop = worldhigh;
|
||||
}
|
||||
|
||||
|
||||
|
||||
markfloor = worldlow != worldbottom
|
||||
|| backsector->floorpic != frontsector->floorpic
|
||||
|| backsector->lightlevel != frontsector->lightlevel
|
||||
|| backsector->floorpic != frontsector->floorpic
|
||||
|
||||
// killough 3/7/98: Add checks for (x,y) offsets
|
||||
|| backsector->floor_xoffs != frontsector->floor_xoffs
|
||||
|
@ -633,11 +644,14 @@ void R_StoreWallRange (int start, int stop)
|
|||
|
||||
// killough 4/17/98: draw floors if different light levels
|
||||
|| backsector->floorlightsec != frontsector->floorlightsec
|
||||
|
||||
// [RH] Add checks for colormaps
|
||||
|| backsector->colormap != frontsector->colormap
|
||||
;
|
||||
|
||||
markceiling = worldhigh != worldtop
|
||||
|| backsector->ceilingpic != frontsector->ceilingpic
|
||||
|| backsector->lightlevel != frontsector->lightlevel
|
||||
|| backsector->ceilingpic != frontsector->ceilingpic
|
||||
|
||||
// killough 3/7/98: Add checks for (x,y) offsets
|
||||
|| backsector->ceiling_xoffs != frontsector->ceiling_xoffs
|
||||
|
@ -650,6 +664,9 @@ void R_StoreWallRange (int start, int stop)
|
|||
|
||||
// killough 4/17/98: draw ceilings if different light levels
|
||||
|| backsector->ceilinglightsec != frontsector->ceilinglightsec
|
||||
|
||||
// [RH] Add check for colormaps
|
||||
|| backsector->colormap != frontsector->colormap
|
||||
;
|
||||
|
||||
if (backsector->ceilingheight <= frontsector->floorheight
|
||||
|
@ -773,8 +790,7 @@ void R_StoreWallRange (int start, int stop)
|
|||
// if a floor / ceiling plane is on the wrong side
|
||||
// of the view plane, it is definitely invisible
|
||||
// and doesn't need to be marked.
|
||||
|
||||
|
||||
|
||||
// killough 3/7/98: add deep water check
|
||||
if (frontsector->heightsec == -1)
|
||||
{
|
||||
|
@ -814,17 +830,19 @@ void R_StoreWallRange (int start, int stop)
|
|||
}
|
||||
|
||||
// render it
|
||||
if (markceiling)
|
||||
if (markceiling) {
|
||||
if (ceilingplane) // killough 4/11/98: add NULL ptr checks
|
||||
ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1);
|
||||
else
|
||||
markceiling = 0;
|
||||
}
|
||||
|
||||
if (markfloor)
|
||||
if (markfloor) {
|
||||
if (floorplane) // killough 4/11/98: add NULL ptr checks
|
||||
floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1);
|
||||
else
|
||||
markfloor = 0;
|
||||
}
|
||||
|
||||
R_RenderSegLoop ();
|
||||
|
||||
|
|
19
code/R_sky.c
19
code/R_sky.c
|
@ -74,7 +74,7 @@ void R_InitSkyMap (cvar_t *var)
|
|||
sky1texturemid = 200/2*FRACUNIT;
|
||||
sky1stretch = (var->value && !(dmflags & DF_NO_FREELOOK)) ? 1 : 0;
|
||||
} else {
|
||||
sky1texturemid = 240/2*FRACUNIT;
|
||||
sky1texturemid = 200*FRACUNIT;
|
||||
sky1stretch = 0;
|
||||
}
|
||||
sky1height = textureheight[sky1texture] << sky1stretch;
|
||||
|
@ -83,18 +83,19 @@ void R_InitSkyMap (cvar_t *var)
|
|||
sky2texturemid = 200/2*FRACUNIT;
|
||||
sky2stretch = (var->value && !(dmflags & DF_NO_FREELOOK)) ? 1 : 0;
|
||||
} else {
|
||||
sky2texturemid = 240/2*FRACUNIT;
|
||||
sky2texturemid = 200*FRACUNIT;
|
||||
sky2stretch = 0;
|
||||
}
|
||||
sky2height = textureheight[sky2texture] << sky2stretch;
|
||||
if (viewwidth && viewheight) {
|
||||
sky1iscale = (sky1texturemid << 1) / (((freelookviewheight<<detailxshift) * viewwidth) / (viewwidth<<detailxshift));
|
||||
sky1scale = ((((freelookviewheight<<detailxshift) * viewwidth) / (viewwidth<<detailxshift)) << FRACBITS) /
|
||||
(sky1texturemid>>(FRACBITS-1));
|
||||
|
||||
sky2iscale = (sky2texturemid << FRACBITS) / (((viewheight<<detailxshift) * viewwidth) / (viewwidth<<detailxshift));
|
||||
sky2scale = ((((viewheight<<detailxshift) * viewwidth) / (viewwidth<<detailxshift)) << FRACBITS) /
|
||||
(sky2texturemid>>(FRACBITS-1));
|
||||
if (viewwidth && viewheight) {
|
||||
sky1iscale = (200*FRACUNIT) / (((freelookviewheight<<detailxshift) * viewwidth) / (viewwidth<<detailxshift));
|
||||
sky1scale = ((((freelookviewheight<<detailxshift) * viewwidth) / (viewwidth<<detailxshift)) << FRACBITS) /
|
||||
(200);
|
||||
|
||||
sky2iscale = (200*FRACUNIT) / (((viewheight<<detailxshift) * viewwidth) / (viewwidth<<detailxshift));
|
||||
sky2scale = ((((freelookviewheight<<detailxshift) * viewwidth) / (viewwidth<<detailxshift)) << FRACBITS) /
|
||||
(200);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
562
code/R_things.c
562
code/R_things.c
|
@ -46,6 +46,9 @@
|
|||
|
||||
#include "v_video.h"
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "s_sound.h"
|
||||
|
||||
|
||||
|
||||
#define MINZ (FRACUNIT*4)
|
||||
|
@ -58,19 +61,6 @@ cvar_t *crosshair;
|
|||
cvar_t *r_drawfuzz;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x1;
|
||||
int x2;
|
||||
|
||||
int column;
|
||||
int topclip;
|
||||
int bottomclip;
|
||||
|
||||
} maskdraw_t;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Sprite rotation 0 is facing the viewer,
|
||||
// rotation 1 is one angle turn CLOCKWISE around the axis.
|
||||
|
@ -80,11 +70,11 @@ typedef struct
|
|||
//
|
||||
fixed_t pspritescale;
|
||||
fixed_t pspriteiscale;
|
||||
fixed_t pspriteyscale; // [RH] Aspect ratio handling (from doom3)
|
||||
fixed_t pspriteyscale; // [RH] Aspect ratio handling (from doom legacy)
|
||||
fixed_t sky1scale; // [RH] Sky 1 scale factor
|
||||
fixed_t sky2scale; // [RH] Sky 2 scale factor
|
||||
|
||||
lighttable_t** spritelights;
|
||||
int* spritelights; // [RH] Changed from lighttable_t** to int*
|
||||
|
||||
// constant arrays
|
||||
// used for psprite clipping and initializing clipping
|
||||
|
@ -109,6 +99,9 @@ spriteframe_t sprtemp[MAX_SPRITE_FRAMES];
|
|||
int maxframe;
|
||||
char* spritename;
|
||||
|
||||
// [RH] skin globals
|
||||
playerskin_t *skins;
|
||||
size_t numskins;
|
||||
|
||||
|
||||
//
|
||||
|
@ -118,11 +111,20 @@ char* spritename;
|
|||
// [RH] Removed checks for coexistance of rotation 0 with other
|
||||
// rotations and made it look more like BOOM's version.
|
||||
//
|
||||
void R_InstallSpriteLump (int lump, unsigned frame, unsigned rotation, BOOL flipped)
|
||||
static void R_InstallSpriteLump (int lump, unsigned frame, unsigned rotation, BOOL flipped)
|
||||
{
|
||||
// [RH] Record the sprite's width, offset, and topoffset here
|
||||
// instead of in R_InitSpriteLumps().
|
||||
patch_t *patch;
|
||||
|
||||
if (frame >= MAX_SPRITE_FRAMES || rotation > 8)
|
||||
I_Error("R_InstallSpriteLump: Bad frame characters in lump %i", lump);
|
||||
|
||||
I_FatalError ("R_InstallSpriteLump: Bad frame characters in lump %i", lump);
|
||||
|
||||
patch = W_CacheLumpNum (lump, PU_CACHE);
|
||||
|
||||
if (!(lump & 127))
|
||||
Printf ("."); // [RH] Print ticker
|
||||
|
||||
if ((int)frame > maxframe)
|
||||
maxframe = frame;
|
||||
|
||||
|
@ -134,19 +136,78 @@ void R_InstallSpriteLump (int lump, unsigned frame, unsigned rotation, BOOL flip
|
|||
|
||||
for (r = 7; r >= 0; r--)
|
||||
if (sprtemp[frame].lump[r] == -1) {
|
||||
sprtemp[frame].lump[r] = (short)(lump - firstspritelump);
|
||||
sprtemp[frame].lump[r] = (short)(lump);
|
||||
sprtemp[frame].flip[r] = (byte)flipped;
|
||||
sprtemp[frame].rotate = false;
|
||||
|
||||
// [RH] Need to set these, too.
|
||||
sprtemp[frame].width[r] = SHORT(patch->width)<<FRACBITS;
|
||||
sprtemp[frame].offset[r] = SHORT(patch->leftoffset)<<FRACBITS;
|
||||
sprtemp[frame].topoffset[r] = SHORT(patch->topoffset)<<FRACBITS;
|
||||
}
|
||||
} else if (sprtemp[frame].lump[--rotation] == -1) {
|
||||
// the lump is only used for one rotation
|
||||
sprtemp[frame].lump[rotation] = (short)(lump - firstspritelump);
|
||||
sprtemp[frame].lump[rotation] = (short)(lump);
|
||||
sprtemp[frame].flip[rotation] = (byte)flipped;
|
||||
sprtemp[frame].rotate = true;
|
||||
|
||||
// [RH] Need to set these, too.
|
||||
sprtemp[frame].width[rotation] = SHORT(patch->width)<<FRACBITS;
|
||||
sprtemp[frame].offset[rotation] = SHORT(patch->leftoffset)<<FRACBITS;
|
||||
sprtemp[frame].topoffset[rotation] = SHORT(patch->topoffset)<<FRACBITS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// [RH] Seperated out of R_InitSpriteDefs()
|
||||
static void R_InstallSprite (const char *name, int num)
|
||||
{
|
||||
char sprname[5];
|
||||
int frame;
|
||||
|
||||
if (maxframe == -1) {
|
||||
sprites[num].numframes = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
strncpy (sprname, name, 4);
|
||||
sprname[4] = 0;
|
||||
|
||||
maxframe++;
|
||||
|
||||
for (frame = 0 ; frame < maxframe ; frame++)
|
||||
{
|
||||
switch ((int)sprtemp[frame].rotate)
|
||||
{
|
||||
case -1:
|
||||
// no rotations were found for that frame at all
|
||||
I_FatalError ("R_InstallSprite: No patches found for %s frame %c", sprname, frame+'A');
|
||||
break;
|
||||
|
||||
case 0:
|
||||
// only the first rotation is needed
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// must have all 8 frames
|
||||
{
|
||||
int rotation;
|
||||
|
||||
for (rotation = 0; rotation < 8; rotation++)
|
||||
if (sprtemp[frame].lump[rotation] == -1)
|
||||
I_FatalError ("R_InstallSprite: Sprite %s frame %c is missing rotations",
|
||||
sprname, frame+'A');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// allocate space for the frames present and copy sprtemp to it
|
||||
sprites[num].numframes = maxframe;
|
||||
sprites[num].spriteframes =
|
||||
Z_Malloc (maxframe * sizeof(spriteframe_t), PU_STATIC, NULL);
|
||||
memcpy (sprites[num].spriteframes, sprtemp, maxframe * sizeof(spriteframe_t));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
@ -164,21 +225,25 @@ void R_InstallSpriteLump (int lump, unsigned frame, unsigned rotation, BOOL flip
|
|||
// letter/number appended.
|
||||
// The rotation character can be 0 to signify no rotations.
|
||||
//
|
||||
void R_InitSpriteDefs (char** namelist)
|
||||
void R_InitSpriteDefs (char **namelist)
|
||||
{
|
||||
int i;
|
||||
int l;
|
||||
int intname;
|
||||
int start;
|
||||
int end;
|
||||
int i;
|
||||
int l;
|
||||
int intname;
|
||||
int start;
|
||||
int end;
|
||||
int realsprites;
|
||||
|
||||
// count the number of sprite names
|
||||
for (numsprites = 0; namelist[numsprites]; numsprites++)
|
||||
;
|
||||
// [RH] include skins in the count
|
||||
realsprites = numsprites;
|
||||
numsprites += numskins - 1;
|
||||
|
||||
if (!numsprites)
|
||||
return;
|
||||
|
||||
|
||||
sprites = Z_Malloc (numsprites * sizeof(*sprites), PU_STATIC, NULL);
|
||||
|
||||
start = firstspritelump - 1;
|
||||
|
@ -187,7 +252,7 @@ void R_InitSpriteDefs (char** namelist)
|
|||
// scan all the lump names for each of the names,
|
||||
// noting the highest frame letter.
|
||||
// Just compare 4 characters as ints
|
||||
for (i = 0; i < numsprites; i++)
|
||||
for (i = 0; i < realsprites; i++)
|
||||
{
|
||||
spritename = namelist[i];
|
||||
memset (sprtemp, -1, sizeof(sprtemp));
|
||||
|
@ -214,59 +279,213 @@ void R_InitSpriteDefs (char** namelist)
|
|||
}
|
||||
}
|
||||
|
||||
// check the frames that were found for completeness
|
||||
if (maxframe == -1)
|
||||
{
|
||||
sprites[i].numframes = 0;
|
||||
R_InstallSprite (namelist[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
// [RH]
|
||||
// R_InitSkins
|
||||
// Reads in everything applicable to a skin. The skins should have already
|
||||
// been counted and had their identifiers assigned to namespaces.
|
||||
//
|
||||
static const char *skinsoundnames[8][2] = {
|
||||
"dsplpain", NULL,
|
||||
"dspldeth", NULL,
|
||||
"dspdiehi", "xdeath1",
|
||||
"dsoof", "land1",
|
||||
"dsnoway", "grunt1",
|
||||
"dsslop", "gibbed",
|
||||
"dspunch", "fist",
|
||||
"dsjump", "jump1",
|
||||
};
|
||||
|
||||
static char facenames[7][8] = {
|
||||
"xxxTR", "xxxTL", "xxxOUCH", "xxxEVL", "xxxKILL", "xxxGOD0", "xxxDEAD0"
|
||||
};
|
||||
static const int facelens[7] = {
|
||||
5, 5, 7, 6, 7, 7, 8
|
||||
};
|
||||
|
||||
void R_InitSkins (void)
|
||||
{
|
||||
char sndname[128];
|
||||
int sndlumps[8];
|
||||
char key[10];
|
||||
int intname;
|
||||
size_t i;
|
||||
int j, k, base;
|
||||
int stop;
|
||||
char *def;
|
||||
|
||||
key[9] = 0;
|
||||
|
||||
for (i = 1; i < numskins; i++) {
|
||||
for (j = 0; j < 8; j++)
|
||||
sndlumps[j] = -1;
|
||||
base = (W_CheckNumForName) ("S_SKIN", skins[i].namespc);
|
||||
// The player sprite has 23 frames. This means that the S_SKIN
|
||||
// marker needs a minimum of 23 lumps after it (probably more).
|
||||
if (base >= numlumps - 23 || base == -1)
|
||||
continue;
|
||||
}
|
||||
|
||||
maxframe++;
|
||||
|
||||
{
|
||||
int frame;
|
||||
def = W_CacheLumpNum (base, PU_CACHE);
|
||||
intname = 0;
|
||||
|
||||
for (frame = 0 ; frame < maxframe ; frame++)
|
||||
{
|
||||
switch ((int)sprtemp[frame].rotate)
|
||||
{
|
||||
case -1:
|
||||
// no rotations were found for that frame at all
|
||||
I_Error ("R_InitSprites: No patches found "
|
||||
"for %s frame %c", namelist[i], frame+'A');
|
||||
break;
|
||||
|
||||
case 0:
|
||||
// only the first rotation is needed
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// must have all 8 frames
|
||||
{
|
||||
int rotation;
|
||||
|
||||
for (rotation=0 ; rotation<8 ; rotation++)
|
||||
if (sprtemp[frame].lump[rotation] == -1)
|
||||
I_Error ("R_InitSprites: Sprite %s frame %c "
|
||||
"is missing rotations",
|
||||
namelist[i], frame+'A');
|
||||
// Data is stored as "key = data". Don't see why the =
|
||||
// is necessary, but that's the way the Doom Legacy
|
||||
// guys decided to do it.
|
||||
while (def = COM_Parse (def)) {
|
||||
strncpy (key, com_token, 9);
|
||||
def = COM_Parse (def);
|
||||
if (com_token[0] != '=') {
|
||||
Printf ("Bad format for skin %d: %s %s", i, key, com_token);
|
||||
break;
|
||||
}
|
||||
def = COM_Parse (def);
|
||||
if (!stricmp (key, "name")) {
|
||||
strncpy (skins[i].name, com_token, 16);
|
||||
} else if (!stricmp (key, "sprite")) {
|
||||
for (j = 3; j >= 0; j--)
|
||||
com_token[j] = toupper (com_token[j]);
|
||||
intname = *((int *)com_token);
|
||||
} else if (!stricmp (key, "face")) {
|
||||
for (j = 2; j >= 0; j--)
|
||||
skins[i].face[j] = toupper (com_token[j]);
|
||||
} else {
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (!stricmp (key, skinsoundnames[j][0])) {
|
||||
// Can't use W_CheckNumForName because skin sounds
|
||||
// haven't been assigned a namespace yet.
|
||||
for (k = base + 1; k < numlumps &&
|
||||
lumpinfo[k].handle == lumpinfo[base].handle; k++) {
|
||||
if (!strnicmp (com_token, lumpinfo[k].name, 8)) {
|
||||
W_SetLumpNamespace (k, skins[i].namespc);
|
||||
sndlumps[j] = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sndlumps[j] == -1) {
|
||||
// Replacement not found, try finding it in the global namespace
|
||||
sndlumps[j] = S_FindSoundByLump (W_CheckNumForName (com_token));
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
//if (j == 8)
|
||||
// Printf ("Funny info for skin %i: %s = %s\n", i, key, com_token);
|
||||
}
|
||||
}
|
||||
|
||||
if (skins[i].name[0] == 0)
|
||||
sprintf (skins[i].name, "skin%i", i);
|
||||
|
||||
// Register any sounds this skin provides
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (sndlumps[j] != -1) {
|
||||
if (j > 1) {
|
||||
sprintf (sndname, "player/%s/%s", skins[i].name, skinsoundnames[j][1]);
|
||||
S_AddSoundLump (sndname, sndlumps[j]);
|
||||
} else if (j == 1) {
|
||||
int r;
|
||||
|
||||
for (r = 1; r <= 4; r++) {
|
||||
sprintf (sndname, "player/%s/death%d", skins[i].name, r);
|
||||
S_AddSoundLump (sndname, sndlumps[j]);
|
||||
}
|
||||
} else { // j == 0
|
||||
int l, r;
|
||||
|
||||
for (l = 1; l <= 4; l++)
|
||||
for (r = 1; r <= 2; r++) {
|
||||
sprintf (sndname, "player/%s/pain%d_%d", skins[i].name, l*25, r);
|
||||
S_AddSoundLump (sndname, sndlumps[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// allocate space for the frames present and copy sprtemp to it
|
||||
sprites[i].numframes = maxframe;
|
||||
sprites[i].spriteframes =
|
||||
Z_Malloc (maxframe * sizeof(spriteframe_t), PU_STATIC, NULL);
|
||||
memcpy (sprites[i].spriteframes, sprtemp, maxframe*sizeof(spriteframe_t));
|
||||
}
|
||||
|
||||
// Now collect the sprite frames for this skin. If the sprite name was not
|
||||
// specified, use whatever immediately follows the specifier lump.
|
||||
if (intname == 0) {
|
||||
intname = *(int *)(lumpinfo[base+1].name);
|
||||
for (stop = base + 2; stop < numlumps &&
|
||||
lumpinfo[stop].handle == lumpinfo[base].handle &&
|
||||
*(int *)lumpinfo[stop].name == intname; stop++)
|
||||
;
|
||||
} else {
|
||||
stop = numlumps;
|
||||
}
|
||||
|
||||
memset (sprtemp, -1, sizeof(sprtemp));
|
||||
maxframe = -1;
|
||||
|
||||
for (k = base + 1;
|
||||
k < stop && lumpinfo[k].handle == lumpinfo[base].handle;
|
||||
k++) {
|
||||
if (*(int *)lumpinfo[k].name == intname)
|
||||
{
|
||||
|
||||
R_InstallSpriteLump (k,
|
||||
lumpinfo[k].name[4] - 'A',
|
||||
lumpinfo[k].name[5] - '0',
|
||||
false);
|
||||
|
||||
if (lumpinfo[k].name[6])
|
||||
R_InstallSpriteLump (k,
|
||||
lumpinfo[k].name[6] - 'A',
|
||||
lumpinfo[k].name[7] - '0',
|
||||
true);
|
||||
|
||||
W_SetLumpNamespace (k, skins[i].namespc);
|
||||
}
|
||||
}
|
||||
R_InstallSprite ((char *)&intname, (skins[i].sprite = numsprites - numskins + i));
|
||||
|
||||
// Now go back and check for face graphics (if necessary)
|
||||
if (skins[i].face[0] == 0 || skins[i].face[1] == 0 || skins[i].face[2] == 0) {
|
||||
// No face name specified, so this skin doesn't replace it
|
||||
skins[i].face[0] = 0;
|
||||
} else {
|
||||
// Need to go through and find all face graphics for the skin
|
||||
// and assign them to the skin's namespace.
|
||||
for (j = 0; j < 7; j++)
|
||||
strncpy (facenames[j], skins[i].face, 3);
|
||||
|
||||
for (k = base + 1;
|
||||
k < numlumps && lumpinfo[k].handle == lumpinfo[base].handle;
|
||||
k++) {
|
||||
for (j = 0; j < 7; j++)
|
||||
if (!strncmp (facenames[j], lumpinfo[k].name, facelens[j])) {
|
||||
W_SetLumpNamespace (k, skins[i].namespc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Grrk. May have changed sound table. Fix it.
|
||||
if (numskins > 1)
|
||||
S_HashSounds ();
|
||||
}
|
||||
|
||||
// [RH] Find a skin by name
|
||||
int R_FindSkin (char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numskins; i++)
|
||||
if (!strnicmp (skins[i].name, name, 16))
|
||||
return i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// [RH] List the names of all installed skins
|
||||
void Cmd_Skins (player_t *plyr, int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numskins; i++)
|
||||
Printf ("% 3d %s\n", i, skins[i].name);
|
||||
}
|
||||
|
||||
//
|
||||
// GAME FUNCTIONS
|
||||
|
@ -283,13 +502,48 @@ int newvissprite;
|
|||
// R_InitSprites
|
||||
// Called at program start.
|
||||
//
|
||||
void R_InitSprites (char** namelist)
|
||||
void R_InitSprites (char **namelist)
|
||||
{
|
||||
int i;
|
||||
|
||||
MaxVisSprites = 128; // [RH] This is the initial default value. It grows as needed.
|
||||
vissprites = Malloc (MaxVisSprites * sizeof(vissprite_t));
|
||||
lastvissprite = &vissprites[MaxVisSprites];
|
||||
|
||||
// [RH] Count the number of skins, rename each S_SKIN?? identifier
|
||||
// to just S_SKIN, and assign it a unique namespace.
|
||||
for (i = 0; i < numlumps; i++) {
|
||||
if (!strncmp (lumpinfo[i].name, "S_SKIN", 6)) {
|
||||
numskins++;
|
||||
lumpinfo[i].name[6] = lumpinfo[i].name[7] = 0;
|
||||
W_SetLumpNamespace (i, ns_skinbase + numskins);
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] We always have a default "base" skin.
|
||||
numskins++;
|
||||
|
||||
// [RH] We may have just renamed some lumps, so we need to create the
|
||||
// hash chains again.
|
||||
W_InitHashChains ();
|
||||
|
||||
// [RH] Do some preliminary setup
|
||||
skins = Z_Malloc (sizeof(*skins) * numskins, PU_STATIC, 0);
|
||||
memset (skins, 0, sizeof(*skins) * numskins);
|
||||
for (i = 1; i < numskins; i++) {
|
||||
skins[i].namespc = i + ns_skinbase;
|
||||
}
|
||||
|
||||
R_InitSpriteDefs (namelist);
|
||||
R_InitSkins (); // [RH] Finish loading skin data
|
||||
|
||||
// [RH] Set up base skin
|
||||
strcpy (skins[0].name, "Base");
|
||||
skins[0].face[0] = 'S';
|
||||
skins[0].face[1] = 'T';
|
||||
skins[0].face[2] = 'F';
|
||||
skins[0].sprite = SPR_PLAY;
|
||||
skins[0].namespc = ns_global;
|
||||
}
|
||||
|
||||
|
||||
|
@ -307,12 +561,12 @@ void R_ClearSprites (void)
|
|||
//
|
||||
// R_NewVisSprite
|
||||
//
|
||||
vissprite_t* R_NewVisSprite (void)
|
||||
vissprite_t *R_NewVisSprite (void)
|
||||
{
|
||||
if (vissprite_p == lastvissprite) {
|
||||
int prevvisspritenum = vissprite_p - vissprites;
|
||||
|
||||
MaxVisSprites += 64;
|
||||
MaxVisSprites *= 2;
|
||||
vissprites = Realloc (vissprites, MaxVisSprites * sizeof(vissprite_t));
|
||||
lastvissprite = &vissprites[MaxVisSprites];
|
||||
vissprite_p = &vissprites[prevvisspritenum];
|
||||
|
@ -324,7 +578,6 @@ vissprite_t* R_NewVisSprite (void)
|
|||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// R_DrawMaskedColumn
|
||||
// Used for sprites and masked mid textures.
|
||||
|
@ -391,20 +644,18 @@ void R_DrawVisSprite (vissprite_t *vis, int x1, int x2)
|
|||
// [RH] Tutti-Frutti fix (also allows sprites up to 256 pixels tall)
|
||||
dc_mask = 0xff;
|
||||
|
||||
patch = W_CacheLumpNum (vis->patch+firstspritelump, PU_CACHE);
|
||||
patch = W_CacheLumpNum (vis->patch, PU_CACHE);
|
||||
|
||||
dc_colormap = vis->colormap;
|
||||
|
||||
if (!dc_colormap)
|
||||
if (vis->mobjflags & MF_SHADOW)
|
||||
{
|
||||
// NULL colormap = shadow draw
|
||||
if (!r_drawfuzz->value && TransTable) {
|
||||
dc_colormap = DefaultPalette->maps.colormaps;
|
||||
colfunc = lucentcolfunc;
|
||||
dc_transmap = TransTable + 65536;
|
||||
} else {
|
||||
colfunc = fuzzcolfunc;
|
||||
}
|
||||
// [RH] I use MF_SHADOW to recognize fuzz effect now instead of
|
||||
// a NULL colormap. This allow proper substition of
|
||||
// MF_TRANSLUC25 with light levels if desired.
|
||||
dc_transmap = TransTable + 65536; // Just in case
|
||||
colfunc = r_drawfuzz->value ? fuzzcolfunc : lucentcolfunc;
|
||||
}
|
||||
else if (vis->palette)
|
||||
{
|
||||
|
@ -425,6 +676,10 @@ void R_DrawVisSprite (vissprite_t *vis, int x1, int x2)
|
|||
colfunc = lucentcolfunc;
|
||||
dc_transmap = TransTable + ((vis->mobjflags & MF_TRANSLUCBITS) >> (MF_TRANSLUCSHIFT - 16));
|
||||
}
|
||||
else
|
||||
{
|
||||
colfunc = basecolfunc;
|
||||
}
|
||||
|
||||
//dc_iscale = abs(vis->xiscale)>>detailshift;
|
||||
dc_iscale = FixedDiv (FRACUNIT, vis->scale); // [RH] from Doom Legacy
|
||||
|
@ -459,7 +714,7 @@ void R_DrawVisSprite (vissprite_t *vis, int x1, int x2)
|
|||
// Generates a vissprite for a thing
|
||||
// if it might be visible.
|
||||
//
|
||||
void R_ProjectSprite (mobj_t* thing)
|
||||
void R_ProjectSprite (mobj_t *thing)
|
||||
{
|
||||
fixed_t tr_x;
|
||||
fixed_t tr_y;
|
||||
|
@ -495,7 +750,7 @@ void R_ProjectSprite (mobj_t* thing)
|
|||
|
||||
|
||||
// [RH] Andy Baker's stealth monsters
|
||||
if (thing->invisible == true)
|
||||
if (thing->flags2 & MF2_INVISIBLE)
|
||||
return;
|
||||
|
||||
// transform the origin point
|
||||
|
@ -550,26 +805,26 @@ void R_ProjectSprite (mobj_t* thing)
|
|||
else
|
||||
{
|
||||
// use single rotation for all views
|
||||
lump = sprframe->lump[0];
|
||||
lump = sprframe->lump[rot = 0];
|
||||
flip = (BOOL)sprframe->flip[0];
|
||||
}
|
||||
|
||||
// calculate edges of the shape
|
||||
tx -= spriteoffset[lump];
|
||||
tx -= sprframe->offset[rot]; // [RH] Moved out of spriteoffset[]
|
||||
x1 = (centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS;
|
||||
|
||||
// off the right side?
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
|
||||
tx += spritewidth[lump];
|
||||
tx += sprframe->width[rot]; // [RH] Moved out of spritewidth[]
|
||||
x2 = ((centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS) - 1;
|
||||
|
||||
// off the left side
|
||||
if (x2 < 0)
|
||||
return;
|
||||
|
||||
gzt = thing->z + spritetopoffset[lump];
|
||||
gzt = thing->z + sprframe->topoffset[rot]; // [RH] Moved out of spritetopoffset[]
|
||||
|
||||
// killough 4/9/98: clip things which are out of view due to height
|
||||
// [RH] This doesn't work too well with freelook
|
||||
|
@ -585,7 +840,7 @@ void R_ProjectSprite (mobj_t* thing)
|
|||
|
||||
if (heightsec != -1) // only clip things which are in special sectors
|
||||
{
|
||||
int phs = viewplayer->mo->subsector->sector->heightsec;
|
||||
int phs = camera->subsector->sector->heightsec;
|
||||
|
||||
if (phs != -1 && viewz < sectors[phs].floorheight ?
|
||||
thing->z >= sectors[heightsec].floorheight :
|
||||
|
@ -618,7 +873,7 @@ void R_ProjectSprite (mobj_t* thing)
|
|||
|
||||
if (flip)
|
||||
{
|
||||
vis->startfrac = spritewidth[lump]-1;
|
||||
vis->startfrac = sprframe->width[rot]-1; // [RH] Moved out of spritewidth
|
||||
vis->xiscale = -iscale;
|
||||
}
|
||||
else
|
||||
|
@ -632,12 +887,7 @@ void R_ProjectSprite (mobj_t* thing)
|
|||
vis->patch = lump;
|
||||
|
||||
// get light level
|
||||
if (thing->flags & MF_SHADOW)
|
||||
{
|
||||
// shadow draw
|
||||
vis->colormap = NULL;
|
||||
}
|
||||
else if (fixedcolormap)
|
||||
if (fixedcolormap)
|
||||
{
|
||||
// fixed map
|
||||
vis->colormap = fixedcolormap;
|
||||
|
@ -645,29 +895,26 @@ void R_ProjectSprite (mobj_t* thing)
|
|||
else if (thing->frame & FF_FULLBRIGHT)
|
||||
{
|
||||
// full bright
|
||||
vis->colormap = DefaultPalette->maps.colormaps;
|
||||
vis->colormap = basecolormap; // [RH] Use basecolormap
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// diminished light
|
||||
index = xscale>>LIGHTSCALESHIFT;
|
||||
index = (xscale*lightscalexmul)>>LIGHTSCALESHIFT; // [RH]
|
||||
|
||||
if (index >= MAXLIGHTSCALE)
|
||||
index = MAXLIGHTSCALE-1;
|
||||
|
||||
vis->colormap = spritelights[index];
|
||||
vis->colormap = spritelights[index] + basecolormap; // [RH] Use basecolormap
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// R_AddSprites
|
||||
// During BSP traversal, this adds sprites by sector.
|
||||
//
|
||||
void R_AddSprites (sector_t* sec)
|
||||
void R_AddSprites (sector_t *sec)
|
||||
{
|
||||
mobj_t *thing;
|
||||
int lightnum;
|
||||
|
@ -722,7 +969,7 @@ void R_DrawPSprite (pspdef_t* psp, unsigned flags)
|
|||
sprdef = &sprites[psp->state->sprite];
|
||||
#ifdef RANGECHECK
|
||||
if ( (psp->state->frame & FF_FRAMEMASK) >= sprdef->numframes) {
|
||||
DPrintf ("R_ProjectSprite: invalid sprite frame %i : %i\n", psp->state->sprite, psp->state->frame);
|
||||
DPrintf ("R_DrawPSprite: invalid sprite frame %i : %i\n", psp->state->sprite, psp->state->frame);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -734,14 +981,14 @@ void R_DrawPSprite (pspdef_t* psp, unsigned flags)
|
|||
// calculate edges of the shape
|
||||
tx = psp->sx-((320/2)<<FRACBITS);
|
||||
|
||||
tx -= spriteoffset[lump];
|
||||
tx -= sprframe->offset[0]; // [RH] Moved out of spriteoffset[]
|
||||
x1 = (centerxfrac + FixedMul (tx,pspritescale) ) >>FRACBITS;
|
||||
|
||||
// off the right side
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
|
||||
tx += spritewidth[lump];
|
||||
tx += sprframe->width[0]; // [RH] Moved out of spritewidth[]
|
||||
x2 = ((centerxfrac + FixedMul (tx, pspritescale) ) >>FRACBITS) - 1;
|
||||
|
||||
// off the left side
|
||||
|
@ -751,7 +998,8 @@ void R_DrawPSprite (pspdef_t* psp, unsigned flags)
|
|||
// store information in a vissprite
|
||||
vis = &avis;
|
||||
vis->mobjflags = flags;
|
||||
vis->texturemid = (BASEYCENTER<<FRACBITS)+FRACUNIT/2-(psp->sy-spritetopoffset[lump]);
|
||||
vis->texturemid = (BASEYCENTER<<FRACBITS)+FRACUNIT/2-
|
||||
(psp->sy-sprframe->topoffset[0]); // [RH] Moved out of spritetopoffset[]
|
||||
vis->x1 = x1 < 0 ? 0 : x1;
|
||||
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
|
||||
vis->scale = pspriteyscale;
|
||||
|
@ -760,7 +1008,7 @@ void R_DrawPSprite (pspdef_t* psp, unsigned flags)
|
|||
if (flip)
|
||||
{
|
||||
vis->xiscale = -pspriteiscale;
|
||||
vis->startfrac = spritewidth[lump]-1;
|
||||
vis->startfrac = sprframe->width[0]-1; // [RH] Moved out of spritewidth[]
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -773,13 +1021,7 @@ void R_DrawPSprite (pspdef_t* psp, unsigned flags)
|
|||
|
||||
vis->patch = lump;
|
||||
|
||||
if (viewplayer->powers[pw_invisibility] > 4*32
|
||||
|| viewplayer->powers[pw_invisibility] & 8)
|
||||
{
|
||||
// shadow draw
|
||||
vis->colormap = NULL;
|
||||
}
|
||||
else if (fixedcolormap)
|
||||
if (fixedcolormap)
|
||||
{
|
||||
// fixed color
|
||||
vis->colormap = fixedcolormap;
|
||||
|
@ -787,12 +1029,19 @@ void R_DrawPSprite (pspdef_t* psp, unsigned flags)
|
|||
else if (psp->state->frame & FF_FULLBRIGHT)
|
||||
{
|
||||
// full bright
|
||||
vis->colormap = DefaultPalette->maps.colormaps;
|
||||
vis->colormap = basecolormap; // [RH] use basecolormap
|
||||
}
|
||||
else
|
||||
{
|
||||
// local light
|
||||
vis->colormap = spritelights[MAXLIGHTSCALE-1];
|
||||
vis->colormap = spritelights[MAXLIGHTSCALE-1] + basecolormap; // [RH] add basecolormap
|
||||
if (camera->player &&
|
||||
(camera->player->powers[pw_invisibility] > 4*32
|
||||
|| camera->player->powers[pw_invisibility] & 8))
|
||||
{
|
||||
// shadow draw
|
||||
vis->mobjflags = MF_SHADOW;
|
||||
}
|
||||
}
|
||||
|
||||
R_DrawVisSprite (vis, vis->x1, vis->x2);
|
||||
|
@ -810,10 +1059,12 @@ void R_DrawPlayerSprites (void)
|
|||
pspdef_t* psp;
|
||||
|
||||
if (r_drawplayersprites->value) {
|
||||
// [RH] set basecolormap
|
||||
basecolormap = camera->subsector->sector->colormap->maps;
|
||||
|
||||
// get light level
|
||||
lightnum =
|
||||
(viewplayer->mo->subsector->sector->lightlevel >> LIGHTSEGSHIFT)
|
||||
+extralight;
|
||||
(camera->subsector->sector->lightlevel >> LIGHTSEGSHIFT) + extralight;
|
||||
|
||||
if (lightnum < 0)
|
||||
spritelights = scalelight[0];
|
||||
|
@ -834,17 +1085,18 @@ void R_DrawPlayerSprites (void)
|
|||
centeryfrac = centery << FRACBITS;
|
||||
|
||||
// add all active psprites
|
||||
for (i=0, psp=viewplayer->psprites;
|
||||
i<NUMPSPRITES;
|
||||
i++,psp++)
|
||||
{
|
||||
if (psp->state) {
|
||||
if (i == 1)
|
||||
R_DrawPSprite (psp, MF_TRANSLUC75);
|
||||
else
|
||||
R_DrawPSprite (psp, 0);
|
||||
if (camera->player)
|
||||
for (i=0, psp=camera->player->psprites;
|
||||
i<NUMPSPRITES;
|
||||
i++,psp++)
|
||||
{
|
||||
if (psp->state) {
|
||||
if (i == 1)
|
||||
R_DrawPSprite (psp, MF_TRANSLUC75);
|
||||
else
|
||||
R_DrawPSprite (psp, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
centery = centerhack;
|
||||
centeryfrac = centerhack << FRACBITS;
|
||||
|
@ -902,6 +1154,13 @@ void R_SortVisSprites (void)
|
|||
// [RH] Allocated in R_MultiresInit() to
|
||||
// SCREENWIDTH entries each.
|
||||
short *r_dsclipbot, *r_dscliptop;
|
||||
|
||||
// [RH] The original code used -2 to indicate that a sprite was not clipped.
|
||||
// With ZDoom's freelook, it's possible that the rendering process
|
||||
// could actually generate a clip value of -2, and the rendering code
|
||||
// would mistake this to indicate the the sprite wasn't clipped.
|
||||
#define NOT_CLIPPED (-32768)
|
||||
|
||||
//
|
||||
// R_DrawSprite
|
||||
//
|
||||
|
@ -915,7 +1174,7 @@ void R_DrawSprite (vissprite_t* spr)
|
|||
fixed_t lowscale;
|
||||
|
||||
for (x = spr->x1 ; x<=spr->x2 ; x++)
|
||||
r_dsclipbot[x] = r_dscliptop[x] = -2;
|
||||
r_dsclipbot[x] = r_dscliptop[x] = NOT_CLIPPED;
|
||||
|
||||
// Scan drawsegs from end to start for obscuring segs.
|
||||
// The first drawseg that has a greater scale is the clip seg.
|
||||
|
@ -968,13 +1227,13 @@ void R_DrawSprite (vissprite_t* spr)
|
|||
|
||||
if (ds->silhouette&SIL_BOTTOM && spr->gz < ds->bsilheight) //bottom sil
|
||||
for (x=r1 ; x<=r2 ; x++)
|
||||
if (r_dsclipbot[x] == -2)
|
||||
if (r_dsclipbot[x] == NOT_CLIPPED)
|
||||
r_dsclipbot[x] = ds->sprbottomclip[x];
|
||||
|
||||
if (ds->silhouette&SIL_TOP && spr->gzt > ds->tsilheight) // top sil
|
||||
for (x=r1 ; x<=r2 ; x++)
|
||||
if (r_dscliptop[x] == -2)
|
||||
r_dscliptop[x] = ds->sprtopclip[x];
|
||||
if (r_dscliptop[x] == NOT_CLIPPED)
|
||||
r_dscliptop[x] = ds->sprtopclip[x];
|
||||
}
|
||||
|
||||
// killough 3/27/98:
|
||||
|
@ -985,20 +1244,24 @@ void R_DrawSprite (vissprite_t* spr)
|
|||
if (spr->heightsec != -1) // only things in specially marked sectors
|
||||
{
|
||||
fixed_t h,mh;
|
||||
int phs = viewplayer->mo->subsector->sector->heightsec;
|
||||
int phs = camera->subsector->sector->heightsec;
|
||||
if ((mh = sectors[spr->heightsec].floorheight) > spr->gz &&
|
||||
(h = centeryfrac - FixedMul(mh-=viewz, spr->scale)) >= 0 &&
|
||||
(h >>= FRACBITS) < viewheight)
|
||||
if (mh <= 0 || (phs != -1 && viewz > sectors[phs].floorheight))
|
||||
{ // clip bottom
|
||||
for (x=spr->x1 ; x<=spr->x2 ; x++)
|
||||
if (r_dsclipbot[x] == -2 || h < r_dsclipbot[x])
|
||||
r_dsclipbot[x] = h;
|
||||
{
|
||||
if (mh <= 0 || (phs != -1 && viewz > sectors[phs].floorheight))
|
||||
{ // clip bottom
|
||||
for (x=spr->x1 ; x<=spr->x2 ; x++)
|
||||
if (r_dsclipbot[x] == NOT_CLIPPED || h < r_dsclipbot[x])
|
||||
r_dsclipbot[x] = h;
|
||||
}
|
||||
else
|
||||
{ // clip top
|
||||
for (x=spr->x1 ; x<=spr->x2 ; x++)
|
||||
if (r_dscliptop[x] == NOT_CLIPPED || h > r_dscliptop[x])
|
||||
r_dscliptop[x] = h;
|
||||
}
|
||||
}
|
||||
else // clip top
|
||||
for (x=spr->x1 ; x<=spr->x2 ; x++)
|
||||
if (r_dscliptop[x] == -2 || h > r_dscliptop[x])
|
||||
r_dscliptop[x] = h;
|
||||
|
||||
if ((mh = sectors[spr->heightsec].ceilingheight) < spr->gzt &&
|
||||
(h = centeryfrac - FixedMul(mh-viewz, spr->scale)) >= 0 &&
|
||||
|
@ -1007,13 +1270,13 @@ void R_DrawSprite (vissprite_t* spr)
|
|||
if (phs != -1 && viewz >= sectors[phs].ceilingheight)
|
||||
{ // clip bottom
|
||||
for (x=spr->x1 ; x<=spr->x2 ; x++)
|
||||
if (r_dsclipbot[x] == -2 || h < r_dsclipbot[x])
|
||||
if (r_dsclipbot[x] == NOT_CLIPPED || h < r_dsclipbot[x])
|
||||
r_dsclipbot[x] = h;
|
||||
}
|
||||
else
|
||||
{ // clip top
|
||||
for (x=spr->x1 ; x<=spr->x2 ; x++)
|
||||
if (r_dscliptop[x] == -2 || h > r_dscliptop[x])
|
||||
if (r_dscliptop[x] == NOT_CLIPPED || h > r_dscliptop[x])
|
||||
r_dscliptop[x] = h;
|
||||
}
|
||||
}
|
||||
|
@ -1025,10 +1288,10 @@ void R_DrawSprite (vissprite_t* spr)
|
|||
// check for unclipped columns
|
||||
for (x = spr->x1 ; x<=spr->x2 ; x++)
|
||||
{
|
||||
if (r_dsclipbot[x] == -2)
|
||||
if (r_dsclipbot[x] == NOT_CLIPPED)
|
||||
r_dsclipbot[x] = (short)viewheight;
|
||||
|
||||
if (r_dscliptop[x] == -2)
|
||||
if (r_dscliptop[x] == NOT_CLIPPED)
|
||||
r_dscliptop[x] = -1;
|
||||
}
|
||||
|
||||
|
@ -1122,6 +1385,3 @@ void R_DrawMasked (void)
|
|||
R_DrawPlayerSprites ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
604
code/S_sound.c
604
code/S_sound.c
|
@ -20,9 +20,6 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "m_alloc.h"
|
||||
|
@ -30,8 +27,8 @@
|
|||
#include "i_system.h"
|
||||
#include "i_sound.h"
|
||||
#include "i_music.h"
|
||||
#include "sounds.h"
|
||||
#include "s_sound.h"
|
||||
#include "c_dispch.h"
|
||||
|
||||
#include "z_zone.h"
|
||||
#include "m_random.h"
|
||||
|
@ -42,6 +39,8 @@
|
|||
|
||||
#include "doomstat.h"
|
||||
#include "cmdlib.h"
|
||||
#include "v_video.h"
|
||||
#include "v_text.h"
|
||||
|
||||
|
||||
#define S_MAX_VOLUME 255
|
||||
|
@ -72,27 +71,32 @@ typedef struct
|
|||
void* origin; // origin of sound
|
||||
int handle; // handle of the sound being played
|
||||
int volume; // [RH] volume of sound at origin
|
||||
int priority; // [RH] priority of sound
|
||||
} channel_t;
|
||||
|
||||
// [RH] Hacks for pitch variance
|
||||
int sfx_sawup, sfx_sawidl, sfx_sawful, sfx_sawhit;
|
||||
int sfx_itemup, sfx_tink;
|
||||
|
||||
typedef struct sndname_s
|
||||
{
|
||||
struct sndname_s *left, *right;
|
||||
int sfxid;
|
||||
char name[1];
|
||||
} sndname_t;
|
||||
// [RH] Use surround sounds?
|
||||
cvar_t *snd_surround;
|
||||
|
||||
// [RH] Print sound debugging info?
|
||||
cvar_t *noisedebug;
|
||||
|
||||
// the set of channels available
|
||||
static channel_t* channels;
|
||||
static channel_t *channels;
|
||||
|
||||
// Maximum volume of a sound effect.
|
||||
// Internal default is max out of 0-15.
|
||||
cvar_t *snd_SfxVolume;
|
||||
|
||||
// Maximum volume of music. Almost useless so far.
|
||||
// Maximum volume of MOD music.
|
||||
cvar_t *snd_MusicVolume;
|
||||
|
||||
// Maximum volume of MIDI/MUS music.
|
||||
cvar_t *snd_MidiVolume;
|
||||
|
||||
// whether songs are mus_paused
|
||||
static BOOL mus_paused;
|
||||
|
||||
|
@ -105,31 +109,80 @@ static struct {
|
|||
// following is set
|
||||
// by the defaults code in M_misc:
|
||||
// number of channels available
|
||||
cvar_t *snd_channels;
|
||||
int numChannels;
|
||||
cvar_t *snd_channels;
|
||||
int numChannels;
|
||||
|
||||
static int nextcleanup;
|
||||
static int nextcleanup;
|
||||
|
||||
|
||||
//
|
||||
// [RH] Separated out of S_UpdateSoundParams
|
||||
//
|
||||
static fixed_t P_ApproxDistance (mobj_t *one, mobj_t *two)
|
||||
{
|
||||
// calculate the distance to sound origin
|
||||
// and clip it if necessary
|
||||
fixed_t adx = abs (one->x - two->x);
|
||||
fixed_t ady = abs (one->y - two->y);
|
||||
// From _GG1_ p.428. Appox. eucledian distance fast.
|
||||
return adx + ady - ((adx < ady ? adx : ady)>>1);
|
||||
}
|
||||
|
||||
//
|
||||
// [RH] Print sound debug info. Called from D_Display()
|
||||
//
|
||||
void S_NoiseDebug (void)
|
||||
{
|
||||
int i, y;
|
||||
|
||||
y = 32;
|
||||
if (level.time & 16)
|
||||
V_DrawText (0, y, "*** SOUND DEBUG INFO ***");
|
||||
y += 8;
|
||||
|
||||
V_DrawText (0, y, "name");
|
||||
V_DrawText (100, y, "mo.x");
|
||||
V_DrawText (150, y, "mo.y");
|
||||
V_DrawText (200, y, "id");
|
||||
V_DrawText (230, y, "pri");
|
||||
V_DrawText (260, y, "dist");
|
||||
y += 8;
|
||||
|
||||
for (i = 0; i < numChannels && y < screens[0].height - 16; i++, y += 8) {
|
||||
if (channels[i].sfxinfo) {
|
||||
char temp[16];
|
||||
mobj_t *origin = (mobj_t *)channels[i].origin;
|
||||
|
||||
if ((unsigned int)origin < (unsigned int)ORIGIN_STARTOFNORMAL)
|
||||
origin = players[consoleplayer].camera;
|
||||
|
||||
strcpy (temp, lumpinfo[channels[i].sfxinfo->lumpnum].name);
|
||||
temp[8] = 0;
|
||||
V_DrawText (0, y, temp);
|
||||
sprintf (temp, "%d", origin->x / FRACUNIT);
|
||||
V_DrawText (100, y, temp);
|
||||
sprintf (temp, "%d", origin->y / FRACUNIT);
|
||||
V_DrawText (150, y, temp);
|
||||
sprintf (temp, "%d", channels[i].sfxinfo - S_sfx);
|
||||
V_DrawText (200, y, temp);
|
||||
sprintf (temp, "%d", channels[i].priority);
|
||||
V_DrawText (230, y, temp);
|
||||
sprintf (temp, "%d", P_ApproxDistance (players[consoleplayer].camera, origin) / FRACUNIT);
|
||||
V_DrawText (260, y, temp);
|
||||
} else {
|
||||
V_DrawText (0, y, "------");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Internals.
|
||||
//
|
||||
int
|
||||
S_getChannel
|
||||
( void* origin,
|
||||
sfxinfo_t* sfxinfo );
|
||||
|
||||
|
||||
int
|
||||
S_AdjustSoundParams
|
||||
( mobj_t* listener,
|
||||
mobj_t* source,
|
||||
int* vol,
|
||||
int* sep,
|
||||
int* pitch );
|
||||
|
||||
void S_StopChannel(int cnum);
|
||||
static int S_getChannel (void *origin, sfxinfo_t *sfxinfo, int pri);
|
||||
static int S_AdjustSoundParams (mobj_t *listener, mobj_t *source,
|
||||
int *vol, int *sep, int *pitch );
|
||||
static void S_StopChannel (int cnum);
|
||||
|
||||
|
||||
static void ChangeMusicVol (cvar_t *var)
|
||||
|
@ -142,6 +195,10 @@ static void ChangeSfxVol (cvar_t *var)
|
|||
S_SetSfxVolume ((int)var->value);
|
||||
}
|
||||
|
||||
static void ChangeMidiVol (cvar_t *var)
|
||||
{
|
||||
I_SetMIDIVolume (var->value);
|
||||
}
|
||||
|
||||
//
|
||||
// Initializes sound stuff, including volume
|
||||
|
@ -152,24 +209,27 @@ void S_Init (int sfxVolume, int musicVolume)
|
|||
{
|
||||
int i;
|
||||
|
||||
snd_MidiVolume->u.callback = ChangeMidiVol;
|
||||
snd_MusicVolume->u.callback = ChangeMusicVol;
|
||||
snd_SfxVolume->u.callback = ChangeSfxVol;
|
||||
ChangeMidiVol (snd_MidiVolume);
|
||||
|
||||
Printf ("S_Init: default sfx volume %d\n", sfxVolume);
|
||||
|
||||
// [RH] Read in sound sequences (TODO)
|
||||
//S_ParseSndSeq ();
|
||||
|
||||
// Whatever these did with DMX, these are rather dummies now.
|
||||
I_SetChannels();
|
||||
|
||||
S_SetSfxVolume(sfxVolume);
|
||||
// No music with Linux - another dummy.
|
||||
S_SetMusicVolume(musicVolume);
|
||||
|
||||
// Allocating the internal channels for mixing
|
||||
// (the maximum numer of sounds rendered
|
||||
// simultaneously) within zone memory.
|
||||
numChannels = (int)snd_channels->value;
|
||||
channels =
|
||||
(channel_t *) Z_Malloc(numChannels*sizeof(channel_t), PU_STATIC, 0);
|
||||
channels = (channel_t *) Z_Malloc(numChannels*sizeof(channel_t), PU_STATIC, 0);
|
||||
|
||||
// Free all channels for use
|
||||
for (i=0 ; i<numChannels ; i++)
|
||||
|
@ -179,13 +239,12 @@ void S_Init (int sfxVolume, int musicVolume)
|
|||
mus_paused = 0;
|
||||
|
||||
// Note that sounds have not been cached (yet).
|
||||
for (i=1 ; i<NUMSFX ; i++)
|
||||
S_sfx[i].lumpnum = S_sfx[i].usefulness = -1;
|
||||
for (i=1; i < numsfx; i++)
|
||||
S_sfx[i].usefulness = -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Per level startup code.
|
||||
// Kills playing sounds at start of level,
|
||||
|
@ -197,118 +256,125 @@ void S_Start(void)
|
|||
|
||||
// kill all playing sounds at start of level
|
||||
// (trust me - a good idea)
|
||||
for (cnum=0 ; cnum<numChannels ; cnum++)
|
||||
for (cnum = 0; cnum < numChannels; cnum++)
|
||||
if (channels[cnum].sfxinfo)
|
||||
S_StopChannel(cnum);
|
||||
S_StopChannel (cnum);
|
||||
|
||||
// start new music for the level
|
||||
mus_paused = 0;
|
||||
|
||||
// [RH] This is a lot simpler now.
|
||||
S_ChangeMusic(level.music, true);
|
||||
S_ChangeMusic (level.music, true);
|
||||
|
||||
nextcleanup = 15;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void S_StartSoundAtVolume (void *origin_p, int sfx_id, int volume)
|
||||
// [RH] Split S_StartSoundAtVolume into two parts so that sounds can
|
||||
// be specified both by id and by name.
|
||||
void S_StartSfxAtVolume (void *origin_p, int sfx_id, int pri, int volume)
|
||||
{
|
||||
|
||||
int rc;
|
||||
int sep;
|
||||
int pitch;
|
||||
int priority;
|
||||
sfxinfo_t* sfx;
|
||||
int cnum;
|
||||
int rc;
|
||||
int sep;
|
||||
int pitch;
|
||||
int priority;
|
||||
sfxinfo_t* sfx;
|
||||
int cnum;
|
||||
|
||||
mobj_t* origin = (mobj_t *) origin_p;
|
||||
mobj_t* origin = (mobj_t *) origin_p;
|
||||
|
||||
if (sfx_id == -1) {
|
||||
S_StopSound (origin);
|
||||
return;
|
||||
}
|
||||
|
||||
// Debug.
|
||||
/*fprintf( stderr,
|
||||
"S_StartSoundAtVolume: playing sound %d (%s)\n",
|
||||
sfx_id, S_sfx[sfx_id].name );*/
|
||||
|
||||
// check for bogus sound #
|
||||
if (sfx_id < 1 || sfx_id > NUMSFX)
|
||||
I_Error("Bad sfx #: %d", sfx_id);
|
||||
|
||||
|
||||
sfx = &S_sfx[sfx_id];
|
||||
|
||||
// Initialize sound parameters
|
||||
if (sfx->link)
|
||||
{
|
||||
pitch = sfx->pitch;
|
||||
priority = sfx->priority;
|
||||
volume += sfx->volume;
|
||||
|
||||
if (volume < 1)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
pitch = NORM_PITCH;
|
||||
priority = NORM_PRIORITY;
|
||||
}
|
||||
|
||||
pitch = NORM_PITCH;
|
||||
priority = NORM_PRIORITY;
|
||||
|
||||
// Check to see if it is audible,
|
||||
// and if not, modify the params
|
||||
if (((unsigned int)origin >= (unsigned int)ORIGIN_STARTOFNORMAL) &&
|
||||
origin != players[displayplayer].mo)
|
||||
origin != players[consoleplayer].camera) // [RH] Use camera
|
||||
{
|
||||
rc = S_AdjustSoundParams(players[displayplayer].mo,
|
||||
rc = S_AdjustSoundParams(players[consoleplayer].camera, // [RH] Use camera
|
||||
origin,
|
||||
&volume,
|
||||
&sep,
|
||||
&pitch);
|
||||
|
||||
if ( origin->x == players[displayplayer].mo->x
|
||||
&& origin->y == players[displayplayer].mo->y)
|
||||
if (!rc)
|
||||
return;
|
||||
|
||||
if ( origin->x == players[consoleplayer].camera->x // [RH] use camera
|
||||
&& origin->y == players[consoleplayer].camera->y)
|
||||
{
|
||||
sep = NORM_SEP;
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
return;
|
||||
#if 0
|
||||
else
|
||||
{
|
||||
// [RH] Don't play more than two sounds w/ approximately
|
||||
// the same origin. (Doesn't work.)
|
||||
int similarseps = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numChannels; i++) {
|
||||
if (channels[i].sfxinfo && channels[i].origin &&
|
||||
P_ApproxDistance (channels[i].origin, origin) < 64)
|
||||
similarseps++;
|
||||
}
|
||||
if (similarseps > 1)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
} else if (((unsigned int)origin < (unsigned int)ORIGIN_STARTOFNORMAL) &&
|
||||
((unsigned int)origin) & 128) {
|
||||
(((unsigned int)origin) & 128) &&
|
||||
snd_surround->value) {
|
||||
sep = -1;
|
||||
} else {
|
||||
sep = NORM_SEP;
|
||||
}
|
||||
// hacks to vary the sfx pitches
|
||||
if (sfx_id >= sfx_sawup && sfx_id <= sfx_sawhit)
|
||||
if (sfx_id == sfx_sawup || sfx_id == sfx_sawhit ||
|
||||
sfx_id == sfx_sawidl || sfx_id == sfx_sawful)
|
||||
pitch += 8 - (M_Random()&15);
|
||||
else if (sfx_id != sfx_itemup && sfx_id != sfx_tink)
|
||||
pitch += 16 - (M_Random()&31);
|
||||
|
||||
// kill old sound
|
||||
S_StopSound(origin);
|
||||
S_StopSound (origin);
|
||||
|
||||
// try to find a channel
|
||||
cnum = S_getChannel(origin, sfx);
|
||||
cnum = S_getChannel (origin, sfx, pri);
|
||||
|
||||
if (cnum<0)
|
||||
if (cnum < 0)
|
||||
return;
|
||||
|
||||
if (sfx->link)
|
||||
sfx = sfx->link;
|
||||
|
||||
//
|
||||
// This is supposed to handle the loading/caching.
|
||||
// For some odd reason, the caching is done nearly
|
||||
// each time the sound is needed?
|
||||
//
|
||||
|
||||
// get lumpnum if necessary
|
||||
if (sfx->lumpnum < 0)
|
||||
sfx->lumpnum = I_GetSfxLumpNum(sfx);
|
||||
|
||||
// cache data if necessary
|
||||
if (!sfx->data)
|
||||
{
|
||||
Printf ("S_StartSoundAtVolume: 16bit and not pre-cached - wtf?\n");
|
||||
//Printf ("S_StartSoundAtVolume: 16bit and not pre-cached - wtf?\n");
|
||||
I_LoadSound (sfx);
|
||||
if (sfx->link)
|
||||
sfx = sfx->link;
|
||||
|
||||
// DOS remains, 8bit handling
|
||||
//sfx->data = (void *) W_CacheLumpNum(sfx->lumpnum, PU_MUSIC);
|
||||
|
@ -327,7 +393,7 @@ void S_StartSoundAtVolume (void *origin_p, int sfx_id, int volume)
|
|||
|
||||
// Assigns the handle to one of the channels in the
|
||||
// mix/output buffer.
|
||||
channels[cnum].handle = I_StartSound(sfx_id,
|
||||
channels[cnum].handle = I_StartSound(sfx,
|
||||
/*sfx->data,*/
|
||||
volume,
|
||||
sep,
|
||||
|
@ -335,20 +401,45 @@ void S_StartSoundAtVolume (void *origin_p, int sfx_id, int volume)
|
|||
priority);
|
||||
}
|
||||
|
||||
void S_StartSound (void *origin, int sfx_id)
|
||||
void S_StartSoundAtVolume (void *origin_p, char *name, int pri, int volume)
|
||||
{
|
||||
S_StartSoundAtVolume(origin, sfx_id, 255);
|
||||
int sfx_id;
|
||||
|
||||
if (*name == '*') {
|
||||
// Sexed sound
|
||||
char nametemp[128];
|
||||
const char templat[] = "player/%s/%s";
|
||||
const char *genders[] = { "male", "female", "neuter" };
|
||||
player_t *player;
|
||||
|
||||
sfx_id = -1;
|
||||
if (origin_p >= ORIGIN_STARTOFNORMAL && (player = ((mobj_t *)origin_p)->player)) {
|
||||
sprintf (nametemp, templat, skins[player->userinfo.skin].name, name + 1);
|
||||
sfx_id = S_FindSound (nametemp);
|
||||
if (sfx_id == -1) {
|
||||
sprintf (nametemp, templat, genders[player->userinfo.gender], name + 1);
|
||||
sfx_id = S_FindSound (nametemp);
|
||||
}
|
||||
}
|
||||
if (sfx_id == -1) {
|
||||
sprintf (nametemp, templat, "male", name + 1);
|
||||
sfx_id = S_FindSound (nametemp);
|
||||
}
|
||||
} else
|
||||
sfx_id = S_FindSound (name);
|
||||
|
||||
if (sfx_id == -1)
|
||||
DPrintf ("Unknown sound %s\n", name);
|
||||
|
||||
S_StartSfxAtVolume (origin_p, sfx_id, pri, volume);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void S_StopSound(void *origin)
|
||||
void S_StopSound (void *origin)
|
||||
{
|
||||
|
||||
int cnum;
|
||||
|
||||
for (cnum=0 ; cnum<numChannels ; cnum++)
|
||||
for (cnum = 0; cnum < numChannels; cnum++)
|
||||
{
|
||||
if (channels[cnum].sfxinfo && channels[cnum].origin == origin)
|
||||
{
|
||||
|
@ -359,13 +450,6 @@ void S_StopSound(void *origin)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Stop and resume music, during game PAUSE.
|
||||
//
|
||||
|
@ -378,11 +462,11 @@ void S_PauseSound(void)
|
|||
}
|
||||
}
|
||||
|
||||
void S_ResumeSound(void)
|
||||
void S_ResumeSound (void)
|
||||
{
|
||||
if (mus_playing.handle && mus_paused)
|
||||
{
|
||||
I_ResumeSong(mus_playing.handle);
|
||||
I_ResumeSong (mus_playing.handle);
|
||||
mus_paused = false;
|
||||
}
|
||||
}
|
||||
|
@ -391,7 +475,7 @@ void S_ResumeSound(void)
|
|||
//
|
||||
// Updates music & sounds
|
||||
//
|
||||
void S_UpdateSounds(void* listener_p)
|
||||
void S_UpdateSounds (void *listener_p)
|
||||
{
|
||||
int audible;
|
||||
int cnum;
|
||||
|
@ -412,8 +496,7 @@ void S_UpdateSounds(void* listener_p)
|
|||
{
|
||||
for (i=1 ; i<NUMSFX ; i++)
|
||||
{
|
||||
if (S_sfx[i].usefulness < 1
|
||||
&& S_sfx[i].usefulness > -1)
|
||||
if (S_sfx[i].usefulness < 1 && S_sfx[i].usefulness > -1)
|
||||
{
|
||||
if (--S_sfx[i].usefulness == -1)
|
||||
{
|
||||
|
@ -425,31 +508,20 @@ void S_UpdateSounds(void* listener_p)
|
|||
nextcleanup = gametic + 15;
|
||||
}*/
|
||||
|
||||
for (cnum=0 ; cnum<numChannels ; cnum++)
|
||||
for (cnum = 0; cnum < numChannels; cnum++)
|
||||
{
|
||||
c = &channels[cnum];
|
||||
sfx = c->sfxinfo;
|
||||
|
||||
if (c->sfxinfo)
|
||||
{
|
||||
if (I_SoundIsPlaying(c->handle))
|
||||
if (I_SoundIsPlaying (c->handle))
|
||||
{
|
||||
// initialize parameters
|
||||
volume = c->volume;
|
||||
pitch = NORM_PITCH;
|
||||
sep = NORM_SEP;
|
||||
|
||||
if (sfx->link)
|
||||
{
|
||||
pitch = sfx->pitch;
|
||||
volume += sfx->volume;
|
||||
if (volume < 1)
|
||||
{
|
||||
S_StopChannel(cnum);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// check non-local sounds for distance clipping
|
||||
// or modify their params
|
||||
if (c->origin >= ORIGIN_STARTOFNORMAL && listener_p != c->origin)
|
||||
|
@ -462,10 +534,10 @@ void S_UpdateSounds(void* listener_p)
|
|||
|
||||
if (!audible)
|
||||
{
|
||||
S_StopChannel(cnum);
|
||||
S_StopChannel (cnum);
|
||||
}
|
||||
else
|
||||
I_UpdateSoundParams(c->handle, volume, sep, pitch);
|
||||
I_UpdateSoundParams (c->handle, volume, sep, pitch);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -589,7 +661,7 @@ void S_StopMusic(void)
|
|||
|
||||
|
||||
|
||||
void S_StopChannel(int cnum)
|
||||
static void S_StopChannel(int cnum)
|
||||
{
|
||||
|
||||
int i;
|
||||
|
@ -629,20 +701,13 @@ void S_StopChannel(int cnum)
|
|||
// If the sound is not audible, returns a 0.
|
||||
// Otherwise, modifies parameters and returns 1.
|
||||
//
|
||||
int S_AdjustSoundParams (mobj_t *listener, mobj_t *source, int *vol, int *sep, int *pitch)
|
||||
static int S_AdjustSoundParams (mobj_t *listener, mobj_t *source,
|
||||
int *vol, int *sep, int *pitch)
|
||||
{
|
||||
fixed_t approx_dist;
|
||||
fixed_t adx;
|
||||
fixed_t ady;
|
||||
angle_t angle;
|
||||
|
||||
// calculate the distance to sound origin
|
||||
// and clip it if necessary
|
||||
adx = abs(listener->x - source->x);
|
||||
ady = abs(listener->y - source->y);
|
||||
|
||||
// From _GG1_ p.428. Appox. eucledian distance fast.
|
||||
approx_dist = adx + ady - ((adx < ady ? adx : ady)>>1);
|
||||
approx_dist = P_ApproxDistance (listener, source);
|
||||
|
||||
if (!(level.flags & LEVEL_NOSOUNDCLIPPING) && approx_dist > S_CLIPPING_DIST)
|
||||
{
|
||||
|
@ -694,18 +759,14 @@ int S_AdjustSoundParams (mobj_t *listener, mobj_t *source, int *vol, int *sep, i
|
|||
// S_getChannel :
|
||||
// If none available, return -1. Otherwise channel #.
|
||||
//
|
||||
int
|
||||
S_getChannel
|
||||
( void* origin,
|
||||
sfxinfo_t* sfxinfo )
|
||||
static int S_getChannel (void *origin, sfxinfo_t *sfxinfo, int pri)
|
||||
{
|
||||
// channel number to use
|
||||
int cnum;
|
||||
|
||||
channel_t* c;
|
||||
int cnum;
|
||||
channel_t *c;
|
||||
|
||||
// Find an open channel
|
||||
for (cnum=0 ; cnum<numChannels ; cnum++)
|
||||
for (cnum = 0; cnum < numChannels; cnum++)
|
||||
{
|
||||
if (!channels[cnum].sfxinfo)
|
||||
break;
|
||||
|
@ -720,8 +781,8 @@ S_getChannel
|
|||
if (cnum == numChannels)
|
||||
{
|
||||
// Look for lower priority
|
||||
for (cnum=0 ; cnum<numChannels ; cnum++)
|
||||
if (channels[cnum].sfxinfo->priority >= sfxinfo->priority) break;
|
||||
for (cnum = 0; cnum < numChannels; cnum++)
|
||||
if (channels[cnum].priority >= pri) break;
|
||||
|
||||
if (cnum == numChannels)
|
||||
{
|
||||
|
@ -740,6 +801,7 @@ S_getChannel
|
|||
// channel is decided to be cnum.
|
||||
c->sfxinfo = sfxinfo;
|
||||
c->origin = origin;
|
||||
c->priority = pri;
|
||||
|
||||
return cnum;
|
||||
}
|
||||
|
@ -750,110 +812,105 @@ S_getChannel
|
|||
//
|
||||
// =============================== [RH]
|
||||
|
||||
typedef struct {
|
||||
thinker_t thinker;
|
||||
struct AmbientSound *ambient;
|
||||
int ticker;
|
||||
} ambientthinker_t;
|
||||
sfxinfo_t *S_sfx; // [RH] This is no longer defined in sounds.c
|
||||
static int maxsfx; // [RH] Current size of S_sfx array.
|
||||
int numsfx; // [RH] Current number of sfx defined.
|
||||
|
||||
static struct AmbientSound {
|
||||
unsigned type; // type of ambient sound
|
||||
int periodmin; // # of tics between repeats
|
||||
int periodmax; // max # of tics for random ambients
|
||||
int volume; // relative volume of sound
|
||||
int sfxid; // ID of attached real sound
|
||||
ambientthinker_t *thinker; // thinker for world sound
|
||||
} Ambients[64];
|
||||
char sound[MAX_SNDNAME+1]; // Logical name of sound to play
|
||||
} Ambients[256];
|
||||
|
||||
#define RANDOM 1
|
||||
#define PERIODIC 2
|
||||
#define POSITIONAL 4
|
||||
#define SURROUND 16
|
||||
|
||||
static sndname_t *LogicalNames;
|
||||
|
||||
int S_GetFreeSoundIndex (void)
|
||||
void S_HashSounds (void)
|
||||
{
|
||||
static int freeIndex = sfx_ambient0;
|
||||
int i;
|
||||
unsigned j;
|
||||
|
||||
if (freeIndex <= sfx_ambient63)
|
||||
return freeIndex++;
|
||||
else
|
||||
return sfx_None;
|
||||
// Mark all buckets as empty
|
||||
for (i = 0; i < numsfx; i++)
|
||||
S_sfx[i].index = -1;
|
||||
|
||||
// Now set up the chains
|
||||
for (i = 0; i < numsfx; i++) {
|
||||
j = MakeKey (S_sfx[i].name) % (unsigned)numsfx;
|
||||
S_sfx[i].next = S_sfx[j].index;
|
||||
S_sfx[j].index = i;
|
||||
}
|
||||
}
|
||||
|
||||
int S_GetSoundIndexFromLumpName (char *lumpname)
|
||||
int S_FindSound (const char *logicalname)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = sfx_ambient0; i <= sfx_ambient63; i++)
|
||||
if (S_sfx[i].name)
|
||||
if (!stricmp (S_sfx[i].name, lumpname))
|
||||
return i;
|
||||
i = S_sfx[MakeKey (logicalname) % (unsigned)numsfx].index;
|
||||
|
||||
return sfx_None;
|
||||
while ((i != -1) && strnicmp (S_sfx[i].name, logicalname, MAX_SNDNAME))
|
||||
i = S_sfx[i].next;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static sndname_t **InsertionPoint;
|
||||
|
||||
sndname_t *S_FindLogicalName (char *logicalname)
|
||||
int S_FindSoundByLump (int lump)
|
||||
{
|
||||
sndname_t *sound;
|
||||
int cmpval;
|
||||
if (lump != -1) {
|
||||
int i;
|
||||
|
||||
InsertionPoint = &LogicalNames;
|
||||
sound = LogicalNames;
|
||||
for (i = 0; i < numsfx; i++)
|
||||
if (S_sfx[i].lumpnum == lump)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (sound) {
|
||||
cmpval = strcmp (sound->name, logicalname);
|
||||
if (cmpval == 0) {
|
||||
return sound;
|
||||
} else if (cmpval < 0) {
|
||||
InsertionPoint = &sound->left;
|
||||
sound = sound->left;
|
||||
} else {
|
||||
InsertionPoint = &sound->right;
|
||||
sound = sound->right;
|
||||
}
|
||||
int S_AddSoundLump (char *logicalname, int lump)
|
||||
{
|
||||
if (numsfx == maxsfx) {
|
||||
maxsfx = maxsfx ? maxsfx*2 : 128;
|
||||
S_sfx = Realloc (S_sfx, maxsfx * sizeof(*S_sfx));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
// logicalname MUST be < MAX_SNDNAME chars long
|
||||
strcpy (S_sfx[numsfx].name, logicalname);
|
||||
S_sfx[numsfx].data = NULL;
|
||||
S_sfx[numsfx].link = NULL;
|
||||
S_sfx[numsfx].usefulness = 0;
|
||||
S_sfx[numsfx].lumpnum = lump;
|
||||
return numsfx++;
|
||||
}
|
||||
|
||||
void S_AddLogicalName (char *logicalname, char *lumpname)
|
||||
int S_AddSound (char *logicalname, char *lumpname)
|
||||
{
|
||||
sndname_t *sound;
|
||||
int sfxid;
|
||||
|
||||
lumpname += 2; // Skip ds header
|
||||
// If the sound has already been defined, change the old definition.
|
||||
for (sfxid = 0; sfxid < numsfx; sfxid++)
|
||||
if (0 == stricmp (logicalname, S_sfx[sfxid].name))
|
||||
break;
|
||||
|
||||
if (!(sound = S_FindLogicalName (logicalname))) {
|
||||
sound = Malloc (sizeof(sndname_t) + strlen (logicalname));
|
||||
sound->left = NULL;
|
||||
sound->right = NULL;
|
||||
strcpy (sound->name, logicalname);
|
||||
*InsertionPoint = sound;
|
||||
// Otherwise, prepare a new one.
|
||||
if (sfxid == numsfx) {
|
||||
sfxid = S_AddSoundLump (logicalname, W_CheckNumForName (lumpname));
|
||||
} else {
|
||||
S_sfx[sfxid].lumpnum = W_CheckNumForName (lumpname);
|
||||
}
|
||||
|
||||
if ((sfxid = S_GetSoundIndexFromLumpName (lumpname)) == sfx_None) {
|
||||
if ((sfxid = S_GetFreeSoundIndex ()) == sfx_None) {
|
||||
Printf ("no room to add %s to sound table\n", lumpname);
|
||||
} else {
|
||||
S_sfx[sfxid].name = copystring (lumpname);
|
||||
}
|
||||
}
|
||||
|
||||
sound->sfxid = sfxid;
|
||||
return sfxid;
|
||||
}
|
||||
|
||||
// S_ParseSndInfo
|
||||
// Parses all loaded SNDINFO lumps. Currently, this is only used
|
||||
// to gather information for ambient sounds.
|
||||
// Parses all loaded SNDINFO lumps.
|
||||
void S_ParseSndInfo (void)
|
||||
{
|
||||
int lastlump, lump;
|
||||
char *sndinfo;
|
||||
char *logicalname;
|
||||
char *data;
|
||||
|
||||
lastlump = 0;
|
||||
|
@ -876,41 +933,31 @@ void S_ParseSndInfo (void)
|
|||
if (!stricmp (com_token + 1, "ambient")) {
|
||||
// $ambient <num> <logical name> [point|surround] <type> [secs] <relative volume>
|
||||
struct AmbientSound *ambient, dummy;
|
||||
sndname_t *logicalinfo;
|
||||
int index;
|
||||
|
||||
sndinfo = COM_Parse (sndinfo);
|
||||
index = atoi (com_token);
|
||||
if (index < 1 || index > 64) {
|
||||
if (index < 0 || index > 255) {
|
||||
Printf ("Bad ambient index (%d)\n", index);
|
||||
ambient = &dummy;
|
||||
} else {
|
||||
index--;
|
||||
ambient = Ambients + index;
|
||||
}
|
||||
memset (ambient, 0, sizeof(struct AmbientSound));
|
||||
|
||||
sndinfo = COM_Parse (sndinfo);
|
||||
logicalinfo = S_FindLogicalName (com_token);
|
||||
if (logicalinfo)
|
||||
ambient->sfxid = logicalinfo->sfxid;
|
||||
else
|
||||
ambient->sfxid = sfx_None;
|
||||
strncpy (ambient->sound, com_token, MAX_SNDNAME);
|
||||
ambient->sound[MAX_SNDNAME] = 0;
|
||||
|
||||
sndinfo = COM_Parse (sndinfo);
|
||||
if (!stricmp (com_token, "point")) {
|
||||
ambient->type = POSITIONAL;
|
||||
sndinfo = COM_Parse (sndinfo);
|
||||
if (ambient != &dummy) {
|
||||
mobjinfo[MT_AMBIENT0 + index].spawnstate = S_AMBIENTSOUND;
|
||||
}
|
||||
} else {
|
||||
if (!stricmp (com_token, "surround")) {
|
||||
ambient->type = SURROUND;
|
||||
sndinfo = COM_Parse (sndinfo);
|
||||
}
|
||||
if (ambient != &dummy)
|
||||
mobjinfo[MT_AMBIENT0 + index].spawnstate = S_NULL;
|
||||
}
|
||||
|
||||
if (!stricmp (com_token, "continuous")) {
|
||||
|
@ -951,14 +998,57 @@ void S_ParseSndInfo (void)
|
|||
}
|
||||
} else {
|
||||
// com_token is a logical sound mapping
|
||||
char name[MAX_SNDNAME+1];
|
||||
|
||||
logicalname = copystring (com_token);
|
||||
strncpy (name, com_token, MAX_SNDNAME);
|
||||
name[MAX_SNDNAME] = 0;
|
||||
sndinfo = COM_Parse (sndinfo);
|
||||
S_AddLogicalName (logicalname, com_token);
|
||||
free (logicalname);
|
||||
S_AddSound (name, com_token);
|
||||
}
|
||||
}
|
||||
}
|
||||
S_HashSounds ();
|
||||
|
||||
// [RH] Hack for pitch varying
|
||||
sfx_sawup = S_FindSound ("weapons/sawup");
|
||||
sfx_sawidl = S_FindSound ("weapons/sawidle");
|
||||
sfx_sawful = S_FindSound ("weapons/sawfull");
|
||||
sfx_sawhit = S_FindSound ("weapons/sawhit");
|
||||
sfx_itemup = S_FindSound ("misc/i_pkup");
|
||||
sfx_tink = S_FindSound ("misc/chat2");
|
||||
}
|
||||
|
||||
void Cmd_Soundlist (void *plyr, int argc, char **argv)
|
||||
{
|
||||
char lumpname[9];
|
||||
int i;
|
||||
|
||||
lumpname[8] = 0;
|
||||
for (i = 0; i < numsfx; i++)
|
||||
if (S_sfx[i].lumpnum != -1) {
|
||||
strncpy (lumpname, lumpinfo[S_sfx[i].lumpnum].name, 8);
|
||||
Printf ("%3d. %s (%s)\n", i+1, S_sfx[i].name, lumpname);
|
||||
} else
|
||||
Printf ("%3d. %s **not present**\n", i+1, S_sfx[i].name);
|
||||
}
|
||||
|
||||
void Cmd_Soundlinks (void *plyr, int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numsfx; i++)
|
||||
if (S_sfx[i].link)
|
||||
Printf ("%s -> %s\n", S_sfx[i].name, S_sfx[i].link->name);
|
||||
}
|
||||
|
||||
void S_StartAmbient (char *name, int volume, BOOL surround)
|
||||
{
|
||||
static int last = -1;
|
||||
|
||||
if (++last >= 64)
|
||||
last = 0;
|
||||
|
||||
S_StartSoundAtVolume ((mobj_t *)((8+last)|(surround?128:0)), name, 32, volume);
|
||||
}
|
||||
|
||||
static void SetTicker (int *tics, struct AmbientSound *ambient)
|
||||
|
@ -974,12 +1064,13 @@ static void SetTicker (int *tics, struct AmbientSound *ambient)
|
|||
|
||||
void A_Ambient (mobj_t *actor)
|
||||
{
|
||||
struct AmbientSound *ambient;
|
||||
struct AmbientSound *ambient = &Ambients[actor->args[0]];
|
||||
|
||||
ambient = &Ambients[actor->type - MT_AMBIENT0];
|
||||
|
||||
if (ambient->sfxid) {
|
||||
S_StartSoundAtVolume (actor, ambient->sfxid, ambient->volume);
|
||||
if (ambient->sound[0]) {
|
||||
if (ambient->type & POSITIONAL)
|
||||
S_StartSoundAtVolume (actor, ambient->sound, 32, ambient->volume);
|
||||
else
|
||||
S_StartAmbient (ambient->sound, ambient->volume, ambient->type & SURROUND);
|
||||
|
||||
SetTicker (&actor->tics, ambient);
|
||||
} else {
|
||||
|
@ -987,58 +1078,21 @@ void A_Ambient (mobj_t *actor)
|
|||
}
|
||||
}
|
||||
|
||||
void T_WorldAmbient (ambientthinker_t *thinker)
|
||||
{
|
||||
struct AmbientSound *ambient;
|
||||
int channel;
|
||||
|
||||
if (thinker->ticker) {
|
||||
thinker->ticker--;
|
||||
return;
|
||||
}
|
||||
|
||||
ambient = thinker->ambient;
|
||||
|
||||
channel = ambient - Ambients + 8;
|
||||
if (ambient->type & SURROUND)
|
||||
channel |= 128;
|
||||
S_StartSoundAtVolume ((void *)channel, ambient->sfxid, ambient->volume);
|
||||
SetTicker (&thinker->ticker, ambient);
|
||||
}
|
||||
|
||||
void S_ActivateAmbient (void *origin, int ambient)
|
||||
void S_ActivateAmbient (mobj_t *origin, int ambient)
|
||||
{
|
||||
struct AmbientSound *amb = &Ambients[ambient];
|
||||
|
||||
if (!(amb->type & 3) && !amb->periodmin)
|
||||
amb->periodmin = (S_sfx[amb->sfxid].ms * TICRATE) / 1000;
|
||||
if (!(amb->type & 3) && !amb->periodmin) {
|
||||
sfxinfo_t *sfx = S_sfx + S_FindSound (amb->sound);
|
||||
|
||||
if (amb->type & POSITIONAL) {
|
||||
// Point sounds
|
||||
} else {
|
||||
// World sounds
|
||||
DPrintf ("ActivateAmbient %d\n", ambient);
|
||||
|
||||
if (!amb->thinker) {
|
||||
Z_Malloc (sizeof(ambientthinker_t), PU_LEVSPEC, &amb->thinker);
|
||||
P_AddThinker (&amb->thinker->thinker);
|
||||
amb->thinker->ambient = amb;
|
||||
amb->thinker->thinker.function.acp1 = (actionf_p1) T_WorldAmbient;
|
||||
if (amb->type & 3)
|
||||
SetTicker (&amb->thinker->ticker, amb);
|
||||
else
|
||||
amb->thinker->ticker = 0;
|
||||
}
|
||||
// Make sure the sound has been loaded so we know how long it is
|
||||
if (!sfx->data)
|
||||
I_LoadSound (sfx);
|
||||
amb->periodmin = (sfx->ms * TICRATE) / 1000;
|
||||
}
|
||||
|
||||
if (amb->type & (RANDOM|PERIODIC))
|
||||
SetTicker (&origin->tics, amb);
|
||||
else
|
||||
origin->tics = 1;
|
||||
}
|
||||
|
||||
void S_ClearAmbients (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
if (Ambients[i].thinker) {
|
||||
P_RemoveThinker ((thinker_t *)Ambients[i].thinker);
|
||||
Ambients[i].thinker = NULL;
|
||||
}
|
||||
}
|
|
@ -25,38 +25,56 @@
|
|||
|
||||
|
||||
|
||||
#define MAX_SNDNAME 63
|
||||
|
||||
//
|
||||
// SoundFX struct.
|
||||
//
|
||||
typedef struct sfxinfo_struct sfxinfo_t;
|
||||
|
||||
struct sfxinfo_struct
|
||||
{
|
||||
char name[MAX_SNDNAME+1]; // [RH] Sound name defined in SNDINFO
|
||||
void* data; // sound data
|
||||
|
||||
struct sfxinfo_struct *link;
|
||||
|
||||
// this is checked every second to see if sound
|
||||
// can be thrown out (if 0, then decrement, if -1,
|
||||
// then throw out, if > 0, then it is in use)
|
||||
int usefulness;
|
||||
|
||||
int lumpnum; // lump number of sfx
|
||||
unsigned int ms; // [RH] length of sfx in milliseconds
|
||||
unsigned int next, index; // [RH] For hashing
|
||||
};
|
||||
|
||||
// the complete set of sound effects
|
||||
extern sfxinfo_t *S_sfx;
|
||||
|
||||
// [RH] Number of defined sounds
|
||||
extern int numsfx;
|
||||
|
||||
// Initializes sound stuff, including volume
|
||||
// Sets channels, SFX and music volume,
|
||||
// allocates channel buffer, sets S_sfx lookup.
|
||||
//
|
||||
void
|
||||
S_Init
|
||||
( int sfxVolume,
|
||||
int musicVolume );
|
||||
void S_Init (int sfxVolume, int musicVolume);
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Per level startup code.
|
||||
// Kills playing sounds at start of level,
|
||||
// determines music if any, changes music.
|
||||
//
|
||||
void S_Start(void);
|
||||
|
||||
|
||||
//
|
||||
// Start sound for thing at <origin>
|
||||
// using <sound_id> from sounds.h
|
||||
//
|
||||
void S_StartSound (void *origin, int sound_id);
|
||||
|
||||
|
||||
// Start sound for thing at <origin> using <sound_id> from sounds.h
|
||||
// [RH] macro-fied
|
||||
#define S_StartSound(o,n,p) S_StartSoundAtVolume (o,n,p,255)
|
||||
#define S_StartSfx(o,n,p) S_StartSfxAtVolume (o,n,p,255)
|
||||
|
||||
// Will start a sound at a given volume.
|
||||
void S_StartSoundAtVolume (void *origin, int sound_id, int volume);
|
||||
void S_StartSoundAtVolume (void *origin, char *name, int pri, int volume);
|
||||
void S_StartSfxAtVolume (void *origin, int sfxid, int pri, int volume);
|
||||
|
||||
#define ORIGIN_SURROUNDBIT (128)
|
||||
#define ORIGIN_AMBIENT (NULL) // Sound is not attenuated
|
||||
|
@ -71,11 +89,14 @@ void S_StartSoundAtVolume (void *origin, int sound_id, int volume);
|
|||
|
||||
#define ORIGIN_STARTOFNORMAL ((void *)256) // [RH] Used internally
|
||||
|
||||
// [RH] Simplified world ambient playing. Will cycle through all
|
||||
// ORIGIN_WORLDAMBIENTS positions automatically.
|
||||
void S_StartAmbient (char *name, int volume, int surround);
|
||||
|
||||
|
||||
// Stop sound for thing at <origin>
|
||||
void S_StopSound (void *origin);
|
||||
|
||||
|
||||
// Start music using <music_name>
|
||||
void S_StartMusic (char *music_name);
|
||||
|
||||
|
@ -100,15 +121,25 @@ void S_SetMusicVolume (int volume);
|
|||
void S_SetSfxVolume (int volume);
|
||||
|
||||
|
||||
// [RH] Parses all SNDINFO lumps. Should be called from I_InitSound()
|
||||
void S_ParseSndInfo (void);
|
||||
|
||||
// [RH] Activates an ambient sound. Called when the thing is added to the map.
|
||||
// (0-biased)
|
||||
void S_ActivateAmbient (void *mobj, int ambient);
|
||||
|
||||
// [RH] Deactivates all ambient sounds.
|
||||
void S_ClearAmbients (void);
|
||||
// [RH] S_sfx "maintenance" routines
|
||||
void S_ParseSndInfo (void);
|
||||
|
||||
void S_HashSounds (void);
|
||||
int S_FindSound (const char *logicalname);
|
||||
int S_FindSoundByLump (int lump);
|
||||
int S_AddSound (char *logicalname, char *lumpname); // Add sound by lumpname
|
||||
int S_AddSoundLump (char *logicalname, int lump); // Add sound by lump index
|
||||
|
||||
// [RH] Prints sound debug info to the screen.
|
||||
// Modelled after Hexen's noise cheat.
|
||||
void S_NoiseDebug (void);
|
||||
extern struct cvar_s *noisedebug;
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
//
|
||||
// Information about all the sfx
|
||||
//
|
||||
#if 0
|
||||
|
||||
sfxinfo_t S_sfx[] =
|
||||
{
|
||||
|
@ -212,4 +213,5 @@ sfxinfo_t S_sfx[] =
|
|||
{ 0L, false, 32, 0, -1, -1, 0 },
|
||||
{ 0L, false, 32, 0, -1, -1, 0 }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
264
code/Sounds.h
264
code/Sounds.h
|
@ -1,264 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Created by the sound utility written by Dave Taylor.
|
||||
// Kept as a sample, DOOM2 sounds. Frozen.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __SOUNDS__
|
||||
#define __SOUNDS__
|
||||
|
||||
|
||||
//
|
||||
// SoundFX struct.
|
||||
//
|
||||
typedef struct sfxinfo_struct sfxinfo_t;
|
||||
|
||||
struct sfxinfo_struct
|
||||
{
|
||||
// up to 6-character name
|
||||
char *name;
|
||||
|
||||
// Sfx singularity (only one at a time)
|
||||
int singularity;
|
||||
|
||||
// Sfx priority
|
||||
int priority;
|
||||
|
||||
// referenced sound if a link
|
||||
sfxinfo_t* link;
|
||||
|
||||
// pitch if a link
|
||||
int pitch;
|
||||
|
||||
// volume if a link
|
||||
int volume;
|
||||
|
||||
// sound data
|
||||
void* data;
|
||||
|
||||
// this is checked every second to see if sound
|
||||
// can be thrown out (if 0, then decrement, if -1,
|
||||
// then throw out, if > 0, then it is in use)
|
||||
int usefulness;
|
||||
|
||||
// lump number of sfx
|
||||
int lumpnum;
|
||||
|
||||
// [RH] length of sfx in milliseconds
|
||||
unsigned ms;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// the complete set of sound effects
|
||||
extern sfxinfo_t S_sfx[];
|
||||
|
||||
//
|
||||
// Identifiers for all sfx in game.
|
||||
//
|
||||
|
||||
typedef enum
|
||||
{
|
||||
sfx_None,
|
||||
sfx_pistol,
|
||||
sfx_shotgn,
|
||||
sfx_sgcock,
|
||||
sfx_dshtgn,
|
||||
sfx_dbopn,
|
||||
sfx_dbcls,
|
||||
sfx_dbload,
|
||||
sfx_plasma,
|
||||
sfx_bfg,
|
||||
sfx_sawup,
|
||||
sfx_sawidl,
|
||||
sfx_sawful,
|
||||
sfx_sawhit,
|
||||
sfx_rlaunc,
|
||||
sfx_rxplod,
|
||||
sfx_firsht,
|
||||
sfx_firxpl,
|
||||
sfx_pstart,
|
||||
sfx_pstop,
|
||||
sfx_doropn,
|
||||
sfx_dorcls,
|
||||
sfx_stnmov,
|
||||
sfx_swtchn,
|
||||
sfx_swtchx,
|
||||
sfx_plpain,
|
||||
sfx_dmpain,
|
||||
sfx_popain,
|
||||
sfx_vipain,
|
||||
sfx_mnpain,
|
||||
sfx_pepain,
|
||||
sfx_slop,
|
||||
sfx_itemup,
|
||||
sfx_wpnup,
|
||||
sfx_oof,
|
||||
sfx_telept,
|
||||
sfx_posit1,
|
||||
sfx_posit2,
|
||||
sfx_posit3,
|
||||
sfx_bgsit1,
|
||||
sfx_bgsit2,
|
||||
sfx_sgtsit,
|
||||
sfx_cacsit,
|
||||
sfx_brssit,
|
||||
sfx_cybsit,
|
||||
sfx_spisit,
|
||||
sfx_bspsit,
|
||||
sfx_kntsit,
|
||||
sfx_vilsit,
|
||||
sfx_mansit,
|
||||
sfx_pesit,
|
||||
sfx_sklatk,
|
||||
sfx_sgtatk,
|
||||
sfx_skepch,
|
||||
sfx_vilatk,
|
||||
sfx_claw,
|
||||
sfx_skeswg,
|
||||
sfx_pldeth,
|
||||
sfx_pdiehi,
|
||||
sfx_podth1,
|
||||
sfx_podth2,
|
||||
sfx_podth3,
|
||||
sfx_bgdth1,
|
||||
sfx_bgdth2,
|
||||
sfx_sgtdth,
|
||||
sfx_cacdth,
|
||||
sfx_skldth,
|
||||
sfx_brsdth,
|
||||
sfx_cybdth,
|
||||
sfx_spidth,
|
||||
sfx_bspdth,
|
||||
sfx_vildth,
|
||||
sfx_kntdth,
|
||||
sfx_pedth,
|
||||
sfx_skedth,
|
||||
sfx_posact,
|
||||
sfx_bgact,
|
||||
sfx_dmact,
|
||||
sfx_bspact,
|
||||
sfx_bspwlk,
|
||||
sfx_vilact,
|
||||
sfx_noway,
|
||||
sfx_barexp,
|
||||
sfx_punch,
|
||||
sfx_hoof,
|
||||
sfx_metal,
|
||||
sfx_chgun,
|
||||
sfx_tink,
|
||||
sfx_bdopn,
|
||||
sfx_bdcls,
|
||||
sfx_itmbk,
|
||||
sfx_flame,
|
||||
sfx_flamst,
|
||||
sfx_getpow,
|
||||
sfx_bospit,
|
||||
sfx_boscub,
|
||||
sfx_bossit,
|
||||
sfx_bospn,
|
||||
sfx_bosdth,
|
||||
sfx_manatk,
|
||||
sfx_mandth,
|
||||
sfx_sssit,
|
||||
sfx_ssdth,
|
||||
sfx_keenpn,
|
||||
sfx_keendt,
|
||||
sfx_skeact,
|
||||
sfx_skesit,
|
||||
sfx_skeatk,
|
||||
sfx_radio,
|
||||
// [RH] Sound played when entering secret sector
|
||||
sfx_secret,
|
||||
// [RH] Up to 64 ambient sounds
|
||||
sfx_ambient0,
|
||||
sfx_ambient1,
|
||||
sfx_ambient2,
|
||||
sfx_ambient3,
|
||||
sfx_ambient4,
|
||||
sfx_ambient5,
|
||||
sfx_ambient6,
|
||||
sfx_ambient7,
|
||||
sfx_ambient8,
|
||||
sfx_ambient9,
|
||||
sfx_ambient10,
|
||||
sfx_ambient11,
|
||||
sfx_ambient12,
|
||||
sfx_ambient13,
|
||||
sfx_ambient14,
|
||||
sfx_ambient15,
|
||||
sfx_ambient16,
|
||||
sfx_ambient17,
|
||||
sfx_ambient18,
|
||||
sfx_ambient19,
|
||||
sfx_ambient20,
|
||||
sfx_ambient21,
|
||||
sfx_ambient22,
|
||||
sfx_ambient23,
|
||||
sfx_ambient24,
|
||||
sfx_ambient25,
|
||||
sfx_ambient26,
|
||||
sfx_ambient27,
|
||||
sfx_ambient28,
|
||||
sfx_ambient29,
|
||||
sfx_ambient30,
|
||||
sfx_ambient31,
|
||||
sfx_ambient32,
|
||||
sfx_ambient33,
|
||||
sfx_ambient34,
|
||||
sfx_ambient35,
|
||||
sfx_ambient36,
|
||||
sfx_ambient37,
|
||||
sfx_ambient38,
|
||||
sfx_ambient39,
|
||||
sfx_ambient40,
|
||||
sfx_ambient41,
|
||||
sfx_ambient42,
|
||||
sfx_ambient43,
|
||||
sfx_ambient44,
|
||||
sfx_ambient45,
|
||||
sfx_ambient46,
|
||||
sfx_ambient47,
|
||||
sfx_ambient48,
|
||||
sfx_ambient49,
|
||||
sfx_ambient50,
|
||||
sfx_ambient51,
|
||||
sfx_ambient52,
|
||||
sfx_ambient53,
|
||||
sfx_ambient54,
|
||||
sfx_ambient55,
|
||||
sfx_ambient56,
|
||||
sfx_ambient57,
|
||||
sfx_ambient58,
|
||||
sfx_ambient59,
|
||||
sfx_ambient60,
|
||||
sfx_ambient61,
|
||||
sfx_ambient62,
|
||||
sfx_ambient63,
|
||||
NUMSFX
|
||||
} sfxenum_t;
|
||||
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Log:$
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
219
code/St_stuff.c
219
code/St_stuff.c
|
@ -58,7 +58,6 @@
|
|||
|
||||
// Data.
|
||||
#include "dstrings.h"
|
||||
#include "sounds.h"
|
||||
|
||||
// Cheats and cvars
|
||||
#include "c_cmds.h"
|
||||
|
@ -84,20 +83,16 @@ void ST_initNew (void);
|
|||
void ST_unloadNew (void);
|
||||
void ST_newDraw (void);
|
||||
|
||||
// [RH] Base blending values (for e.g. underwater)
|
||||
int BaseBlendR, BaseBlendG, BaseBlendB;
|
||||
float BaseBlendA;
|
||||
|
||||
|
||||
//
|
||||
// STATUS BAR DATA
|
||||
//
|
||||
|
||||
|
||||
// Palette indices.
|
||||
// For damage/bonus red-/gold-shifts
|
||||
#define STARTREDPALS 1
|
||||
#define STARTBONUSPALS 9
|
||||
#define NUMREDPALS 8
|
||||
#define NUMBONUSPALS 4
|
||||
// Radiation suit, green shift.
|
||||
#define RADIATIONPAL 13
|
||||
|
||||
// N/256*100% probability
|
||||
// that the normal face state will change
|
||||
#define ST_FACEPROBABILITY 96
|
||||
|
@ -106,10 +101,7 @@ void ST_newDraw (void);
|
|||
#define ST_TOGGLECHAT KEY_ENTER
|
||||
|
||||
// Location of status bar
|
||||
#define ST_X2 (104)
|
||||
|
||||
#define ST_FX (143)
|
||||
#define ST_FY (1)
|
||||
|
||||
// Should be set to patch width
|
||||
// for tall numbers later on
|
||||
|
@ -298,9 +290,6 @@ BOOL st_firsttime;
|
|||
// used to execute ST_Init() only once
|
||||
static int veryfirsttime = 1;
|
||||
|
||||
// lump number for PLAYPAL
|
||||
static int lu_palette;
|
||||
|
||||
// used for timing
|
||||
static unsigned int st_clock;
|
||||
|
||||
|
@ -348,11 +337,10 @@ patch_t* tallpercent;
|
|||
// 0-9, short, yellow (,different!) numbers
|
||||
static patch_t* shortnum[10];
|
||||
|
||||
// 3 key-cards, 3 skulls
|
||||
static patch_t* keys[NUMCARDS];
|
||||
// 3 key-cards, 3 skulls, [RH] 3 combined
|
||||
static patch_t* keys[NUMCARDS+NUMCARDS/2];
|
||||
|
||||
// face status patches
|
||||
// [RH] no longer static
|
||||
// face status patches [RH] no longer static
|
||||
patch_t* faces[ST_NUMFACES];
|
||||
|
||||
// face background
|
||||
|
@ -535,8 +523,7 @@ void ST_refreshBackground(void)
|
|||
if (netgame) {
|
||||
// [RH] Always draw faceback with the player's color
|
||||
// using a translation rather than a different patch.
|
||||
// Use displayplayer instead of consoleplayer.
|
||||
V_ColorMap = translationtables + displayplayer*256;
|
||||
V_ColorMap = translationtables + (plyr - players)*256;
|
||||
V_DrawTranslatedPatch (ST_FX, 0, &BG, faceback);
|
||||
}
|
||||
|
||||
|
@ -552,15 +539,15 @@ void ST_refreshBackground(void)
|
|||
|
||||
BOOL CheckCheatmode (void);
|
||||
|
||||
// Respond to keyboard input events,
|
||||
// intercept cheats.
|
||||
// Respond to keyboard input events, intercept cheats.
|
||||
// [RH] Cheats eat the last keypress used to trigger them
|
||||
BOOL ST_Responder (event_t *ev)
|
||||
{
|
||||
BOOL eat = false;
|
||||
int i;
|
||||
|
||||
// Filter automap on/off.
|
||||
if (ev->type == ev_keyup
|
||||
&& ((ev->data1 & 0xffff0000) == AM_MSGHEADER))
|
||||
if (ev->type == ev_keyup && ((ev->data1 & 0xffff0000) == AM_MSGHEADER))
|
||||
{
|
||||
switch(ev->data1)
|
||||
{
|
||||
|
@ -570,7 +557,6 @@ BOOL ST_Responder (event_t *ev)
|
|||
break;
|
||||
|
||||
case AM_MSGEXITED:
|
||||
// fprintf(stderr, "AM exited\n");
|
||||
st_gamestate = FirstPersonState;
|
||||
break;
|
||||
}
|
||||
|
@ -590,6 +576,7 @@ BOOL ST_Responder (event_t *ev)
|
|||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_IDDQD);
|
||||
eat = true;
|
||||
}
|
||||
|
||||
// 'fa' cheat for killer fucking arsenal
|
||||
|
@ -600,6 +587,7 @@ BOOL ST_Responder (event_t *ev)
|
|||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_IDFA);
|
||||
eat = true;
|
||||
}
|
||||
|
||||
// 'kfa' cheat for key full ammo
|
||||
|
@ -610,6 +598,7 @@ BOOL ST_Responder (event_t *ev)
|
|||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_IDKFA);
|
||||
eat = true;
|
||||
}
|
||||
|
||||
// Simplified, accepting both "noclip" and "idspispopd".
|
||||
|
@ -622,6 +611,7 @@ BOOL ST_Responder (event_t *ev)
|
|||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_NOCLIP);
|
||||
eat = true;
|
||||
}
|
||||
// 'behold?' power-up cheats
|
||||
for (i=0;i<6;i++)
|
||||
|
@ -633,6 +623,7 @@ BOOL ST_Responder (event_t *ev)
|
|||
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte ((byte)(CHT_BEHOLDV + i));
|
||||
eat = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -650,12 +641,14 @@ BOOL ST_Responder (event_t *ev)
|
|||
{
|
||||
Net_WriteByte (DEM_GENERICCHEAT);
|
||||
Net_WriteByte (CHT_CHAINSAW);
|
||||
eat = true;
|
||||
}
|
||||
|
||||
// 'mypos' for player position
|
||||
else if (cht_CheckCheat(&cheat_mypos, (char)ev->data2))
|
||||
{
|
||||
AddCommandString ("toggle idmypos");
|
||||
eat = true;
|
||||
}
|
||||
|
||||
// 'clev' change-level cheat
|
||||
|
@ -670,6 +663,7 @@ BOOL ST_Responder (event_t *ev)
|
|||
argv[0] = "idclev";
|
||||
argv[1] = buf;
|
||||
Cmd_idclev (plyr, 2, argv);
|
||||
eat = true;
|
||||
}
|
||||
|
||||
// 'idmus' change-music cheat
|
||||
|
@ -682,10 +676,11 @@ BOOL ST_Responder (event_t *ev)
|
|||
|
||||
sprintf (buf + 3, "idmus %s\n", buf);
|
||||
AddCommandString (buf + 3);
|
||||
eat = true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return eat;
|
||||
}
|
||||
|
||||
|
||||
|
@ -918,8 +913,9 @@ void ST_updateWidgets(void)
|
|||
{
|
||||
keyboxes[i] = plyr->cards[i] ? i : -1;
|
||||
|
||||
// [RH] show multiple keys per box, too
|
||||
if (plyr->cards[i+3])
|
||||
keyboxes[i] = i+3;
|
||||
keyboxes[i] = (keyboxes[i] == -1) ? i+3 : i+6;
|
||||
}
|
||||
|
||||
// refresh everything if this is him coming back to life
|
||||
|
@ -951,21 +947,66 @@ void ST_Ticker (void)
|
|||
|
||||
}
|
||||
|
||||
static int st_palette = 0;
|
||||
static float st_palette[4];
|
||||
|
||||
// [RH] Amount of red flash for up to 114 damage points. Calculated by hand
|
||||
// using a logarithmic scale and my trusty HP48G.
|
||||
static byte damageToAlpha[114] = {
|
||||
0, 8, 16, 23, 30, 36, 42, 47, 53, 58, 62, 67, 71, 75, 79,
|
||||
83, 87, 90, 94, 97, 100, 103, 107, 109, 112, 115, 118, 120, 123, 125,
|
||||
128, 130, 133, 135, 137, 139, 141, 143, 145, 147, 149, 151, 153, 155, 157,
|
||||
159, 160, 162, 164, 165, 167, 169, 170, 172, 173, 175, 176, 178, 179, 181,
|
||||
182, 183, 185, 186, 187, 189, 190, 191, 192, 194, 195, 196, 197, 198, 200,
|
||||
201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212, 213, 214, 215, 216,
|
||||
217, 218, 219, 220, 221, 221, 222, 223, 224, 225, 226, 227, 228, 229, 229,
|
||||
230, 231, 232, 233, 234, 235, 235, 236, 237
|
||||
};
|
||||
|
||||
/*
|
||||
=============
|
||||
SV_AddBlend
|
||||
[RH] This is from Q2.
|
||||
=============
|
||||
*/
|
||||
void SV_AddBlend (float r, float g, float b, float a, float *v_blend)
|
||||
{
|
||||
float a2, a3;
|
||||
|
||||
if (a <= 0)
|
||||
return;
|
||||
a2 = v_blend[3] + (1-v_blend[3])*a; // new total alpha
|
||||
a3 = v_blend[3]/a2; // fraction of color from old
|
||||
|
||||
v_blend[0] = v_blend[0]*a3 + r*(1-a3);
|
||||
v_blend[1] = v_blend[1]*a3 + g*(1-a3);
|
||||
v_blend[2] = v_blend[2]*a3 + b*(1-a3);
|
||||
v_blend[3] = a2;
|
||||
}
|
||||
|
||||
void ST_doPaletteStuff (void)
|
||||
{
|
||||
float blend[4];
|
||||
int cnt;
|
||||
|
||||
int palette;
|
||||
int cnt;
|
||||
int bzc;
|
||||
blend[0] = blend[1] = blend[2] = blend[3] = 0;
|
||||
|
||||
cnt = plyr->damagecount << 1;
|
||||
SV_AddBlend (BaseBlendR / 255.0f, BaseBlendG / 255.0f, BaseBlendB / 255.0f, BaseBlendA, blend);
|
||||
if (plyr->powers[pw_ironfeet] > 4*32 || plyr->powers[pw_ironfeet]&8)
|
||||
SV_AddBlend (0.0f, 1.0f, 0.0f, 0.125f, blend);
|
||||
if (plyr->bonuscount) {
|
||||
cnt = plyr->bonuscount << 3;
|
||||
SV_AddBlend (0.8431f, 0.7294f, 0.2706f, cnt > 128 ? 0.5f : cnt / 255.0f, blend);
|
||||
}
|
||||
|
||||
if (plyr->damagecount < 114)
|
||||
cnt = damageToAlpha[plyr->damagecount];
|
||||
else
|
||||
cnt = damageToAlpha[113];
|
||||
|
||||
if (plyr->powers[pw_strength])
|
||||
{
|
||||
// slowly fade the berzerk out
|
||||
bzc = 128 - ((plyr->powers[pw_strength]>>3) & (~0x1f));
|
||||
int bzc = 128 - ((plyr->powers[pw_strength]>>3) & (~0x1f));
|
||||
|
||||
if (bzc > cnt)
|
||||
cnt = bzc;
|
||||
|
@ -975,31 +1016,14 @@ void ST_doPaletteStuff (void)
|
|||
{
|
||||
if (cnt > 228)
|
||||
cnt = 228;
|
||||
else if (cnt < 28)
|
||||
cnt = 28;
|
||||
|
||||
palette = MAKEARGB(cnt,255,0,0);
|
||||
SV_AddBlend (1.0f, 0.0f, 0.0f, cnt / 255.0f, blend);
|
||||
}
|
||||
|
||||
else if (plyr->bonuscount)
|
||||
{
|
||||
cnt = plyr->bonuscount << 3;
|
||||
|
||||
palette = MAKEARGB((cnt > 128) ? 128 : cnt,215,186,69);
|
||||
}
|
||||
|
||||
else if ( plyr->powers[pw_ironfeet] > 4*32
|
||||
|| plyr->powers[pw_ironfeet]&8)
|
||||
{
|
||||
palette = MAKEARGB(32,0,255,0);
|
||||
}
|
||||
|
||||
else
|
||||
palette = MAKEARGB(0,0,0,0);
|
||||
|
||||
if (palette != st_palette) {
|
||||
st_palette = palette;
|
||||
V_SetBlend (RPART(palette), GPART(palette), BPART(palette), APART(palette));
|
||||
if (memcmp (blend, st_palette, sizeof(blend))) {
|
||||
memcpy (st_palette, blend, sizeof(blend));
|
||||
V_SetBlend ((int)(blend[0] * 255.0f), (int)(blend[1] * 255.0f),
|
||||
(int)(blend[2] * 255.0f), (int)(blend[3] * 256.0f));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1062,7 +1086,7 @@ void ST_diffDraw(void)
|
|||
|
||||
void ST_Drawer (BOOL fullscreen, BOOL refresh)
|
||||
{
|
||||
|
||||
|
||||
st_statusbaron = (!fullscreen) || automapactive;
|
||||
st_firsttime = st_firsttime || refresh;
|
||||
|
||||
|
@ -1081,22 +1105,26 @@ void ST_Drawer (BOOL fullscreen, BOOL refresh)
|
|||
V_UnlockScreen (&stbarscreen);
|
||||
|
||||
// [RH] Hey, it's somewhere to put the idmypos stuff!
|
||||
// Use displayplayer instead of consoleplayer
|
||||
if (idmypos->value)
|
||||
Printf ("ang=%d;x,y=(%d,%d)\n",
|
||||
players[displayplayer].mo->angle/FRACUNIT,
|
||||
players[displayplayer].mo->x/FRACUNIT,
|
||||
players[displayplayer].mo->y/FRACUNIT);
|
||||
players[consoleplayer].camera->angle/FRACUNIT,
|
||||
players[consoleplayer].camera->x/FRACUNIT,
|
||||
players[consoleplayer].camera->y/FRACUNIT);
|
||||
}
|
||||
|
||||
void ST_loadGraphics(void)
|
||||
{
|
||||
|
||||
int i;
|
||||
int j;
|
||||
int facenum;
|
||||
playerskin_t *skin;
|
||||
int i, j;
|
||||
int namespc;
|
||||
int facenum;
|
||||
|
||||
char namebuf[9];
|
||||
char namebuf[9];
|
||||
|
||||
if (plyr)
|
||||
skin = &skins[plyr->userinfo.skin];
|
||||
else
|
||||
skin = &skins[players[consoleplayer].userinfo.skin];
|
||||
|
||||
// Load the numbers, tall and short
|
||||
for (i=0;i<10;i++)
|
||||
|
@ -1113,7 +1141,7 @@ void ST_loadGraphics(void)
|
|||
tallpercent = (patch_t *) W_CacheLumpName("STTPRCNT", PU_STATIC);
|
||||
|
||||
// key cards
|
||||
for (i=0;i<NUMCARDS;i++)
|
||||
for (i=0;i<NUMCARDS+NUMCARDS/2;i++)
|
||||
{
|
||||
sprintf(namebuf, "STKEYS%d", i);
|
||||
keys[i] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
|
||||
|
@ -1144,32 +1172,44 @@ void ST_loadGraphics(void)
|
|||
|
||||
// face states
|
||||
facenum = 0;
|
||||
for (i=0;i<ST_NUMPAINFACES;i++)
|
||||
|
||||
// [RH] Use face specified by "skin"
|
||||
if (skin->face[0]) {
|
||||
// The skin has its own face
|
||||
strncpy (namebuf, skin->face, 3);
|
||||
namespc = skin->namespc;
|
||||
} else {
|
||||
// The skin doesn't have its own face; use the normal one
|
||||
namebuf[0] = 'S'; namebuf[1] = 'T'; namebuf[2] = 'F';
|
||||
namespc = ns_global;
|
||||
}
|
||||
|
||||
for (i = 0; i < ST_NUMPAINFACES; i++)
|
||||
{
|
||||
for (j=0;j<ST_NUMSTRAIGHTFACES;j++)
|
||||
for (j = 0; j < ST_NUMSTRAIGHTFACES; j++)
|
||||
{
|
||||
sprintf(namebuf, "STFST%d%d", i, j);
|
||||
sprintf(namebuf+3, "ST%d%d", i, j);
|
||||
faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
|
||||
}
|
||||
sprintf(namebuf, "STFTR%d0", i); // turn right
|
||||
faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
|
||||
sprintf(namebuf, "STFTL%d0", i); // turn left
|
||||
faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
|
||||
sprintf(namebuf, "STFOUCH%d", i); // ouch!
|
||||
faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
|
||||
sprintf(namebuf, "STFEVL%d", i); // evil grin ;)
|
||||
faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
|
||||
sprintf(namebuf, "STFKILL%d", i); // pissed off
|
||||
faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
|
||||
sprintf(namebuf+3, "TR%d0", i); // turn right
|
||||
faces[facenum++] = W_CacheLumpNum ((W_CheckNumForName)(namebuf, namespc), PU_STATIC);
|
||||
sprintf(namebuf+3, "TL%d0", i); // turn left
|
||||
faces[facenum++] = W_CacheLumpNum ((W_CheckNumForName)(namebuf, namespc), PU_STATIC);
|
||||
sprintf(namebuf+3, "OUCH%d", i); // ouch!
|
||||
faces[facenum++] = W_CacheLumpNum ((W_CheckNumForName)(namebuf, namespc), PU_STATIC);
|
||||
sprintf(namebuf+3, "EVL%d", i); // evil grin ;)
|
||||
faces[facenum++] = W_CacheLumpNum ((W_CheckNumForName)(namebuf, namespc), PU_STATIC);
|
||||
sprintf(namebuf+3, "KILL%d", i); // pissed off
|
||||
faces[facenum++] = W_CacheLumpNum ((W_CheckNumForName)(namebuf, namespc), PU_STATIC);
|
||||
}
|
||||
faces[facenum++] = W_CacheLumpName("STFGOD0", PU_STATIC);
|
||||
faces[facenum++] = W_CacheLumpName("STFDEAD0", PU_STATIC);
|
||||
|
||||
strcpy (namebuf+3, "GOD0");
|
||||
faces[facenum++] = W_CacheLumpNum ((W_CheckNumForName)(namebuf, namespc), PU_STATIC);
|
||||
strcpy (namebuf+3, "DEAD0");
|
||||
faces[facenum++] = W_CacheLumpNum ((W_CheckNumForName)(namebuf, namespc), PU_STATIC);
|
||||
}
|
||||
|
||||
void ST_loadData(void)
|
||||
{
|
||||
lu_palette = W_GetNumForName ("PLAYPAL");
|
||||
ST_loadGraphics();
|
||||
}
|
||||
|
||||
|
@ -1195,7 +1235,7 @@ void ST_unloadGraphics(void)
|
|||
Z_ChangeTag(arms[i][0], PU_CACHE);
|
||||
|
||||
// unload the key cards
|
||||
for (i=0;i<NUMCARDS;i++)
|
||||
for (i=0;i<NUMCARDS+NUMCARDS/2;i++)
|
||||
Z_ChangeTag(keys[i], PU_CACHE);
|
||||
|
||||
Z_ChangeTag(sbar, PU_CACHE);
|
||||
|
@ -1222,7 +1262,10 @@ void ST_initData(void)
|
|||
int i;
|
||||
|
||||
st_firsttime = true;
|
||||
plyr = &players[displayplayer]; // [RH] Not consoleplayer
|
||||
if (players[consoleplayer].camera && players[consoleplayer].camera->player)
|
||||
plyr = players[consoleplayer].camera->player; // [RH] use camera
|
||||
else
|
||||
plyr = &players[consoleplayer];
|
||||
|
||||
st_clock = 0;
|
||||
st_chatstate = StartChatState;
|
||||
|
@ -1233,7 +1276,7 @@ void ST_initData(void)
|
|||
st_cursoron = false;
|
||||
|
||||
st_faceindex = 0;
|
||||
st_palette = -1;
|
||||
memset (st_palette, 255, sizeof(st_palette));
|
||||
|
||||
st_oldhealth = -1;
|
||||
|
||||
|
|
|
@ -58,6 +58,9 @@ void ST_Init (void);
|
|||
// Draw the HUD (only if old status bar is not drawn)
|
||||
void ST_newDraw (void);
|
||||
|
||||
// Called on init and whenever player's skin changes
|
||||
void ST_loadGraphics (void);
|
||||
|
||||
|
||||
// States for status bar code.
|
||||
typedef enum
|
||||
|
@ -80,6 +83,9 @@ typedef enum
|
|||
|
||||
BOOL ST_Responder(event_t* ev);
|
||||
|
||||
// [RH] Base blending values (for e.g. underwater)
|
||||
extern int BaseBlendR, BaseBlendG, BaseBlendB;
|
||||
extern float BaseBlendA;
|
||||
|
||||
|
||||
#endif
|
249
code/V_video.c
249
code/V_video.c
|
@ -25,6 +25,12 @@
|
|||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "minilzo.h"
|
||||
// [RH] Output buffer size for LZO compression.
|
||||
// Extra space in case uncompressable.
|
||||
#define OUT_LEN(a) ((a) + (a) / 64 + 16 + 3)
|
||||
|
||||
#include "m_alloc.h"
|
||||
|
||||
#include "i_system.h"
|
||||
|
@ -38,6 +44,7 @@
|
|||
#include "doomdata.h"
|
||||
#include "doomstat.h"
|
||||
|
||||
#include "c_consol.h"
|
||||
#include "hu_stuff.h"
|
||||
|
||||
#include "m_argv.h"
|
||||
|
@ -57,13 +64,17 @@
|
|||
|
||||
extern void STACK_ARGS DimScreenPLoop (byte *colormap, byte *screen, int width, int modulo, int height);
|
||||
|
||||
extern char *IdStrings[22];
|
||||
extern int DisplayID;
|
||||
|
||||
|
||||
|
||||
// [RH] Screens are no longer mere byte arrays.
|
||||
screen_t screens[2];
|
||||
|
||||
|
||||
int dirtybox[4];
|
||||
|
||||
cvar_t *vid_defwidth, *vid_defheight, *vid_defbpp;
|
||||
cvar_t *vid_defwidth, *vid_defheight, *vid_defid;
|
||||
cvar_t *dimamount, *dimcolor;
|
||||
|
||||
byte *TransTable;
|
||||
|
@ -74,7 +85,7 @@ palette_t *DefaultPalette;
|
|||
// [RH] Set true when vid_setmode command has been executed
|
||||
BOOL setmodeneeded = false;
|
||||
// [RH] Resolution to change to when setmodeneeded is true
|
||||
int NewWidth, NewHeight, NewBpp;
|
||||
int NewWidth, NewHeight, NewID;
|
||||
|
||||
|
||||
//
|
||||
|
@ -485,9 +496,10 @@ void V_Blit (screen_t *src, int srcx, int srcy, int srcwidth, int srcheight,
|
|||
//
|
||||
// V_SetResolution
|
||||
//
|
||||
BOOL V_DoModeSetup (int width, int height, int bpp)
|
||||
BOOL V_DoModeSetup (int width, int height, int id)
|
||||
{
|
||||
int i;
|
||||
int bpp;
|
||||
|
||||
CleanXfac = width / 320;
|
||||
CleanYfac = height / 200;
|
||||
|
@ -499,8 +511,8 @@ BOOL V_DoModeSetup (int width, int height, int bpp)
|
|||
if (screens[i].impdata)
|
||||
V_FreeScreen (&screens[i]);
|
||||
|
||||
I_SetMode (width, height, bpp);
|
||||
bpp = (bpp == 8) ? bpp : 32;
|
||||
I_SetMode (width, height, id);
|
||||
bpp = (id == 1010) ? 8 : 32;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (!I_AllocateScreen (&screens[i], width, height, bpp))
|
||||
|
@ -517,98 +529,127 @@ BOOL V_DoModeSetup (int width, int height, int bpp)
|
|||
return true;
|
||||
}
|
||||
|
||||
BOOL V_SetResolution (int width, int height, int Bpp)
|
||||
BOOL V_SetResolution (int width, int height, int id)
|
||||
{
|
||||
int oldwidth, oldheight;
|
||||
int oldBpp;
|
||||
int oldID;
|
||||
|
||||
if (screens[0].impdata) {
|
||||
oldwidth = screens[0].width;
|
||||
oldheight = screens[0].height;
|
||||
oldBpp = screens[0].Bpp * 8;
|
||||
oldID = DisplayID;
|
||||
} else {
|
||||
// Harmless if screens[0] wasn't allocated
|
||||
oldwidth = width;
|
||||
oldheight = height;
|
||||
oldBpp = Bpp;
|
||||
oldID = id;
|
||||
}
|
||||
|
||||
if (!I_CheckResolution (width, height, Bpp)) { // Try specified resolution
|
||||
if (!I_CheckResolution (oldwidth, oldheight, oldBpp)) { // Try previous resolution (if any)
|
||||
if (!I_CheckResolution (320, 200, 8)) { // Try "standard" resolution
|
||||
if (!I_CheckResolution (640, 480, 8)) { // Try a resolution that *should* be available
|
||||
if (!I_CheckResolution (width, height, id)) { // Try specified resolution
|
||||
if (!I_CheckResolution (oldwidth, oldheight, oldID)) { // Try previous resolution (if any)
|
||||
if (!I_CheckResolution (320, 200, 1010)) { // Try "standard" resolution
|
||||
if (!I_CheckResolution (640, 480, 1010)) { // Try a resolution that *should* be available
|
||||
return false;
|
||||
} else {
|
||||
width = 640;
|
||||
height = 480;
|
||||
Bpp = 8;
|
||||
id = 1010;
|
||||
}
|
||||
} else {
|
||||
width = 320;
|
||||
height = 200;
|
||||
Bpp = 8;
|
||||
id = 1010;
|
||||
}
|
||||
} else {
|
||||
width = oldwidth;
|
||||
height = oldheight;
|
||||
Bpp = oldBpp;
|
||||
id = oldID;
|
||||
}
|
||||
}
|
||||
|
||||
return V_DoModeSetup (width, height, Bpp);
|
||||
return V_DoModeSetup (width, height, id);
|
||||
}
|
||||
|
||||
void Cmd_Vid_SetMode (void *plyr, int argc, char **argv)
|
||||
{
|
||||
BOOL goodmode = false;
|
||||
int width = 0, height = screens[0].height, bpp = screens[0].Bpp * 8;
|
||||
int width = 0, height = screens[0].height;
|
||||
int id = DisplayID;
|
||||
|
||||
if (argc > 1) {
|
||||
width = atoi (argv[1]);
|
||||
if (argc > 2) {
|
||||
height = atoi (argv[2]);
|
||||
if (argc > 3)
|
||||
bpp = atoi (argv[3]);
|
||||
if (argc > 3) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 22; i++)
|
||||
if (!stricmp (IdStrings[i], argv[3]))
|
||||
break;
|
||||
|
||||
if (i < 22)
|
||||
id = 1000 + i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (width) {
|
||||
if (I_CheckResolution (width, height, bpp))
|
||||
if (I_CheckResolution (width, height, id))
|
||||
goodmode = true;
|
||||
}
|
||||
|
||||
if (goodmode) {
|
||||
// The actual change of resolution will take place
|
||||
// near the beginning of D_Display().
|
||||
setmodeneeded = true;
|
||||
NewWidth = width;
|
||||
NewHeight = height;
|
||||
NewBpp = bpp;
|
||||
if (gamestate != GS_STARTUP) {
|
||||
setmodeneeded = true;
|
||||
NewWidth = width;
|
||||
NewHeight = height;
|
||||
NewID = id;
|
||||
}
|
||||
} else if (width) {
|
||||
Printf ("Unknown resolution %d x %d x %d\n", width, height, bpp);
|
||||
Printf ("Unknown resolution %d x %d (%s)\n", width, height, IdStrings[id-1000]);
|
||||
} else {
|
||||
Printf ("Usage: vid_setmode <width> <height> <bpp>\n");
|
||||
Printf ("Usage: vid_setmode <width> <height> <mode>\n");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// V_Init
|
||||
//
|
||||
//
|
||||
extern char *IdStrings[22];
|
||||
extern int DisplayID;
|
||||
|
||||
static int IdNameToId (char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 22; i++) {
|
||||
if (!stricmp (IdStrings[0], name))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < 22)
|
||||
return i + 1000;
|
||||
else
|
||||
return 1010; // INDEX8
|
||||
}
|
||||
|
||||
void V_Init (void)
|
||||
{
|
||||
static const char tag[] = "LZO-Compressed ZDoom Translucency Cache File v01";
|
||||
int i;
|
||||
int width, height, bpp;
|
||||
int width, height, id;
|
||||
|
||||
// [RH] Setup gamma callback
|
||||
gammalevel->u.callback = GammaCallback;
|
||||
GammaCallback (gammalevel);
|
||||
|
||||
// [RH] Initialize palette subsystem
|
||||
Printf ("InitPalettes\n");
|
||||
if (!(DefaultPalette = InitPalettes ("PLAYPAL")))
|
||||
I_FatalError ("Could not start palette subsystem");
|
||||
I_FatalError ("Could not initialize palette");
|
||||
|
||||
width = height = bpp = 0;
|
||||
width = height = id = 0;
|
||||
|
||||
if ( (i = M_CheckParm ("-width")) )
|
||||
if (i < myargc - 1)
|
||||
|
@ -616,11 +657,11 @@ void V_Init (void)
|
|||
|
||||
if ( (i = M_CheckParm ("-height")) )
|
||||
if (i < myargc - 1)
|
||||
height = atoi (myargv[i + 1]);
|
||||
height = atoi (myargv[i + 1]);
|
||||
|
||||
if ( (i = M_CheckParm ("-bpp")) )
|
||||
if ( (i = M_CheckParm ("-mode")) )
|
||||
if (i < myargc - 1)
|
||||
bpp = atoi (myargv[i + 1]);
|
||||
id = IdNameToId (myargv[i + 1]);
|
||||
|
||||
if (width == 0) {
|
||||
if (height == 0) {
|
||||
|
@ -633,19 +674,20 @@ void V_Init (void)
|
|||
height = (width * 6) / 8;
|
||||
}
|
||||
|
||||
if (bpp == 0) {
|
||||
bpp = (int)(vid_defbpp->value);
|
||||
if (id == 0) {
|
||||
id = IdNameToId (vid_defid->string);
|
||||
}
|
||||
|
||||
if (!V_SetResolution (width, height, bpp)) {
|
||||
I_FatalError ("Could not set resolution to %d x %d x %d", width, height, bpp);
|
||||
if (!V_SetResolution (width, height, id)) {
|
||||
I_FatalError ("Could not set resolution to %d x %d (%s)", width, height, IdStrings[id-1000]);
|
||||
} else {
|
||||
Printf ("Resolution: %d x %d x %d\n", screens[0].width, screens[0].height, screens[0].Bpp * 8);
|
||||
Printf ("Resolution: %d x %d (%s)\n", screens[0].width, screens[0].height, IdStrings[id-1000]);
|
||||
}
|
||||
|
||||
V_InitConChars (0xf7);
|
||||
C_InitConsole (screens[0].width, screens[0].height, true);
|
||||
|
||||
{
|
||||
{/*
|
||||
static int palpoop[256];
|
||||
byte *palette = W_CacheLumpName ("PLAYPAL", PU_CACHE);
|
||||
int i;
|
||||
|
@ -656,15 +698,14 @@ void V_Init (void)
|
|||
(palette[2]);
|
||||
palette += 3;
|
||||
}
|
||||
|
||||
V_Palette = palpoop;
|
||||
*/
|
||||
V_Palette = DefaultPalette->colors;
|
||||
}
|
||||
|
||||
if (!M_CheckParm ("-notrans")) {
|
||||
char cachename[256];
|
||||
byte *palette;
|
||||
BOOL isCached = false;
|
||||
FILE *cached;
|
||||
FILE *cache;
|
||||
int i;
|
||||
|
||||
// Align TransTable on a 64k boundary
|
||||
|
@ -674,6 +715,7 @@ void V_Init (void)
|
|||
i = M_CheckParm("-transfile");
|
||||
if (i && i < myargc - 1) {
|
||||
strcpy (cachename, myargv[i+1]);
|
||||
FixPathSeperator (cachename);
|
||||
DefaultExtension (cachename, ".tch");
|
||||
} else {
|
||||
sprintf (cachename, "%stranstab.tch", progdir);
|
||||
|
@ -681,36 +723,109 @@ void V_Init (void)
|
|||
palette = W_CacheLumpName ("PLAYPAL", PU_CACHE);
|
||||
|
||||
{ // Check for cached translucency table
|
||||
byte cachepal[768];
|
||||
byte *cachemem;
|
||||
byte *out;
|
||||
int newlen;
|
||||
int cachelen;
|
||||
int insidelen;
|
||||
int r;
|
||||
|
||||
cached = fopen (cachename, "rb");
|
||||
if (cached) {
|
||||
if (fread (cachepal, 1, 768, cached) == 768) {
|
||||
if (memcmp (cachepal, palette, 768)) {
|
||||
Printf ("Translucency cache was generated with a different palette\n");
|
||||
} else {
|
||||
isCached = (fread (TransTable, 1, 65536*3, cached) == 65536*3);
|
||||
}
|
||||
cache = fopen (cachename, "rb");
|
||||
if (cache) {
|
||||
fseek (cache, 0, SEEK_END);
|
||||
cachelen = ftell (cache);
|
||||
fseek (cache, 0, SEEK_SET);
|
||||
|
||||
if (cachelen <= strlen(tag) + sizeof(int)) {
|
||||
fclose (cache);
|
||||
cache = NULL;
|
||||
goto maketable;
|
||||
}
|
||||
if (!isCached) {
|
||||
Printf ("Bad translucency cache file\n");
|
||||
|
||||
cachemem = Z_Malloc (cachelen, PU_STATIC, 0);
|
||||
if (fread (cachemem, 1, cachelen, cache) != cachelen) {
|
||||
fclose (cache);
|
||||
cache = NULL;
|
||||
Printf ("Trouble reading tranlucency cache\n");
|
||||
goto maketable;
|
||||
}
|
||||
|
||||
fclose (cache);
|
||||
|
||||
if (strncmp (tag, cachemem, strlen(tag)) != 0) {
|
||||
Printf ("Regenerating old translucency cache\n");
|
||||
cache = NULL;
|
||||
goto maketable;
|
||||
}
|
||||
|
||||
// So far, so good. Try expanding the cached data.
|
||||
memcpy (&insidelen, cachemem + strlen(tag), sizeof(int));
|
||||
if (insidelen != cachelen - strlen(tag) - sizeof(int)) {
|
||||
Printf ("Translucency cache wrong size\n");
|
||||
cache = NULL;
|
||||
goto maketable;
|
||||
}
|
||||
|
||||
out = Z_Malloc (65536*3+768, PU_STATIC, 0);
|
||||
|
||||
r = lzo1x_decompress (cachemem + strlen(tag) + sizeof(int),
|
||||
insidelen, out, &newlen, NULL);
|
||||
|
||||
if (r != LZO_E_OK || newlen != 65536*3+768) {
|
||||
Printf ("Bad translucency cache\n");
|
||||
cache = NULL;
|
||||
Z_Free (out);
|
||||
goto maketable;
|
||||
}
|
||||
|
||||
// Check to make sure if the cache was generated from the
|
||||
// current PLAYPAL. If not, we need to generate it, but
|
||||
// don't bother replacing this one.
|
||||
if (memcmp (out, palette, 768)) {
|
||||
Printf ("Translucency cache was generated with a different palette\n");
|
||||
Z_Free (out);
|
||||
goto maketable;
|
||||
}
|
||||
|
||||
// Everything's good. Use the cached data.
|
||||
memcpy (TransTable, out+768, 65536*3);
|
||||
TransTable -= 65536;
|
||||
Z_Free (out);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isCached) {
|
||||
Printf ("Creating translucency tables\n");
|
||||
BuildTransTable (TransTable, DefaultPalette->basecolors);
|
||||
if (!cached) {
|
||||
cached = fopen (cachename, "wb");
|
||||
if (cached) {
|
||||
fwrite (palette, 1, 768, cached);
|
||||
fwrite (TransTable, 1, 65536*3, cached);
|
||||
maketable:
|
||||
Printf ("Creating translucency tables\n");
|
||||
BuildTransTable (TransTable, DefaultPalette->basecolors);
|
||||
if (!cache) {
|
||||
byte *out, *wrkmem, *in;
|
||||
int outlen, r;
|
||||
|
||||
wrkmem = Z_Malloc (LZO1X_1_MEM_COMPRESS, PU_STATIC, 0);
|
||||
in = Z_Malloc (768 + 65536*3, PU_STATIC, 0);
|
||||
out = Z_Malloc (768 + 65536*3, PU_STATIC, 0);
|
||||
|
||||
strncpy (in, tag, strlen (tag));
|
||||
memcpy (in, palette, 768);
|
||||
memcpy (in+768, TransTable, 65536*3);
|
||||
|
||||
r = lzo1x_1_compress (in, 768+65536*3, out, &outlen, wrkmem);
|
||||
|
||||
Z_Free (wrkmem);
|
||||
Z_Free (in);
|
||||
|
||||
if (r == LZO_E_OK) {
|
||||
cache = fopen (cachename, "wb");
|
||||
|
||||
if (cache) {
|
||||
fwrite (tag, 1, strlen(tag), cache);
|
||||
fwrite (&outlen, sizeof(outlen), 1, cache);
|
||||
fwrite (out, 1, outlen, cache);
|
||||
fclose (cache);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cached)
|
||||
fclose (cached);
|
||||
|
||||
TransTable -= 65536;
|
||||
}
|
||||
|
|
90
code/W_wad.c
90
code/W_wad.c
|
@ -18,6 +18,7 @@
|
|||
//
|
||||
// DESCRIPTION:
|
||||
// Handles WAD file header, directory, lump I/O.
|
||||
// [RH] Changed to use buffered I/O (fread, etc)
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -57,14 +58,19 @@ int numlumps;
|
|||
void** lumpcache;
|
||||
|
||||
|
||||
int W_filelength (int handle)
|
||||
int W_filelength (FILE *handle)
|
||||
{
|
||||
struct stat fileinfo;
|
||||
int len;
|
||||
|
||||
if (fstat (handle,&fileinfo) == -1)
|
||||
I_Error ("Error fstating");
|
||||
if (fseek (handle, 0, SEEK_END))
|
||||
I_Error ("Error fseeking");
|
||||
|
||||
return fileinfo.st_size;
|
||||
len = ftell (handle);
|
||||
|
||||
if (fseek (handle, 0, SEEK_SET))
|
||||
I_Error ("Error fseeking");
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
// [RH] Copy up to 8 chars, upper-casing them in the process
|
||||
|
@ -102,7 +108,7 @@ void W_AddFile (char *filename)
|
|||
wadinfo_t header;
|
||||
lumpinfo_t* lump_p;
|
||||
unsigned i;
|
||||
int handle;
|
||||
FILE *handle;
|
||||
int length;
|
||||
int startlump;
|
||||
filelump_t* fileinfo, *fileinfo2free;
|
||||
|
@ -116,17 +122,17 @@ void W_AddFile (char *filename)
|
|||
|
||||
// open the file and add to directory
|
||||
|
||||
if ((handle = open (name, O_RDONLY | O_BINARY)) == -1)
|
||||
if ((handle = fopen (name, "rb")) == NULL)
|
||||
{
|
||||
Printf (" couldn't open %s\n",filename);
|
||||
return;
|
||||
}
|
||||
|
||||
Printf (" adding %s",filename);
|
||||
Printf (" adding %s", name);
|
||||
startlump = numlumps;
|
||||
|
||||
// [RH] Determine if file is a WAD based on its signature, not its name.
|
||||
read (handle, &header, sizeof(header));
|
||||
fread (&header, sizeof(header), 1, handle);
|
||||
|
||||
if (header.identification == IWAD_ID ||
|
||||
header.identification == PWAD_ID) {
|
||||
|
@ -136,8 +142,8 @@ void W_AddFile (char *filename)
|
|||
header.infotableofs = LONG(header.infotableofs);
|
||||
length = header.numlumps * sizeof(filelump_t);
|
||||
fileinfo = fileinfo2free = Z_Malloc (length, PU_STATIC, 0);
|
||||
lseek (handle, header.infotableofs, SEEK_SET);
|
||||
read (handle, fileinfo, length);
|
||||
fseek (handle, header.infotableofs, SEEK_SET);
|
||||
fread (fileinfo, 1, length, handle);
|
||||
numlumps += header.numlumps;
|
||||
Printf (" (%d lumps)", header.numlumps);
|
||||
} else {
|
||||
|
@ -188,7 +194,7 @@ void W_AddFile (char *filename)
|
|||
// The name searcher looks backwards, so a later file
|
||||
// does override all earlier ones.
|
||||
//
|
||||
void W_InitMultipleFiles (char** filenames)
|
||||
void W_InitMultipleFiles (wadlist_t **filenames)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -198,11 +204,16 @@ void W_InitMultipleFiles (char** filenames)
|
|||
// will be realloced as lumps are added
|
||||
lumpinfo = NULL; // [RH] Start out as NULL
|
||||
|
||||
for ( ; *filenames ; filenames++)
|
||||
W_AddFile (*filenames);
|
||||
while (*filenames) {
|
||||
wadlist_t *next = (*filenames)->next;
|
||||
|
||||
W_AddFile ((*filenames)->name);
|
||||
Z_Free (*filenames);
|
||||
*filenames = next;
|
||||
}
|
||||
|
||||
if (!numlumps)
|
||||
I_Error ("W_InitFiles: no files found");
|
||||
I_FatalError ("W_InitFiles: no files found");
|
||||
|
||||
// [RH] Set namespace markers to global for everything
|
||||
for (i = 0; i < numlumps; i++)
|
||||
|
@ -232,13 +243,13 @@ void W_InitMultipleFiles (char** filenames)
|
|||
// W_InitFile
|
||||
// Just initialize from a single file.
|
||||
//
|
||||
void W_InitFile (char* filename)
|
||||
void W_InitFile (char *filename)
|
||||
{
|
||||
char *names[2];
|
||||
wadlist_t *names = Z_Malloc (sizeof(*names)+strlen(filename), PU_STATIC, 0);
|
||||
|
||||
names[0] = filename;
|
||||
names[1] = NULL;
|
||||
W_InitMultipleFiles (names);
|
||||
names->next = NULL;
|
||||
strcpy (names->name, filename);
|
||||
W_InitMultipleFiles (&names);
|
||||
}
|
||||
|
||||
|
||||
|
@ -328,8 +339,8 @@ void W_ReadLump (int lump, void *dest)
|
|||
|
||||
l = lumpinfo + lump;
|
||||
|
||||
lseek (l->handle, l->position, SEEK_SET);
|
||||
c = read (l->handle, dest, l->size);
|
||||
fseek (l->handle, l->position, SEEK_SET);
|
||||
c = fread (dest, 1, l->size, l->handle);
|
||||
|
||||
if (c < l->size)
|
||||
I_Error ("W_ReadLump: only read %i of %i on lump %i",
|
||||
|
@ -348,7 +359,7 @@ void *W_CacheLumpNum (int lump, int tag)
|
|||
int lumplen;
|
||||
|
||||
if ((unsigned)lump >= numlumps)
|
||||
I_Error ("W_CacheLumpNum: %i >= numlumps",lump);
|
||||
I_Error ("W_CacheLumpNum: %u >= numlumps",lump);
|
||||
|
||||
if (!lumpcache[lump])
|
||||
{
|
||||
|
@ -463,8 +474,8 @@ void W_MergeLumps (const char *start, const char *end, int space)
|
|||
if (!newlumps) {
|
||||
newlumps++;
|
||||
strncpy (newlumpinfos[0].name, ustart, 8);
|
||||
newlumpinfos[0].handle =
|
||||
newlumpinfos[0].position =
|
||||
newlumpinfos[0].handle = NULL;
|
||||
newlumpinfos[0].position =
|
||||
newlumpinfos[0].size = 0;
|
||||
newlumpinfos[0].namespc = ns_global;
|
||||
}
|
||||
|
@ -492,8 +503,8 @@ void W_MergeLumps (const char *start, const char *end, int space)
|
|||
// Only create an end marker if there was one in the original list.
|
||||
if (haveEndMarker) {
|
||||
strncpy (newlumpinfos[newlumps].name, uend, 8);
|
||||
newlumpinfos[newlumps].handle =
|
||||
newlumpinfos[newlumps].position =
|
||||
newlumpinfos[newlumps].handle = NULL;
|
||||
newlumpinfos[newlumps].position =
|
||||
newlumpinfos[newlumps].size = 0;
|
||||
newlumpinfos[newlumps].namespc = ns_global;
|
||||
newlumps++;
|
||||
|
@ -623,4 +634,29 @@ BOOL W_CheckLumpName (int lump, const char *name)
|
|||
return false;
|
||||
|
||||
return !strnicmp (lumpinfo[lump].name, name, 8);
|
||||
}
|
||||
|
||||
// [RH] Copies the lump name to to using uppercopy
|
||||
void W_GetLumpName (char *to, int lump)
|
||||
{
|
||||
if (lump >= numlumps)
|
||||
*to = 0;
|
||||
else
|
||||
uppercopy (to, lumpinfo[lump].name);
|
||||
}
|
||||
|
||||
// [RH] Returns file ptr for specified lump
|
||||
FILE *W_GetLumpFile (int lump)
|
||||
{
|
||||
if (lump >= numlumps)
|
||||
return NULL;
|
||||
else
|
||||
return lumpinfo[lump].handle;
|
||||
}
|
||||
|
||||
// [RH] Put a lump in a certain namespace
|
||||
void W_SetLumpNamespace (int lump, int nmspace)
|
||||
{
|
||||
if (lump < numlumps)
|
||||
lumpinfo[lump].namespc = nmspace;
|
||||
}
|
|
@ -42,9 +42,6 @@
|
|||
|
||||
#include "doomstat.h"
|
||||
|
||||
// Data.
|
||||
#include "sounds.h"
|
||||
|
||||
// Needs access to LFB.
|
||||
#include "v_video.h"
|
||||
|
||||
|
@ -976,7 +973,7 @@ void WI_updateDeathmatchStats(void)
|
|||
}
|
||||
|
||||
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_barexp);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/rocklx", 60);
|
||||
dm_state = 4;
|
||||
}
|
||||
|
||||
|
@ -984,7 +981,7 @@ void WI_updateDeathmatchStats(void)
|
|||
if (dm_state == 2)
|
||||
{
|
||||
if (!(bcnt&3))
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_pistol);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/pistol", 64);
|
||||
|
||||
stillticking = false;
|
||||
|
||||
|
@ -1023,7 +1020,7 @@ void WI_updateDeathmatchStats(void)
|
|||
}
|
||||
if (!stillticking)
|
||||
{
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_barexp);
|
||||
S_StartSound(ORIGIN_AMBIENT, "weapons/rocklx", 60);
|
||||
dm_state++;
|
||||
}
|
||||
|
||||
|
@ -1032,7 +1029,7 @@ void WI_updateDeathmatchStats(void)
|
|||
{
|
||||
if (acceleratestage)
|
||||
{
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_slop);
|
||||
S_StartSound(ORIGIN_AMBIENT, "players/male/gibbed", 78);
|
||||
|
||||
if ( gamemode == commercial)
|
||||
WI_initNoState();
|
||||
|
@ -1206,16 +1203,16 @@ void WI_updateNetgameStats(void)
|
|||
cnt_secret[i] = plrs[i].ssecret;
|
||||
|
||||
if (dofrags)
|
||||
cnt_frags[i] = WI_fragSum(i);
|
||||
cnt_frags[i] = WI_fragSum (i);
|
||||
}
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_barexp);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/rocklx", 60);
|
||||
ng_state = 10;
|
||||
}
|
||||
|
||||
if (ng_state == 2)
|
||||
{
|
||||
if (!(bcnt&3))
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_pistol);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/pistol", 64);
|
||||
|
||||
stillticking = false;
|
||||
|
||||
|
@ -1234,14 +1231,14 @@ void WI_updateNetgameStats(void)
|
|||
|
||||
if (!stillticking)
|
||||
{
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_barexp);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/rocklx", 60);
|
||||
ng_state++;
|
||||
}
|
||||
}
|
||||
else if (ng_state == 4)
|
||||
{
|
||||
if (!(bcnt&3))
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_pistol);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/pistol", 64);
|
||||
|
||||
stillticking = false;
|
||||
|
||||
|
@ -1258,14 +1255,14 @@ void WI_updateNetgameStats(void)
|
|||
}
|
||||
if (!stillticking)
|
||||
{
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_barexp);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/rocklx", 60);
|
||||
ng_state++;
|
||||
}
|
||||
}
|
||||
else if (ng_state == 6)
|
||||
{
|
||||
if (!(bcnt&3))
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_pistol);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/pistol", 64);
|
||||
|
||||
stillticking = false;
|
||||
|
||||
|
@ -1284,14 +1281,14 @@ void WI_updateNetgameStats(void)
|
|||
|
||||
if (!stillticking)
|
||||
{
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_barexp);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/rocklx", 60);
|
||||
ng_state += 1 + 2*!dofrags;
|
||||
}
|
||||
}
|
||||
else if (ng_state == 8)
|
||||
{
|
||||
if (!(bcnt&3))
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_pistol);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/pistol", 64);
|
||||
|
||||
stillticking = false;
|
||||
|
||||
|
@ -1310,7 +1307,7 @@ void WI_updateNetgameStats(void)
|
|||
|
||||
if (!stillticking)
|
||||
{
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_pldeth);
|
||||
S_StartSound (ORIGIN_AMBIENT, "player/male/death1", 32);
|
||||
ng_state++;
|
||||
}
|
||||
}
|
||||
|
@ -1318,7 +1315,7 @@ void WI_updateNetgameStats(void)
|
|||
{
|
||||
if (acceleratestage)
|
||||
{
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_sgcock);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/shotgr", 64);
|
||||
if ( gamemode == commercial )
|
||||
WI_initNoState();
|
||||
else
|
||||
|
@ -1425,7 +1422,7 @@ void WI_updateStats(void)
|
|||
cnt_secret[0] = plrs[me].ssecret;
|
||||
cnt_time = plrs[me].stime / TICRATE;
|
||||
cnt_par = wbs->partime / TICRATE;
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_barexp);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/rocklx", 60);
|
||||
sp_state = 10;
|
||||
}
|
||||
|
||||
|
@ -1434,12 +1431,12 @@ void WI_updateStats(void)
|
|||
cnt_kills[0] += 2;
|
||||
|
||||
if (!(bcnt&3))
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_pistol);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/pistol", 64);
|
||||
|
||||
if (cnt_kills[0] >= plrs[me].skills)
|
||||
{
|
||||
cnt_kills[0] = plrs[me].skills;
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_barexp);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/rocklx", 60);
|
||||
sp_state++;
|
||||
}
|
||||
}
|
||||
|
@ -1448,12 +1445,12 @@ void WI_updateStats(void)
|
|||
cnt_items[0] += 2;
|
||||
|
||||
if (!(bcnt&3))
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_pistol);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/pistol", 64);
|
||||
|
||||
if (cnt_items[0] >= plrs[me].sitems)
|
||||
{
|
||||
cnt_items[0] = plrs[me].sitems;
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_barexp);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/rocklx", 60);
|
||||
sp_state++;
|
||||
}
|
||||
}
|
||||
|
@ -1462,12 +1459,12 @@ void WI_updateStats(void)
|
|||
cnt_secret[0] += 2;
|
||||
|
||||
if (!(bcnt&3))
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_pistol);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/pistol", 64);
|
||||
|
||||
if (cnt_secret[0] >= plrs[me].ssecret)
|
||||
{
|
||||
cnt_secret[0] = plrs[me].ssecret;
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_barexp);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/rocklx", 60);
|
||||
sp_state++;
|
||||
}
|
||||
}
|
||||
|
@ -1475,7 +1472,7 @@ void WI_updateStats(void)
|
|||
else if (sp_state == 8)
|
||||
{
|
||||
if (!(bcnt&3))
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_pistol);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/pistol", 64);
|
||||
|
||||
cnt_time += 3;
|
||||
|
||||
|
@ -1490,7 +1487,7 @@ void WI_updateStats(void)
|
|||
|
||||
if (cnt_time >= plrs[me].stime / TICRATE)
|
||||
{
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_barexp);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/rocklx", 60);
|
||||
sp_state++;
|
||||
}
|
||||
}
|
||||
|
@ -1499,7 +1496,7 @@ void WI_updateStats(void)
|
|||
{
|
||||
if (acceleratestage)
|
||||
{
|
||||
S_StartSound(ORIGIN_AMBIENT, sfx_sgcock);
|
||||
S_StartSound (ORIGIN_AMBIENT, "weapons/shotgr", 64);
|
||||
|
||||
if (gamemode == commercial)
|
||||
WI_initNoState();
|
||||
|
|
135
code/c_bind.c
135
code/c_bind.c
|
@ -3,6 +3,8 @@
|
|||
#include "cmdlib.h"
|
||||
#include "c_dispch.h"
|
||||
#include "c_bind.h"
|
||||
#include "g_level.h"
|
||||
#include "dstrings.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -57,7 +59,7 @@ char DefBindings[] =
|
|||
"bind \\ +showscores; " // <- Another new command
|
||||
"bind f12 spynext";
|
||||
|
||||
static const char *KeyNames[256+8+32] = {
|
||||
static const char *KeyNames[NUM_KEYS] = {
|
||||
// This array is dependant on the particular keyboard input
|
||||
// codes generated in i_input.c. If they change there, they
|
||||
// also need to change here. In this case, we use the
|
||||
|
@ -98,9 +100,9 @@ static const char *KeyNames[256+8+32] = {
|
|||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, "pause", //F8
|
||||
|
||||
// non-keyboard buttons that can be bound
|
||||
"mouse1", "mouse2", "mouse3", "mouse4", // DInput has four of these...
|
||||
NULL, NULL, NULL, NULL, // Space for double clicking if I feel like it
|
||||
"joy1", "joy2", "joy3", "joy4", // 32 joystick buttons!
|
||||
"mouse1", "mouse2", "mouse3", "mouse4", // 4 mouse buttons
|
||||
"mwheelup", "mwheeldown",NULL, NULL, // the wheel and some extra space
|
||||
"joy1", "joy2", "joy3", "joy4", // 32 joystick buttons
|
||||
"joy5", "joy6", "joy7", "joy8",
|
||||
"joy9", "joy10", "joy11", "joy12",
|
||||
"joy13", "joy14", "joy15", "joy16",
|
||||
|
@ -110,7 +112,10 @@ static const char *KeyNames[256+8+32] = {
|
|||
"joy29", "joy30", "joy31", "joy32"
|
||||
};
|
||||
|
||||
static char *Bindings[256+8+32];
|
||||
static char *Bindings[NUM_KEYS];
|
||||
static char *DoubleBindings[NUM_KEYS];
|
||||
static int DClickTime[NUM_KEYS];
|
||||
static byte DClicked[(NUM_KEYS+7)/8];
|
||||
|
||||
static int GetKeyFromName (const char *name)
|
||||
{
|
||||
|
@ -122,7 +127,7 @@ static int GetKeyFromName (const char *name)
|
|||
}
|
||||
|
||||
// Otherwise, we scan the KeyNames[] array for a matching name
|
||||
for (i = 0; i < 256+8+32; i++) {
|
||||
for (i = 0; i < NUM_KEYS; i++) {
|
||||
if (KeyNames[i] && !stricmp (KeyNames[i], name))
|
||||
return i;
|
||||
}
|
||||
|
@ -144,12 +149,17 @@ void Cmd_Unbindall (void *plyr, int argc, char **argv)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256+8+32; i++) {
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
if (Bindings[i]) {
|
||||
free (Bindings[i]);
|
||||
Bindings[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
if (DoubleBindings[i]) {
|
||||
free (DoubleBindings[i]);
|
||||
DoubleBindings[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Cmd_Unbind (void *plyr, int argc, char **argv)
|
||||
|
@ -183,43 +193,115 @@ void Cmd_Bind (void *plyr, int argc, char **argv)
|
|||
if (argc == 2) {
|
||||
Printf ("\"%s\" = \"%s\"\n", argv[1], (Bindings[i] ? Bindings[i] : ""));
|
||||
} else {
|
||||
if (Bindings[i])
|
||||
free (Bindings[i]);
|
||||
|
||||
Bindings[i] = copystring (argv[2]);
|
||||
ReplaceString (&Bindings[i], argv[2]);
|
||||
}
|
||||
} else {
|
||||
Printf ("Current key bindings:\n");
|
||||
|
||||
for (i = 0; i < 256+8+32; i++) {
|
||||
for (i = 0; i < NUM_KEYS; i++) {
|
||||
if (Bindings[i])
|
||||
Printf ("%s \"%s\"\n", KeyName (i), Bindings[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cmd_UnDoubleBind (void *plyr, int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argc > 1) {
|
||||
if ( (i = GetKeyFromName (argv[1])) ) {
|
||||
if (DoubleBindings[i]) {
|
||||
free (DoubleBindings[i]);
|
||||
DoubleBindings[i] = NULL;
|
||||
}
|
||||
} else {
|
||||
Printf ("Unknown key \"%s\"\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Cmd_DoubleBind (void *plyr, int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argc > 1) {
|
||||
i = GetKeyFromName (argv[1]);
|
||||
if (!i) {
|
||||
Printf ("Unknown key \"%s\"\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
if (argc == 2) {
|
||||
Printf ("\"%s\" = \"%s\"\n", argv[1], (DoubleBindings[i] ? DoubleBindings[i] : ""));
|
||||
} else {
|
||||
ReplaceString (&DoubleBindings[i], argv[2]);
|
||||
}
|
||||
} else {
|
||||
Printf ("Current key doublebindings:\n");
|
||||
|
||||
for (i = 0; i < NUM_KEYS; i++) {
|
||||
if (DoubleBindings[i])
|
||||
Printf ("%s \"%s\"\n", KeyName (i), DoubleBindings[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cmd_BindDefaults (void *plyr, int argc, char **argv)
|
||||
{
|
||||
AddCommandString (DefBindings);
|
||||
}
|
||||
|
||||
BOOL C_DoKey (int key, BOOL up)
|
||||
BOOL C_DoKey (event_t *ev)
|
||||
{
|
||||
extern BOOL chat_on;
|
||||
char *binding = NULL;
|
||||
int dclickspot;
|
||||
byte dclickmask;
|
||||
|
||||
if (Bindings[key] && (!chat_on || key < 256)) {
|
||||
if (!up) {
|
||||
AddCommandString (Bindings[key]);
|
||||
if (ev->type != ev_keydown && ev->type != ev_keyup)
|
||||
return false;
|
||||
|
||||
dclickspot = ev->data1 >> 3;
|
||||
dclickmask = 1 << (ev->data1 & 7);
|
||||
|
||||
if (DClickTime[ev->data1] > level.time && ev->type == ev_keydown) {
|
||||
// Key pressed for a double click
|
||||
binding = DoubleBindings[ev->data1];
|
||||
DClicked[dclickspot] |= dclickmask;
|
||||
} else {
|
||||
if (ev->type == ev_keydown) {
|
||||
// Key pressed for a normal press
|
||||
binding = Bindings[ev->data1];
|
||||
DClickTime[ev->data1] = level.time + 20;
|
||||
} else if (DClicked[dclickspot] & dclickmask) {
|
||||
// Key released from a double click
|
||||
binding = DoubleBindings[ev->data1];
|
||||
DClicked[dclickspot] &= ~dclickmask;
|
||||
DClickTime[ev->data1] = 0;
|
||||
} else {
|
||||
// Key released from a normal press
|
||||
binding = Bindings[ev->data1];
|
||||
}
|
||||
}
|
||||
|
||||
if (!binding)
|
||||
binding = Bindings[ev->data1];
|
||||
|
||||
if (binding && (!chat_on || ev->data1 < 256)) {
|
||||
if (ev->type == ev_keydown) {
|
||||
AddCommandString (binding);
|
||||
} else {
|
||||
char *achar;
|
||||
|
||||
achar = strchr (Bindings[key], '+');
|
||||
achar = strchr (binding, '+');
|
||||
if (!achar)
|
||||
return false;
|
||||
|
||||
if ((achar == Bindings[key]) || (*(achar - 1) <= ' ')) {
|
||||
if ((achar == binding) || (*(achar - 1) <= ' ')) {
|
||||
*achar = '-';
|
||||
AddCommandString (Bindings[key]);
|
||||
AddCommandString (binding);
|
||||
*achar = '+';
|
||||
}
|
||||
}
|
||||
|
@ -233,11 +315,12 @@ void C_ArchiveBindings (FILE *f)
|
|||
int i;
|
||||
|
||||
fprintf (f, "unbindall\n");
|
||||
for (i = 0; i < 256+8+32; i++) {
|
||||
if (Bindings[i]) {
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
if (Bindings[i])
|
||||
fprintf (f, "bind \"%s\" \"%s\"\n", KeyName (i), Bindings[i]);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NUM_KEYS; i++)
|
||||
if (DoubleBindings[i])
|
||||
fprintf (f, "doublebind \"%s\" \"%s\"\n", KeyName (i), DoubleBindings[i]);
|
||||
}
|
||||
|
||||
int C_GetKeysForCommand (char *cmd, int *first, int *second)
|
||||
|
@ -246,7 +329,7 @@ int C_GetKeysForCommand (char *cmd, int *first, int *second)
|
|||
|
||||
*first = *second = c = i = 0;
|
||||
|
||||
while (i < 256+8+32 && c < 2) {
|
||||
while (i < NUM_KEYS && c < 2) {
|
||||
if (Bindings[i] && !stricmp (cmd, Bindings[i])) {
|
||||
if (c++ == 0)
|
||||
*first = i;
|
||||
|
@ -283,7 +366,7 @@ void C_UnbindACommand (char *str)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 256+8+32; i++) {
|
||||
for (i = 0; i < NUM_KEYS; i++) {
|
||||
if (Bindings[i] && !stricmp (str, Bindings[i])) {
|
||||
free (Bindings[i]);
|
||||
Bindings[i] = NULL;
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
#define __C_BINDINGS_H__
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "d_event.h"
|
||||
#include <stdio.h>
|
||||
|
||||
BOOL C_DoKey (int key, BOOL up);
|
||||
BOOL C_DoKey (event_t *ev);
|
||||
void C_ArchiveBindings (FILE *f);
|
||||
|
||||
// Stuff used by the customize controls menu
|
||||
|
|
|
@ -7,6 +7,9 @@ void C_InstallCommands (void);
|
|||
// am_map.c
|
||||
CMD(Cmd_Togglemap)
|
||||
|
||||
// d_main.c
|
||||
CMD(Cmd_Endgame)
|
||||
|
||||
// m_menu.c
|
||||
CMD(Cmd_Menu_Main)
|
||||
CMD(Cmd_Menu_Load)
|
||||
|
@ -34,9 +37,12 @@ CMD(Cmd_Menu_Gameplay)
|
|||
CMD(Cmd_Impulse)
|
||||
CMD(Cmd_CenterView)
|
||||
CMD(Cmd_Pause)
|
||||
CMD(Cmd_WeapNext)
|
||||
CMD(Cmd_WeapPrev)
|
||||
CMD(Cmd_Stop)
|
||||
CMD(Cmd_SpyNext)
|
||||
CMD(Cmd_SpyPrev)
|
||||
CMD(Cmd_Turn180)
|
||||
|
||||
// g_level.c
|
||||
CMD(Cmd_Map)
|
||||
|
@ -51,6 +57,8 @@ CMD(Cmd_Bind)
|
|||
CMD(Cmd_BindDefaults)
|
||||
CMD(Cmd_Unbind)
|
||||
CMD(Cmd_Unbindall)
|
||||
CMD(Cmd_DoubleBind)
|
||||
CMD(Cmd_UnDoubleBind)
|
||||
|
||||
// c_consol.c
|
||||
void C_ToggleConsole (void);
|
||||
|
@ -78,6 +86,12 @@ CMD(Cmd_DumpHeap)
|
|||
CMD(Cmd_Logfile)
|
||||
CMD(Cmd_Limits)
|
||||
CMD(Cmd_ChangeMap)
|
||||
CMD(Cmd_Quit)
|
||||
CMD(Cmd_Puke)
|
||||
CMD(Cmd_Error)
|
||||
|
||||
// d_net.c
|
||||
CMD(Cmd_Pings)
|
||||
|
||||
// p_inter.c
|
||||
CMD(Cmd_Kill)
|
||||
|
@ -92,5 +106,17 @@ CMD(Cmd_Screenshot)
|
|||
// hu_stuff.c
|
||||
CMD(Cmd_MessageMode)
|
||||
CMD(Cmd_Say)
|
||||
CMD(Cmd_MessageMode2)
|
||||
CMD(Cmd_Say_Team)
|
||||
|
||||
// r_things.c
|
||||
CMD(Cmd_Skins)
|
||||
|
||||
// s_sounds.c
|
||||
CMD(Cmd_Soundlist)
|
||||
CMD(Cmd_Soundlinks)
|
||||
|
||||
// z_zone.c
|
||||
CMD(Cmd_Mem)
|
||||
|
||||
#undef CMD
|
167
code/c_consol.c
167
code/c_consol.c
|
@ -4,13 +4,16 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "dstrings.h"
|
||||
#include "g_game.h"
|
||||
#include "c_consol.h"
|
||||
#include "c_cvars.h"
|
||||
#include "c_dispch.h"
|
||||
#include "hu_stuff.h"
|
||||
#include "i_input.h"
|
||||
#include "i_system.h"
|
||||
#include "i_video.h"
|
||||
#include "m_swap.h"
|
||||
#include "v_video.h"
|
||||
#include "v_text.h"
|
||||
|
@ -19,6 +22,7 @@
|
|||
#include "r_main.h"
|
||||
#include "r_draw.h"
|
||||
#include "st_stuff.h"
|
||||
#include "s_sound.h"
|
||||
|
||||
#include "doomstat.h"
|
||||
|
||||
|
@ -31,11 +35,7 @@ static screen_t conback; // As of 1.13, Console backdrop is just another screen
|
|||
|
||||
extern int gametic;
|
||||
extern BOOL automapactive; // in AM_map.c
|
||||
|
||||
typedef enum cstate_t {
|
||||
up=0, down=1, falling=2, rising=3
|
||||
} constate;
|
||||
|
||||
extern BOOL advancedemo;
|
||||
|
||||
int ConRows, ConCols, PhysRows;
|
||||
char *Lines, *Last = NULL;
|
||||
|
@ -43,7 +43,7 @@ BOOL vidactive = false, gotconback = false;
|
|||
BOOL cursoron = false;
|
||||
int ShowRows, SkipRows, ConsoleTicker, ConBottom, ConScroll, RowAdjust;
|
||||
int CursorTicker, ScrollState = 0;
|
||||
int ConsoleState = up;
|
||||
constate_e ConsoleState = c_up;
|
||||
char VersionString[8];
|
||||
|
||||
event_t RepeatEvent; // always type ev_keydown
|
||||
|
@ -56,8 +56,7 @@ BOOL KeysShifted;
|
|||
#define SCROLLNO 0
|
||||
|
||||
extern cvar_t *showMessages;
|
||||
extern BOOL message_dontfuckwithme; // Who came up with this name?
|
||||
|
||||
extern BOOL message_dontfuckwithme;
|
||||
extern BOOL chat_on;
|
||||
|
||||
struct History {
|
||||
|
@ -86,7 +85,7 @@ FILE *Logfile = NULL;
|
|||
|
||||
extern patch_t *hu_font[HU_FONTSIZE]; // from hu_stuff.c
|
||||
|
||||
void C_HandleKey (event_t *ev, byte *buffer, int len);
|
||||
BOOL C_HandleKey (event_t *ev, byte *buffer, int len);
|
||||
|
||||
|
||||
static int C_hu_CharWidth (int c)
|
||||
|
@ -152,8 +151,15 @@ void C_InitConsole (int width, int height, BOOL ingame)
|
|||
}
|
||||
}
|
||||
}
|
||||
sprintf (VersionString, "v%d.%d", VERSION / 100, VERSION % 100);
|
||||
|
||||
{
|
||||
int i;
|
||||
|
||||
VersionString[0] = 0x11;
|
||||
for (i = 0; i < strlen(DOTVERSIONSTR); i++)
|
||||
VersionString[i+1] = DOTVERSIONSTR[i]-30;
|
||||
VersionString[i+1] = 0;
|
||||
}
|
||||
V_UnlockScreen (&conback);
|
||||
|
||||
gotconback = true;
|
||||
|
@ -179,9 +185,10 @@ void C_InitConsole (int width, int height, BOOL ingame)
|
|||
|
||||
if (old) {
|
||||
char string[256];
|
||||
FILE *templog;
|
||||
gamestate_t oldstate = gamestate; // Don't print during reformatting
|
||||
FILE *templog = Logfile; // Don't log our reformatting pass
|
||||
|
||||
templog = Logfile; // Don't log our reformatting pass
|
||||
gamestate = -1;
|
||||
Logfile = NULL;
|
||||
|
||||
for (row = 0, zap = old; row < rows; row++, zap += cols + 2) {
|
||||
|
@ -198,7 +205,11 @@ void C_InitConsole (int width, int height, BOOL ingame)
|
|||
ShowRows = 0;
|
||||
|
||||
Logfile = templog;
|
||||
gamestate = oldstate;
|
||||
}
|
||||
|
||||
if (ingame && gamestate == GS_STARTUP)
|
||||
C_FullConsole ();
|
||||
}
|
||||
|
||||
void C_AddNotifyString (const char *source)
|
||||
|
@ -303,13 +314,31 @@ int PrintString (const char *outline) {
|
|||
|
||||
printxormask = 0;
|
||||
|
||||
if (vidactive &&
|
||||
((gameaction != ga_nothing && ConsoleState == c_down)
|
||||
|| gamestate == GS_STARTUP)) {
|
||||
static size_t lastprinttime = 0;
|
||||
size_t nowtime = I_GetTime();
|
||||
|
||||
if (nowtime - lastprinttime > 1) {
|
||||
I_BeginUpdate ();
|
||||
C_DrawConsole ();
|
||||
I_FinishUpdate ();
|
||||
lastprinttime = nowtime;
|
||||
}
|
||||
}
|
||||
|
||||
return strlen (outline);
|
||||
}
|
||||
|
||||
extern BOOL gameisdead;
|
||||
int VPrintf (const char *format, va_list parms)
|
||||
{
|
||||
char outline[8192];
|
||||
|
||||
if (gameisdead)
|
||||
return 0;
|
||||
|
||||
vsprintf (outline, format, parms);
|
||||
return PrintString (outline);
|
||||
}
|
||||
|
@ -359,12 +388,19 @@ void C_FlushDisplay (void)
|
|||
ShowRows = 0;
|
||||
}
|
||||
|
||||
void C_AdjustBottom (void)
|
||||
{
|
||||
if (gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP)
|
||||
ConBottom = screens[0].height / 8;
|
||||
else if (ConBottom > screens[0].height / 16 || ConsoleState == c_down)
|
||||
ConBottom = screens[0].height / 16;
|
||||
}
|
||||
|
||||
void C_NewModeAdjust (void)
|
||||
{
|
||||
C_InitConsole (screens[0].width, screens[0].height, true);
|
||||
ShowRows = 0;
|
||||
if (ConBottom > screens[0].height / 16 || ConsoleState == down)
|
||||
ConBottom = screens[0].height / 16;
|
||||
C_AdjustBottom ();
|
||||
}
|
||||
|
||||
void C_Ticker (void)
|
||||
|
@ -374,7 +410,7 @@ void C_Ticker (void)
|
|||
if (lasttic == 0)
|
||||
lasttic = gametic - 1;
|
||||
|
||||
if (ConsoleState != up) {
|
||||
if (ConsoleState != c_up) {
|
||||
// Handle repeating keys
|
||||
switch (ScrollState) {
|
||||
case SCROLLUP:
|
||||
|
@ -396,16 +432,16 @@ void C_Ticker (void)
|
|||
break;
|
||||
}
|
||||
|
||||
if (ConsoleState == falling) {
|
||||
if (ConsoleState == c_falling) {
|
||||
ConBottom += (gametic - lasttic) * (screens[0].height / 100);
|
||||
if (ConBottom >= screens[0].height / 16) {
|
||||
ConBottom = screens[0].height / 16;
|
||||
ConsoleState = down;
|
||||
ConsoleState = c_down;
|
||||
}
|
||||
} else if (ConsoleState == rising) {
|
||||
} else if (ConsoleState == c_rising) {
|
||||
ConBottom -= (gametic - lasttic) * (screens[0].height / 100);
|
||||
if (ConBottom <= 0) {
|
||||
ConsoleState = up;
|
||||
ConsoleState = c_up;
|
||||
ConBottom = 0;
|
||||
}
|
||||
}
|
||||
|
@ -474,7 +510,7 @@ void C_DrawConsole (void)
|
|||
|
||||
oldbottom = ConBottom;
|
||||
|
||||
if (ConsoleState == up) {
|
||||
if (ConsoleState == c_up) {
|
||||
C_DrawNotifyText ();
|
||||
return;
|
||||
} else if (ConBottom) {
|
||||
|
@ -486,60 +522,88 @@ void C_DrawConsole (void)
|
|||
V_Blit (&conback, 0, conback.height - realheight, conback.width, realheight,
|
||||
&screens[0], 0, 0, screens[0].width, visheight);
|
||||
|
||||
if (ConBottom >= 2)
|
||||
if (ConBottom >= 2) {
|
||||
V_PrintStr (screens[0].width - 8 - strlen(VersionString) * 8,
|
||||
ConBottom * 8 - 16,
|
||||
VersionString, strlen(VersionString), 0x80);
|
||||
VersionString, strlen (VersionString));
|
||||
if (gamestate == GS_STARTUP)
|
||||
V_PrintStr (8, ConBottom * 8 - 16, DoomStartupTitle, strlen (DoomStartupTitle));
|
||||
}
|
||||
}
|
||||
|
||||
if (menuactive)
|
||||
return;
|
||||
|
||||
if (lines > 0) {
|
||||
for (; lines; lines--) {
|
||||
V_PrintStr (left, -8 + lines * 8, &zap[2], zap[1], 0);
|
||||
V_PrintStr (left, -8 + lines * 8, &zap[2], zap[1]);
|
||||
zap -= ConCols + 2;
|
||||
}
|
||||
if (ConBottom > 1) {
|
||||
V_PrintStr (left, (ConBottom - 2) * 8, "]", 1, 0x80);
|
||||
if (gamestate != GS_STARTUP)
|
||||
V_PrintStr (left, (ConBottom - 2) * 8, "\x8c", 1);
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
V_PrintStr (left + 8, (ConBottom - 2) * 8,
|
||||
&CmdLine[2+CmdLine[259]],
|
||||
MIN(CmdLine[0] - CmdLine[259], ConCols - 1), 0);
|
||||
MIN(CmdLine[0] - CmdLine[259], ConCols - 1));
|
||||
#undef MIN
|
||||
if (cursoron) {
|
||||
V_PrintStr (left + 8 + (CmdLine[1] - CmdLine[259])* 8,
|
||||
(ConBottom - 2) * 8, "\xb", 1, 0);
|
||||
(ConBottom - 2) * 8, "\xb", 1);
|
||||
}
|
||||
if (RowAdjust && ConBottom > 2) {
|
||||
char c;
|
||||
|
||||
// Indicate that the view has been scrolled up...
|
||||
if (SkipRows + RowAdjust + ConBottom != ConRows)
|
||||
c = '^';
|
||||
// and if we can scroll no further
|
||||
else
|
||||
c = '*';
|
||||
V_PrintStr (0, (ConBottom - 3) * 8 + 6, &c, 1, 0x80);
|
||||
// Indicate that the view has been scrolled up (10)
|
||||
// and if we can scroll no further (12)
|
||||
c = (SkipRows + RowAdjust + ConBottom != ConRows) ? 10 : 12;
|
||||
V_PrintStr (0, (ConBottom - 3) * 8 + 4, &c, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C_FullConsole (void)
|
||||
{
|
||||
if (demoplayback)
|
||||
G_CheckDemoStatus ();
|
||||
advancedemo = false;
|
||||
ConsoleState = c_down;
|
||||
HistPos = NULL;
|
||||
TabbedLast = false;
|
||||
if (gamestate != GS_STARTUP) {
|
||||
gamestate = GS_FULLCONSOLE;
|
||||
level.music[0] = '\0';
|
||||
S_Start ();
|
||||
I_PauseMouse ();
|
||||
} else
|
||||
C_AdjustBottom ();
|
||||
}
|
||||
|
||||
void C_ToggleConsole (void)
|
||||
{
|
||||
// Only let the console go up if chat mode is on
|
||||
if (!chat_on && (ConsoleState == up || ConsoleState == rising)) {
|
||||
ConsoleState = falling;
|
||||
if (gamestate == GS_DEMOSCREEN || demoplayback) {
|
||||
gameaction = ga_fullconsole;
|
||||
} else if (!chat_on && (ConsoleState == c_up || ConsoleState == c_rising)) {
|
||||
ConsoleState = c_falling;
|
||||
HistPos = NULL;
|
||||
TabbedLast = false;
|
||||
} else {
|
||||
ConsoleState = rising;
|
||||
I_PauseMouse ();
|
||||
} else if (gamestate != GS_FULLCONSOLE && gamestate != GS_STARTUP) {
|
||||
ConsoleState = c_rising;
|
||||
I_ResumeMouse ();
|
||||
}
|
||||
}
|
||||
|
||||
void C_HideConsole (void)
|
||||
{
|
||||
ConsoleState = up;
|
||||
ConBottom = 0;
|
||||
HistPos = NULL;
|
||||
if (gamestate != GS_FULLCONSOLE && gamestate != GS_STARTUP) {
|
||||
ConsoleState = c_up;
|
||||
ConBottom = 0;
|
||||
HistPos = NULL;
|
||||
if (!menuactive)
|
||||
I_ResumeMouse ();
|
||||
}
|
||||
}
|
||||
|
||||
static void makestartposgood (void)
|
||||
|
@ -571,7 +635,7 @@ static void makestartposgood (void)
|
|||
CmdLine[259] = n;
|
||||
}
|
||||
|
||||
void C_HandleKey (event_t *ev, byte *buffer, int len)
|
||||
BOOL C_HandleKey (event_t *ev, byte *buffer, int len)
|
||||
{
|
||||
switch (ev->data1) {
|
||||
case KEY_TAB:
|
||||
|
@ -744,8 +808,11 @@ void C_HandleKey (event_t *ev, byte *buffer, int len)
|
|||
AddCommandString (&buffer[2]);
|
||||
TabbedLast = false;
|
||||
} else if (ev->data2 == '`' || ev->data1 == KEY_ESCAPE) {
|
||||
// Close console, both ` and ESC clear command line
|
||||
|
||||
// Close console, clear command line, but if we're in the
|
||||
// fullscreen console mode, there's nothing to fall back on
|
||||
// if it's closed.
|
||||
if (gamestate == GS_FULLCONSOLE || gamestate == GS_STARTUP)
|
||||
return false;
|
||||
buffer[0] = buffer[1] = buffer[len+4] = 0;
|
||||
HistPos = NULL;
|
||||
C_ToggleConsole ();
|
||||
|
@ -779,11 +846,12 @@ void C_HandleKey (event_t *ev, byte *buffer, int len)
|
|||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL C_Responder (event_t *ev)
|
||||
{
|
||||
if (ConsoleState == up || ConsoleState == rising) {
|
||||
if (ConsoleState == c_up || ConsoleState == c_rising || menuactive) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -816,12 +884,9 @@ BOOL C_Responder (event_t *ev)
|
|||
// Others do.
|
||||
RepeatCountdown = KeyRepeatDelay;
|
||||
RepeatEvent = *ev;
|
||||
C_HandleKey (ev, CmdLine, 255);
|
||||
|
||||
return C_HandleKey (ev, CmdLine, 255);
|
||||
} else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Cmd_History (player_t *plyr, int argc, char **argv)
|
||||
|
@ -880,11 +945,11 @@ void C_DrawMid (void)
|
|||
int i, line, x, y;
|
||||
byte *holdwhite = WhiteMap;
|
||||
|
||||
// Hack! Hack! I need to get mult-colored text output written...
|
||||
// Hack! Hack! I need to get multi-colored text output written (still)...
|
||||
WhiteMap = Ranges + 5 * 256;
|
||||
y = 8 * CleanYfac;
|
||||
x = screens[0].width >> 1;
|
||||
for (i = 0, line = (ST_Y >> 1) - MidLines * 4 * CleanYfac; i < MidLines; i++, line += y) {
|
||||
for (i = 0, line = (ST_Y * 3) / 8 - MidLines * 4 * CleanYfac; i < MidLines; i++, line += y) {
|
||||
V_DrawTextClean (x - (MidMsg[i].width >> 1) * CleanXfac, line, MidMsg[i].string);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
|
||||
#define C_BLINKRATE (TICRATE/2)
|
||||
|
||||
typedef enum cstate_t {
|
||||
c_up=0, c_down=1, c_falling=2, c_rising=3
|
||||
} constate_e;
|
||||
|
||||
// Initialize the console
|
||||
void C_InitConsole (int width, int height, BOOL ingame);
|
||||
|
||||
|
@ -26,7 +30,9 @@ int Printf_Bold (const char *format, ...);
|
|||
void C_AddNotifyString (const char *s);
|
||||
void C_DrawConsole (void);
|
||||
void C_ToggleConsole (void);
|
||||
void C_FullConsole (void);
|
||||
void C_HideConsole (void);
|
||||
void C_AdjustBottom (void);
|
||||
void C_FlushDisplay (void);
|
||||
|
||||
void C_MidPrint (char *message);
|
||||
|
|
|
@ -21,24 +21,24 @@ struct CmdData *Commands[HASH_SIZE];
|
|||
struct CmdData *Aliases[HASH_SIZE];
|
||||
|
||||
struct ActionBits actionbits[NUM_ACTIONS] = {
|
||||
{ 0x116716a2, ACTION_SPEED, "speed" },
|
||||
{ 0x1e60dad4, ACTION_RIGHT, "right" },
|
||||
{ 0x206c10aa, ACTION_KLOOK, "klook" },
|
||||
{ 0x226a20ae, ACTION_MLOOK, "mlook" },
|
||||
{ 0x4d63cc88, ACTION_USE, "use" },
|
||||
{ 0x50183a64, ACTION_SHOWSCORES, "showscores" },
|
||||
{ 0x620a3c5e, ACTION_MOVELEFT, "moveleft" },
|
||||
{ 0x6d157234, ACTION_LOOKDOWN, "lookdown" },
|
||||
{ 0x6f03745a, ACTION_MOVEDOWN, "movedown" },
|
||||
{ 0x78086cf0, ACTION_ATTACK, "attack" },
|
||||
{ 0x8517869e, ACTION_STRAFE, "strafe" },
|
||||
{ 0x910b0cac, ACTION_BACK, "back" },
|
||||
{ 0x9a02b460, ACTION_LOOKUP, "lookup" },
|
||||
{ 0x9c14ae86, ACTION_MOVEUP, "moveup" },
|
||||
{ 0xab1b201e, ACTION_LEFT, "left" },
|
||||
{ 0xbc02544e, ACTION_JUMP, "jump" },
|
||||
{ 0xd571f880, ACTION_MOVERIGHT, "moveright" },
|
||||
{ 0xf57be8e2, ACTION_FORWARD, "forward" }
|
||||
{ 0x00409, ACTION_USE, "use" },
|
||||
{ 0x0074d, ACTION_BACK, "back" },
|
||||
{ 0x007e4, ACTION_LEFT, "left" },
|
||||
{ 0x00816, ACTION_JUMP, "jump" },
|
||||
{ 0x0106d, ACTION_KLOOK, "klook" },
|
||||
{ 0x0109d, ACTION_MLOOK, "mlook" },
|
||||
{ 0x010d8, ACTION_RIGHT, "right" },
|
||||
{ 0x0110a, ACTION_SPEED, "speed" },
|
||||
{ 0x01fc5, ACTION_ATTACK, "attack" },
|
||||
{ 0x021ae, ACTION_LOOKUP, "lookup" },
|
||||
{ 0x021fe, ACTION_MOVEUP, "moveup" },
|
||||
{ 0x02315, ACTION_STRAFE, "strafe" },
|
||||
{ 0x041c4, ACTION_FORWARD, "forward" },
|
||||
{ 0x08788, ACTION_LOOKDOWN, "lookdown" },
|
||||
{ 0x088c4, ACTION_MOVELEFT, "moveleft" },
|
||||
{ 0x088c8, ACTION_MOVEDOWN, "movedown" },
|
||||
{ 0x11268, ACTION_MOVERIGHT, "moveright" },
|
||||
{ 0x2314d, ACTION_SHOWSCORES, "showscores" }
|
||||
};
|
||||
int Actions;
|
||||
|
||||
|
@ -53,21 +53,18 @@ static int ListActionCommands (void)
|
|||
return NUM_ACTIONS * 2;
|
||||
}
|
||||
|
||||
unsigned int MakeKey (char *s)
|
||||
unsigned int MakeKey (const char *s)
|
||||
{
|
||||
byte a,b,c,d,e;
|
||||
register unsigned int v = 0;
|
||||
|
||||
a = b = c = d = 0;
|
||||
if (*s)
|
||||
v = tolower(*s++);
|
||||
if (*s)
|
||||
v = (v*3) + tolower(*s++);
|
||||
while (*s)
|
||||
v = (v << 1) + tolower(*s++);
|
||||
|
||||
while (*s) {
|
||||
e = tolower (*s++);
|
||||
a += e;
|
||||
b ^= e;
|
||||
c += a - b;
|
||||
d += a + b;
|
||||
}
|
||||
|
||||
return (a << 24) | (b << 16) | (c << 8) | d;
|
||||
return v;
|
||||
}
|
||||
|
||||
// GetActionBit scans through the actionbits[] array
|
||||
|
|
|
@ -68,4 +68,6 @@ struct ActionBits {
|
|||
char name[12];
|
||||
};
|
||||
|
||||
extern unsigned int MakeKey (const char *s);
|
||||
|
||||
#endif //__C_DISPATCH_H__
|
|
@ -13,7 +13,6 @@ typedef struct {
|
|||
|
||||
extern cvar_t *gammalevel,
|
||||
*st_scale,
|
||||
*var_language,
|
||||
*gameskill,
|
||||
*crosshair,
|
||||
*WI_Percents,
|
||||
|
@ -27,17 +26,21 @@ extern cvar_t *gammalevel,
|
|||
*idmypos,
|
||||
*vid_defwidth,
|
||||
*vid_defheight,
|
||||
*vid_defbpp,
|
||||
*vid_defid,
|
||||
*i_remapkeypad,
|
||||
*cl_run,
|
||||
*chat_macros[10],
|
||||
*showMessages,
|
||||
*nobfgaim,
|
||||
|
||||
*snd_surround,
|
||||
*snd_samplerate,
|
||||
*snd_pitched,
|
||||
*snd_channels,
|
||||
*snd_SfxVolume,
|
||||
*snd_MusicVolume,
|
||||
*snd_MidiVolume,
|
||||
*noisedebug,
|
||||
|
||||
*sv_gravity,
|
||||
*sv_friction,
|
||||
|
@ -72,14 +75,7 @@ extern cvar_t *gammalevel,
|
|||
*am_gridcolor,
|
||||
*am_xhaircolor,
|
||||
*am_notseencolor,
|
||||
*am_key1color,
|
||||
*am_key2color,
|
||||
*am_key3color,
|
||||
/*
|
||||
*am_key4color,
|
||||
*am_key5color,
|
||||
*am_key6color,
|
||||
*/
|
||||
*am_lockedcolor,
|
||||
*am_ovyourcolor,
|
||||
*am_ovwallcolor,
|
||||
*am_ovthingcolor,
|
||||
|
@ -89,6 +85,7 @@ extern cvar_t *gammalevel,
|
|||
*dimamount,
|
||||
*dimcolor,
|
||||
|
||||
*teamplay,
|
||||
*deathmatch,
|
||||
*dmflagsvar,
|
||||
*fraglimit,
|
||||
|
@ -97,25 +94,35 @@ extern cvar_t *gammalevel,
|
|||
*autoaim,
|
||||
*name,
|
||||
*color,
|
||||
*skin,
|
||||
*team,
|
||||
*gender,
|
||||
|
||||
*boom_pushers,
|
||||
*boom_friction,
|
||||
|
||||
*splashfactor,
|
||||
*testgibs;
|
||||
|
||||
|
||||
|
||||
static const cvarinit_t Initializers[] = {
|
||||
{ &gammalevel, "gamma", "1", CVAR_ARCHIVE|CVAR_CALLBACK },
|
||||
{ &testgibs, "testgibs", "0", 0 },
|
||||
{ &st_scale, "st_scale", "0", CVAR_ARCHIVE|CVAR_CALLBACK },
|
||||
{ &var_language, "language", "english", CVAR_ARCHIVE|CVAR_CALLBACK },
|
||||
{ &dimamount, "dimamount", "1", CVAR_ARCHIVE },
|
||||
{ &dimcolor, "dimcolor", "ffff d7d7 0000", CVAR_ARCHIVE },
|
||||
{ &crosshair, "crosshair", "0", CVAR_ARCHIVE },
|
||||
{ &developer, "developer", "0", 0 },
|
||||
|
||||
{ &snd_surround, "snd_surround", "1", CVAR_ARCHIVE },
|
||||
{ &snd_SfxVolume, "snd_sfxvolume", "8", CVAR_ARCHIVE|CVAR_CALLBACK },
|
||||
{ &snd_MusicVolume, "snd_musicvolume", "9", CVAR_ARCHIVE|CVAR_CALLBACK },
|
||||
{ &snd_MidiVolume, "snd_midivolume", "0.5", CVAR_ARCHIVE|CVAR_CALLBACK },
|
||||
{ &snd_channels, "snd_channels", "8", CVAR_ARCHIVE },
|
||||
{ &snd_pitched, "snd_pitched", "0", CVAR_ARCHIVE },
|
||||
{ &snd_samplerate, "snd_samplerate", "44100", CVAR_ARCHIVE },
|
||||
{ &noisedebug, "noise", "0", 0 },
|
||||
|
||||
{ &screenblocks, "screenblocks", "10", CVAR_ARCHIVE|CVAR_CALLBACK },
|
||||
{ &usemouse, "use_mouse", "1", CVAR_ARCHIVE },
|
||||
|
@ -143,7 +150,7 @@ static const cvarinit_t Initializers[] = {
|
|||
{ &idmypos, "idmypos", "0", 0 },
|
||||
{ &vid_defwidth, "vid_defwidth", "320", CVAR_ARCHIVE },
|
||||
{ &vid_defheight, "vid_defheight", "200", CVAR_ARCHIVE },
|
||||
{ &vid_defbpp, "vid_defbpp", "8", CVAR_ARCHIVE },
|
||||
{ &vid_defid, "vid_defid", "INDEX8", CVAR_ARCHIVE },
|
||||
{ &i_remapkeypad, "i_remapkeypad", "1", CVAR_ARCHIVE },
|
||||
{ &cl_run, "cl_run", "0", CVAR_ARCHIVE },
|
||||
{ &showMessages, "show_messages", "1", CVAR_ARCHIVE },
|
||||
|
@ -175,28 +182,31 @@ static const cvarinit_t Initializers[] = {
|
|||
{ &am_gridcolor, "am_gridcolor", "8b8b 5a5a 2b2b", CVAR_ARCHIVE },
|
||||
{ &am_xhaircolor, "am_xhaircolor", "8080 8080 8080", CVAR_ARCHIVE },
|
||||
{ &am_notseencolor, "am_notseencolor", "6c6c 6c6c 6c6c", CVAR_ARCHIVE },
|
||||
{ &am_key1color, "am_key1color", "0000 0000 9898", CVAR_ARCHIVE },
|
||||
{ &am_key2color, "am_key2color", "9898 0000 0000", CVAR_ARCHIVE },
|
||||
{ &am_key3color, "am_key3color", "e8e8 d8d8 5454", CVAR_ARCHIVE },
|
||||
/*
|
||||
&am_key4color, "am_key4color", "0000 0000 9898", CVAR_ARCHIVE,
|
||||
&am_key5color, "am_key5color", "9898 0000 0000", CVAR_ARCHIVE,
|
||||
&am_key6color, "am_key6color", "e8e8 d8d8 5454", CVAR_ARCHIVE,
|
||||
*/
|
||||
{ &am_lockedcolor, "am_lockedcolor", "0000 0000 9898", CVAR_ARCHIVE },
|
||||
{ &am_ovyourcolor, "am_ovyourcolor", "fcfc e8e8 d8d8", CVAR_ARCHIVE },
|
||||
{ &am_ovwallcolor, "am_ovwallcolor", "0000 ffff 0000", CVAR_ARCHIVE },
|
||||
{ &am_ovthingcolor, "am_ovthingcolor", "e8e8 8888 0000", CVAR_ARCHIVE },
|
||||
{ &am_ovotherwallscolor,"am_ovotherwallscolor", "0000 8888 4444", CVAR_ARCHIVE },
|
||||
{ &am_ovunseencolor, "am_ovunseencolor", "0000 2222 6e6e", CVAR_ARCHIVE },
|
||||
|
||||
{ &teamplay, "teamplay", "0", CVAR_SERVERINFO },
|
||||
{ &deathmatch, "deathmatch", "0", CVAR_SERVERINFO|CVAR_LATCH },
|
||||
{ &dmflagsvar, "dmflags", "0", CVAR_SERVERINFO|CVAR_CALLBACK },
|
||||
{ &timelimit, "timelimit", "0", CVAR_SERVERINFO },
|
||||
{ &fraglimit, "fraglimit", "0", CVAR_SERVERINFO },
|
||||
{ &nobfgaim, "nobfgaim", "0", CVAR_SERVERINFO },
|
||||
|
||||
{ &autoaim, "autoaim", "5000", CVAR_USERINFO|CVAR_ARCHIVE },
|
||||
{ &name, "name", "Player", CVAR_USERINFO|CVAR_ARCHIVE },
|
||||
{ &color, "color", "4040 cfcf 0000", CVAR_USERINFO|CVAR_ARCHIVE },
|
||||
{ &skin, "skin", "base", CVAR_USERINFO|CVAR_ARCHIVE },
|
||||
{ &team, "team", "", CVAR_USERINFO|CVAR_ARCHIVE },
|
||||
{ &gender, "gender", "male", CVAR_USERINFO|CVAR_ARCHIVE },
|
||||
|
||||
{ &boom_friction, "var_friction", "1", CVAR_SERVERINFO },
|
||||
{ &boom_pushers, "var_pushers", "1", CVAR_SERVERINFO },
|
||||
|
||||
{ &splashfactor, "splashfactor", "1.0", CVAR_SERVERINFO|CVAR_CALLBACK },
|
||||
|
||||
{ NULL }
|
||||
};
|
||||
|
|
|
@ -61,7 +61,8 @@ typedef enum
|
|||
ga_completed,
|
||||
ga_victory,
|
||||
ga_worlddone,
|
||||
ga_screenshot
|
||||
ga_screenshot,
|
||||
ga_fullconsole
|
||||
} gameaction_t;
|
||||
|
||||
|
||||
|
|
433
code/d_french.h
433
code/d_french.h
|
@ -1,433 +0,0 @@
|
|||
// Emacs style mode select -*- C++ -*-
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Id:$
|
||||
//
|
||||
// Copyright (C) 1993-1996 by id Software, Inc.
|
||||
//
|
||||
// This source is available for distribution and/or modification
|
||||
// only under the terms of the DOOM Source Code License as
|
||||
// published by id Software. All rights reserved.
|
||||
//
|
||||
// The source is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
|
||||
// for more details.
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// Printed strings, french translation.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __D_FRENCH__
|
||||
#define __D_FRENCH__
|
||||
|
||||
//
|
||||
// D_Main.C
|
||||
//
|
||||
#define D_DEVSTR "MODE DEVELOPPEMENT ON.\n"
|
||||
#define D_CDROM "VERSION CD-ROM: DEFAULT.CFG DANS C:\\DOOMDATA\n"
|
||||
|
||||
//
|
||||
// M_Menu.C
|
||||
//
|
||||
#define PRESSKEY "APPUYEZ SUR UNE TOUCHE."
|
||||
#define PRESSYN "APPUYEZ SUR Y OU N"
|
||||
#define QUITMSG "VOUS VOULEZ VRAIMENT\nQUITTER CE SUPER JEU?"
|
||||
#define LOADNET "VOUS NE POUVEZ PAS CHARGER\nUN JEU EN RESEAU!\n\n"PRESSKEY
|
||||
#define QLOADNET "CHARGEMENT RAPIDE INTERDIT EN RESEAU!\n\n"PRESSKEY
|
||||
#define QSAVESPOT "VOUS N'AVEZ PAS CHOISI UN EMPLACEMENT!\n\n"PRESSKEY
|
||||
#define SAVEDEAD "VOUS NE POUVEZ PAS SAUVER SI VOUS NE JOUEZ "\
|
||||
"PAS!\n\n"PRESSKEY
|
||||
#define QSPROMPT "SAUVEGARDE RAPIDE DANS LE FICHIER \n\n'%s'?\n\n"PRESSYN
|
||||
#define QLPROMPT "VOULEZ-VOUS CHARGER LA SAUVEGARDE"\
|
||||
"\n\n'%s'?\n\n"PRESSYN
|
||||
#define NEWGAME "VOUS NE POUVEZ PAS LANCER\n"\
|
||||
"UN NOUVEAU JEU SUR RESEAU.\n\n"PRESSKEY
|
||||
#define NIGHTMARE "VOUS CONFIRMEZ? CE NIVEAU EST\n"\
|
||||
"VRAIMENT IMPITOYABLE!n"PRESSYN
|
||||
#define SWSTRING "CECI EST UNE VERSION SHAREWARE DE DOOM.\n\n"\
|
||||
"VOUS DEVRIEZ COMMANDER LA TRILOGIE COMPLETE.\n\n"PRESSKEY
|
||||
#define MSGOFF "MESSAGES OFF"
|
||||
#define MSGON "MESSAGES ON"
|
||||
#define NETEND "VOUS NE POUVEZ PAS METTRE FIN A UN JEU SUR "\
|
||||
"RESEAU!\n\n"PRESSKEY
|
||||
#define ENDGAME "VOUS VOULEZ VRAIMENT METTRE FIN AU JEU?\n\n"PRESSYN
|
||||
|
||||
#define DOSY "(APPUYEZ SUR Y POUR REVENIR AU OS.)"
|
||||
|
||||
#define DETAILHI "GRAPHISMES MAXIMUM "
|
||||
#define DETAILLO "GRAPHISMES MINIMUM "
|
||||
#define GAMMALVL0 "CORRECTION GAMMA OFF"
|
||||
#define GAMMALVL1 "CORRECTION GAMMA NIVEAU 1"
|
||||
#define GAMMALVL2 "CORRECTION GAMMA NIVEAU 2"
|
||||
#define GAMMALVL3 "CORRECTION GAMMA NIVEAU 3"
|
||||
#define GAMMALVL4 "CORRECTION GAMMA NIVEAU 4"
|
||||
#define EMPTYSTRING "EMPLACEMENT VIDE"
|
||||
|
||||
//
|
||||
// P_inter.C
|
||||
//
|
||||
#define GOTARMOR "ARMURE RECUPEREE."
|
||||
#define GOTMEGA "MEGA-ARMURE RECUPEREE!"
|
||||
#define GOTHTHBONUS "BONUS DE SANTE RECUPERE."
|
||||
#define GOTARMBONUS "BONUS D'ARMURE RECUPERE."
|
||||
#define GOTSTIM "STIMPACK RECUPERE."
|
||||
#define GOTMEDINEED "MEDIKIT RECUPERE. VOUS EN AVEZ VRAIMENT BESOIN!"
|
||||
#define GOTMEDIKIT "MEDIKIT RECUPERE."
|
||||
#define GOTSUPER "SUPERCHARGE!"
|
||||
|
||||
#define GOTBLUECARD "CARTE MAGNETIQUE BLEUE RECUPEREE."
|
||||
#define GOTYELWCARD "CARTE MAGNETIQUE JAUNE RECUPEREE."
|
||||
#define GOTREDCARD "CARTE MAGNETIQUE ROUGE RECUPEREE."
|
||||
#define GOTBLUESKUL "CLEF CRANE BLEUE RECUPEREE."
|
||||
#define GOTYELWSKUL "CLEF CRANE JAUNE RECUPEREE."
|
||||
#define GOTREDSKULL "CLEF CRANE ROUGE RECUPEREE."
|
||||
|
||||
#define GOTINVUL "INVULNERABILITE!"
|
||||
#define GOTBERSERK "BERSERK!"
|
||||
#define GOTINVIS "INVISIBILITE PARTIELLE "
|
||||
#define GOTSUIT "COMBINAISON ANTI-RADIATIONS "
|
||||
#define GOTMAP "CARTE INFORMATIQUE "
|
||||
#define GOTVISOR "VISEUR A AMPLIFICATION DE LUMIERE "
|
||||
#define GOTMSPHERE "MEGASPHERE!"
|
||||
|
||||
#define GOTCLIP "CHARGEUR RECUPERE."
|
||||
#define GOTCLIPBOX "BOITE DE BALLES RECUPEREE."
|
||||
#define GOTROCKET "ROQUETTE RECUPEREE."
|
||||
#define GOTROCKBOX "CAISSE DE ROQUETTES RECUPEREE."
|
||||
#define GOTCELL "CELLULE D'ENERGIE RECUPEREE."
|
||||
#define GOTCELLBOX "PACK DE CELLULES D'ENERGIE RECUPERE."
|
||||
#define GOTSHELLS "4 CARTOUCHES RECUPEREES."
|
||||
#define GOTSHELLBOX "BOITE DE CARTOUCHES RECUPEREE."
|
||||
#define GOTBACKPACK "SAC PLEIN DE MUNITIONS RECUPERE!"
|
||||
|
||||
#define GOTBFG9000 "VOUS AVEZ UN BFG9000! OH, OUI!"
|
||||
#define GOTCHAINGUN "VOUS AVEZ LA MITRAILLEUSE!"
|
||||
#define GOTCHAINSAW "UNE TRONCONNEUSE!"
|
||||
#define GOTLAUNCHER "VOUS AVEZ UN LANCE-ROQUETTES!"
|
||||
#define GOTPLASMA "VOUS AVEZ UN FUSIL A PLASMA!"
|
||||
#define GOTSHOTGUN "VOUS AVEZ UN FUSIL!"
|
||||
#define GOTSHOTGUN2 "VOUS AVEZ UN SUPER FUSIL!"
|
||||
|
||||
//
|
||||
// P_Doors.C
|
||||
//
|
||||
#define PD_BLUEO "IL VOUS FAUT UNE CLEF BLEUE"
|
||||
#define PD_REDO "IL VOUS FAUT UNE CLEF ROUGE"
|
||||
#define PD_YELLOWO "IL VOUS FAUT UNE CLEF JAUNE"
|
||||
#define PD_BLUEK PD_BLUEO
|
||||
#define PD_REDK PD_REDO
|
||||
#define PD_YELLOWK PD_YELLOWO
|
||||
|
||||
//
|
||||
// G_game.C
|
||||
//
|
||||
#define GGSAVED "JEU SAUVEGARDE."
|
||||
|
||||
//
|
||||
// HU_stuff.C
|
||||
//
|
||||
#define HUSTR_MSGU "[MESSAGE NON ENVOYE]"
|
||||
|
||||
#define HUSTR_E1M1 "E1M1: HANGAR"
|
||||
#define HUSTR_E1M2 "E1M2: USINE NUCLEAIRE "
|
||||
#define HUSTR_E1M3 "E1M3: RAFFINERIE DE TOXINES "
|
||||
#define HUSTR_E1M4 "E1M4: CENTRE DE CONTROLE "
|
||||
#define HUSTR_E1M5 "E1M5: LABORATOIRE PHOBOS "
|
||||
#define HUSTR_E1M6 "E1M6: TRAITEMENT CENTRAL "
|
||||
#define HUSTR_E1M7 "E1M7: CENTRE INFORMATIQUE "
|
||||
#define HUSTR_E1M8 "E1M8: ANOMALIE PHOBOS "
|
||||
#define HUSTR_E1M9 "E1M9: BASE MILITAIRE "
|
||||
|
||||
#define HUSTR_E2M1 "E2M1: ANOMALIE DEIMOS "
|
||||
#define HUSTR_E2M2 "E2M2: ZONE DE CONFINEMENT "
|
||||
#define HUSTR_E2M3 "E2M3: RAFFINERIE"
|
||||
#define HUSTR_E2M4 "E2M4: LABORATOIRE DEIMOS "
|
||||
#define HUSTR_E2M5 "E2M5: CENTRE DE CONTROLE "
|
||||
#define HUSTR_E2M6 "E2M6: HALLS DES DAMNES "
|
||||
#define HUSTR_E2M7 "E2M7: CUVES DE REPRODUCTION "
|
||||
#define HUSTR_E2M8 "E2M8: TOUR DE BABEL "
|
||||
#define HUSTR_E2M9 "E2M9: FORTERESSE DU MYSTERE "
|
||||
|
||||
#define HUSTR_E3M1 "E3M1: DONJON DE L'ENFER "
|
||||
#define HUSTR_E3M2 "E3M2: BOURBIER DU DESESPOIR "
|
||||
#define HUSTR_E3M3 "E3M3: PANDEMONIUM"
|
||||
#define HUSTR_E3M4 "E3M4: MAISON DE LA DOULEUR "
|
||||
#define HUSTR_E3M5 "E3M5: CATHEDRALE PROFANE "
|
||||
#define HUSTR_E3M6 "E3M6: MONT EREBUS"
|
||||
#define HUSTR_E3M7 "E3M7: LIMBES"
|
||||
#define HUSTR_E3M8 "E3M8: DIS"
|
||||
#define HUSTR_E3M9 "E3M9: CLAPIERS"
|
||||
|
||||
#define HUSTR_1 "NIVEAU 1: ENTREE "
|
||||
#define HUSTR_2 "NIVEAU 2: HALLS SOUTERRAINS "
|
||||
#define HUSTR_3 "NIVEAU 3: LE FEU NOURRI "
|
||||
#define HUSTR_4 "NIVEAU 4: LE FOYER "
|
||||
#define HUSTR_5 "NIVEAU 5: LES EGOUTS "
|
||||
#define HUSTR_6 "NIVEAU 6: LE BROYEUR "
|
||||
#define HUSTR_7 "NIVEAU 7: L'HERBE DE LA MORT"
|
||||
#define HUSTR_8 "NIVEAU 8: RUSES ET PIEGES "
|
||||
#define HUSTR_9 "NIVEAU 9: LE PUITS "
|
||||
#define HUSTR_10 "NIVEAU 10: BASE DE RAVITAILLEMENT "
|
||||
#define HUSTR_11 "NIVEAU 11: LE CERCLE DE LA MORT!"
|
||||
|
||||
#define HUSTR_12 "NIVEAU 12: L'USINE "
|
||||
#define HUSTR_13 "NIVEAU 13: LE CENTRE VILLE"
|
||||
#define HUSTR_14 "NIVEAU 14: LES ANTRES PROFONDES "
|
||||
#define HUSTR_15 "NIVEAU 15: LA ZONE INDUSTRIELLE "
|
||||
#define HUSTR_16 "NIVEAU 16: LA BANLIEUE"
|
||||
#define HUSTR_17 "NIVEAU 17: LES IMMEUBLES"
|
||||
#define HUSTR_18 "NIVEAU 18: LA COUR "
|
||||
#define HUSTR_19 "NIVEAU 19: LA CITADELLE "
|
||||
#define HUSTR_20 "NIVEAU 20: JE T'AI EU!"
|
||||
|
||||
#define HUSTR_21 "NIVEAU 21: LE NIRVANA"
|
||||
#define HUSTR_22 "NIVEAU 22: LES CATACOMBES "
|
||||
#define HUSTR_23 "NIVEAU 23: LA GRANDE FETE "
|
||||
#define HUSTR_24 "NIVEAU 24: LE GOUFFRE "
|
||||
#define HUSTR_25 "NIVEAU 25: LES CHUTES DE SANG"
|
||||
#define HUSTR_26 "NIVEAU 26: LES MINES ABANDONNEES "
|
||||
#define HUSTR_27 "NIVEAU 27: CHEZ LES MONSTRES "
|
||||
#define HUSTR_28 "NIVEAU 28: LE MONDE DE L'ESPRIT "
|
||||
#define HUSTR_29 "NIVEAU 29: LA LIMITE "
|
||||
#define HUSTR_30 "NIVEAU 30: L'ICONE DU PECHE "
|
||||
|
||||
#define HUSTR_31 "NIVEAU 31: WOLFENSTEIN"
|
||||
#define HUSTR_32 "NIVEAU 32: LE MASSACRE"
|
||||
|
||||
|
||||
#define HUSTR_CHATMACRO1 "JE SUIS PRET A LEUR EN FAIRE BAVER!"
|
||||
#define HUSTR_CHATMACRO2 "JE VAIS BIEN."
|
||||
#define HUSTR_CHATMACRO3 "JE N'AI PAS L'AIR EN FORME!"
|
||||
#define HUSTR_CHATMACRO4 "AU SECOURS!"
|
||||
#define HUSTR_CHATMACRO5 "TU CRAINS!"
|
||||
#define HUSTR_CHATMACRO6 "LA PROCHAINE FOIS, MINABLE..."
|
||||
#define HUSTR_CHATMACRO7 "VIENS ICI!"
|
||||
#define HUSTR_CHATMACRO8 "JE VAIS M'EN OCCUPER."
|
||||
#define HUSTR_CHATMACRO9 "OUI"
|
||||
#define HUSTR_CHATMACRO0 "NON"
|
||||
|
||||
#define HUSTR_TALKTOSELF1 "VOUS PARLEZ TOUT SEUL "
|
||||
#define HUSTR_TALKTOSELF2 "QUI EST LA?"
|
||||
#define HUSTR_TALKTOSELF3 "VOUS VOUS FAITES PEUR "
|
||||
#define HUSTR_TALKTOSELF4 "VOUS COMMENCEZ A DELIRER "
|
||||
#define HUSTR_TALKTOSELF5 "VOUS ETES LARGUE..."
|
||||
|
||||
#define HUSTR_MESSAGESENT "[MESSAGE ENVOYE]"
|
||||
|
||||
// The following should NOT be changed unless it seems
|
||||
// just AWFULLY necessary
|
||||
|
||||
#define HUSTR_PLRGREEN "VERT: "
|
||||
#define HUSTR_PLRINDIGO "INDIGO: "
|
||||
#define HUSTR_PLRBROWN "BRUN: "
|
||||
#define HUSTR_PLRRED "ROUGE: "
|
||||
|
||||
#define HUSTR_KEYGREEN 'g' // french key should be "V"
|
||||
#define HUSTR_KEYINDIGO 'i'
|
||||
#define HUSTR_KEYBROWN 'b'
|
||||
#define HUSTR_KEYRED 'r'
|
||||
|
||||
//
|
||||
// AM_map.C
|
||||
//
|
||||
|
||||
#define AMSTR_FOLLOWON "MODE POURSUITE ON"
|
||||
#define AMSTR_FOLLOWOFF "MODE POURSUITE OFF"
|
||||
|
||||
#define AMSTR_GRIDON "GRILLE ON"
|
||||
#define AMSTR_GRIDOFF "GRILLE OFF"
|
||||
|
||||
#define AMSTR_MARKEDSPOT "REPERE MARQUE "
|
||||
#define AMSTR_MARKSCLEARED "REPERES EFFACES "
|
||||
|
||||
//
|
||||
// ST_stuff.C
|
||||
//
|
||||
|
||||
#define STSTR_MUS "CHANGEMENT DE MUSIQUE "
|
||||
#define STSTR_NOMUS "IMPOSSIBLE SELECTION"
|
||||
#define STSTR_DQDON "INVULNERABILITE ON "
|
||||
#define STSTR_DQDOFF "INVULNERABILITE OFF"
|
||||
|
||||
#define STSTR_KFAADDED "ARMEMENT MAXIMUM! "
|
||||
#define STSTR_FAADDED "ARMES (SAUF CLEFS) AJOUTEES"
|
||||
|
||||
#define STSTR_NCON "BARRIERES ON"
|
||||
#define STSTR_NCOFF "BARRIERES OFF"
|
||||
|
||||
#define STSTR_BEHOLD " inVuln, Str, Inviso, Rad, Allmap, or Lite-amp"
|
||||
#define STSTR_BEHOLDX "AMELIORATION ACTIVEE"
|
||||
|
||||
#define STSTR_CHOPPERS "... DOESN'T SUCK - GM"
|
||||
#define STSTR_CLEV "CHANGEMENT DE NIVEAU..."
|
||||
|
||||
//
|
||||
// F_Finale.C
|
||||
//
|
||||
#define E1TEXT "APRES AVOIR VAINCU LES GROS MECHANTS\n"\
|
||||
"ET NETTOYE LA BASE LUNAIRE, VOUS AVEZ\n"\
|
||||
"GAGNE, NON? PAS VRAI? OU EST DONC VOTRE\n"\
|
||||
" RECOMPENSE ET VOTRE BILLET DE\n"\
|
||||
"RETOUR? QU'EST-QUE CA VEUT DIRE?CE"\
|
||||
"N'EST PAS LA FIN ESPEREE!\n"\
|
||||
"\n" \
|
||||
"CA SENT LA VIANDE PUTREFIEE, MAIS\n"\
|
||||
"ON DIRAIT LA BASE DEIMOS. VOUS ETES\n"\
|
||||
"APPAREMMENT BLOQUE AUX PORTES DE L'ENFER.\n"\
|
||||
"LA SEULE ISSUE EST DE L'AUTRE COTE.\n"\
|
||||
"\n"\
|
||||
"POUR VIVRE LA SUITE DE DOOM, JOUEZ\n"\
|
||||
"A 'AUX PORTES DE L'ENFER' ET A\n"\
|
||||
"L'EPISODE SUIVANT, 'L'ENFER'!\n"
|
||||
|
||||
#define E2TEXT "VOUS AVEZ REUSSI. L'INFAME DEMON\n"\
|
||||
"QUI CONTROLAIT LA BASE LUNAIRE DE\n"\
|
||||
"DEIMOS EST MORT, ET VOUS AVEZ\n"\
|
||||
"TRIOMPHE! MAIS... OU ETES-VOUS?\n"\
|
||||
"VOUS GRIMPEZ JUSQU'AU BORD DE LA\n"\
|
||||
"LUNE ET VOUS DECOUVREZ L'ATROCE\n"\
|
||||
"VERITE.\n" \
|
||||
"\n"\
|
||||
"DEIMOS EST AU-DESSUS DE L'ENFER!\n"\
|
||||
"VOUS SAVEZ QUE PERSONNE NE S'EN\n"\
|
||||
"EST JAMAIS ECHAPPE, MAIS CES FUMIERS\n"\
|
||||
"VONT REGRETTER DE VOUS AVOIR CONNU!\n"\
|
||||
"VOUS REDESCENDEZ RAPIDEMENT VERS\n"\
|
||||
"LA SURFACE DE L'ENFER.\n"\
|
||||
"\n" \
|
||||
"VOICI MAINTENANT LE CHAPITRE FINAL DE\n"\
|
||||
"DOOM! -- L'ENFER."
|
||||
|
||||
#define E3TEXT "LE DEMON ARACHNEEN ET REPUGNANT\n"\
|
||||
"QUI A DIRIGE L'INVASION DES BASES\n"\
|
||||
"LUNAIRES ET SEME LA MORT VIENT DE SE\n"\
|
||||
"FAIRE PULVERISER UNE FOIS POUR TOUTES.\n"\
|
||||
"\n"\
|
||||
"UNE PORTE SECRETE S'OUVRE. VOUS ENTREZ.\n"\
|
||||
"VOUS AVEZ PROUVE QUE VOUS POUVIEZ\n"\
|
||||
"RESISTER AUX HORREURS DE L'ENFER.\n"\
|
||||
"IL SAIT ETRE BEAU JOUEUR, ET LORSQUE\n"\
|
||||
"VOUS SORTEZ, VOUS REVOYEZ LES VERTES\n"\
|
||||
"PRAIRIES DE LA TERRE, VOTRE PLANETE.\n"\
|
||||
"\n"\
|
||||
"VOUS VOUS DEMANDEZ CE QUI S'EST PASSE\n"\
|
||||
"SUR TERRE PENDANT QUE VOUS AVEZ\n"\
|
||||
"COMBATTU LE DEMON. HEUREUSEMENT,\n"\
|
||||
"AUCUN GERME DU MAL N'A FRANCHI\n"\
|
||||
"CETTE PORTE AVEC VOUS..."
|
||||
|
||||
|
||||
|
||||
// after level 6, put this:
|
||||
|
||||
#define C1TEXT "VOUS ETES AU PLUS PROFOND DE L'ASTROPORT\n" \
|
||||
"INFESTE DE MONSTRES, MAIS QUELQUE CHOSE\n" \
|
||||
"NE VA PAS. ILS ONT APPORTE LEUR PROPRE\n" \
|
||||
"REALITE, ET LA TECHNOLOGIE DE L'ASTROPORT\n" \
|
||||
"EST AFFECTEE PAR LEUR PRESENCE.\n" \
|
||||
"\n"\
|
||||
"DEVANT VOUS, VOUS VOYEZ UN POSTE AVANCE\n" \
|
||||
"DE L'ENFER, UNE ZONE FORTIFIEE. SI VOUS\n" \
|
||||
"POUVEZ PASSER, VOUS POURREZ PENETRER AU\n" \
|
||||
"COEUR DE LA BASE HANTEE ET TROUVER \n" \
|
||||
"L'INTERRUPTEUR DE CONTROLE QUI GARDE LA \n" \
|
||||
"POPULATION DE LA TERRE EN OTAGE."
|
||||
|
||||
// After level 11, put this:
|
||||
|
||||
#define C2TEXT "VOUS AVEZ GAGNE! VOTRE VICTOIRE A PERMIS\n" \
|
||||
"A L'HUMANITE D'EVACUER LA TERRE ET \n"\
|
||||
"D'ECHAPPER AU CAUCHEMAR. VOUS ETES \n"\
|
||||
"MAINTENANT LE DERNIER HUMAIN A LA SURFACE \n"\
|
||||
"DE LA PLANETE. VOUS ETES ENTOURE DE \n"\
|
||||
"MUTANTS CANNIBALES, D'EXTRATERRESTRES \n"\
|
||||
"CARNIVORES ET D'ESPRITS DU MAL. VOUS \n"\
|
||||
"ATTENDEZ CALMEMENT LA MORT, HEUREUX \n"\
|
||||
"D'AVOIR PU SAUVER VOTRE RACE.\n"\
|
||||
"MAIS UN MESSAGE VOUS PARVIENT SOUDAIN\n"\
|
||||
"DE L'ESPACE: \"NOS CAPTEURS ONT LOCALISE\n"\
|
||||
"LA SOURCE DE L'INVASION EXTRATERRESTRE.\n"\
|
||||
"SI VOUS Y ALLEZ, VOUS POURREZ PEUT-ETRE\n"\
|
||||
"LES ARRETER. LEUR BASE EST SITUEE AU COEUR\n"\
|
||||
"DE VOTRE VILLE NATALE, PRES DE L'ASTROPORT.\n"\
|
||||
"VOUS VOUS RELEVEZ LENTEMENT ET PENIBLEMENT\n"\
|
||||
"ET VOUS REPARTEZ POUR LE FRONT."
|
||||
|
||||
// After level 20, put this:
|
||||
|
||||
#define C3TEXT "VOUS ETES AU COEUR DE LA CITE CORROMPUE,\n"\
|
||||
"ENTOURE PAR LES CADAVRES DE VOS ENNEMIS.\n"\
|
||||
"VOUS NE VOYEZ PAS COMMENT DETRUIRE LA PORTE\n"\
|
||||
"DES CREATURES DE CE COTE. VOUS SERREZ\n"\
|
||||
"LES DENTS ET PLONGEZ DANS L'OUVERTURE.\n"\
|
||||
"\n"\
|
||||
"IL DOIT Y AVOIR UN MOYEN DE LA FERMER\n"\
|
||||
"DE L'AUTRE COTE. VOUS ACCEPTEZ DE\n"\
|
||||
"TRAVERSER L'ENFER POUR LE FAIRE?"
|
||||
|
||||
// After level 29, put this:
|
||||
|
||||
#define C4TEXT "LE VISAGE HORRIBLE D'UN DEMON D'UNE\n"\
|
||||
"TAILLE INCROYABLE S'EFFONDRE DEVANT\n"\
|
||||
"VOUS LORSQUE VOUS TIREZ UNE SALVE DE\n"\
|
||||
"ROQUETTES DANS SON CERVEAU. LE MONSTRE\n"\
|
||||
"SE RATATINE, SES MEMBRES DECHIQUETES\n"\
|
||||
"SE REPANDANT SUR DES CENTAINES DE\n"\
|
||||
"KILOMETRES A LA SURFACE DE L'ENFER.\n"\
|
||||
"\n"\
|
||||
"VOUS AVEZ REUSSI. L'INVASION N'AURA.\n"\
|
||||
"PAS LIEU. LA TERRE EST SAUVEE. L'ENFER\n"\
|
||||
"EST ANEANTI. EN VOUS DEMANDANT OU IRONT\n"\
|
||||
"MAINTENANT LES DAMNES, VOUS ESSUYEZ\n"\
|
||||
"VOTRE FRONT COUVERT DE SUEUR ET REPARTEZ\n"\
|
||||
"VERS LA TERRE. SA RECONSTRUCTION SERA\n"\
|
||||
"BEAUCOUP PLUS DROLE QUE SA DESTRUCTION.\n"
|
||||
|
||||
// Before level 31, put this:
|
||||
|
||||
#define C5TEXT "FELICITATIONS! VOUS AVEZ TROUVE LE\n"\
|
||||
"NIVEAU SECRET! IL SEMBLE AVOIR ETE\n"\
|
||||
"CONSTRUIT PAR LES HUMAINS. VOUS VOUS\n"\
|
||||
"DEMANDEZ QUELS PEUVENT ETRE LES\n"\
|
||||
"HABITANTS DE CE COIN PERDU DE L'ENFER."
|
||||
|
||||
// Before level 32, put this:
|
||||
|
||||
#define C6TEXT "FELICITATIONS! VOUS AVEZ DECOUVERT\n"\
|
||||
"LE NIVEAU SUPER SECRET! VOUS FERIEZ\n"\
|
||||
"MIEUX DE FONCER DANS CELUI-LA!\n"
|
||||
|
||||
//
|
||||
// Character cast strings F_FINALE.C
|
||||
//
|
||||
#define CC_ZOMBIE "ZOMBIE"
|
||||
#define CC_SHOTGUN "TYPE AU FUSIL"
|
||||
#define CC_HEAVY "MEC SUPER-ARME"
|
||||
#define CC_IMP "DIABLOTIN"
|
||||
#define CC_DEMON "DEMON"
|
||||
#define CC_LOST "AME PERDUE"
|
||||
#define CC_CACO "CACODEMON"
|
||||
#define CC_HELL "CHEVALIER DE L'ENFER"
|
||||
#define CC_BARON "BARON DE L'ENFER"
|
||||
#define CC_ARACH "ARACHNOTRON"
|
||||
#define CC_PAIN "ELEMENTAIRE DE LA DOULEUR"
|
||||
#define CC_REVEN "REVENANT"
|
||||
#define CC_MANCU "MANCUBUS"
|
||||
#define CC_ARCH "ARCHI-INFAME"
|
||||
#define CC_SPIDER "L'ARAIGNEE CERVEAU"
|
||||
#define CC_CYBER "LE CYBERDEMON"
|
||||
#define CC_HERO "NOTRE HEROS"
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Log:$
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ weaponinfo_t weaponinfo[NUMWEAPONS] =
|
|||
int num_items;
|
||||
|
||||
// [RH] Guess what. These next three functions are from Quake2:
|
||||
// game/g_items.c
|
||||
// g_items.c
|
||||
|
||||
/*
|
||||
===============
|
||||
|
@ -140,7 +140,7 @@ gitem_t *GetItemByIndex (int index)
|
|||
if (index == 0 || index >= num_items)
|
||||
return NULL;
|
||||
|
||||
return &ItemList[index];
|
||||
return &itemlist[index];
|
||||
}
|
||||
|
||||
|
||||
|
@ -150,19 +150,15 @@ FindItemByClassname
|
|||
|
||||
===============
|
||||
*/
|
||||
gitem_t *FindItemByClassname (char *classname)
|
||||
gitem_t *FindItemByClassname (const char *classname)
|
||||
{
|
||||
int i;
|
||||
gitem_t *it;
|
||||
|
||||
it = ItemList;
|
||||
for (i=0 ; i<num_items ; i++, it++)
|
||||
{
|
||||
if (!it->classname)
|
||||
continue;
|
||||
if (!stricmp(it->classname, classname))
|
||||
it = itemlist;
|
||||
for (i = 0; i < num_items; i++, it++)
|
||||
if (it->classname && !stricmp(it->classname, classname))
|
||||
return it;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -173,19 +169,15 @@ FindItem
|
|||
|
||||
===============
|
||||
*/
|
||||
gitem_t *FindItem (char *pickup_name)
|
||||
gitem_t *FindItem (const char *pickup_name)
|
||||
{
|
||||
int i;
|
||||
gitem_t *it;
|
||||
|
||||
it = ItemList;
|
||||
for (i=0 ; i<num_items ; i++, it++)
|
||||
{
|
||||
if (!it->pickup_name)
|
||||
continue;
|
||||
if (!stricmp(it->pickup_name, pickup_name))
|
||||
it = itemlist;
|
||||
for (i = 0; i < num_items; i++, it++)
|
||||
if (it->pickup_name && !stricmp(it->pickup_name, pickup_name))
|
||||
return it;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -195,7 +187,7 @@ gitem_t *FindItem (char *pickup_name)
|
|||
// Used mainly by the give command. Hopefully will
|
||||
// become more general-purpose later.
|
||||
// (Yes, this was inspired by Quake 2)
|
||||
gitem_t ItemList[] = {
|
||||
gitem_t itemlist[] = {
|
||||
{
|
||||
NULL
|
||||
}, // leave index 0 alone
|
||||
|
@ -240,6 +232,16 @@ gitem_t ItemList[] = {
|
|||
"Fist"
|
||||
},
|
||||
|
||||
{
|
||||
"weapon_chainsaw",
|
||||
NULL,
|
||||
NULL,
|
||||
IT_WEAPON,
|
||||
wp_chainsaw,
|
||||
0,
|
||||
"Chainsaw"
|
||||
},
|
||||
|
||||
{
|
||||
"weapon_pistol",
|
||||
NULL,
|
||||
|
@ -260,6 +262,16 @@ gitem_t ItemList[] = {
|
|||
"Shotgun"
|
||||
},
|
||||
|
||||
{
|
||||
"weapon_supershotgun",
|
||||
NULL,
|
||||
NULL,
|
||||
IT_WEAPON,
|
||||
wp_supershotgun,
|
||||
0,
|
||||
"Super Shotgun"
|
||||
},
|
||||
|
||||
{
|
||||
"weapon_chaingun",
|
||||
NULL,
|
||||
|
@ -300,26 +312,6 @@ gitem_t ItemList[] = {
|
|||
"BFG9000"
|
||||
},
|
||||
|
||||
{
|
||||
"weapon_chainsaw",
|
||||
NULL,
|
||||
NULL,
|
||||
IT_WEAPON,
|
||||
wp_chainsaw,
|
||||
0,
|
||||
"Chainsaw"
|
||||
},
|
||||
|
||||
{
|
||||
"weapon_supershotgun",
|
||||
NULL,
|
||||
NULL,
|
||||
IT_WEAPON,
|
||||
wp_supershotgun,
|
||||
0,
|
||||
"Super Shotgun"
|
||||
},
|
||||
|
||||
{
|
||||
"ammo_bullets",
|
||||
NULL,
|
||||
|
@ -367,7 +359,7 @@ gitem_t ItemList[] = {
|
|||
"item_invulnerability",
|
||||
NULL,
|
||||
NULL,
|
||||
IT_POWER,
|
||||
IT_POWERUP,
|
||||
pw_invulnerability,
|
||||
0,
|
||||
"Invulnerability"
|
||||
|
@ -377,7 +369,7 @@ gitem_t ItemList[] = {
|
|||
"item_berserk",
|
||||
NULL,
|
||||
NULL,
|
||||
IT_POWER,
|
||||
IT_POWERUP,
|
||||
pw_strength,
|
||||
0,
|
||||
"Berserk"
|
||||
|
@ -387,7 +379,7 @@ gitem_t ItemList[] = {
|
|||
"item_invisibility",
|
||||
NULL,
|
||||
NULL,
|
||||
IT_POWER,
|
||||
IT_POWERUP,
|
||||
pw_invisibility,
|
||||
0,
|
||||
"Partial Invisibility"
|
||||
|
@ -397,7 +389,7 @@ gitem_t ItemList[] = {
|
|||
"item_ironfeet",
|
||||
NULL,
|
||||
NULL,
|
||||
IT_POWER,
|
||||
IT_POWERUP,
|
||||
pw_ironfeet,
|
||||
0,
|
||||
"Iron Feet"
|
||||
|
@ -407,7 +399,7 @@ gitem_t ItemList[] = {
|
|||
"item_allmap",
|
||||
NULL,
|
||||
NULL,
|
||||
IT_POWER,
|
||||
IT_POWERUP,
|
||||
pw_allmap,
|
||||
0,
|
||||
"Computer Map"
|
||||
|
@ -417,7 +409,7 @@ gitem_t ItemList[] = {
|
|||
"item_visor",
|
||||
NULL,
|
||||
NULL,
|
||||
IT_POWER,
|
||||
IT_POWERUP,
|
||||
pw_infrared,
|
||||
0,
|
||||
"Light Amplification Visor"
|
||||
|
@ -493,5 +485,5 @@ gitem_t ItemList[] = {
|
|||
|
||||
void InitItems (void)
|
||||
{
|
||||
num_items = sizeof(ItemList)/sizeof(ItemList[0]) - 1;
|
||||
num_items = sizeof(itemlist)/sizeof(itemlist[0]) - 1;
|
||||
}
|
|
@ -25,13 +25,10 @@
|
|||
#ifndef __D_MAIN__
|
||||
#define __D_MAIN__
|
||||
|
||||
#include <setjmp.h>
|
||||
#include "d_event.h"
|
||||
|
||||
|
||||
|
||||
#define MAXWADFILES 20
|
||||
extern char* wadfiles[MAXWADFILES];
|
||||
|
||||
void D_AddFile (char *file);
|
||||
|
||||
|
||||
|
@ -47,7 +44,7 @@ void D_DoomMain (void);
|
|||
// Called by IO functions when input is detected.
|
||||
void D_PostEvent (const event_t* ev);
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// BASE LEVEL
|
||||
|
@ -57,4 +54,13 @@ void D_PageDrawer (void);
|
|||
void D_AdvanceDemo (void);
|
||||
void D_StartTitle (void);
|
||||
|
||||
|
||||
// [RH] Set this to something to draw an icon during the next screen refresh.
|
||||
extern char *D_DrawIcon;
|
||||
|
||||
// [RH] Allow for recoverable errors to drop to console only
|
||||
extern char errortext[2048];
|
||||
extern jmp_buf errorjmp;
|
||||
extern BOOL errorjmpable;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "doomdef.h"
|
||||
|
@ -11,28 +12,43 @@
|
|||
#include "v_video.h"
|
||||
#include "i_system.h"
|
||||
#include "r_draw.h"
|
||||
#include "r_state.h"
|
||||
#include "st_stuff.h"
|
||||
|
||||
extern BOOL st_firsttime;
|
||||
|
||||
cvar_t *autoaim;
|
||||
cvar_t *name;
|
||||
cvar_t *color;
|
||||
cvar_t *skin;
|
||||
cvar_t *team;
|
||||
cvar_t *gender;
|
||||
|
||||
static userinfo_t userinfos[MAXPLAYERS];
|
||||
int D_GenderToInt (const char *gender)
|
||||
{
|
||||
if (!stricmp (gender, "female"))
|
||||
return GENDER_FEMALE;
|
||||
else if (!stricmp (gender, "neuter"))
|
||||
return GENDER_NEUTER;
|
||||
else
|
||||
return GENDER_MALE;
|
||||
}
|
||||
|
||||
void D_SetupUserInfo (void)
|
||||
{
|
||||
int i;
|
||||
userinfo_t *coninfo = &players[consoleplayer].userinfo;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++) {
|
||||
memset (&userinfos[i], 0, sizeof(userinfo_t));
|
||||
players[i].userinfo = &userinfos[i];
|
||||
}
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
memset (&players[i].userinfo, 0, sizeof(userinfo_t));
|
||||
|
||||
strncpy (userinfos[consoleplayer].netname, name->string, MAXPLAYERNAME);
|
||||
userinfos[consoleplayer].aimdist = (fixed_t)(autoaim->value * 16384.0);
|
||||
userinfos[consoleplayer].color = V_GetColorFromString (NULL, color->string);
|
||||
R_BuildPlayerTranslation (consoleplayer, userinfos[consoleplayer].color);
|
||||
strncpy (coninfo->netname, name->string, MAXPLAYERNAME);
|
||||
strncpy (coninfo->team, team->string, MAXPLAYERNAME);
|
||||
coninfo->aimdist = (fixed_t)(autoaim->value * 16384.0);
|
||||
coninfo->color = V_GetColorFromString (NULL, color->string);
|
||||
coninfo->skin = R_FindSkin (skin->string);
|
||||
coninfo->gender = D_GenderToInt (gender->string);
|
||||
R_BuildPlayerTranslation (consoleplayer, coninfo->color);
|
||||
}
|
||||
|
||||
void D_UserInfoChanged (cvar_t *cvar)
|
||||
|
@ -122,12 +138,15 @@ void D_WriteUserInfoStrings (int i, byte **stream)
|
|||
if (i >= MAXPLAYERS) {
|
||||
WriteByte (0, stream);
|
||||
} else {
|
||||
userinfo_t *info = players[i].userinfo;
|
||||
userinfo_t *info = &players[i].userinfo;
|
||||
|
||||
sprintf (*stream, "\\name\\%s\\autoaim\\%g\\color\\%x %x %x",
|
||||
sprintf (*stream, "\\name\\%s\\autoaim\\%g\\color\\%x %x %x\\skin\\%s\\team\\%s\\gender\\%s",
|
||||
info->netname,
|
||||
(double)info->aimdist / 16384.0,
|
||||
RPART(info->color), GPART(info->color), BPART(info->color)
|
||||
RPART(info->color), GPART(info->color), BPART(info->color),
|
||||
skins[info->skin].name, info->team,
|
||||
info->gender == GENDER_FEMALE ? "female" :
|
||||
info->gender == GENDER_NEUTER ? "neuter" : "male"
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -136,7 +155,7 @@ void D_WriteUserInfoStrings (int i, byte **stream)
|
|||
|
||||
void D_ReadUserInfoStrings (int i, byte **stream, BOOL update)
|
||||
{
|
||||
userinfo_t *info = players[i].userinfo;
|
||||
userinfo_t *info = &players[i].userinfo;
|
||||
byte *ptr = *stream;
|
||||
byte *breakpt;
|
||||
byte *value;
|
||||
|
@ -163,10 +182,27 @@ void D_ReadUserInfoStrings (int i, byte **stream, BOOL update)
|
|||
|
||||
if (update)
|
||||
Printf ("%s is now known as %s\n", oldname, info->netname);
|
||||
} else if (!stricmp (ptr, "team")) {
|
||||
strncpy (info->team, value, MAXPLAYERNAME);
|
||||
info->team[MAXPLAYERNAME] = 0;
|
||||
if (update) {
|
||||
if (info->team[0])
|
||||
Printf ("%s joined the %s team\n", info->netname, info->team);
|
||||
else
|
||||
Printf ("%s is not on a team\n", info->netname);
|
||||
}
|
||||
} else if (!stricmp (ptr, "color")) {
|
||||
info->color = V_GetColorFromString (NULL, value);
|
||||
R_BuildPlayerTranslation (i, info->color);
|
||||
st_firsttime = true;
|
||||
} else if (!stricmp (ptr, "skin")) {
|
||||
info->skin = R_FindSkin (value);
|
||||
if (players[i].mo)
|
||||
players[i].mo->sprite = skins[info->skin].sprite;
|
||||
ST_loadGraphics ();
|
||||
st_firsttime = true;
|
||||
} else if (!stricmp (ptr, "gender")) {
|
||||
info->gender = D_GenderToInt (value);
|
||||
}
|
||||
|
||||
*(value - 1) = '\\';
|
||||
|
|
|
@ -5,12 +5,19 @@
|
|||
|
||||
extern cvar_t *autoaim;
|
||||
|
||||
#define MAXPLAYERNAME 23
|
||||
#define MAXPLAYERNAME 15
|
||||
|
||||
#define GENDER_MALE 0
|
||||
#define GENDER_FEMALE 1
|
||||
#define GENDER_NEUTER 2
|
||||
|
||||
struct userinfo_s {
|
||||
char netname[MAXPLAYERNAME+1];
|
||||
char team[MAXPLAYERNAME+1];
|
||||
fixed_t aimdist;
|
||||
int color;
|
||||
int skin;
|
||||
int gender;
|
||||
};
|
||||
typedef struct userinfo_s userinfo_t;
|
||||
|
||||
|
|
78
code/docs/README.Carmack
Normal file
78
code/docs/README.Carmack
Normal file
|
@ -0,0 +1,78 @@
|
|||
|
||||
Here it is, at long last. The DOOM source code is released for your
|
||||
non-profit use. You still need real DOOM data to work with this code.
|
||||
If you don't actually own a real copy of one of the DOOMs, you should
|
||||
still be able to find them at software stores.
|
||||
|
||||
Many thanks to Bernd Kreimeier for taking the time to clean up the
|
||||
project and make sure that it actually works. Projects tends to rot if
|
||||
you leave it alone for a few years, and it takes effort for someone to
|
||||
deal with it again.
|
||||
|
||||
The bad news: this code only compiles and runs on linux. We couldn't
|
||||
release the dos code because of a copyrighted sound library we used
|
||||
(wow, was that a mistake -- I write my own sound code now), and I
|
||||
honestly don't even know what happened to the port that microsoft did
|
||||
to windows.
|
||||
|
||||
Still, the code is quite portable, and it should be straightforward to
|
||||
bring it up on just about any platform.
|
||||
|
||||
I wrote this code a long, long time ago, and there are plenty of things
|
||||
that seem downright silly in retrospect (using polar coordinates for
|
||||
clipping comes to mind), but overall it should still be a usefull base
|
||||
to experiment and build on.
|
||||
|
||||
The basic rendering concept -- horizontal and vertical lines of constant
|
||||
Z with fixed light shading per band was dead-on, but the implementation
|
||||
could be improved dramatically from the original code if it were
|
||||
revisited. The way the rendering proceded from walls to floors to
|
||||
sprites could be collapsed into a single front-to-back walk of the bsp
|
||||
tree to collect information, then draw all the contents of a subsector
|
||||
on the way back up the tree. It requires treating floors and ceilings
|
||||
as polygons, rather than just the gaps between walls, and it requires
|
||||
clipping sprite billboards into subsector fragments, but it would be
|
||||
The Right Thing.
|
||||
|
||||
The movement and line of sight checking against the lines is one of the
|
||||
bigger misses that I look back on. It is messy code that had some
|
||||
failure cases, and there was a vastly simpler (and faster) solution
|
||||
sitting in front of my face. I used the BSP tree for rendering things,
|
||||
but I didn't realize at the time that it could also be used for
|
||||
environment testing. Replacing the line of sight test with a bsp line
|
||||
clip would be pretty easy. Sweeping volumes for movement gets a bit
|
||||
tougher, and touches on many of the challenges faced in quake / quake2
|
||||
with edge bevels on polyhedrons.
|
||||
|
||||
Some project ideas:
|
||||
|
||||
Port it to your favorite operating system.
|
||||
|
||||
Add some rendering features -- transparency, look up / down, slopes,
|
||||
etc.
|
||||
|
||||
Add some game features -- weapons, jumping, ducking, flying, etc.
|
||||
|
||||
Create a packet server based internet game.
|
||||
|
||||
Create a client / server based internet game.
|
||||
|
||||
Do a 3D accelerated version. On modern hardware (fast pentium + 3DFX)
|
||||
you probably wouldn't even need to be clever -- you could just draw the
|
||||
entire level and get reasonable speed. With a touch of effort, it should
|
||||
easily lock at 60 fps (well, there are some issues with DOOM's 35 hz
|
||||
timebase...). The biggest issues would probably be the non-power of two
|
||||
texture sizes and the walls composed of multiple textures.
|
||||
|
||||
|
||||
I don't have a real good guess at how many people are going to be
|
||||
playing with this, but if significant projects are undertaken, it would
|
||||
be cool to see a level of community cooperation. I know that most early
|
||||
projects are going to be rough hacks done in isolation, but I would be
|
||||
very pleased to see a coordinated 'net release of an improved, backwards
|
||||
compatable version of DOOM on multiple platforms next year.
|
||||
|
||||
Have fun.
|
||||
|
||||
John Carmack
|
||||
12-23-97
|
136
code/docs/README.LZO
Normal file
136
code/docs/README.LZO
Normal file
|
@ -0,0 +1,136 @@
|
|||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
|
||||
|
||||
============================================================================
|
||||
miniLZO -- mini subset of the LZO real-time data compression library
|
||||
============================================================================
|
||||
|
||||
Author : Markus Franz Xaver Johannes Oberhumer
|
||||
<markus.oberhumer@jk.uni-linz.ac.at>
|
||||
http://wildsau.idv.uni-linz.ac.at/mfx/lzo.html
|
||||
Version : 1.04
|
||||
Date : 15-Mar-1998
|
||||
|
||||
I've created miniLZO for projects where it is inconvenient to
|
||||
include (or require) the full LZO source code just because you
|
||||
want to add a little bit of data compression to your application.
|
||||
|
||||
miniLZO implements the LZO1X-1 compressor and both the standard and
|
||||
safe LZO1X decompressor. Apart from fast compression it also useful
|
||||
for situations where you want to use pre-compressed data files (which
|
||||
must have been compressed with LZO1X-999).
|
||||
|
||||
miniLZO consists of one C source file and two header files:
|
||||
minilzo.c
|
||||
minilzo.h
|
||||
lzoconf.h
|
||||
|
||||
To use miniLZO just copy these files into your source directory, add
|
||||
minilzo.c to your Makefile and #include minilzo.h from your program.
|
||||
Note: you also must distribute this file (`README.LZO') with your project.
|
||||
|
||||
minilzo.o compiles to about 6 kB (using gcc or Watcom C on a i386), and
|
||||
the sources are about 14 kB when packed with zip - so there's no more
|
||||
excuse that your application doesn't support data compression :-)
|
||||
|
||||
For more information, documentation, example programs and other support
|
||||
files (like Makefiles and build scripts) please download the full LZO
|
||||
package from
|
||||
http://wildsau.idv.uni-linz.ac.at/mfx/lzo.html
|
||||
|
||||
Have fun,
|
||||
Markus
|
||||
|
||||
|
||||
P.S. minilzo.c is generated automatically from the LZO sources and
|
||||
therefore functionality is completely identical
|
||||
|
||||
|
||||
Appendix A: building miniLZO
|
||||
----------------------------
|
||||
miniLZO is written such a way that it should compile and run
|
||||
out-of-the-box on most machines.
|
||||
|
||||
If you are running on a very unusual architecture and lzo_init() fails then
|
||||
you should first recompile with `-DLZO_DEBUG' to see what causes the failure.
|
||||
The most probable case is something like `sizeof(char *) != sizeof(long)'.
|
||||
After identifying the problem you can compile by adding some defines
|
||||
like `-DSIZEOF_CHAR_P=8' to your Makefile.
|
||||
|
||||
The best solution is (of course) using Autoconf - if your project uses
|
||||
Autoconf anyway just add `-DMINILZO_HAVE_CONFIG_H' to your compiler
|
||||
flags when compiling minilzo.c. See the LZO distribution for an example
|
||||
how to set up configure.in.
|
||||
|
||||
|
||||
Appendix B: list of public functions available in miniLZO
|
||||
---------------------------------------------------------
|
||||
Library initialization
|
||||
lzo_init()
|
||||
|
||||
Compression
|
||||
lzo1x_1_compress()
|
||||
|
||||
Decompression
|
||||
lzo1x_decompress()
|
||||
lzo1x_decompress_safe()
|
||||
|
||||
Checksum functions
|
||||
lzo_adler32()
|
||||
|
||||
Version functions
|
||||
lzo_version()
|
||||
lzo_version_string()
|
||||
lzo_version_date()
|
||||
|
||||
Portable (but slow) string functions
|
||||
lzo_memcmp()
|
||||
lzo_memcpy()
|
||||
lzo_memmove()
|
||||
lzo_memset()
|
||||
|
||||
|
||||
Appendix C: suggested macros for `configure.in' when using Autoconf
|
||||
-------------------------------------------------------------------
|
||||
Checks for typedefs and structures
|
||||
AC_CHECK_TYPE(ptrdiff_t,long)
|
||||
AC_TYPE_SIZE_T
|
||||
AC_CHECK_SIZEOF(unsigned short)
|
||||
AC_CHECK_SIZEOF(unsigned)
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
AC_CHECK_SIZEOF(char *)
|
||||
AC_CHECK_SIZEOF(ptrdiff_t)
|
||||
AC_CHECK_SIZEOF(size_t)
|
||||
|
||||
Checks for compiler characteristics
|
||||
AC_C_CONST
|
||||
|
||||
Checks for library functions
|
||||
AC_CHECK_FUNCS(memcmp memcpy memmove memset)
|
||||
|
||||
|
||||
Appendix D: Copyright
|
||||
---------------------
|
||||
LZO and miniLZO are Copyright (C) 1996, 1997, 1998
|
||||
Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
LZO and miniLZO are distributed under the terms of the GNU General
|
||||
Public License (GPL). See the file COPYING.
|
||||
|
||||
Special licenses for commercial and other applications which
|
||||
are not willing to accept the GNU General Public License
|
||||
are available by contacting the author.
|
||||
|
||||
|
||||
|
||||
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: 2.6.3ia
|
||||
Charset: noconv
|
||||
|
||||
iQCVAwUBNQv2B210fyLu8beJAQFC8QQAzxteZ5VRs+iDmBz40HQmsfr+RZVnyccK
|
||||
9vJ7BtFKaxAwpfa6AzothnHa1zmSaKqbltLzAQHQ6elAIYegELdpV9HRHddx0Q/y
|
||||
ATDhaVlsSGJLiOazPRBpJq6ne0J9phIH9n2hZmNQFDTm3bKmcm6PYVxt39iDVgg0
|
||||
hMwf5skDc+k=
|
||||
=qpUY
|
||||
-----END PGP SIGNATURE-----
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue