mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-06-01 17:42:25 +00:00
ZDoom 1.14a.
This commit is contained in:
parent
58c4b68204
commit
25f75d4f53
56 changed files with 2709 additions and 1177 deletions
|
@ -261,7 +261,8 @@ void C_BackupCVars (void)
|
|||
cvar_t *cvar = CVars;
|
||||
|
||||
while (cvar) {
|
||||
if ((cvar->flags & CVAR_SERVERINFO) || (cvar->flags & CVAR_DEMOSAVE)) {
|
||||
if (((cvar->flags & CVAR_SERVERINFO) || (cvar->flags & CVAR_DEMOSAVE))
|
||||
&& !(cvar->flags & CVAR_LATCH)) {
|
||||
if (backup == &CVarBackups[MAX_DEMOCVARS])
|
||||
I_Error ("C_BackupDemoCVars: Too many cvars to save (%d)", MAX_DEMOCVARS);
|
||||
backup->name = copystring (cvar->name);
|
||||
|
|
|
@ -179,6 +179,10 @@ BOOL FileExists (char *filename)
|
|||
{
|
||||
FILE *f;
|
||||
|
||||
// [RH] Empty filenames are never there
|
||||
if (*filename == 0)
|
||||
return false;
|
||||
|
||||
f = fopen (filename, "r");
|
||||
if (!f)
|
||||
return false;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef __D_DEHACK_H__
|
||||
#define __D_DEHACK_H__
|
||||
|
||||
void DoDehPatch (char *patchfile);
|
||||
void DoDehPatch (char *patchfile, BOOL autoloading);
|
||||
|
||||
#endif //__D_DEHACK_H__
|
|
@ -700,16 +700,29 @@ donewithtext:
|
|||
}
|
||||
|
||||
|
||||
void DoDehPatch (char *patchfile)
|
||||
void DoDehPatch (char *patchfile, BOOL autoloading)
|
||||
{
|
||||
char file[256];
|
||||
int cont;
|
||||
int filelen;
|
||||
int lump;
|
||||
|
||||
BackUpData ();
|
||||
PatchFile = NULL;
|
||||
|
||||
if (patchfile) {
|
||||
lump = W_CheckNumForName ("DEHACKED");
|
||||
|
||||
if (lump >= 0 && autoloading) {
|
||||
// Execute the DEHACKED lump as a patch.
|
||||
filelen = W_LumpLength (lump);
|
||||
if ( (PatchFile = malloc (filelen + 1)) ) {
|
||||
W_ReadLump (lump, PatchFile);
|
||||
} else {
|
||||
Printf ("Not enough memory to apply internal DeHackEd patch\n");
|
||||
return;
|
||||
}
|
||||
} else if (patchfile) {
|
||||
// Try to execute patchfile as a patch.
|
||||
FILE *deh;
|
||||
|
||||
strcpy (file, patchfile);
|
||||
|
@ -728,22 +741,9 @@ void DoDehPatch (char *patchfile)
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
int lump = W_CheckNumForName ("DEHACKED");
|
||||
|
||||
if (lump < 0)
|
||||
return;
|
||||
|
||||
filelen = W_LumpLength (lump);
|
||||
if ( (PatchFile = malloc (filelen + 1)) ) {
|
||||
W_ReadLump (lump, PatchFile);
|
||||
} else {
|
||||
Printf ("Not enough memory to apply internal DeHackEd patch\n");
|
||||
// Nothing to do.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PatchFile)
|
||||
return;
|
||||
|
||||
// End lump with a NULL for our parser
|
||||
PatchFile[filelen] = 0;
|
||||
|
|
|
@ -547,7 +547,11 @@ void D_AdvanceDemo (void)
|
|||
// This cycles through the demo sequences.
|
||||
// FIXME - version dependend demo numbers?
|
||||
//
|
||||
void D_DoAdvanceDemo (void)
|
||||
// [RH] If M_DemoNoPlay is true, then any
|
||||
// demos are skipped.
|
||||
extern M_DemoNoPlay;
|
||||
|
||||
void D_DoAdvanceDemo (void)
|
||||
{
|
||||
players[consoleplayer].playerstate = PST_LIVE; // not reborn
|
||||
advancedemo = false;
|
||||
|
@ -575,16 +579,20 @@ void D_AdvanceDemo (void)
|
|||
S_StartMusic ("d_intro");
|
||||
break;
|
||||
case 1:
|
||||
if (!M_DemoNoPlay) {
|
||||
G_DeferedPlayDemo ("demo1");
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
pagetic = 200;
|
||||
gamestate = GS_DEMOSCREEN;
|
||||
pagename = "CREDIT";
|
||||
break;
|
||||
case 3:
|
||||
if (!M_DemoNoPlay) {
|
||||
G_DeferedPlayDemo ("demo2");
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
gamestate = GS_DEMOSCREEN;
|
||||
if ( gamemode == commercial)
|
||||
|
@ -604,10 +612,16 @@ void D_AdvanceDemo (void)
|
|||
}
|
||||
break;
|
||||
case 5:
|
||||
if (M_DemoNoPlay)
|
||||
advancedemo = true;
|
||||
else
|
||||
G_DeferedPlayDemo ("demo3");
|
||||
break;
|
||||
// THE DEFINITIVE DOOM Special Edition demo
|
||||
case 6:
|
||||
if (M_DemoNoPlay)
|
||||
advancedemo = true;
|
||||
else
|
||||
G_DeferedPlayDemo ("demo4");
|
||||
break;
|
||||
}
|
||||
|
@ -1094,12 +1108,21 @@ void D_DoomMain (void)
|
|||
// [RH] Apply any DeHackEd patch
|
||||
{
|
||||
int hack;
|
||||
cvar_t *autopatch;
|
||||
|
||||
hack = M_CheckParm ("-deh");
|
||||
if (hack && hack < myargc - 1)
|
||||
DoDehPatch (myargv[hack + 1]);
|
||||
// Use patch from command line
|
||||
DoDehPatch (myargv[hack + 1], false);
|
||||
else {
|
||||
autopatch = cvar ("def_patch", "", CVAR_ARCHIVE);
|
||||
if (FileExists (autopatch->string))
|
||||
// Use patch specified by def_patch.
|
||||
// (Any patches in a PWAD take precedence.)
|
||||
DoDehPatch (autopatch->string, true);
|
||||
else
|
||||
DoDehPatch (NULL); // See if there's a patch in a PWAD
|
||||
DoDehPatch (NULL, true); // See if there's a patch in a PWAD
|
||||
}
|
||||
}
|
||||
|
||||
// [RH] Now that all text strings are set up,
|
||||
|
@ -1138,7 +1161,8 @@ void D_DoomMain (void)
|
|||
// but w/o all the lumps of the registered version.
|
||||
if (gamemode == registered || gamemode == retail)
|
||||
for (i = 0;i < 23; i++)
|
||||
if (W_CheckNumForName(name[i])<0)
|
||||
if (W_CheckNumForName(name[i])<0 &&
|
||||
(W_CheckNumForName)(name[i],ns_sprites)<0)
|
||||
I_Error("\nThis is not the registered version.");
|
||||
}
|
||||
|
||||
|
|
|
@ -986,7 +986,6 @@ void Net_DoCommand (int type, byte **stream, int player)
|
|||
case DEM_CHANGEMAP:
|
||||
// Change to another map without disconnecting other players
|
||||
s = ReadString (stream);
|
||||
strncpy (level.mapname, s, 8);
|
||||
strncpy (level.nextmap, s, 8);
|
||||
// Using LEVEL_NOINTERMISSION tends to throw the game out of sync.
|
||||
level.flags |= LEVEL_CHANGEMAPCHEAT;
|
||||
|
|
|
@ -32,7 +32,7 @@ void ReplaceString (char **ptr, char *str);
|
|||
|
||||
|
||||
// Misc. other strings.
|
||||
#define SAVEGAMENAME "doomsav"
|
||||
#define SAVEGAMENAME "zdoomsv"
|
||||
|
||||
// QuitDOOM messages
|
||||
#define NUM_QUITMESSAGES 14
|
||||
|
|
|
@ -133,7 +133,7 @@ void F_Ticker (void)
|
|||
|
||||
// check for skipping
|
||||
// [RH] Non-commercial can be skipped now, too
|
||||
if (finalecount > 50) {
|
||||
if (finalecount > 50 && finalestage != 1) {
|
||||
// go on to the next level
|
||||
// [RH] or just reveal the entire message if we're still ticking it
|
||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
||||
|
@ -191,7 +191,11 @@ void F_TextWrite (void)
|
|||
int cy;
|
||||
|
||||
// erase the entire screen to a tiled background
|
||||
V_FlatFill (0,0,screens[0].width,screens[0].height,&screens[0],W_CacheLumpName (finaleflat , PU_CACHE));
|
||||
{
|
||||
int lump = R_FlatNumForName (finaleflat) + firstflat;
|
||||
V_FlatFill (0,0,screens[0].width,screens[0].height,&screens[0],
|
||||
W_CacheLumpNum (lump, PU_CACHE));
|
||||
}
|
||||
V_MarkRect (0, 0, screens[0].width, screens[0].height);
|
||||
|
||||
// draw some of the text onto the screen
|
||||
|
|
|
@ -1047,7 +1047,7 @@ void G_DoLoadGame (void)
|
|||
|
||||
// skip the description field
|
||||
memset (vcheck,0,sizeof(vcheck));
|
||||
sprintf (vcheck,"version %i",VERSION);
|
||||
sprintf (vcheck,"version %ia",VERSION);
|
||||
if (strcmp (save_p, vcheck))
|
||||
return; // bad version
|
||||
save_p += VERSIONSIZE;
|
||||
|
@ -1116,7 +1116,7 @@ void G_DoSaveGame (void)
|
|||
memcpy (save_p, description, SAVESTRINGSIZE);
|
||||
save_p += SAVESTRINGSIZE;
|
||||
memset (name2,0,sizeof(name2));
|
||||
sprintf (name2,"version %i",VERSION);
|
||||
sprintf (name2,"version %ia",VERSION);
|
||||
memcpy (save_p, name2, VERSIONSIZE);
|
||||
save_p += VERSIONSIZE;
|
||||
|
||||
|
@ -1583,8 +1583,17 @@ void G_TimeDemo (char* name)
|
|||
===================
|
||||
*/
|
||||
|
||||
extern cvar_t *name;
|
||||
extern cvar_t *autoaim;
|
||||
extern cvar_t *color;
|
||||
|
||||
BOOL G_CheckDemoStatus (void)
|
||||
{
|
||||
// [RH] Restore the player's userinfo settings.
|
||||
D_UserInfoChanged (name);
|
||||
D_UserInfoChanged (autoaim);
|
||||
D_UserInfoChanged (color);
|
||||
|
||||
if (timingdemo)
|
||||
{
|
||||
extern int starttime;
|
||||
|
|
|
@ -88,6 +88,14 @@ void G_ParseMapInfo (void)
|
|||
mapinfo = W_CacheLumpNum (lump, PU_CACHE);
|
||||
|
||||
while ( (data = COM_Parse (mapinfo)) ) {
|
||||
if (com_token[0] == ';') {
|
||||
// Handle comments from Hexen MAPINFO lumps
|
||||
while (*mapinfo && *mapinfo != ';')
|
||||
mapinfo++;
|
||||
while (*mapinfo && *mapinfo != '\n')
|
||||
mapinfo++;
|
||||
continue;
|
||||
}
|
||||
if (!stricmp (com_token, "map")) {
|
||||
// map <MAPNAME> <Nice Name>
|
||||
if (levelindex > -1) {
|
||||
|
@ -97,6 +105,12 @@ void G_ParseMapInfo (void)
|
|||
levelflags = 0;
|
||||
clusterindex = -1;
|
||||
data = COM_Parse (data);
|
||||
if (IsNum (com_token)) {
|
||||
// Handle Hexen MAPINFO map commands
|
||||
int map = atoi (com_token);
|
||||
sprintf (com_token, "MAP%02u", map);
|
||||
SKYFLATNAME[5] = 0;
|
||||
}
|
||||
if ((levelindex = FindWadLevelInfo (com_token)) == -1)
|
||||
{
|
||||
levelindex = numwadlevelinfos++;
|
||||
|
@ -110,7 +124,8 @@ void G_ParseMapInfo (void)
|
|||
|
||||
mapinfo = data;
|
||||
} else if (levelindex > -1) {
|
||||
if (!stricmp (com_token, "levelnum")) {
|
||||
if (!stricmp (com_token, "levelnum") ||
|
||||
!stricmp (com_token, "warptrans")) {
|
||||
// levelnum <levelnum>
|
||||
mapinfo = COM_Parse (data);
|
||||
levelinfo->levelnum = atoi (com_token);
|
||||
|
@ -118,6 +133,11 @@ void G_ParseMapInfo (void)
|
|||
} else if (!stricmp (com_token, "next")) {
|
||||
// next <MAPNAME>
|
||||
mapinfo = COM_Parse (data);
|
||||
if (IsNum (com_token)) {
|
||||
// Handle Hexen MAPINFO next entries
|
||||
int map = atoi (com_token);
|
||||
sprintf (com_token, "MAP%02u", map);
|
||||
}
|
||||
strncpy (levelinfo->nextmap, com_token, 8);
|
||||
|
||||
} else if (!stricmp (com_token, "secretnext")) {
|
||||
|
@ -226,6 +246,20 @@ void G_ParseMapInfo (void)
|
|||
mapinfo = data;
|
||||
levelflags = (levelflags & (~LEVEL_SPECACTIONSMASK)) | LEVEL_SPECLOWERFLOOR;
|
||||
|
||||
} else if (!stricmp (com_token, "lightning")) {
|
||||
// lightning
|
||||
mapinfo = data;
|
||||
|
||||
} 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")) {
|
||||
mapinfo = COM_Parse (data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,7 +394,7 @@ void G_InitNew (char *mapname)
|
|||
I_Error ("Could not start map %s\n", mapname);
|
||||
}
|
||||
|
||||
if (gameskill->value == sk_nightmare || dmflags & DF_MONSTERS_RESPAWN )
|
||||
if ((gameskill->value == sk_nightmare) || (dmflags & DF_MONSTERS_RESPAWN) )
|
||||
respawnmonsters = true;
|
||||
else
|
||||
respawnmonsters = false;
|
||||
|
@ -450,7 +484,9 @@ void G_DoCompleted (void)
|
|||
strncpy (wminfo.lname0, level.info->pname, 8);
|
||||
strncpy (wminfo.current, level.mapname, 8);
|
||||
|
||||
if (deathmatch->value && dmflags & DF_SAME_LEVEL) {
|
||||
if (deathmatch->value &&
|
||||
(dmflags & DF_SAME_LEVEL) &&
|
||||
!(level.flags & LEVEL_CHANGEMAPCHEAT)) {
|
||||
strncpy (wminfo.next, level.mapname, 8);
|
||||
strncpy (wminfo.lname1, level.info->pname, 8);
|
||||
} else {
|
||||
|
@ -546,6 +582,17 @@ void G_DoLoadLevel (void)
|
|||
players[i].fragcount = 0;
|
||||
}
|
||||
|
||||
// initialize the msecnode_t freelist. phares 3/25/98
|
||||
// any nodes in the freelist are gone by now, cleared
|
||||
// by Z_FreeTags() when the previous level ended or player
|
||||
// died.
|
||||
|
||||
{
|
||||
extern msecnode_t *headsecnode; // phares 3/25/98
|
||||
headsecnode = NULL;
|
||||
}
|
||||
|
||||
|
||||
S_ClearAmbients (); // [RH] Clear all ambient sounds
|
||||
P_SetupLevel (level.mapname);
|
||||
displayplayer = consoleplayer; // view the guy you are playing
|
||||
|
@ -715,6 +762,26 @@ level_info_t *FindLevelInfo (char *mapname)
|
|||
return FindDefLevelInfo (mapname);
|
||||
}
|
||||
|
||||
level_info_t *FindLevelByNum (int num)
|
||||
{
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < numwadlevelinfos; i++)
|
||||
if (wadlevelinfos[i].levelnum == num)
|
||||
return (level_info_t *)(wadlevelinfos + i);
|
||||
}
|
||||
{
|
||||
level_info_t *i = LevelInfos;
|
||||
while (i->level_name) {
|
||||
if (i->levelnum == num)
|
||||
return i;
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static cluster_info_t *FindDefClusterInfo (int cluster)
|
||||
{
|
||||
cluster_info_t *i;
|
||||
|
|
|
@ -126,6 +126,7 @@ void G_SetLevelStrings (void);
|
|||
|
||||
cluster_info_t *FindClusterInfo (int cluster);
|
||||
level_info_t *FindLevelInfo (char *mapname);
|
||||
level_info_t *FindLevelByNum (int num);
|
||||
|
||||
char *CalcMapName (int episode, int level);
|
||||
|
||||
|
|
|
@ -83,59 +83,29 @@ extern BOOL automapactive;
|
|||
|
||||
static BOOL headsupactive = false;
|
||||
|
||||
const char english_shiftxform[] =
|
||||
{
|
||||
|
||||
0,
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
||||
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
|
||||
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
|
||||
31,
|
||||
' ', '!', '"', '#', '$', '%', '&',
|
||||
'"', // shift-'
|
||||
'(', ')', '*', '+',
|
||||
'<', // shift-,
|
||||
'_', // shift--
|
||||
'>', // shift-.
|
||||
'?', // shift-/
|
||||
')', // shift-0
|
||||
'!', // shift-1
|
||||
'@', // shift-2
|
||||
'#', // shift-3
|
||||
'$', // shift-4
|
||||
'%', // shift-5
|
||||
'^', // shift-6
|
||||
'&', // shift-7
|
||||
'*', // shift-8
|
||||
'(', // shift-9
|
||||
':',
|
||||
':', // shift-;
|
||||
'<',
|
||||
'+', // shift-=
|
||||
'>', '?', '@',
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
|
||||
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'[', // shift-[
|
||||
'!', // shift-backslash - OH MY GOD DOES WATCOM SUCK
|
||||
']', // shift-]
|
||||
'"', '_',
|
||||
'\'', // shift-`
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
|
||||
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'{', '|', '}', '~', 127
|
||||
};
|
||||
|
||||
void HU_Init(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
char buffer[9];
|
||||
char *tplate;
|
||||
int sub;
|
||||
|
||||
// load the heads-up font
|
||||
j = HU_FONTSTART;
|
||||
|
||||
// [RH] Quick hack to handle the FONTA of Heretic and Hexen
|
||||
if (W_CheckNumForName ("FONTA01") >= 0) {
|
||||
tplate = "FONTA%02u";
|
||||
sub = HU_FONTSTART - 1;
|
||||
} else {
|
||||
tplate = "STCFN%.3d";
|
||||
sub = 0;
|
||||
}
|
||||
|
||||
for (i=0;i<HU_FONTSIZE;i++)
|
||||
{
|
||||
sprintf(buffer, "STCFN%.3d", j++);
|
||||
sprintf(buffer, tplate, j++ - sub);
|
||||
hu_font[i] = (patch_t *) W_CacheLumpName(buffer, PU_STATIC);
|
||||
}
|
||||
}
|
||||
|
@ -306,8 +276,7 @@ BOOL HU_Responder (event_t *ev)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (shiftdown || (c >= 'a' && c <= 'z'))
|
||||
c = english_shiftxform[c];
|
||||
c = toupper (c);
|
||||
|
||||
eatkey = HUlib_keyInIText(&w_chat, c);
|
||||
|
||||
|
|
|
@ -74,7 +74,9 @@ LPDIRECTINPUTDEVICE g_pKey;
|
|||
LPDIRECTINPUTDEVICE g_pMouse;
|
||||
|
||||
//Other globals
|
||||
int MouseCurX,MouseCurY,GDx,GDy;
|
||||
int GDx,GDy;
|
||||
|
||||
extern int ConsoleState;
|
||||
|
||||
cvar_t *i_remapkeypad;
|
||||
cvar_t *usejoystick;
|
||||
|
@ -103,9 +105,15 @@ static const byte Convert []={
|
|||
};
|
||||
|
||||
// Convert DIK_* code to ASCII using user keymap (built at run-time)
|
||||
static byte Convert2[256];
|
||||
// New on 19.7.1998 - Now has 8 tables for each possible combination
|
||||
// of CTRL, ALT, and SHIFT.
|
||||
static byte Convert2[256][8];
|
||||
|
||||
static BOOL altdown = FALSE;
|
||||
#define SHIFT_SHIFT 0
|
||||
#define CTRL_SHIFT 1
|
||||
#define ALT_SHIFT 2
|
||||
|
||||
static BOOL altdown, shiftdown, ctrldown;
|
||||
|
||||
LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
@ -143,6 +151,18 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
event.data1 = DIK_LALT;
|
||||
D_PostEvent (&event);
|
||||
}
|
||||
if (shiftdown) {
|
||||
shiftdown = FALSE;
|
||||
event.type = ev_keyup;
|
||||
event.data1 = DIK_LSHIFT;
|
||||
D_PostEvent (&event);
|
||||
}
|
||||
if (ctrldown) {
|
||||
ctrldown = FALSE;
|
||||
event.type = ev_keyup;
|
||||
event.data1 = DIK_LCONTROL;
|
||||
D_PostEvent (&event);
|
||||
}
|
||||
havefocus = FALSE;
|
||||
if (!paused)
|
||||
S_PauseSound ();
|
||||
|
@ -194,15 +214,21 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
break;
|
||||
case VK_TAB:
|
||||
event.data1 = DIK_TAB;
|
||||
event.data2 = '\t';
|
||||
event.data3 = Convert2[DIK_TAB][(shiftdown << SHIFT_SHIFT) |
|
||||
(ctrldown << CTRL_SHIFT) |
|
||||
(altdown << ALT_SHIFT)];
|
||||
break;
|
||||
case VK_NUMLOCK:
|
||||
event.data1 = DIK_NUMLOCK;
|
||||
break;
|
||||
case VK_SHIFT:
|
||||
event.data1 = KEY_LSHIFT;
|
||||
shiftdown = (event.type == ev_keydown);
|
||||
break;
|
||||
case VK_CONTROL:
|
||||
event.data1 = KEY_LCTRL;
|
||||
ctrldown = (event.type == ev_keydown);
|
||||
break;
|
||||
}
|
||||
if (event.data1)
|
||||
|
@ -221,6 +247,7 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
{
|
||||
WPARAM cmdType = wParam & 0xfff0;
|
||||
|
||||
// Prevent activation of the window menu with Alt-Space
|
||||
if (cmdType != SC_KEYMENU)
|
||||
return DefWindowProc (hWnd, message, wParam, lParam);
|
||||
}
|
||||
|
@ -249,10 +276,19 @@ LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
static void BuildCvt2Table (void)
|
||||
{
|
||||
byte vk2scan[256];
|
||||
int i;
|
||||
|
||||
memset (vk2scan, 0, 256);
|
||||
for (i = 0; i < 256; i++)
|
||||
Convert2[i] = tolower ((byte)MapVirtualKey (MapVirtualKey (i, 1), 2));
|
||||
vk2scan[MapVirtualKey (i, 1)] = i;
|
||||
|
||||
vk2scan[0] = 0;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
int code = VkKeyScan ((TCHAR)i);
|
||||
Convert2[vk2scan[code & 0xff]][(code >> 8) & 7] = i;
|
||||
}
|
||||
}
|
||||
|
||||
/****** Stuff from Andy Bay's myjoy.c ******/
|
||||
|
@ -804,7 +840,6 @@ static void KeyRead (void) {
|
|||
event.type = ev_keyup;
|
||||
}
|
||||
|
||||
event.data3 = Convert2[key];
|
||||
switch (key) {
|
||||
case DIK_NUMPADENTER: // These keys always translated
|
||||
key = DIK_RETURN;
|
||||
|
@ -821,7 +856,9 @@ static void KeyRead (void) {
|
|||
key = 0;
|
||||
break;
|
||||
default:
|
||||
if (i_remapkeypad->value) {
|
||||
// Don't remap the keypad if the console is accepting input.
|
||||
if (i_remapkeypad->value &&
|
||||
ConsoleState != 1 && ConsoleState != 2) {
|
||||
switch (key) {
|
||||
case DIK_NUMPAD4:
|
||||
key = DIK_LEFT;
|
||||
|
@ -860,7 +897,9 @@ static void KeyRead (void) {
|
|||
if (key) {
|
||||
event.data1 = key;
|
||||
event.data2 = Convert[key];
|
||||
event.data3 = Convert2[key];
|
||||
event.data3 = Convert2[key][(altdown << ALT_SHIFT) |
|
||||
(shiftdown << SHIFT_SHIFT) |
|
||||
(ctrldown << CTRL_SHIFT)];
|
||||
D_PostEvent (&event);
|
||||
if (key == DIK_LALT)
|
||||
altdown = (event.type == ev_keydown);
|
||||
|
|
28
code/Info.c
28
code/Info.c
|
@ -1212,7 +1212,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
|
|||
sfx_vildth, // deathsound
|
||||
15, // speed
|
||||
20*FRACUNIT, // radius
|
||||
76*FRACUNIT, // height
|
||||
56*FRACUNIT, // height
|
||||
500, // mass
|
||||
0, // damage
|
||||
sfx_vilact, // activesound
|
||||
|
@ -1264,7 +1264,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
|
|||
sfx_skedth, // deathsound
|
||||
10, // speed
|
||||
20*FRACUNIT, // radius
|
||||
80*FRACUNIT, // height
|
||||
56*FRACUNIT, // height
|
||||
500, // mass
|
||||
0, // damage
|
||||
sfx_skeact, // activesound
|
||||
|
@ -1394,7 +1394,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
|
|||
sfx_podth2, // deathsound
|
||||
8, // speed
|
||||
20*FRACUNIT, // radius
|
||||
60*FRACUNIT, // height
|
||||
56*FRACUNIT, // height
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_posact, // activesound
|
||||
|
@ -1524,7 +1524,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
|
|||
sfx_brsdth, // deathsound
|
||||
8, // speed
|
||||
24*FRACUNIT, // radius
|
||||
74*FRACUNIT, // height
|
||||
64*FRACUNIT, // height
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_dmact, // activesound
|
||||
|
@ -1576,7 +1576,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
|
|||
sfx_kntdth, // deathsound
|
||||
8, // speed
|
||||
24*FRACUNIT, // radius
|
||||
74*FRACUNIT, // height
|
||||
64*FRACUNIT, // height
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_dmact, // activesound
|
||||
|
@ -1628,7 +1628,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
|
|||
sfx_spidth, // deathsound
|
||||
12, // speed
|
||||
128*FRACUNIT, // radius
|
||||
110*FRACUNIT, // height
|
||||
100*FRACUNIT, // height
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_dmact, // activesound
|
||||
|
@ -1654,7 +1654,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
|
|||
sfx_bspdth, // deathsound
|
||||
12, // speed
|
||||
64*FRACUNIT, // radius
|
||||
56*FRACUNIT, // height
|
||||
64*FRACUNIT, // height
|
||||
600, // mass
|
||||
0, // damage
|
||||
sfx_bspact, // activesound
|
||||
|
@ -4698,7 +4698,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
|
|||
sfx_bspdth, // deathsound
|
||||
12, // speed
|
||||
64*FRACUNIT, // radius
|
||||
56*FRACUNIT, // height
|
||||
64*FRACUNIT, // height
|
||||
600, // mass
|
||||
0, // damage
|
||||
sfx_bspact, // activesound
|
||||
|
@ -4724,7 +4724,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
|
|||
sfx_vildth, // deathsound
|
||||
15, // speed
|
||||
20*FRACUNIT, // radius
|
||||
76*FRACUNIT, // height
|
||||
56*FRACUNIT, // height
|
||||
500, // mass
|
||||
0, // damage
|
||||
sfx_vilact, // activesound
|
||||
|
@ -4750,7 +4750,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
|
|||
sfx_brsdth, // deathsound
|
||||
8, // speed
|
||||
24*FRACUNIT, // radius
|
||||
74*FRACUNIT, // height
|
||||
64*FRACUNIT, // height
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_dmact, // activesound
|
||||
|
@ -4802,7 +4802,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
|
|||
sfx_podth2, // deathsound
|
||||
8, // speed
|
||||
20*FRACUNIT, // radius
|
||||
60*FRACUNIT, // height
|
||||
56*FRACUNIT, // height
|
||||
100, // mass
|
||||
0, // damage
|
||||
sfx_posact, // activesound
|
||||
|
@ -4854,7 +4854,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
|
|||
sfx_kntdth, // deathsound
|
||||
8, // speed
|
||||
24*FRACUNIT, // radius
|
||||
74*FRACUNIT, // height
|
||||
64*FRACUNIT, // height
|
||||
1000, // mass
|
||||
0, // damage
|
||||
sfx_dmact, // activesound
|
||||
|
@ -4932,7 +4932,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
|
|||
sfx_skedth, // deathsound
|
||||
10, // speed
|
||||
20*FRACUNIT, // radius
|
||||
80*FRACUNIT, // height
|
||||
56*FRACUNIT, // height
|
||||
500, // mass
|
||||
0, // damage
|
||||
sfx_skeact, // activesound
|
||||
|
@ -5222,7 +5222,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = {
|
|||
100, // mass
|
||||
0, // damage
|
||||
sfx_None, // activesound
|
||||
0, // flags
|
||||
MF_NOGRAVITY, // flags
|
||||
S_NULL // raisestate
|
||||
},
|
||||
|
||||
|
|
|
@ -219,10 +219,7 @@ static void M_SlidePlayerRed (int choice);
|
|||
static void M_SlidePlayerGreen (int choice);
|
||||
static void M_SlidePlayerBlue (int choice);
|
||||
static void M_ChangeAutoAim (int choice);
|
||||
|
||||
|
||||
// [RH] Used to make left and right arrows repeat.
|
||||
static int Lefting = -1, Righting = -1;
|
||||
BOOL M_DemoNoPlay;
|
||||
|
||||
|
||||
//
|
||||
|
@ -1121,6 +1118,9 @@ static void M_PlayerSetup (int choice)
|
|||
choice = 0;
|
||||
strncpy (savegamestrings[0], name->string, 23);
|
||||
savegamestrings[0][23] = 0;
|
||||
M_DemoNoPlay = true;
|
||||
if (demoplayback)
|
||||
G_CheckDemoStatus ();
|
||||
M_SetupNextMenu (&PSetupDef);
|
||||
PlayerState = &states[mobjinfo[MT_PLAYER].seestate];
|
||||
PlayerTics = PlayerState->tics;
|
||||
|
@ -1398,20 +1398,7 @@ BOOL M_Responder (event_t* ev)
|
|||
ch2 = ev->data2; // ASCII
|
||||
}
|
||||
|
||||
// [RH] Repeat left and right arrow keys
|
||||
if (ev->type == ev_keydown) {
|
||||
if (ev->data1 == KEY_LEFTARROW)
|
||||
Lefting = KeyRepeatDelay >> 1;
|
||||
else if (ev->data1 == KEY_RIGHTARROW)
|
||||
Righting = KeyRepeatDelay >> 1;
|
||||
} else if (ev->type == ev_keyup) {
|
||||
if (ev->data1 == KEY_LEFTARROW)
|
||||
Lefting = -1;
|
||||
else if (ev->data1 == KEY_RIGHTARROW)
|
||||
Righting = -1;
|
||||
}
|
||||
|
||||
if (ch == -1 && !menuactive && Lefting == -1 && Righting == -1)
|
||||
if (ch == -1 && !menuactive)
|
||||
return false;
|
||||
|
||||
if (menuactive && OptionsActive) {
|
||||
|
@ -1569,8 +1556,13 @@ BOOL M_Responder (event_t* ev)
|
|||
currentMenu->lastOn = itemOn;
|
||||
if (currentMenu->prevMenu)
|
||||
{
|
||||
M_DemoNoPlay = false;
|
||||
currentMenu = currentMenu->prevMenu;
|
||||
itemOn = currentMenu->lastOn;
|
||||
// [RH] Make sure the skull is always visible on the
|
||||
// main menu (for backing out of Read This!.
|
||||
if (currentMenu == &MainDef)
|
||||
drawSkull = true;
|
||||
S_StartSound(ORIGIN_AMBIENT,sfx_swtchn);
|
||||
} else {
|
||||
M_ClearMenus ();
|
||||
|
@ -1713,6 +1705,7 @@ void M_ClearMenus (void)
|
|||
menuactive = 0;
|
||||
drawSkull = true;
|
||||
I_ResumeMouse (); // [RH] Recapture the mouse in windowed modes.
|
||||
M_DemoNoPlay = false;
|
||||
// if (!netgame && usergame && paused)
|
||||
// sendpause = true;
|
||||
}
|
||||
|
@ -1743,23 +1736,6 @@ void M_Ticker (void)
|
|||
}
|
||||
if (currentMenu == &PSetupDef)
|
||||
M_PlayerSetupTicker ();
|
||||
|
||||
// [RH] Make left and right arrow keys repeat
|
||||
if (Lefting != -1 && --Lefting == 0) {
|
||||
event_t ev;
|
||||
|
||||
ev.type = ev_keydown;
|
||||
ev.data1 = KEY_LEFTARROW;
|
||||
Lefting = 2;
|
||||
M_Responder (&ev);
|
||||
} else if (Righting != -1 && --Righting == 0) {
|
||||
event_t ev;
|
||||
|
||||
ev.type = ev_keydown;
|
||||
ev.data1 = KEY_RIGHTARROW;
|
||||
Righting = 2;
|
||||
M_Responder (&ev);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -127,15 +127,14 @@ void T_VerticalDoor (vldoor_t* door)
|
|||
{
|
||||
case blazeRaise:
|
||||
case blazeClose:
|
||||
door->sector->specialdata = NULL;
|
||||
door->sector->ceilingdata = NULL; //jff 2/22/98
|
||||
P_RemoveThinker (&door->thinker); // unlink and free
|
||||
S_StartSound((mobj_t *)&door->sector->soundorg,
|
||||
sfx_bdcls);
|
||||
S_StartSound((mobj_t *)&door->sector->soundorg, sfx_bdcls);
|
||||
break;
|
||||
|
||||
case normal:
|
||||
case close:
|
||||
door->sector->specialdata = NULL;
|
||||
door->sector->ceilingdata = NULL; //jff 2/22/98
|
||||
P_RemoveThinker (&door->thinker); // unlink and free
|
||||
break;
|
||||
|
||||
|
@ -185,7 +184,7 @@ void T_VerticalDoor (vldoor_t* door)
|
|||
case close30ThenOpen:
|
||||
case blazeOpen:
|
||||
case open:
|
||||
door->sector->specialdata = NULL;
|
||||
door->sector->ceilingdata = NULL; //jff 2/22/98
|
||||
P_RemoveThinker (&door->thinker); // unlink and free
|
||||
break;
|
||||
|
||||
|
@ -254,10 +253,7 @@ EV_DoLockedDoor
|
|||
}
|
||||
|
||||
|
||||
int
|
||||
EV_DoDoor
|
||||
( line_t* line,
|
||||
vldoor_e type )
|
||||
int EV_DoDoor (line_t *line, vldoor_e type)
|
||||
{
|
||||
int secnum,rtn;
|
||||
sector_t* sec;
|
||||
|
@ -269,15 +265,15 @@ EV_DoDoor
|
|||
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
if (sec->specialdata)
|
||||
// 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->specialdata = door;
|
||||
sec->ceilingdata = door; //jff 2/22/98
|
||||
|
||||
door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
|
@ -344,10 +340,7 @@ EV_DoDoor
|
|||
//
|
||||
// EV_VerticalDoor : open a door manually, no tag value
|
||||
//
|
||||
void
|
||||
EV_VerticalDoor
|
||||
( line_t* line,
|
||||
mobj_t* thing )
|
||||
void EV_VerticalDoor (line_t *line, mobj_t *thing)
|
||||
{
|
||||
player_t* player;
|
||||
int secnum;
|
||||
|
@ -403,13 +396,21 @@ EV_VerticalDoor
|
|||
break;
|
||||
}
|
||||
|
||||
// if the sector has an active thinker, use it
|
||||
sec = sides[ line->sidenum[side^1]] .sector;
|
||||
// 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 (sec->specialdata)
|
||||
// if door already has a thinker, use it
|
||||
if (sec->ceilingdata) //jff 2/22/98
|
||||
{
|
||||
door = sec->specialdata;
|
||||
door = sec->ceilingdata; //jff 2/22/98
|
||||
switch(line->special)
|
||||
{
|
||||
case 1: // ONLY FOR "RAISE" DOORS, NOT "OPEN"s
|
||||
|
@ -452,7 +453,7 @@ EV_VerticalDoor
|
|||
// new door thinker
|
||||
door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
|
||||
P_AddThinker (&door->thinker);
|
||||
sec->specialdata = door;
|
||||
sec->ceilingdata = door; //jff 2/22/98
|
||||
door->thinker.function.acp1 = (actionf_p1) T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
door->direction = 1;
|
||||
|
@ -504,7 +505,7 @@ void P_SpawnDoorCloseIn30 (sector_t* sec)
|
|||
|
||||
P_AddThinker (&door->thinker);
|
||||
|
||||
sec->specialdata = door;
|
||||
sec->ceilingdata = door; //jff 2/22/98
|
||||
sec->special = 0;
|
||||
|
||||
door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
|
||||
|
@ -526,7 +527,7 @@ void P_SpawnDoorRaiseIn5Mins (sector_t *sec, int secnum)
|
|||
|
||||
P_AddThinker (&door->thinker);
|
||||
|
||||
sec->specialdata = door;
|
||||
sec->ceilingdata = door; //jff 2/22/98
|
||||
sec->special = 0;
|
||||
|
||||
door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
|
||||
|
@ -554,7 +555,7 @@ void P_SpawnDoorRaiseIn5Mins (sector_t *sec, int secnum)
|
|||
|
||||
slideframe_t slideFrames[MAXSLIDEDOORS];
|
||||
|
||||
void P_InitSlidingDoorFrames(void)
|
||||
void P_InitSlidingDoorFrames (void)
|
||||
{
|
||||
int i;
|
||||
int f1;
|
||||
|
@ -598,7 +599,7 @@ void P_InitSlidingDoorFrames(void)
|
|||
// Return index into "slideFrames" array
|
||||
// for which door type to use
|
||||
//
|
||||
int P_FindSlidingDoorType(line_t* line)
|
||||
int P_FindSlidingDoorType (line_t *line)
|
||||
{
|
||||
int i;
|
||||
int val;
|
||||
|
@ -613,7 +614,7 @@ int P_FindSlidingDoorType(line_t* line)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void T_SlidingDoor (slidedoor_t* door)
|
||||
void T_SlidingDoor (slidedoor_t *door)
|
||||
{
|
||||
switch(door->status)
|
||||
{
|
||||
|
@ -700,10 +701,7 @@ void T_SlidingDoor (slidedoor_t* door)
|
|||
|
||||
|
||||
|
||||
void
|
||||
EV_SlidingDoor
|
||||
( line_t* line,
|
||||
mobj_t* thing )
|
||||
void EV_SlidingDoor (line_t *line, mobj_t *thing)
|
||||
{
|
||||
sector_t* sec;
|
||||
slidedoor_t* door;
|
||||
|
|
|
@ -1937,6 +1937,10 @@ void A_BrainSpit (mobj_t *mo)
|
|||
|
||||
static int easy = 0;
|
||||
|
||||
// [RH] Do nothing if there are no brain targets.
|
||||
if (numbraintargets == 0)
|
||||
return;
|
||||
|
||||
easy ^= 1;
|
||||
if (gameskill->value <= sk_easy && (!easy))
|
||||
return;
|
||||
|
@ -2015,7 +2019,7 @@ void A_SpawnFly (mobj_t* mo)
|
|||
P_SetMobjState (newmobj, newmobj->info->seestate);
|
||||
|
||||
// telefrag anything in this spot
|
||||
P_TeleportMove (newmobj, newmobj->x, newmobj->y);
|
||||
P_TeleportMove (newmobj, newmobj->x, newmobj->y, newmobj->z, true);
|
||||
|
||||
// remove self (i.e., cube).
|
||||
P_RemoveMobj (mo);
|
||||
|
|
213
code/P_floor.c
213
code/P_floor.c
|
@ -67,11 +67,11 @@ T_MovePlane
|
|||
{
|
||||
lastpos = sector->floorheight;
|
||||
sector->floorheight = dest;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
flag = P_CheckSector(sector,crush);
|
||||
if (flag == true)
|
||||
{
|
||||
sector->floorheight =lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
P_CheckSector(sector,crush);
|
||||
//return crushed;
|
||||
}
|
||||
return pastdest;
|
||||
|
@ -80,11 +80,11 @@ T_MovePlane
|
|||
{
|
||||
lastpos = sector->floorheight;
|
||||
sector->floorheight -= speed;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
flag = P_CheckSector(sector,crush);
|
||||
if (flag == true)
|
||||
{
|
||||
sector->floorheight = lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
P_CheckSector(sector,crush);
|
||||
return crushed;
|
||||
}
|
||||
}
|
||||
|
@ -96,11 +96,11 @@ T_MovePlane
|
|||
{
|
||||
lastpos = sector->floorheight;
|
||||
sector->floorheight = dest;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
flag = P_CheckSector(sector,crush);
|
||||
if (flag == true)
|
||||
{
|
||||
sector->floorheight = lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
P_CheckSector(sector,crush);
|
||||
//return crushed;
|
||||
}
|
||||
return pastdest;
|
||||
|
@ -110,13 +110,13 @@ T_MovePlane
|
|||
// COULD GET CRUSHED
|
||||
lastpos = sector->floorheight;
|
||||
sector->floorheight += speed;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
flag = P_CheckSector(sector,crush);
|
||||
if (flag == true)
|
||||
{
|
||||
if (crush == true)
|
||||
return crushed;
|
||||
sector->floorheight = lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
P_CheckSector(sector,crush);
|
||||
return crushed;
|
||||
}
|
||||
}
|
||||
|
@ -134,12 +134,12 @@ T_MovePlane
|
|||
{
|
||||
lastpos = sector->ceilingheight;
|
||||
sector->ceilingheight = dest;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
flag = P_CheckSector(sector,crush);
|
||||
|
||||
if (flag == true)
|
||||
{
|
||||
sector->ceilingheight = lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
P_CheckSector(sector,crush);
|
||||
//return crushed;
|
||||
}
|
||||
return pastdest;
|
||||
|
@ -149,14 +149,14 @@ T_MovePlane
|
|||
// COULD GET CRUSHED
|
||||
lastpos = sector->ceilingheight;
|
||||
sector->ceilingheight -= speed;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
flag = P_CheckSector(sector,crush);
|
||||
|
||||
if (flag == true)
|
||||
{
|
||||
if (crush == true)
|
||||
return crushed;
|
||||
sector->ceilingheight = lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
P_CheckSector(sector,crush);
|
||||
return crushed;
|
||||
}
|
||||
}
|
||||
|
@ -168,11 +168,11 @@ T_MovePlane
|
|||
{
|
||||
lastpos = sector->ceilingheight;
|
||||
sector->ceilingheight = dest;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
flag = P_CheckSector(sector,crush);
|
||||
if (flag == true)
|
||||
{
|
||||
sector->ceilingheight = lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
P_CheckSector(sector,crush);
|
||||
//return crushed;
|
||||
}
|
||||
return pastdest;
|
||||
|
@ -181,13 +181,13 @@ T_MovePlane
|
|||
{
|
||||
lastpos = sector->ceilingheight;
|
||||
sector->ceilingheight += speed;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
flag = P_CheckSector(sector,crush);
|
||||
// UNUSED
|
||||
#if 0
|
||||
if (flag == true)
|
||||
{
|
||||
sector->ceilingheight = lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
P_CheckSector(sector,crush);
|
||||
return crushed;
|
||||
}
|
||||
#endif
|
||||
|
@ -204,7 +204,7 @@ T_MovePlane
|
|||
//
|
||||
// MOVE A FLOOR TO IT'S DESTINATION (UP OR DOWN)
|
||||
//
|
||||
void T_MoveFloor(floormove_t* floor)
|
||||
void T_MoveFloor (floormove_t *floor)
|
||||
{
|
||||
result_e res;
|
||||
|
||||
|
@ -219,7 +219,7 @@ void T_MoveFloor(floormove_t* floor)
|
|||
|
||||
if (res == pastdest)
|
||||
{
|
||||
floor->sector->specialdata = NULL;
|
||||
floor->sector->floordata = NULL;
|
||||
|
||||
if (floor->direction == 1)
|
||||
{
|
||||
|
@ -251,13 +251,86 @@ void T_MoveFloor(floormove_t* floor)
|
|||
|
||||
}
|
||||
|
||||
//
|
||||
// T_MoveElevator()
|
||||
//
|
||||
// Move an elevator to it's destination (up or down)
|
||||
// Called once per tick for each moving floor.
|
||||
//
|
||||
// Passed an elevator_t structure that contains all pertinent info about the
|
||||
// move. See P_SPEC.H for fields.
|
||||
// No return.
|
||||
//
|
||||
// jff 02/22/98 added to support parallel floor/ceiling motion
|
||||
//
|
||||
void T_MoveElevator (elevator_t* elevator)
|
||||
{
|
||||
result_e res;
|
||||
|
||||
if (elevator->direction<0) // moving down
|
||||
{
|
||||
res = T_MovePlane //jff 4/7/98 reverse order of ceiling/floor
|
||||
(
|
||||
elevator->sector,
|
||||
elevator->speed,
|
||||
elevator->ceilingdestheight,
|
||||
0,
|
||||
1, // move floor
|
||||
elevator->direction
|
||||
);
|
||||
if (res==ok || res==pastdest) // jff 4/7/98 don't move ceil if blocked
|
||||
T_MovePlane
|
||||
(
|
||||
elevator->sector,
|
||||
elevator->speed,
|
||||
elevator->floordestheight,
|
||||
0,
|
||||
0, // move ceiling
|
||||
elevator->direction
|
||||
);
|
||||
}
|
||||
else // up
|
||||
{
|
||||
res = T_MovePlane //jff 4/7/98 reverse order of ceiling/floor
|
||||
(
|
||||
elevator->sector,
|
||||
elevator->speed,
|
||||
elevator->floordestheight,
|
||||
0,
|
||||
0, // move ceiling
|
||||
elevator->direction
|
||||
);
|
||||
if (res==ok || res==pastdest) // jff 4/7/98 don't move floor if blocked
|
||||
T_MovePlane
|
||||
(
|
||||
elevator->sector,
|
||||
elevator->speed,
|
||||
elevator->ceilingdestheight,
|
||||
0,
|
||||
1, // move floor
|
||||
elevator->direction
|
||||
);
|
||||
}
|
||||
|
||||
// make floor move sound
|
||||
if (!(level.time&7))
|
||||
S_StartSound((mobj_t *)&elevator->sector->soundorg, sfx_stnmov);
|
||||
|
||||
if (res == pastdest) // if destination height acheived
|
||||
{
|
||||
elevator->sector->floordata = NULL; //jff 2/22/98
|
||||
elevator->sector->ceilingdata = NULL; //jff 2/22/98
|
||||
P_RemoveThinker(&elevator->thinker); // remove elevator from actives
|
||||
|
||||
// make floor stop sound
|
||||
S_StartSound((mobj_t *)&elevator->sector->soundorg, sfx_pstop);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// HANDLE FLOOR TYPES
|
||||
//
|
||||
int
|
||||
EV_DoFloor
|
||||
( line_t* line,
|
||||
floor_e floortype )
|
||||
int EV_DoFloor (line_t *line, floor_e floortype)
|
||||
{
|
||||
int secnum;
|
||||
int rtn;
|
||||
|
@ -272,14 +345,14 @@ EV_DoFloor
|
|||
sec = §ors[secnum];
|
||||
|
||||
// ALREADY MOVING? IF SO, KEEP GOING...
|
||||
if (sec->specialdata)
|
||||
if (P_SectorActive (floor_special, sec)) //jff 2/33/98
|
||||
continue;
|
||||
|
||||
// new floor thinker
|
||||
rtn = 1;
|
||||
floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
|
||||
P_AddThinker (&floor->thinker);
|
||||
sec->specialdata = floor;
|
||||
sec->floordata = floor; //jff 2/22/98
|
||||
floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;
|
||||
floor->type = floortype;
|
||||
floor->crush = false;
|
||||
|
@ -442,10 +515,7 @@ EV_DoFloor
|
|||
//
|
||||
// BUILD A STAIRCASE!
|
||||
//
|
||||
int
|
||||
EV_BuildStairs
|
||||
( line_t* line,
|
||||
stair_e type )
|
||||
int EV_BuildStairs (line_t *line, stair_e type)
|
||||
{
|
||||
int secnum;
|
||||
int height;
|
||||
|
@ -470,14 +540,14 @@ EV_BuildStairs
|
|||
sec = §ors[secnum];
|
||||
|
||||
// ALREADY MOVING? IF SO, KEEP GOING...
|
||||
if (sec->specialdata)
|
||||
if (P_SectorActive (floor_special, sec)) //jff 2/22/98
|
||||
continue;
|
||||
|
||||
// new floor thinker
|
||||
rtn = 1;
|
||||
floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
|
||||
P_AddThinker (&floor->thinker);
|
||||
sec->specialdata = floor;
|
||||
sec->floordata = floor; //jff 2/22/98
|
||||
floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;
|
||||
floor->direction = 1;
|
||||
floor->sector = sec;
|
||||
|
@ -523,7 +593,8 @@ EV_BuildStairs
|
|||
|
||||
height += stairsize;
|
||||
|
||||
if (tsec->specialdata)
|
||||
// if sector's floor already moving, look for another
|
||||
if (P_SectorActive(floor_special,tsec)) //jff 2/22/98
|
||||
continue;
|
||||
|
||||
sec = tsec;
|
||||
|
@ -532,7 +603,7 @@ EV_BuildStairs
|
|||
|
||||
P_AddThinker (&floor->thinker);
|
||||
|
||||
sec->specialdata = floor;
|
||||
sec->floordata = floor;
|
||||
floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;
|
||||
floor->direction = 1;
|
||||
floor->sector = sec;
|
||||
|
@ -546,3 +617,81 @@ EV_BuildStairs
|
|||
return rtn;
|
||||
}
|
||||
|
||||
//
|
||||
// EV_DoElevator
|
||||
//
|
||||
// Handle elevator linedef types
|
||||
//
|
||||
// Passed the linedef that triggered the elevator and the elevator action
|
||||
//
|
||||
// jff 2/22/98 new type to move floor and ceiling in parallel
|
||||
//
|
||||
int EV_DoElevator (line_t *line, elevator_e elevtype)
|
||||
{
|
||||
int secnum;
|
||||
int rtn;
|
||||
sector_t* sec;
|
||||
elevator_t* elevator;
|
||||
|
||||
secnum = -1;
|
||||
rtn = 0;
|
||||
// act on all sectors with the same tag as the triggering linedef
|
||||
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
|
||||
// If either floor or ceiling is already activated, skip it
|
||||
if (sec->floordata || sec->ceilingdata) //jff 2/22/98
|
||||
continue;
|
||||
|
||||
// create and initialize new elevator thinker
|
||||
rtn = 1;
|
||||
elevator = Z_Malloc (sizeof(*elevator), PU_LEVSPEC, 0);
|
||||
P_AddThinker (&elevator->thinker);
|
||||
sec->floordata = elevator; //jff 2/22/98
|
||||
sec->ceilingdata = elevator; //jff 2/22/98
|
||||
elevator->thinker.function.acp1 = (actionf_p1) T_MoveElevator;
|
||||
elevator->type = elevtype;
|
||||
|
||||
// set up the fields according to the type of elevator action
|
||||
switch(elevtype)
|
||||
{
|
||||
// elevator down to next floor
|
||||
case elevateDown:
|
||||
elevator->direction = -1;
|
||||
elevator->sector = sec;
|
||||
elevator->speed = ELEVATORSPEED;
|
||||
elevator->floordestheight =
|
||||
P_FindNextLowestFloor(sec,sec->floorheight);
|
||||
elevator->ceilingdestheight =
|
||||
elevator->floordestheight + sec->ceilingheight - sec->floorheight;
|
||||
break;
|
||||
|
||||
// elevator up to next floor
|
||||
case elevateUp:
|
||||
elevator->direction = 1;
|
||||
elevator->sector = sec;
|
||||
elevator->speed = ELEVATORSPEED;
|
||||
elevator->floordestheight =
|
||||
P_FindNextHighestFloor(sec,sec->floorheight);
|
||||
elevator->ceilingdestheight =
|
||||
elevator->floordestheight + sec->ceilingheight - sec->floorheight;
|
||||
break;
|
||||
|
||||
// elevator to floor height of activating switch's front sector
|
||||
case elevateCurrent:
|
||||
elevator->sector = sec;
|
||||
elevator->speed = ELEVATORSPEED;
|
||||
elevator->floordestheight = line->frontsector->floorheight;
|
||||
elevator->ceilingdestheight =
|
||||
elevator->floordestheight + sec->ceilingheight - sec->floorheight;
|
||||
elevator->direction =
|
||||
elevator->floordestheight>sec->floorheight? 1 : -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
|
|
@ -211,13 +211,13 @@ void P_SetThingPosition (mobj_t* thing);
|
|||
extern BOOL floatok;
|
||||
extern fixed_t tmfloorz;
|
||||
extern fixed_t tmceilingz;
|
||||
|
||||
extern msecnode_t *sector_list; // phares 3/16/98
|
||||
|
||||
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_TeleportMove (mobj_t* thing, fixed_t x, fixed_t y);
|
||||
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);
|
||||
void P_UseLines (player_t* player);
|
||||
|
@ -233,6 +233,14 @@ void P_LineAttack (mobj_t *t1, angle_t angle, fixed_t distance, fixed_t slope, i
|
|||
// [RH] Means of death
|
||||
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);
|
||||
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
|
||||
BOOL Check_Sides(mobj_t *, int, int); // phares
|
||||
|
||||
|
||||
// [RH] Finds the mobj thing is standing on/in.
|
||||
// Returns NULL if nothing, -1 if the ground,
|
||||
// or a pointer to another mobj.
|
||||
|
|
337
code/P_map.c
337
code/P_map.c
|
@ -44,12 +44,14 @@
|
|||
// 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
|
||||
|
||||
|
||||
// If "floatok" true, move would be ok
|
||||
|
@ -72,6 +74,9 @@ int MaxSpecialCross = 0;
|
|||
line_t** spechit;
|
||||
int numspechit;
|
||||
|
||||
// Temporary holder for thing_sectorlist threads
|
||||
msecnode_t* sector_list = NULL; // phares 3/16/98
|
||||
|
||||
|
||||
|
||||
//
|
||||
|
@ -81,6 +86,8 @@ int numspechit;
|
|||
//
|
||||
// PIT_StompThing
|
||||
//
|
||||
static BOOL StompAlwaysFrags;
|
||||
|
||||
BOOL PIT_StompThing (mobj_t* thing)
|
||||
{
|
||||
fixed_t blockdist;
|
||||
|
@ -102,25 +109,32 @@ BOOL PIT_StompThing (mobj_t* thing)
|
|||
}
|
||||
|
||||
// [RH] Z-Check
|
||||
if (tmthing->z > thing->z + thing->height)
|
||||
if (!olddemo) {
|
||||
if (tmz > thing->z + thing->height)
|
||||
return true; // overhead
|
||||
if (tmthing->z+tmthing->height < thing->z)
|
||||
if (tmz+tmthing->height < thing->z)
|
||||
return true; // underneath
|
||||
}
|
||||
|
||||
// monsters don't stomp things except on boss level
|
||||
if ( !tmthing->player && !(level.flags & LEVEL_MONSTERSTELEFRAG) )
|
||||
return false;
|
||||
|
||||
if (StompAlwaysFrags) {
|
||||
P_DamageMobj (thing, tmthing, tmthing, 10000, MOD_TELEFRAG);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// P_TeleportMove
|
||||
//
|
||||
BOOL P_TeleportMove (mobj_t *thing, fixed_t x, fixed_t y)
|
||||
// [RH] Added telefrag parameter: When true, anything in the spawn spot
|
||||
// will always be telefragged, and the move will be successful.
|
||||
// Added z parameter. Originally, the thing's z was set *after* the
|
||||
// move was made, so the height checking I added for 1.13 could
|
||||
// potentially erroneously indicate the move was okay if the thing
|
||||
// was being teleported between two non-overlapping height ranges.
|
||||
BOOL P_TeleportMove (mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, BOOL telefrag)
|
||||
{
|
||||
int xl;
|
||||
int xh;
|
||||
|
@ -137,6 +151,7 @@ BOOL P_TeleportMove (mobj_t *thing, fixed_t x, fixed_t y)
|
|||
|
||||
tmx = x;
|
||||
tmy = y;
|
||||
tmz = z;
|
||||
|
||||
tmbbox[BOXTOP] = y + tmthing->radius;
|
||||
tmbbox[BOXBOTTOM] = y - tmthing->radius;
|
||||
|
@ -156,6 +171,9 @@ BOOL P_TeleportMove (mobj_t *thing, fixed_t x, fixed_t y)
|
|||
validcount++;
|
||||
numspechit = 0;
|
||||
|
||||
StompAlwaysFrags = tmthing->player || (level.flags & LEVEL_MONSTERSTELEFRAG) ||
|
||||
(!olddemo && telefrag);
|
||||
|
||||
// stomp on any things contacted
|
||||
xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
|
||||
xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
|
||||
|
@ -178,6 +196,8 @@ BOOL P_TeleportMove (mobj_t *thing, fixed_t x, fixed_t y)
|
|||
|
||||
P_SetThingPosition (thing);
|
||||
|
||||
thing->z = z;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1401,7 +1421,9 @@ BOOL PIT_RadiusAttack (mobj_t *thing)
|
|||
if (thing->type == MT_CYBORG || thing->type == MT_SPIDER)
|
||||
return true;
|
||||
|
||||
if (!olddemo) {
|
||||
// Barrels always use the original code, since this makes
|
||||
// them far too "active."
|
||||
if (!olddemo && bombspot->type != MT_BARREL && thing->type != MT_BARREL) {
|
||||
// [RH] New code (based on stuff in Q2)
|
||||
float points;
|
||||
vec3_t thingvec;
|
||||
|
@ -1410,8 +1432,11 @@ BOOL PIT_RadiusAttack (mobj_t *thing)
|
|||
thingvec[2] += (float)(thing->height >> (FRACBITS+1));
|
||||
{
|
||||
vec3_t v;
|
||||
float len;
|
||||
|
||||
VectorSubtract (bombvec, thingvec, v);
|
||||
points = bombdamagefloat - VectorLength (v);
|
||||
len = VectorLength (v);
|
||||
points = bombdamagefloat - len;
|
||||
}
|
||||
if (thing == bombsource)
|
||||
points = points * 0.5f;
|
||||
|
@ -1518,7 +1543,7 @@ BOOL nofit;
|
|||
//
|
||||
// PIT_ChangeSector
|
||||
//
|
||||
BOOL PIT_ChangeSector (mobj_t* thing)
|
||||
BOOL PIT_ChangeSector (mobj_t *thing)
|
||||
{
|
||||
mobj_t *mo;
|
||||
int t;
|
||||
|
@ -1584,10 +1609,7 @@ BOOL PIT_ChangeSector (mobj_t* thing)
|
|||
//
|
||||
// P_ChangeSector
|
||||
//
|
||||
BOOL
|
||||
P_ChangeSector
|
||||
( sector_t* sector,
|
||||
BOOL crunch )
|
||||
BOOL P_ChangeSector (sector_t *sector, BOOL crunch)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
|
@ -1600,7 +1622,294 @@ P_ChangeSector
|
|||
for (y=sector->blockbox[BOXBOTTOM];y<= sector->blockbox[BOXTOP] ; y++)
|
||||
P_BlockThingsIterator (x, y, PIT_ChangeSector);
|
||||
|
||||
return nofit;
|
||||
}
|
||||
|
||||
//
|
||||
// P_CheckSector
|
||||
// jff 3/19/98 added to just check monsters on the periphery
|
||||
// of a moving sector instead of all in bounding box of the
|
||||
// sector. Both more accurate and faster.
|
||||
//
|
||||
|
||||
BOOL P_CheckSector (sector_t *sector, BOOL crunch)
|
||||
{
|
||||
msecnode_t *n;
|
||||
|
||||
if (olddemo) // use the old routine for old demos though
|
||||
return P_ChangeSector(sector,crunch);
|
||||
|
||||
nofit = false;
|
||||
crushchange = crunch;
|
||||
|
||||
// killough 4/4/98: scan list front-to-back until empty or exhausted,
|
||||
// restarting from beginning after each thing is processed. Avoids
|
||||
// crashes, and is sure to examine all things in the sector, and only
|
||||
// the things which are in the sector, until a steady-state is reached.
|
||||
// Things can arbitrarily be inserted and removed and it won't mess up.
|
||||
//
|
||||
// killough 4/7/98: simplified to avoid using complicated counter
|
||||
|
||||
// Mark all things invalid
|
||||
|
||||
for (n=sector->touching_thinglist; n; n=n->m_snext)
|
||||
n->visited = false;
|
||||
|
||||
do
|
||||
for (n=sector->touching_thinglist; n; n=n->m_snext) // go through list
|
||||
if (!n->visited) // unprocessed thing found
|
||||
{
|
||||
n->visited = true; // mark thing as processed
|
||||
if (!(n->m_thing->flags & MF_NOBLOCKMAP)) //jff 4/7/98 don't do these
|
||||
PIT_ChangeSector(n->m_thing); // process it
|
||||
break; // exit and start over
|
||||
}
|
||||
while (n); // repeat from scratch until all things left are marked valid
|
||||
|
||||
return nofit;
|
||||
}
|
||||
|
||||
|
||||
// phares 3/21/98
|
||||
//
|
||||
// Maintain a freelist of msecnode_t's to reduce memory allocs and frees.
|
||||
|
||||
msecnode_t *headsecnode = NULL;
|
||||
|
||||
// P_GetSecnode() retrieves a node from the freelist. The calling routine
|
||||
// should make sure it sets all fields properly.
|
||||
|
||||
msecnode_t *P_GetSecnode()
|
||||
{
|
||||
msecnode_t *node;
|
||||
|
||||
if (headsecnode)
|
||||
{
|
||||
node = headsecnode;
|
||||
headsecnode = headsecnode->m_snext;
|
||||
}
|
||||
else
|
||||
node = Z_Malloc (sizeof(*node), PU_LEVEL, NULL);
|
||||
return(node);
|
||||
}
|
||||
|
||||
// P_PutSecnode() returns a node to the freelist.
|
||||
|
||||
void P_PutSecnode (msecnode_t* node)
|
||||
{
|
||||
node->m_snext = headsecnode;
|
||||
headsecnode = node;
|
||||
}
|
||||
|
||||
// phares 3/16/98
|
||||
//
|
||||
// P_AddSecnode() searches the current list to see if this sector is
|
||||
// already there. If not, it adds a sector node at the head of the list of
|
||||
// sectors this object appears in. This is called when creating a list of
|
||||
// nodes that will get linked in later. Returns a pointer to the new node.
|
||||
|
||||
msecnode_t* P_AddSecnode(sector_t* s, mobj_t* thing, msecnode_t* nextnode)
|
||||
{
|
||||
msecnode_t* node;
|
||||
|
||||
node = nextnode;
|
||||
while (node)
|
||||
{
|
||||
if (node->m_sector == s) // Already have a node for this sector?
|
||||
{
|
||||
node->m_thing = thing; // Yes. Setting m_thing says 'keep it'.
|
||||
return(nextnode);
|
||||
}
|
||||
node = node->m_tnext;
|
||||
}
|
||||
|
||||
// Couldn't find an existing node for this sector. Add one at the head
|
||||
// of the list.
|
||||
|
||||
node = P_GetSecnode();
|
||||
|
||||
// killough 4/4/98, 4/7/98: mark new nodes unvisited.
|
||||
node->visited = 0;
|
||||
|
||||
node->m_sector = s; // sector
|
||||
node->m_thing = thing; // mobj
|
||||
node->m_tprev = NULL; // prev node on Thing thread
|
||||
node->m_tnext = nextnode; // next node on Thing thread
|
||||
if (nextnode)
|
||||
nextnode->m_tprev = node; // set back link on Thing
|
||||
|
||||
// Add new node at head of sector thread starting at s->touching_thinglist
|
||||
|
||||
node->m_sprev = NULL; // prev node on sector thread
|
||||
node->m_snext = s->touching_thinglist; // next node on sector thread
|
||||
if (s->touching_thinglist)
|
||||
node->m_snext->m_sprev = node;
|
||||
s->touching_thinglist = node;
|
||||
return(node);
|
||||
}
|
||||
|
||||
|
||||
// P_DelSecnode() deletes a sector node from the list of
|
||||
// sectors this object appears in. Returns a pointer to the next node
|
||||
// on the linked list, or NULL.
|
||||
|
||||
msecnode_t* P_DelSecnode(msecnode_t* node)
|
||||
{
|
||||
msecnode_t* tp; // prev node on thing thread
|
||||
msecnode_t* tn; // next node on thing thread
|
||||
msecnode_t* sp; // prev node on sector thread
|
||||
msecnode_t* sn; // next node on sector thread
|
||||
|
||||
if (node)
|
||||
{
|
||||
|
||||
// Unlink from the Thing thread. The Thing thread begins at
|
||||
// sector_list and not from mobj_t->touching_sectorlist.
|
||||
|
||||
tp = node->m_tprev;
|
||||
tn = node->m_tnext;
|
||||
if (tp)
|
||||
tp->m_tnext = tn;
|
||||
if (tn)
|
||||
tn->m_tprev = tp;
|
||||
|
||||
// Unlink from the sector thread. This thread begins at
|
||||
// sector_t->touching_thinglist.
|
||||
|
||||
sp = node->m_sprev;
|
||||
sn = node->m_snext;
|
||||
if (sp)
|
||||
sp->m_snext = sn;
|
||||
else
|
||||
node->m_sector->touching_thinglist = sn;
|
||||
if (sn)
|
||||
sn->m_sprev = sp;
|
||||
|
||||
// Return this node to the freelist
|
||||
|
||||
P_PutSecnode(node);
|
||||
return(tn);
|
||||
}
|
||||
return(NULL);
|
||||
} // phares 3/13/98
|
||||
|
||||
// Delete an entire sector list
|
||||
|
||||
void P_DelSeclist(msecnode_t* node)
|
||||
{
|
||||
while (node)
|
||||
node = P_DelSecnode(node);
|
||||
}
|
||||
|
||||
|
||||
// phares 3/14/98
|
||||
//
|
||||
// PIT_GetSectors
|
||||
// Locates all the sectors the object is in by looking at the lines that
|
||||
// cross through it. You have already decided that the object is allowed
|
||||
// at this location, so don't bother with checking impassable or
|
||||
// blocking lines.
|
||||
|
||||
BOOL PIT_GetSectors(line_t* ld)
|
||||
{
|
||||
if (tmbbox[BOXRIGHT] <= ld->bbox[BOXLEFT] ||
|
||||
tmbbox[BOXLEFT] >= ld->bbox[BOXRIGHT] ||
|
||||
tmbbox[BOXTOP] <= ld->bbox[BOXBOTTOM] ||
|
||||
tmbbox[BOXBOTTOM] >= ld->bbox[BOXTOP])
|
||||
return true;
|
||||
|
||||
if (P_BoxOnLineSide(tmbbox, ld) != -1)
|
||||
return true;
|
||||
|
||||
// This line crosses through the object.
|
||||
|
||||
// Collect the sector(s) from the line and add to the
|
||||
// sector_list you're examining. If the Thing ends up being
|
||||
// allowed to move to this position, then the sector_list
|
||||
// will be attached to the Thing's mobj_t at touching_sectorlist.
|
||||
|
||||
sector_list = P_AddSecnode(ld->frontsector,tmthing,sector_list);
|
||||
|
||||
// Don't assume all lines are 2-sided, since some Things
|
||||
// like MT_TFOG are allowed regardless of whether their radius takes
|
||||
// them beyond an impassable linedef.
|
||||
|
||||
// killough 3/27/98, 4/4/98:
|
||||
// Use sidedefs instead of 2s flag to determine two-sidedness.
|
||||
|
||||
if (ld->backsector)
|
||||
sector_list = P_AddSecnode(ld->backsector, tmthing, sector_list);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// phares 3/14/98
|
||||
//
|
||||
// P_CreateSecNodeList alters/creates the sector_list that shows what sectors
|
||||
// the object resides in.
|
||||
|
||||
void P_CreateSecNodeList(mobj_t* thing,fixed_t x,fixed_t y)
|
||||
{
|
||||
int xl;
|
||||
int xh;
|
||||
int yl;
|
||||
int yh;
|
||||
int bx;
|
||||
int by;
|
||||
msecnode_t* node;
|
||||
|
||||
// First, clear out the existing m_thing fields. As each node is
|
||||
// added or verified as needed, m_thing will be set properly. When
|
||||
// finished, delete all nodes where m_thing is still NULL. These
|
||||
// represent the sectors the Thing has vacated.
|
||||
|
||||
node = sector_list;
|
||||
while (node)
|
||||
{
|
||||
node->m_thing = NULL;
|
||||
node = node->m_tnext;
|
||||
}
|
||||
|
||||
tmthing = thing;
|
||||
tmflags = thing->flags;
|
||||
|
||||
tmx = x;
|
||||
tmy = y;
|
||||
|
||||
tmbbox[BOXTOP] = y + tmthing->radius;
|
||||
tmbbox[BOXBOTTOM] = y - tmthing->radius;
|
||||
tmbbox[BOXRIGHT] = x + tmthing->radius;
|
||||
tmbbox[BOXLEFT] = x - tmthing->radius;
|
||||
|
||||
validcount++; // used to make sure we only process a line once
|
||||
|
||||
xl = (tmbbox[BOXLEFT] - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xh = (tmbbox[BOXRIGHT] - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
yl = (tmbbox[BOXBOTTOM] - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yh = (tmbbox[BOXTOP] - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
|
||||
for (bx=xl ; bx<=xh ; bx++)
|
||||
for (by=yl ; by<=yh ; by++)
|
||||
P_BlockLinesIterator(bx,by,PIT_GetSectors);
|
||||
|
||||
// Add the sector of the (x,y) point to sector_list.
|
||||
|
||||
sector_list = P_AddSecnode(thing->subsector->sector,thing,sector_list);
|
||||
|
||||
// Now delete any nodes that won't be used. These are the ones where
|
||||
// m_thing is still NULL.
|
||||
|
||||
node = sector_list;
|
||||
while (node)
|
||||
{
|
||||
if (node->m_thing == NULL)
|
||||
{
|
||||
if (node == sector_list)
|
||||
sector_list = node->m_tnext;
|
||||
node = P_DelSecnode(node);
|
||||
}
|
||||
else
|
||||
node = node->m_tnext;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -321,7 +321,7 @@ void P_UnsetThingPosition (mobj_t *thing)
|
|||
int blockx;
|
||||
int blocky;
|
||||
|
||||
if ( ! (thing->flags & MF_NOSECTOR) )
|
||||
if (!(thing->flags & MF_NOSECTOR))
|
||||
{
|
||||
// inert things don't need to be in blockmap?
|
||||
// unlink from subsector
|
||||
|
@ -332,6 +332,22 @@ void P_UnsetThingPosition (mobj_t *thing)
|
|||
thing->sprev->snext = thing->snext;
|
||||
else
|
||||
thing->subsector->sector->thinglist = thing->snext;
|
||||
|
||||
// phares 3/14/98
|
||||
//
|
||||
// Save the sector list pointed to by touching_sectorlist.
|
||||
// In P_SetThingPosition, we'll keep any nodes that represent
|
||||
// sectors the Thing still touches. We'll add new ones then, and
|
||||
// delete any nodes for sectors the Thing has vacated. Then we'll
|
||||
// put it back into touching_sectorlist. It's done this way to
|
||||
// avoid a lot of deleting/creating for nodes, when most of the
|
||||
// time you just get back what you deleted anyway.
|
||||
//
|
||||
// If this Thing is being removed entirely, then the calling
|
||||
// routine will clear out the nodes in sector_list.
|
||||
|
||||
sector_list = thing->touching_sectorlist;
|
||||
thing->touching_sectorlist = NULL; //to be restored by P_SetThingPosition
|
||||
}
|
||||
|
||||
if ( ! (thing->flags & MF_NOBLOCKMAP) )
|
||||
|
@ -389,6 +405,23 @@ void P_SetThingPosition (mobj_t *thing)
|
|||
sec->thinglist->sprev = thing;
|
||||
|
||||
sec->thinglist = thing;
|
||||
|
||||
// phares 3/16/98
|
||||
//
|
||||
// If sector_list isn't NULL, it has a collection of sector
|
||||
// nodes that were just removed from this Thing.
|
||||
|
||||
// Collect the sectors the object will live in by looking at
|
||||
// the existing sector_list and adding new nodes and deleting
|
||||
// obsolete ones.
|
||||
|
||||
// When a node is deleted, its sector links (the links starting
|
||||
// at sector_t->touching_thinglist) are broken. When a node is
|
||||
// added, new sector links are created.
|
||||
|
||||
P_CreateSecNodeList (thing, thing->x, thing->y);
|
||||
thing->touching_sectorlist = sector_list; // Attach to Thing's mobj_t
|
||||
sector_list = NULL; // clear for next time
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -230,8 +230,13 @@ void P_XYMovement (mobj_t* mo)
|
|||
if (mo->flags & (MF_MISSILE | MF_SKULLFLY) )
|
||||
return; // no friction for missiles ever
|
||||
|
||||
if (olddemo) { // no friction when airborne
|
||||
if (mo->z > mo->floorz)
|
||||
return;
|
||||
} else {
|
||||
if (!P_FindFloor (mo)) // [RH] Z-Check
|
||||
return; // no friction when airborne
|
||||
return;
|
||||
}
|
||||
|
||||
if (mo->flags & MF_CORPSE)
|
||||
{
|
||||
|
@ -311,9 +316,16 @@ void P_ZMovement (mobj_t* mo)
|
|||
}
|
||||
|
||||
// clip movement
|
||||
if (olddemo) {
|
||||
if (mo->z <= mo->floorz)
|
||||
other = (mobj_t *)-1;
|
||||
else
|
||||
other = NULL;
|
||||
} else {
|
||||
other = P_FindFloor (mo); // [RH] Z-Check
|
||||
if ((mo->flags & MF_MISSILE) && (other == mo->target) && (gametic < (signed)mo->targettic))
|
||||
other = NULL;
|
||||
}
|
||||
|
||||
if (other) {
|
||||
// hit the floor ([RH] or something else)
|
||||
|
@ -400,9 +412,16 @@ void P_ZMovement (mobj_t* mo)
|
|||
mo->momz -= (fixed_t)(sv_gravity->value * 81.92);
|
||||
}
|
||||
|
||||
if (olddemo) {
|
||||
if (mo->z + mo->height > mo->ceilingz)
|
||||
other = (mobj_t *) -1;
|
||||
else
|
||||
other = NULL;
|
||||
} else {
|
||||
other = P_FindCeiling (mo); // [RH] Z-Check
|
||||
if ((mo->flags & MF_MISSILE) && (other == mo->target) && (gametic < (signed)mo->targettic))
|
||||
other = NULL;
|
||||
}
|
||||
|
||||
if (other)
|
||||
{
|
||||
|
@ -603,6 +622,7 @@ mobj_t *P_SpawnMobj (fixed_t x, fixed_t y, fixed_t z, mobjtype_t type, int onflo
|
|||
mobj->tics = st->tics;
|
||||
mobj->sprite = st->sprite;
|
||||
mobj->frame = st->frame;
|
||||
mobj->touching_sectorlist = NULL; // NULL head of sector list // phares 3/13/98
|
||||
|
||||
// set subsector and/or block links
|
||||
P_SetThingPosition (mobj);
|
||||
|
@ -657,6 +677,14 @@ void P_RemoveMobj (mobj_t* mobj)
|
|||
// unlink from sector and block lists
|
||||
P_UnsetThingPosition (mobj);
|
||||
|
||||
// Delete all nodes on the current sector_list phares 3/16/98
|
||||
|
||||
if (sector_list)
|
||||
{
|
||||
P_DelSeclist(sector_list);
|
||||
sector_list = NULL;
|
||||
}
|
||||
|
||||
// stop any playing sound
|
||||
S_StopSound (mobj);
|
||||
|
||||
|
|
|
@ -308,6 +308,9 @@ 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
|
||||
|
||||
} mobj_t;
|
||||
|
||||
|
||||
|
|
|
@ -184,9 +184,11 @@ void P_UnArchiveWorld (void)
|
|||
sec->floorpic = *get++;
|
||||
sec->ceilingpic = *get++;
|
||||
sec->lightlevel = *get++;
|
||||
sec->special = *get++; // needed?
|
||||
sec->tag = *get++; // needed?
|
||||
sec->specialdata = 0;
|
||||
sec->special = *get++;
|
||||
sec->tag = *get++;
|
||||
sec->ceilingdata = 0; //jff 2/22/98 now three thinker fields not two
|
||||
sec->floordata = 0;
|
||||
sec->lightingdata = 0;
|
||||
sec->soundtarget = 0;
|
||||
}
|
||||
|
||||
|
@ -337,6 +339,8 @@ enum
|
|||
tc_strobe,
|
||||
tc_glow,
|
||||
tc_fireflicker,
|
||||
tc_elevator,
|
||||
tc_scroll,
|
||||
tc_endspecials
|
||||
} specials_e;
|
||||
|
||||
|
@ -353,6 +357,8 @@ enum
|
|||
// T_Glow, (glow_t: sector_t *),
|
||||
// T_PlatRaise, (plat_t: sector_t *), - active list
|
||||
// T_FireFlicker (fireflicker_t: sector_t * swizze), [RH] Was missed in original code
|
||||
// T_MoveElevator, (plat_t: sector_t *), - active list // jff 2/22/98
|
||||
// T_Scroll // killough 3/7/98
|
||||
//
|
||||
void P_ArchiveSpecials (void)
|
||||
{
|
||||
|
@ -462,6 +468,27 @@ void P_ArchiveSpecials (void)
|
|||
save_p += sizeof(*flick);
|
||||
flick->sector = (sector_t *)(flick->sector - sectors);
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1) T_MoveElevator)
|
||||
{ //jff 2/22/98 new case for elevators
|
||||
|
||||
elevator_t *elevator; //jff 2/22/98
|
||||
|
||||
*save_p++ = tc_elevator;
|
||||
PADSAVEP();
|
||||
elevator = (elevator_t *)save_p;
|
||||
memcpy (elevator, th, sizeof(*elevator));
|
||||
save_p += sizeof(*elevator);
|
||||
elevator->sector = (sector_t *)(elevator->sector - sectors);
|
||||
}
|
||||
else if (th->function.acp1 == (actionf_p1) T_Scroll)
|
||||
{ // killough 3/7/98: Scroll effect thinkers
|
||||
|
||||
*save_p++ = tc_scroll;
|
||||
memcpy (save_p, th, sizeof(scroll_t));
|
||||
save_p += sizeof(scroll_t);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// add a terminating marker
|
||||
|
@ -501,7 +528,7 @@ void P_UnArchiveSpecials (void)
|
|||
memcpy (ceiling, save_p, sizeof(*ceiling));
|
||||
save_p += sizeof(*ceiling);
|
||||
ceiling->sector = §ors[(int)ceiling->sector];
|
||||
ceiling->sector->specialdata = ceiling;
|
||||
ceiling->sector->ceilingdata = ceiling; //jff 2/22/98
|
||||
|
||||
if (ceiling->thinker.function.acp1)
|
||||
ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling;
|
||||
|
@ -516,7 +543,7 @@ void P_UnArchiveSpecials (void)
|
|||
memcpy (door, save_p, sizeof(*door));
|
||||
save_p += sizeof(*door);
|
||||
door->sector = §ors[(int)door->sector];
|
||||
door->sector->specialdata = door;
|
||||
door->sector->ceilingdata = door; //jff 2/22/98
|
||||
door->thinker.function.acp1 = (actionf_p1)T_VerticalDoor;
|
||||
P_AddThinker (&door->thinker);
|
||||
break;
|
||||
|
@ -527,7 +554,7 @@ void P_UnArchiveSpecials (void)
|
|||
memcpy (floor, save_p, sizeof(*floor));
|
||||
save_p += sizeof(*floor);
|
||||
floor->sector = §ors[(int)floor->sector];
|
||||
floor->sector->specialdata = floor;
|
||||
floor->sector->floordata = floor; //jff 2/22/98
|
||||
floor->thinker.function.acp1 = (actionf_p1)T_MoveFloor;
|
||||
P_AddThinker (&floor->thinker);
|
||||
break;
|
||||
|
@ -538,7 +565,7 @@ void P_UnArchiveSpecials (void)
|
|||
memcpy (plat, save_p, sizeof(*plat));
|
||||
save_p += sizeof(*plat);
|
||||
plat->sector = §ors[(int)plat->sector];
|
||||
plat->sector->specialdata = plat;
|
||||
plat->sector->floordata = plat; //jff 2/22/98
|
||||
|
||||
if (plat->thinker.function.acp1)
|
||||
plat->thinker.function.acp1 = (actionf_p1)T_PlatRaise;
|
||||
|
@ -587,6 +614,31 @@ void P_UnArchiveSpecials (void)
|
|||
P_AddThinker (&flick->thinker);
|
||||
break;
|
||||
|
||||
//jff 2/22/98 new case for elevators
|
||||
case tc_elevator:
|
||||
PADSAVEP();
|
||||
{
|
||||
elevator_t *elevator = Z_Malloc (sizeof(*elevator), PU_LEVEL, NULL);
|
||||
memcpy (elevator, save_p, sizeof(*elevator));
|
||||
save_p += sizeof(*elevator);
|
||||
elevator->sector = §ors[(int)elevator->sector];
|
||||
elevator->sector->floordata = elevator; //jff 2/22/98
|
||||
elevator->sector->ceilingdata = elevator; //jff 2/22/98
|
||||
elevator->thinker.function.acp1 = (actionf_p1) T_MoveElevator;
|
||||
P_AddThinker (&elevator->thinker);
|
||||
break;
|
||||
}
|
||||
|
||||
case tc_scroll: // killough 3/7/98: scroll effect thinkers
|
||||
{
|
||||
scroll_t *scroll = Z_Malloc (sizeof(scroll_t), PU_LEVEL, NULL);
|
||||
memcpy (scroll, save_p, sizeof(scroll_t));
|
||||
save_p += sizeof(scroll_t);
|
||||
scroll->thinker.function.acp1 = (actionf_p1) T_Scroll;
|
||||
P_AddThinker(&scroll->thinker);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
I_Error ("P_UnarchiveSpecials:Unknown tclass %i "
|
||||
"in savegame",tclass);
|
||||
|
|
119
code/P_setup.c
119
code/P_setup.c
|
@ -253,6 +253,22 @@ void P_LoadSectors (int lump)
|
|||
ss->special = SHORT(ms->special);
|
||||
ss->tag = SHORT(ms->tag);
|
||||
ss->thinglist = NULL;
|
||||
ss->touching_thinglist = NULL; // phares 3/14/98
|
||||
|
||||
ss->nextsec = -1; //jff 2/26/98 add fields to support locking out
|
||||
ss->prevsec = -1; // stair retriggering until build completes
|
||||
|
||||
// killough 3/7/98:
|
||||
ss->floor_xoffs = 0;
|
||||
ss->floor_yoffs = 0; // floor and ceiling flats offsets
|
||||
ss->ceiling_xoffs = 0;
|
||||
ss->ceiling_yoffs = 0;
|
||||
ss->heightsec = -1; // sector used to get floor and ceiling height
|
||||
ss->floorlightsec = -1; // sector used to get floor lighting
|
||||
// killough 3/7/98: end changes
|
||||
|
||||
// killough 4/11/98 sector used to get ceiling lighting:
|
||||
ss->ceilinglightsec = -1;
|
||||
}
|
||||
|
||||
Z_Free (data);
|
||||
|
@ -378,32 +394,13 @@ void P_LoadThings2 (int lump)
|
|||
// P_LoadLineDefs
|
||||
// Also counts secret lines for intermissions.
|
||||
//
|
||||
void P_LoadLineDefs (int lump)
|
||||
static void P_AdjustLine (line_t *ld)
|
||||
{
|
||||
byte* data;
|
||||
int i;
|
||||
maplinedef_t* mld;
|
||||
line_t* ld;
|
||||
vertex_t* v1;
|
||||
vertex_t* v2;
|
||||
vertex_t *v1, *v2;
|
||||
|
||||
numlines = W_LumpLength (lump) / sizeof(maplinedef_t);
|
||||
lines = Z_Malloc (numlines*sizeof(line_t),PU_LEVEL,0);
|
||||
memset (lines, 0, numlines*sizeof(line_t));
|
||||
data = W_CacheLumpNum (lump,PU_STATIC);
|
||||
v1 = ld->v1;
|
||||
v2 = ld->v2;
|
||||
|
||||
mld = (maplinedef_t *)data;
|
||||
ld = lines;
|
||||
for (i=0 ; i<numlines ; i++, mld++, ld++)
|
||||
{
|
||||
ld->flags = SHORT(mld->flags);
|
||||
// [RH] Remap ML_PASSUSE flag from BOOM.
|
||||
if (!HasBehavior && (ld->flags & ML_PASSUSEORG))
|
||||
ld->flags = (ld->flags & ~ML_PASSUSEORG) | ML_PASSUSE;
|
||||
ld->special = SHORT(mld->special);
|
||||
ld->tag = SHORT(mld->tag);
|
||||
v1 = ld->v1 = &vertexes[SHORT(mld->v1)];
|
||||
v2 = ld->v2 = &vertexes[SHORT(mld->v2)];
|
||||
ld->dx = v2->x - v1->x;
|
||||
ld->dy = v2->y - v1->y;
|
||||
|
||||
|
@ -441,9 +438,6 @@ void P_LoadLineDefs (int lump)
|
|||
ld->bbox[BOXTOP] = v1->y;
|
||||
}
|
||||
|
||||
ld->sidenum[0] = SHORT(mld->sidenum[0]);
|
||||
ld->sidenum[1] = SHORT(mld->sidenum[1]);
|
||||
|
||||
if (ld->sidenum[0] != -1)
|
||||
ld->frontsector = sides[ld->sidenum[0]].sector;
|
||||
else
|
||||
|
@ -453,6 +447,70 @@ void P_LoadLineDefs (int lump)
|
|||
ld->backsector = sides[ld->sidenum[1]].sector;
|
||||
else
|
||||
ld->backsector = 0;
|
||||
}
|
||||
|
||||
void P_LoadLineDefs (int lump)
|
||||
{
|
||||
byte* data;
|
||||
int i;
|
||||
maplinedef_t* mld;
|
||||
line_t* ld;
|
||||
|
||||
numlines = W_LumpLength (lump) / sizeof(maplinedef_t);
|
||||
lines = Z_Malloc (numlines*sizeof(line_t),PU_LEVEL,0);
|
||||
memset (lines, 0, numlines*sizeof(line_t));
|
||||
data = W_CacheLumpNum (lump,PU_STATIC);
|
||||
|
||||
mld = (maplinedef_t *)data;
|
||||
ld = lines;
|
||||
for (i=0 ; i<numlines ; i++, mld++, ld++)
|
||||
{
|
||||
ld->flags = SHORT(mld->flags);
|
||||
// [RH] Remap ML_PASSUSE flag from BOOM.
|
||||
if (ld->flags & ML_PASSUSEORG)
|
||||
ld->flags = (ld->flags & ~ML_PASSUSEORG) | ML_PASSUSE;
|
||||
ld->special = SHORT(mld->special);
|
||||
ld->tag = SHORT(mld->tag);
|
||||
ld->v1 = &vertexes[SHORT(mld->v1)];
|
||||
ld->v2 = &vertexes[SHORT(mld->v2)];
|
||||
|
||||
ld->sidenum[0] = SHORT(mld->sidenum[0]);
|
||||
ld->sidenum[1] = SHORT(mld->sidenum[1]);
|
||||
|
||||
P_AdjustLine (ld);
|
||||
}
|
||||
|
||||
Z_Free (data);
|
||||
}
|
||||
|
||||
// [RH] Same as P_LoadLineDefs() except it uses Hexen-style LineDefs.
|
||||
void P_LoadLineDefs2 (int lump)
|
||||
{
|
||||
byte* data;
|
||||
int i;
|
||||
maplinedef2_t* mld;
|
||||
line_t* ld;
|
||||
|
||||
numlines = W_LumpLength (lump) / sizeof(maplinedef2_t);
|
||||
lines = Z_Malloc (numlines*sizeof(line_t),PU_LEVEL,0);
|
||||
memset (lines, 0, numlines*sizeof(line_t));
|
||||
data = W_CacheLumpNum (lump,PU_STATIC);
|
||||
|
||||
mld = (maplinedef2_t *)data;
|
||||
ld = lines;
|
||||
for (i=0 ; i<numlines ; i++, mld++, ld++)
|
||||
{
|
||||
ld->flags = SHORT(mld->flags);
|
||||
ld->special = mld->special;
|
||||
memcpy (ld->args, mld->args, 5);
|
||||
ld->tag = ld->args[0];
|
||||
ld->v1 = &vertexes[SHORT(mld->v1)];
|
||||
ld->v2 = &vertexes[SHORT(mld->v2)];
|
||||
|
||||
ld->sidenum[0] = SHORT(mld->sidenum[0]);
|
||||
ld->sidenum[1] = SHORT(mld->sidenum[1]);
|
||||
|
||||
P_AdjustLine (ld);
|
||||
}
|
||||
|
||||
Z_Free (data);
|
||||
|
@ -677,7 +735,10 @@ void P_SetupLevel (char *lumpname)
|
|||
P_LoadSectors (lumpnum+ML_SECTORS);
|
||||
P_LoadSideDefs (lumpnum+ML_SIDEDEFS);
|
||||
|
||||
if (!HasBehavior)
|
||||
P_LoadLineDefs (lumpnum+ML_LINEDEFS);
|
||||
else
|
||||
P_LoadLineDefs2 (lumpnum+ML_LINEDEFS); // [RH] Load Hexen-style linedefs
|
||||
P_LoadSubsectors (lumpnum+ML_SSECTORS);
|
||||
P_LoadNodes (lumpnum+ML_NODES);
|
||||
P_LoadSegs (lumpnum+ML_SEGS);
|
||||
|
@ -692,10 +753,10 @@ void P_SetupLevel (char *lumpname)
|
|||
}
|
||||
deathmatch_p = deathmatchstarts;
|
||||
|
||||
if (HasBehavior)
|
||||
P_LoadThings2 (lumpnum+ML_THINGS); // [RH] Load Hexen-style Things
|
||||
else
|
||||
if (!HasBehavior)
|
||||
P_LoadThings (lumpnum+ML_THINGS);
|
||||
else
|
||||
P_LoadThings2 (lumpnum+ML_THINGS); // [RH] Load Hexen-style things
|
||||
|
||||
// if deathmatch, randomly spawn the active players
|
||||
if (deathmatch->value)
|
||||
|
|
612
code/P_spec.c
612
code/P_spec.c
|
@ -68,15 +68,17 @@ typedef struct
|
|||
int basepic;
|
||||
int numpics;
|
||||
int speed;
|
||||
|
||||
} anim_t;
|
||||
|
||||
//
|
||||
// source animation definition
|
||||
//
|
||||
// [RH] Note that in BOOM's ANIMATED lump, this is an array packed to
|
||||
// byte boundaries. Total size: 23 bytes per entry.
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
BOOL istexture; // if false, it is a flat
|
||||
byte istexture; // if false, it is a flat
|
||||
char endname[9];
|
||||
char startname[9];
|
||||
int speed;
|
||||
|
@ -84,110 +86,105 @@ typedef struct
|
|||
|
||||
|
||||
|
||||
#define MAXANIMS 32
|
||||
|
||||
extern anim_t anims[MAXANIMS];
|
||||
extern anim_t* lastanim;
|
||||
|
||||
//
|
||||
// P_InitPicAnims
|
||||
//
|
||||
|
||||
// Floor/ceiling animation sequences,
|
||||
// defined by first and last frame,
|
||||
// i.e. the flat (64x64 tile) name to
|
||||
// be used.
|
||||
// The full animation sequence is given
|
||||
// using all the flats between the start
|
||||
// and end entry, in the order found in
|
||||
// the WAD file.
|
||||
//
|
||||
animdef_t animdefs[] =
|
||||
{
|
||||
{false, "NUKAGE3", "NUKAGE1", 8},
|
||||
{false, "FWATER4", "FWATER1", 8},
|
||||
{false, "SWATER4", "SWATER1", 8},
|
||||
{false, "LAVA4", "LAVA1", 8},
|
||||
{false, "BLOOD3", "BLOOD1", 8},
|
||||
|
||||
// DOOM II flat animations.
|
||||
{false, "RROCK08", "RROCK05", 8},
|
||||
{false, "SLIME04", "SLIME01", 8},
|
||||
{false, "SLIME08", "SLIME05", 8},
|
||||
{false, "SLIME12", "SLIME09", 8},
|
||||
|
||||
{true, "BLODGR4", "BLODGR1", 8},
|
||||
{true, "SLADRIP3", "SLADRIP1", 8},
|
||||
|
||||
{true, "BLODRIP4", "BLODRIP1", 8},
|
||||
{true, "FIREWALL", "FIREWALA", 8},
|
||||
{true, "GSTFONT3", "GSTFONT1", 8},
|
||||
{true, "FIRELAVA", "FIRELAV3", 8},
|
||||
{true, "FIREMAG3", "FIREMAG1", 8},
|
||||
{true, "FIREBLU2", "FIREBLU1", 8},
|
||||
{true, "ROCKRED3", "ROCKRED1", 8},
|
||||
|
||||
{true, "BFALL4", "BFALL1", 8},
|
||||
{true, "SFALL4", "SFALL1", 8},
|
||||
{true, "WFALL4", "WFALL1", 8},
|
||||
{true, "DBRAIN4", "DBRAIN1", 8},
|
||||
|
||||
{-1}
|
||||
};
|
||||
|
||||
anim_t anims[MAXANIMS];
|
||||
anim_t* lastanim;
|
||||
static anim_t* lastanim;
|
||||
static anim_t* anims;
|
||||
|
||||
// killough 3/7/98: Initialize generalized scrolling
|
||||
static void P_SpawnScrollers(void);
|
||||
|
||||
//
|
||||
// Animating line specials
|
||||
//
|
||||
#define MAXLINEANIMS 64
|
||||
|
||||
extern short numlinespecials;
|
||||
extern line_t* linespeciallist[MAXLINEANIMS];
|
||||
//#define MAXLINEANIMS 64
|
||||
|
||||
//extern short numlinespecials;
|
||||
//extern line_t* linespeciallist[MAXLINEANIMS];
|
||||
|
||||
|
||||
//
|
||||
// P_InitPicAnims
|
||||
//
|
||||
// Load the table of animation definitions, checking for existence of
|
||||
// the start and end of each frame. If the start doesn't exist the sequence
|
||||
// is skipped, if the last doesn't exist, BOOM exits.
|
||||
//
|
||||
// Wall/Flat animation sequences, defined by name of first and last frame,
|
||||
// The full animation sequence is given using all lumps between the start
|
||||
// and end entry, in the order found in the WAD file.
|
||||
//
|
||||
// This routine modified to read its data from a predefined lump or
|
||||
// PWAD lump called ANIMATED rather than a static table in this module to
|
||||
// allow wad designers to insert or modify animation sequences.
|
||||
//
|
||||
// Lump format is an array of byte packed animdef_t structures, terminated
|
||||
// by a structure with istexture == -1. The lump can be generated from a
|
||||
// text source file using SWANTBLS.EXE, distributed with the BOOM utils.
|
||||
// The standard list of switches and animations is contained in the example
|
||||
// source text file DEFSWANI.DAT also in the BOOM util distribution.
|
||||
//
|
||||
// [RH] Rewritten to support BOOM ANIMATED lump but also make absolutely
|
||||
// no assumptions about how the compiler packs the animdefs array.
|
||||
//
|
||||
void P_InitPicAnims (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
byte *animdefs = W_CacheLumpName ("ANIMATED", PU_STATIC);
|
||||
byte *anim_p;
|
||||
|
||||
// Init animation
|
||||
lastanim = anims;
|
||||
for (i=0 ; animdefs[i].istexture != -1 ; i++)
|
||||
|
||||
// [RH] Figure out maximum size of anims array
|
||||
{
|
||||
if (animdefs[i].istexture)
|
||||
int i;
|
||||
|
||||
for (i = 0, anim_p = animdefs; *anim_p != 255; anim_p += 23, i++)
|
||||
;
|
||||
|
||||
if (i == 0) {
|
||||
// No animdefs
|
||||
anims = lastanim = NULL;
|
||||
Z_Free (animdefs);
|
||||
return;
|
||||
}
|
||||
|
||||
lastanim = anims = Z_Malloc (i*sizeof(*anims), PU_STATIC, 0);
|
||||
}
|
||||
|
||||
for (anim_p = animdefs; *anim_p != 255; anim_p += 23)
|
||||
{
|
||||
if (*anim_p /* .istexture */)
|
||||
{
|
||||
// different episode ?
|
||||
if (R_CheckTextureNumForName(animdefs[i].startname) == -1)
|
||||
if (R_CheckTextureNumForName (anim_p + 10 /* .startname */) == -1)
|
||||
continue;
|
||||
|
||||
lastanim->picnum = R_TextureNumForName (animdefs[i].endname);
|
||||
lastanim->basepic = R_TextureNumForName (animdefs[i].startname);
|
||||
lastanim->picnum = R_TextureNumForName (anim_p + 1 /* .endname */);
|
||||
lastanim->basepic = R_TextureNumForName (anim_p + 10 /* .startname */);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (W_CheckNumForName(animdefs[i].startname) == -1)
|
||||
if ((W_CheckNumForName)(anim_p + 10 /* .startname */, ns_flats) == -1)
|
||||
continue;
|
||||
|
||||
lastanim->picnum = R_FlatNumForName (animdefs[i].endname);
|
||||
lastanim->basepic = R_FlatNumForName (animdefs[i].startname);
|
||||
lastanim->picnum = R_FlatNumForName (anim_p + 1 /* .endname */);
|
||||
lastanim->basepic = R_FlatNumForName (anim_p + 10 /* .startname */);
|
||||
}
|
||||
|
||||
lastanim->istexture = animdefs[i].istexture;
|
||||
lastanim->istexture = *anim_p /* .istexture */;
|
||||
lastanim->numpics = lastanim->picnum - lastanim->basepic + 1;
|
||||
|
||||
if (lastanim->numpics < 2)
|
||||
I_Error ("P_InitPicAnims: bad cycle from %s to %s",
|
||||
animdefs[i].startname,
|
||||
animdefs[i].endname);
|
||||
anim_p + 10 /* .startname */,
|
||||
anim_p + 1 /* .endname */);
|
||||
|
||||
lastanim->speed = animdefs[i].speed;
|
||||
lastanim->speed = /* .speed */
|
||||
(anim_p[19] << 0) |
|
||||
(anim_p[20] << 8) |
|
||||
(anim_p[21] << 16) |
|
||||
(anim_p[22] << 24);
|
||||
lastanim++;
|
||||
}
|
||||
|
||||
Z_Free (animdefs);
|
||||
}
|
||||
|
||||
|
||||
|
@ -263,6 +260,34 @@ sector_t *getNextSector (line_t *line, sector_t *sec)
|
|||
return line->frontsector;
|
||||
}
|
||||
|
||||
//
|
||||
// P_SectorActive()
|
||||
//
|
||||
// Passed a linedef special class (floor, ceiling, lighting) and a sector
|
||||
// returns whether the sector is already busy with a linedef special of the
|
||||
// same class. If old demo compatibility true, all linedef special classes
|
||||
// are the same.
|
||||
//
|
||||
// jff 2/23/98 added to prevent old demos from
|
||||
// succeeding in starting multiple specials on one sector
|
||||
//
|
||||
int P_SectorActive(special_e t,sector_t *sec)
|
||||
{
|
||||
if (olddemo) { // return whether any thinker is active
|
||||
return sec->floordata || sec->ceilingdata || sec->lightingdata;
|
||||
} else {
|
||||
switch (t) // return whether thinker of same type is active
|
||||
{
|
||||
case floor_special:
|
||||
return (int)sec->floordata;
|
||||
case ceiling_special:
|
||||
return (int)sec->ceilingdata;
|
||||
case lighting_special:
|
||||
return (int)sec->lightingdata;
|
||||
}
|
||||
return 1; // don't know which special, must be active, shouldn't be here
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
@ -320,44 +345,75 @@ fixed_t P_FindHighestFloorSurrounding(sector_t *sec)
|
|||
|
||||
|
||||
//
|
||||
// P_FindNextHighestFloor
|
||||
// FIND NEXT HIGHEST FLOOR IN SURROUNDING SECTORS
|
||||
|
||||
fixed_t
|
||||
P_FindNextHighestFloor
|
||||
( sector_t* sec,
|
||||
int currentheight )
|
||||
// P_FindNextHighestFloor()
|
||||
//
|
||||
// Passed a sector and a floor height, returns the fixed point value
|
||||
// of the smallest floor height in a surrounding sector larger than
|
||||
// the floor height passed. If no such height exists the floorheight
|
||||
// passed is returned.
|
||||
//
|
||||
// Rewritten by Lee Killough to avoid fixed array and to be faster
|
||||
//
|
||||
fixed_t P_FindNextHighestFloor(sector_t *sec, int currentheight)
|
||||
{
|
||||
sector_t *other;
|
||||
int i;
|
||||
line_t* check;
|
||||
sector_t* other;
|
||||
fixed_t min;
|
||||
|
||||
min = MAXINT;
|
||||
|
||||
for (i = 0; i < sec->linecount; i++) {
|
||||
check = sec->lines[i];
|
||||
other = getNextSector (check, sec);
|
||||
if ((other = getNextSector(sec->lines[i],sec)) &&
|
||||
other->floorheight > currentheight) {
|
||||
int height = other->floorheight;
|
||||
|
||||
if (!other)
|
||||
continue;
|
||||
|
||||
if (other->floorheight > currentheight && other->floorheight < min)
|
||||
min = other->floorheight;
|
||||
while (++i < sec->linecount) {
|
||||
if ((other = getNextSector(sec->lines[i],sec)) &&
|
||||
other->floorheight < height &&
|
||||
other->floorheight > currentheight) {
|
||||
height = other->floorheight;
|
||||
}
|
||||
}
|
||||
return height;
|
||||
}
|
||||
}
|
||||
|
||||
if (min == MAXINT)
|
||||
return currentheight;
|
||||
else
|
||||
return min;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// P_FindNextLowestFloor()
|
||||
//
|
||||
// Passed a sector and a floor height, returns the fixed point value
|
||||
// of the largest floor height in a surrounding sector smaller than
|
||||
// the floor height passed. If no such height exists the floorheight
|
||||
// passed is returned.
|
||||
//
|
||||
// jff 02/03/98 Twiddled Lee's P_FindNextHighestFloor to make this
|
||||
//
|
||||
fixed_t P_FindNextLowestFloor(sector_t *sec, int currentheight)
|
||||
{
|
||||
sector_t *other;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sec->linecount; i++)
|
||||
if ((other = getNextSector(sec->lines[i],sec)) &&
|
||||
other->floorheight < currentheight) {
|
||||
int height = other->floorheight;
|
||||
|
||||
while (++i < sec->linecount) {
|
||||
if ((other = getNextSector(sec->lines[i],sec)) &&
|
||||
other->floorheight > height &&
|
||||
other->floorheight < currentheight) {
|
||||
height = other->floorheight;
|
||||
}
|
||||
}
|
||||
return height;
|
||||
}
|
||||
return currentheight;
|
||||
}
|
||||
|
||||
//
|
||||
// FIND LOWEST CEILING IN THE SURROUNDING SECTORS
|
||||
//
|
||||
fixed_t
|
||||
P_FindLowestCeilingSurrounding(sector_t* sec)
|
||||
fixed_t P_FindLowestCeilingSurrounding (sector_t *sec)
|
||||
{
|
||||
int i;
|
||||
line_t* check;
|
||||
|
@ -382,7 +438,7 @@ P_FindLowestCeilingSurrounding(sector_t* sec)
|
|||
//
|
||||
// FIND HIGHEST CEILING IN THE SURROUNDING SECTORS
|
||||
//
|
||||
fixed_t P_FindHighestCeilingSurrounding(sector_t* sec)
|
||||
fixed_t P_FindHighestCeilingSurrounding (sector_t *sec)
|
||||
{
|
||||
int i;
|
||||
line_t* check;
|
||||
|
@ -408,10 +464,7 @@ fixed_t P_FindHighestCeilingSurrounding(sector_t* sec)
|
|||
//
|
||||
// RETURN NEXT SECTOR # THAT LINE TAG REFERS TO
|
||||
//
|
||||
int
|
||||
P_FindSectorFromLineTag
|
||||
( line_t* line,
|
||||
int start )
|
||||
int P_FindSectorFromLineTag (line_t *line, int start)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -422,16 +475,22 @@ P_FindSectorFromLineTag
|
|||
return -1;
|
||||
}
|
||||
|
||||
int P_FindLineFromLineTag (line_t *line, int start)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = start+1; i < numlines; i++)
|
||||
if (lines[i].tag == line->tag)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Find minimum light from an adjacent sector
|
||||
//
|
||||
int
|
||||
P_FindMinSurroundingLight
|
||||
( sector_t* sector,
|
||||
int max )
|
||||
int P_FindMinSurroundingLight (sector_t *sector, int max)
|
||||
{
|
||||
int i;
|
||||
int min;
|
||||
|
@ -466,11 +525,7 @@ P_FindMinSurroundingLight
|
|||
// Called every time a thing origin is about
|
||||
// to cross a line with a non 0 special.
|
||||
//
|
||||
void
|
||||
P_CrossSpecialLine
|
||||
( int linenum,
|
||||
int side,
|
||||
mobj_t* thing )
|
||||
void P_CrossSpecialLine (int linenum, int side, mobj_t *thing)
|
||||
{
|
||||
line_t* line;
|
||||
int ok;
|
||||
|
@ -935,10 +990,7 @@ P_CrossSpecialLine
|
|||
// P_ShootSpecialLine - IMPACT SPECIALS
|
||||
// Called when a thing shoots a special line.
|
||||
//
|
||||
void
|
||||
P_ShootSpecialLine
|
||||
( mobj_t* thing,
|
||||
line_t* line )
|
||||
void P_ShootSpecialLine (mobj_t *thing, line_t *line)
|
||||
{
|
||||
int ok;
|
||||
|
||||
|
@ -1067,7 +1119,6 @@ void P_UpdateSpecials (void)
|
|||
anim_t* anim;
|
||||
int pic;
|
||||
int i;
|
||||
line_t* line;
|
||||
|
||||
|
||||
// LEVEL TIMER
|
||||
|
@ -1096,19 +1147,6 @@ void P_UpdateSpecials (void)
|
|||
sky1pos = (sky1pos + level.skyspeed1) & 0xffffff;
|
||||
sky2pos = (sky2pos + level.skyspeed2) & 0xffffff;
|
||||
|
||||
// ANIMATE LINE SPECIALS
|
||||
for (i = 0; i < numlinespecials; i++)
|
||||
{
|
||||
line = linespeciallist[i];
|
||||
switch(line->special)
|
||||
{
|
||||
case 48:
|
||||
// EFFECT FIRSTCOL SCROLL +
|
||||
sides[line->sidenum[0]].textureoffset += FRACUNIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// DO BUTTONS
|
||||
for (i = 0; i < MAXBUTTONS; i++)
|
||||
|
@ -1160,14 +1198,17 @@ int EV_DoDonut(line_t* line)
|
|||
rtn = 0;
|
||||
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
|
||||
{
|
||||
s1 = §ors[secnum];
|
||||
s1 = §ors[secnum]; // s1 is pillar's sector
|
||||
|
||||
// ALREADY MOVING? IF SO, KEEP GOING...
|
||||
if (s1->specialdata)
|
||||
if (P_SectorActive (floor_special, s1)) //jff 2/22/98
|
||||
continue;
|
||||
|
||||
rtn = 1;
|
||||
s2 = getNextSector(s1->lines[0],s1);
|
||||
s2 = getNextSector(s1->lines[0],s1); // s2 is pool's sector
|
||||
if (!s2) // note lowest numbered line around
|
||||
continue; // pillar must be two-sided
|
||||
|
||||
for (i = 0;i < s2->linecount;i++)
|
||||
{
|
||||
if ((!s2->lines[i]->flags & ML_TWOSIDED) ||
|
||||
|
@ -1178,7 +1219,7 @@ int EV_DoDonut(line_t* line)
|
|||
// Spawn rising slime
|
||||
floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
|
||||
P_AddThinker (&floor->thinker);
|
||||
s2->specialdata = floor;
|
||||
s2->floordata = floor; //jff 2/22/98
|
||||
floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;
|
||||
floor->type = donutRaise;
|
||||
floor->crush = false;
|
||||
|
@ -1192,7 +1233,7 @@ int EV_DoDonut(line_t* line)
|
|||
// Spawn lowering donut-hole
|
||||
floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
|
||||
P_AddThinker (&floor->thinker);
|
||||
s1->specialdata = floor;
|
||||
s1->floordata = floor; //jff 2/22/98
|
||||
floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;
|
||||
floor->type = lowerFloor;
|
||||
floor->crush = false;
|
||||
|
@ -1217,11 +1258,7 @@ int EV_DoDonut(line_t* line)
|
|||
// After the map has been loaded, scan for specials
|
||||
// that spawn thinkers
|
||||
//
|
||||
short numlinespecials;
|
||||
line_t* linespeciallist[MAXLINEANIMS];
|
||||
|
||||
|
||||
// Parses command line parameters.
|
||||
void P_SpawnSpecials (void)
|
||||
{
|
||||
sector_t* sector;
|
||||
|
@ -1293,27 +1330,13 @@ void P_SpawnSpecials (void)
|
|||
break;
|
||||
|
||||
case 17:
|
||||
// fire flickering
|
||||
P_SpawnFireFlicker(sector);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Init line EFFECTs
|
||||
numlinespecials = 0;
|
||||
for (i = 0;i < numlines; i++)
|
||||
{
|
||||
switch(lines[i].special)
|
||||
{
|
||||
case 48:
|
||||
// EFFECT FIRSTCOL SCROLL+
|
||||
linespeciallist[numlinespecials] = &lines[i];
|
||||
numlinespecials++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Init other misc stuff
|
||||
if (!activeceilings) {
|
||||
MaxCeilings = 30; // [RH] Default. Increased as needed.
|
||||
|
@ -1334,4 +1357,281 @@ void P_SpawnSpecials (void)
|
|||
|
||||
// UNUSED: no horizonal sliders.
|
||||
// P_InitSlidingDoorFrames();
|
||||
|
||||
P_SpawnScrollers(); // killough 3/7/98: Add generalized scrollers
|
||||
|
||||
for (i=0; i<numlines; i++)
|
||||
switch (lines[i].special)
|
||||
{
|
||||
int s, sec;
|
||||
|
||||
// killough 3/7/98:
|
||||
// support for drawn heights coming from different sector
|
||||
case 242:
|
||||
sec = sides[*lines[i].sidenum].sector-sectors;
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines+i,s)) >= 0;)
|
||||
sectors[s].heightsec = sec;
|
||||
break;
|
||||
|
||||
// killough 3/16/98: Add support for setting
|
||||
// floor lighting independently (e.g. lava)
|
||||
case 213:
|
||||
sec = sides[*lines[i].sidenum].sector-sectors;
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines+i,s)) >= 0;)
|
||||
sectors[s].floorlightsec = sec;
|
||||
break;
|
||||
|
||||
// killough 4/11/98: Add support for setting
|
||||
// ceiling lighting independently
|
||||
case 261:
|
||||
sec = sides[*lines[i].sidenum].sector-sectors;
|
||||
for (s = -1; (s = P_FindSectorFromLineTag(lines+i,s)) >= 0;)
|
||||
sectors[s].ceilinglightsec = sec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// killough 2/28/98:
|
||||
//
|
||||
// This function, with the help of r_plane.c and r_bsp.c, supports generalized
|
||||
// scrolling floors and walls, with optional mobj-carrying properties, e.g.
|
||||
// conveyor belts, rivers, etc. A linedef with a special type affects all
|
||||
// tagged sectors the same way, by creating scrolling and/or object-carrying
|
||||
// properties. Multiple linedefs may be used on the same sector and are
|
||||
// cumulative, although the special case of scrolling a floor and carrying
|
||||
// things on it, requires only one linedef. The linedef's direction determines
|
||||
// the scrolling direction, and the linedef's length determines the scrolling
|
||||
// speed. This was designed so that an edge around the sector could be used to
|
||||
// control the direction of the sector's scrolling, which is usually what is
|
||||
// desired.
|
||||
//
|
||||
// Process the active scrollers.
|
||||
//
|
||||
// This is the main scrolling code
|
||||
// killough 3/7/98
|
||||
|
||||
void T_Scroll(scroll_t *s)
|
||||
{
|
||||
fixed_t dx = s->dx, dy = s->dy;
|
||||
|
||||
if (s->control != -1)
|
||||
{ // compute scroll amounts based on a sector's height changes
|
||||
fixed_t height = sectors[s->control].floorheight +
|
||||
sectors[s->control].ceilingheight;
|
||||
fixed_t delta = height - s->last_height;
|
||||
s->last_height = height;
|
||||
dx = FixedMul(dx, delta);
|
||||
dy = FixedMul(dy, delta);
|
||||
}
|
||||
|
||||
// killough 3/14/98: Add acceleration
|
||||
if (s->accel)
|
||||
{
|
||||
s->vdx = dx += s->vdx;
|
||||
s->vdy = dy += s->vdy;
|
||||
}
|
||||
|
||||
if (!(dx | dy)) // no-op if both (x,y) offsets 0
|
||||
return;
|
||||
|
||||
switch (s->type)
|
||||
{
|
||||
side_t *side;
|
||||
sector_t *sec;
|
||||
fixed_t height, waterheight; // killough 4/4/98: add waterheight
|
||||
msecnode_t *node;
|
||||
mobj_t *thing;
|
||||
|
||||
case sc_side: // killough 3/7/98: Scroll wall texture
|
||||
side = sides + s->affectee;
|
||||
side->textureoffset += dx;
|
||||
side->rowoffset += dy;
|
||||
break;
|
||||
|
||||
case sc_floor: // killough 3/7/98: Scroll floor texture
|
||||
sec = sectors + s->affectee;
|
||||
sec->floor_xoffs += dx;
|
||||
sec->floor_yoffs += dy;
|
||||
break;
|
||||
|
||||
case sc_ceiling: // killough 3/7/98: Scroll ceiling texture
|
||||
sec = sectors + s->affectee;
|
||||
sec->ceiling_xoffs += dx;
|
||||
sec->ceiling_yoffs += dy;
|
||||
break;
|
||||
|
||||
case sc_carry:
|
||||
|
||||
// killough 3/7/98: Carry things on floor
|
||||
// killough 3/20/98: use new sector list which reflects true members
|
||||
// killough 3/27/98: fix carrier bug
|
||||
// killough 4/4/98: Underwater, carry things even w/o gravity
|
||||
|
||||
sec = sectors + s->affectee;
|
||||
height = sec->floorheight;
|
||||
waterheight = sec->heightsec != -1 &&
|
||||
sectors[sec->heightsec].floorheight > height ?
|
||||
sectors[sec->heightsec].floorheight : MININT;
|
||||
|
||||
for (node = sec->touching_thinglist; node; node = node->m_snext)
|
||||
if (!((thing = node->m_thing)->flags & MF_NOCLIP) &&
|
||||
(!(thing->flags & MF_NOGRAVITY || thing->z > height) ||
|
||||
thing->z < waterheight))
|
||||
{
|
||||
// Move objects only if on floor or underwater,
|
||||
// non-floating, and clipped.
|
||||
thing->momx += dx;
|
||||
thing->momy += dy;
|
||||
}
|
||||
break;
|
||||
|
||||
case sc_carry_ceiling: // to be added later
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Add_Scroller()
|
||||
//
|
||||
// Add a generalized scroller to the thinker list.
|
||||
//
|
||||
// type: the enumerated type of scrolling: floor, ceiling, floor carrier,
|
||||
// wall, floor carrier & scroller
|
||||
//
|
||||
// (dx,dy): the direction and speed of the scrolling or its acceleration
|
||||
//
|
||||
// control: the sector whose heights control this scroller's effect
|
||||
// remotely, or -1 if no control sector
|
||||
//
|
||||
// affectee: the index of the affected object (sector or sidedef)
|
||||
//
|
||||
// accel: non-zero if this is an accelerative effect
|
||||
//
|
||||
|
||||
static void Add_Scroller(int type, fixed_t dx, fixed_t dy,
|
||||
int control, int affectee, int accel)
|
||||
{
|
||||
scroll_t *s = Z_Malloc(sizeof *s, PU_LEVSPEC, 0);
|
||||
s->thinker.function.acp1 = (actionf_p1) T_Scroll;
|
||||
s->type = type;
|
||||
s->dx = dx;
|
||||
s->dy = dy;
|
||||
s->accel = accel;
|
||||
s->vdx = s->vdy = 0;
|
||||
if ((s->control = control) != -1)
|
||||
s->last_height =
|
||||
sectors[control].floorheight + sectors[control].ceilingheight;
|
||||
s->affectee = affectee;
|
||||
P_AddThinker(&s->thinker);
|
||||
}
|
||||
|
||||
// Adds wall scroller. Scroll amount is rotated with respect to wall's
|
||||
// linedef first, so that scrolling towards the wall in a perpendicular
|
||||
// direction is translated into vertical motion, while scrolling along
|
||||
// the wall in a parallel direction is translated into horizontal motion.
|
||||
//
|
||||
// killough 5/25/98: cleaned up arithmetic to avoid drift due to roundoff
|
||||
|
||||
static void Add_WallScroller(fixed_t dx, fixed_t dy, const line_t *l,
|
||||
int control, int accel)
|
||||
{
|
||||
fixed_t x = abs(l->dx), y = abs(l->dy), d;
|
||||
if (y > x)
|
||||
d = x, x = y, y = d;
|
||||
d = FixedDiv(x, finesine[(tantoangle[FixedDiv(y,x) >> DBITS] + ANG90)
|
||||
>> ANGLETOFINESHIFT]);
|
||||
x = -FixedDiv(FixedMul(dy, l->dy) + FixedMul(dx, l->dx), d);
|
||||
y = -FixedDiv(FixedMul(dx, l->dy) - FixedMul(dy, l->dx), d);
|
||||
Add_Scroller(sc_side, x, y, control, *l->sidenum, accel);
|
||||
}
|
||||
|
||||
// Amount (dx,dy) vector linedef is shifted right to get scroll amount
|
||||
#define SCROLL_SHIFT 5
|
||||
|
||||
// Factor to scale scrolling effect into mobj-carrying properties = 3/32.
|
||||
// (This is so scrolling floors and objects on them can move at same speed.)
|
||||
#define CARRYFACTOR ((fixed_t)(FRACUNIT*.09375))
|
||||
|
||||
// Initialize the scrollers
|
||||
static void P_SpawnScrollers(void)
|
||||
{
|
||||
int i;
|
||||
line_t *l = lines;
|
||||
|
||||
for (i=0;i<numlines;i++,l++)
|
||||
{
|
||||
fixed_t dx = l->dx >> SCROLL_SHIFT; // direction and speed of scrolling
|
||||
fixed_t dy = l->dy >> SCROLL_SHIFT;
|
||||
int control = -1, accel = 0; // no control sector or acceleration
|
||||
int special = l->special;
|
||||
|
||||
// killough 3/7/98: Types 245-249 are same as 250-254 except that the
|
||||
// first side's sector's heights cause scrolling when they change, and
|
||||
// this linedef controls the direction and speed of the scrolling. The
|
||||
// most complicated linedef since donuts, but powerful :)
|
||||
//
|
||||
// killough 3/15/98: Add acceleration. Types 214-218 are the same but
|
||||
// are accelerative.
|
||||
|
||||
if (special >= 245 && special <= 249) // displacement scrollers
|
||||
{
|
||||
special += 250-245;
|
||||
control = sides[*l->sidenum].sector - sectors;
|
||||
}
|
||||
else
|
||||
if (special >= 214 && special <= 218) // accelerative scrollers
|
||||
{
|
||||
accel = 1;
|
||||
special += 250-214;
|
||||
control = sides[*l->sidenum].sector - sectors;
|
||||
}
|
||||
|
||||
switch (special)
|
||||
{
|
||||
register int s;
|
||||
|
||||
case 250: // scroll effect ceiling
|
||||
for (s=-1; (s = P_FindSectorFromLineTag(l,s)) >= 0;)
|
||||
Add_Scroller(sc_ceiling, -dx, dy, control, s, accel);
|
||||
break;
|
||||
|
||||
case 251: // scroll effect floor
|
||||
case 253: // scroll and carry objects on floor
|
||||
for (s=-1; (s = P_FindSectorFromLineTag(l,s)) >= 0;)
|
||||
Add_Scroller(sc_floor, -dx, dy, control, s, accel);
|
||||
if (special != 253)
|
||||
break;
|
||||
|
||||
case 252: // carry objects on floor
|
||||
dx = FixedMul(dx,CARRYFACTOR);
|
||||
dy = FixedMul(dy,CARRYFACTOR);
|
||||
for (s=-1; (s = P_FindSectorFromLineTag(l,s)) >= 0;)
|
||||
Add_Scroller(sc_carry, dx, dy, control, s, accel);
|
||||
break;
|
||||
|
||||
// killough 3/1/98: scroll wall according to linedef
|
||||
// (same direction and speed as scrolling floors)
|
||||
case 254:
|
||||
for (s=-1; (s = P_FindLineFromLineTag(l,s)) >= 0;)
|
||||
if (s != i)
|
||||
Add_WallScroller(dx, dy, lines+s, control, accel);
|
||||
break;
|
||||
|
||||
case 255: // killough 3/2/98: scroll according to sidedef offsets
|
||||
s = lines[i].sidenum[0];
|
||||
Add_Scroller(sc_side, -sides[s].textureoffset,
|
||||
sides[s].rowoffset, -1, s, accel);
|
||||
break;
|
||||
|
||||
case 48: // scroll first side
|
||||
Add_Scroller(sc_side, FRACUNIT, 0, -1, lines[i].sidenum[0], accel);
|
||||
break;
|
||||
|
||||
case 85: // jff 1/30/98 2-way scroll
|
||||
Add_Scroller(sc_side, -FRACUNIT, 0, -1, lines[i].sidenum[0], accel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// killough 3/7/98 -- end generalized scroll effects
|
||||
|
|
104
code/P_spec.h
104
code/P_spec.h
|
@ -27,6 +27,36 @@
|
|||
#define __P_SPEC__
|
||||
|
||||
|
||||
//jff 2/23/98 identify the special classes that can share sectors
|
||||
|
||||
typedef enum
|
||||
{
|
||||
floor_special,
|
||||
ceiling_special,
|
||||
lighting_special,
|
||||
} special_e;
|
||||
|
||||
// killough 3/7/98: Add generalized scroll effects
|
||||
|
||||
typedef struct {
|
||||
thinker_t thinker; // Thinker structure for scrolling
|
||||
fixed_t dx, dy; // (dx,dy) scroll speeds
|
||||
int affectee; // Number of affected sidedef, sector, tag, or whatever
|
||||
int control; // Control sector (-1 if none) used to control scrolling
|
||||
fixed_t last_height; // Last known height of control sector
|
||||
fixed_t vdx, vdy; // Accumulated velocity if accelerative
|
||||
int accel; // Whether it's accelerative
|
||||
enum
|
||||
{
|
||||
sc_side,
|
||||
sc_floor,
|
||||
sc_ceiling,
|
||||
sc_carry,
|
||||
sc_carry_ceiling, // killough 4/11/98: carry objects hanging on ceilings
|
||||
} type; // Type of scroll effect
|
||||
} scroll_t;
|
||||
|
||||
|
||||
// Define values for map objects
|
||||
#define MO_TELEPORTMAN 14
|
||||
|
||||
|
@ -64,6 +94,7 @@ fixed_t P_FindLowestFloorSurrounding (sector_t *sec);
|
|||
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);
|
||||
|
@ -75,6 +106,9 @@ int P_FindMinSurroundingLight (sector_t *sector, int max);
|
|||
sector_t *getNextSector (line_t *line, sector_t *sec);
|
||||
|
||||
|
||||
void T_Scroll (scroll_t *); // killough 3/7/98: scroll effect thinker
|
||||
|
||||
|
||||
//
|
||||
// SPECIAL
|
||||
//
|
||||
|
@ -191,11 +225,8 @@ typedef struct
|
|||
|
||||
|
||||
|
||||
// max # of wall switches in a level
|
||||
#define MAXSWITCHES 50
|
||||
|
||||
// 4 players, 4 buttons each at once, max.
|
||||
#define MAXBUTTONS 16
|
||||
#define MAXBUTTONS (MAXPLAYERS*4)
|
||||
|
||||
// 1 second, in ticks.
|
||||
#define BUTTONTIME TICRATE
|
||||
|
@ -463,42 +494,24 @@ void P_ActivateInStasisCeiling(line_t *line);
|
|||
//
|
||||
typedef enum
|
||||
{
|
||||
// lower floor to highest surrounding floor
|
||||
lowerFloor,
|
||||
|
||||
// lower floor to lowest surrounding floor
|
||||
lowerFloorToLowest,
|
||||
|
||||
// lower floor to highest surrounding floor VERY FAST
|
||||
turboLower,
|
||||
|
||||
// raise floor to lowest surrounding CEILING
|
||||
raiseFloor,
|
||||
|
||||
// raise floor to next highest surrounding floor
|
||||
raiseFloorToNearest,
|
||||
|
||||
// raise floor to shortest height texture around it
|
||||
raiseToTexture,
|
||||
|
||||
// lower floor to lowest surrounding floor
|
||||
// and change floorpic
|
||||
lowerAndChange,
|
||||
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
|
||||
|
||||
raiseFloor24,
|
||||
raiseFloor24AndChange,
|
||||
raiseFloorCrush,
|
||||
|
||||
// raise to next highest floor, turbo-speed
|
||||
raiseFloorTurbo,
|
||||
raiseFloorTurbo, // raise to next highest floor, turbo-speed
|
||||
donutRaise,
|
||||
raiseFloor512
|
||||
|
||||
} floor_e;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
build8, // slowly build by 8
|
||||
|
@ -506,7 +519,12 @@ typedef enum
|
|||
|
||||
} stair_e;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
elevateUp,
|
||||
elevateDown,
|
||||
elevateCurrent,
|
||||
} elevator_e;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -522,8 +540,19 @@ typedef struct
|
|||
|
||||
} floormove_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
elevator_e type;
|
||||
sector_t* sector;
|
||||
int direction;
|
||||
fixed_t floordestheight;
|
||||
fixed_t ceilingdestheight;
|
||||
fixed_t speed;
|
||||
} elevator_t;
|
||||
|
||||
|
||||
#define ELEVATORSPEED (FRACUNIT*4)
|
||||
#define FLOORSPEED FRACUNIT
|
||||
|
||||
typedef enum
|
||||
|
@ -537,20 +566,23 @@ typedef enum
|
|||
result_e T_MovePlane (sector_t *sector, fixed_t speed, fixed_t dest,
|
||||
BOOL crush, int floorOrCeiling, int direction);
|
||||
|
||||
int EV_DoElevator (line_t *line, ceiling_e type);
|
||||
|
||||
int EV_BuildStairs (line_t *line, stair_e type);
|
||||
|
||||
int EV_DoFloor (line_t *line, floor_e floortype);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
int P_SectorActive (special_e t, sector_t *s); // [RH] from BOOM
|
||||
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// $Log:$
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
109
code/P_switch.c
109
code/P_switch.c
|
@ -39,75 +39,42 @@
|
|||
#include "doomstat.h"
|
||||
#include "r_state.h"
|
||||
|
||||
#include "z_zone.h"
|
||||
#include "w_wad.h"
|
||||
|
||||
//
|
||||
// CHANGE THE TEXTURE OF A WALL SWITCH TO ITS OPPOSITE
|
||||
//
|
||||
switchlist_t alphSwitchList[] =
|
||||
{
|
||||
// Doom shareware episode 1 switches
|
||||
{"SW1BRCOM", "SW2BRCOM", 1},
|
||||
{"SW1BRN1", "SW2BRN1", 1},
|
||||
{"SW1BRN2", "SW2BRN2", 1},
|
||||
{"SW1BRNGN", "SW2BRNGN", 1},
|
||||
{"SW1BROWN", "SW2BROWN", 1},
|
||||
{"SW1COMM", "SW2COMM", 1},
|
||||
{"SW1COMP", "SW2COMP", 1},
|
||||
{"SW1DIRT", "SW2DIRT", 1},
|
||||
{"SW1EXIT", "SW2EXIT", 1},
|
||||
{"SW1GRAY", "SW2GRAY", 1},
|
||||
{"SW1GRAY1", "SW2GRAY1", 1},
|
||||
{"SW1METAL", "SW2METAL", 1},
|
||||
{"SW1PIPE", "SW2PIPE", 1},
|
||||
{"SW1SLAD", "SW2SLAD", 1},
|
||||
{"SW1STARG", "SW2STARG", 1},
|
||||
{"SW1STON1", "SW2STON1", 1},
|
||||
{"SW1STON2", "SW2STON2", 1},
|
||||
{"SW1STONE", "SW2STONE", 1},
|
||||
{"SW1STRTN", "SW2STRTN", 1},
|
||||
|
||||
// Doom registered episodes 2&3 switches
|
||||
{"SW1BLUE", "SW2BLUE", 2},
|
||||
{"SW1CMT", "SW2CMT", 2},
|
||||
{"SW1GARG", "SW2GARG", 2},
|
||||
{"SW1GSTON", "SW2GSTON", 2},
|
||||
{"SW1HOT", "SW2HOT", 2},
|
||||
{"SW1LION", "SW2LION", 2},
|
||||
{"SW1SATYR", "SW2SATYR", 2},
|
||||
{"SW1SKIN", "SW2SKIN", 2},
|
||||
{"SW1VINE", "SW2VINE", 2},
|
||||
{"SW1WOOD", "SW2WOOD", 2},
|
||||
static int *switchlist;
|
||||
static int numswitches;
|
||||
|
||||
// Doom II switches
|
||||
{"SW1PANEL", "SW2PANEL", 3},
|
||||
{"SW1ROCK", "SW2ROCK", 3},
|
||||
{"SW1MET2", "SW2MET2", 3},
|
||||
{"SW1WDMET", "SW2WDMET", 3},
|
||||
{"SW1BRIK", "SW2BRIK", 3},
|
||||
{"SW1MOD1", "SW2MOD1", 3},
|
||||
{"SW1ZIM", "SW2ZIM", 3},
|
||||
{"SW1STON6", "SW2STON6", 3},
|
||||
{"SW1TEK", "SW2TEK", 3},
|
||||
{"SW1MARB", "SW2MARB", 3},
|
||||
{"SW1SKULL", "SW2SKULL", 3},
|
||||
|
||||
{"\0", "\0", 0}
|
||||
};
|
||||
|
||||
int switchlist[MAXSWITCHES * 2];
|
||||
int numswitches;
|
||||
button_t buttonlist[MAXBUTTONS];
|
||||
|
||||
//
|
||||
// P_InitSwitchList
|
||||
// Only called at game initialization.
|
||||
//
|
||||
// [RH] Rewritten to use a BOOM-style SWITCHES lump and remove the
|
||||
// MAXSWITCHES limit.
|
||||
void P_InitSwitchList(void)
|
||||
{
|
||||
byte *alphSwitchList = W_CacheLumpName ("SWITCHES", PU_STATIC);
|
||||
byte *list_p;
|
||||
|
||||
int i;
|
||||
int index;
|
||||
int episode;
|
||||
|
||||
for (i = 0, list_p = alphSwitchList; list_p[18] || list_p[19]; list_p += 20, i++)
|
||||
;
|
||||
|
||||
if (i == 0) {
|
||||
switchlist = Z_Malloc (sizeof(*switchlist), PU_STATIC, 0);
|
||||
*switchlist = -1;
|
||||
numswitches = 0;
|
||||
} else {
|
||||
switchlist = Z_Malloc (sizeof(*switchlist)*(i*2+1), PU_STATIC, 0);
|
||||
|
||||
if (gamemode == registered || gamemode == retail)
|
||||
episode = 2;
|
||||
else if ( gamemode == commercial )
|
||||
|
@ -115,38 +82,22 @@ void P_InitSwitchList(void)
|
|||
else
|
||||
episode = 1;
|
||||
|
||||
for (index = 0,i = 0;i < MAXSWITCHES;i++)
|
||||
for (i = 0, list_p = alphSwitchList; list_p[18] || list_p[19]; list_p += 20) {
|
||||
if (episode >= (list_p[18] | (list_p[19] << 8)))
|
||||
{
|
||||
if (!alphSwitchList[i].episode)
|
||||
{
|
||||
numswitches = index/2;
|
||||
switchlist[index] = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (alphSwitchList[i].episode <= episode)
|
||||
{
|
||||
#if 0 // UNUSED - debug?
|
||||
int value;
|
||||
|
||||
if (R_CheckTextureNumForName(alphSwitchList[i].name1) < 0)
|
||||
{
|
||||
I_Error("Can't find switch texture '%s'!",
|
||||
alphSwitchList[i].name1);
|
||||
continue;
|
||||
}
|
||||
|
||||
value = R_TextureNumForName(alphSwitchList[i].name1);
|
||||
#endif
|
||||
// [RH] Skip this switch if it can't be found (since I want to see
|
||||
// how well ZDoom will run with heretic.wad :-)
|
||||
if (R_CheckTextureNumForName (alphSwitchList[i].name1) < 0)
|
||||
// [RH] Skip this switch if it can't be found.
|
||||
if (R_CheckTextureNumForName (list_p /* .name1 */) < 0)
|
||||
continue;
|
||||
|
||||
switchlist[index++] = R_TextureNumForName(alphSwitchList[i].name1);
|
||||
switchlist[index++] = R_TextureNumForName(alphSwitchList[i].name2);
|
||||
switchlist[i++] = R_TextureNumForName(list_p /* .name1 */);
|
||||
switchlist[i++] = R_TextureNumForName(list_p + 9 /* .name2 */);
|
||||
}
|
||||
}
|
||||
numswitches = i/2;
|
||||
switchlist[i] = -1;
|
||||
}
|
||||
|
||||
Z_Free (alphSwitchList);
|
||||
}
|
||||
|
||||
|
||||
|
|
316
code/R_bsp.c
316
code/R_bsp.c
|
@ -49,15 +49,15 @@ line_t* linedef;
|
|||
sector_t* frontsector;
|
||||
sector_t* backsector;
|
||||
|
||||
// killough 4/7/98: indicates doors closed wrt automap bugfix:
|
||||
int doorclosed;
|
||||
|
||||
int MaxDrawSegs;
|
||||
drawseg_t *drawsegs;
|
||||
drawseg_t* ds_p;
|
||||
|
||||
|
||||
void
|
||||
R_StoreWallRange
|
||||
( int start,
|
||||
int stop );
|
||||
void R_StoreWallRange (int start, int stop);
|
||||
|
||||
|
||||
|
||||
|
@ -81,11 +81,13 @@ void R_ClearDrawSegs (void)
|
|||
// Clips the given range of columns
|
||||
// and includes it in the new clip list.
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
int first;
|
||||
int last;
|
||||
//
|
||||
// 1/11/98 killough: Since a type "short" is sufficient, we
|
||||
// should use it, since smaller arrays fit better in cache.
|
||||
//
|
||||
|
||||
typedef struct {
|
||||
short first, last; // killough
|
||||
} cliprange_t;
|
||||
|
||||
|
||||
|
@ -104,13 +106,9 @@ cliprange_t *lastsolidseg;
|
|||
// e.g. single sided LineDefs (middle texture)
|
||||
// that entirely block the view.
|
||||
//
|
||||
void
|
||||
R_ClipSolidWallSegment
|
||||
( int first,
|
||||
int last )
|
||||
void R_ClipSolidWallSegment (int first, int last)
|
||||
{
|
||||
cliprange_t* next;
|
||||
cliprange_t* start;
|
||||
cliprange_t *next, *start;
|
||||
|
||||
// Find the first range that touches the range
|
||||
// (adjacent pixels are touching).
|
||||
|
@ -122,35 +120,19 @@ R_ClipSolidWallSegment
|
|||
{
|
||||
if (last < start->first-1)
|
||||
{
|
||||
// Post is entirely visible (above start),
|
||||
// so insert a new clippost.
|
||||
// Post is entirely visible (above start), so insert a new clippost.
|
||||
R_StoreWallRange (first, last);
|
||||
// [RH] Get more solidsegs if needed.
|
||||
if (newend == lastsolidseg) {
|
||||
int i = start - solidsegs;
|
||||
|
||||
MaxSegs += 8;
|
||||
solidsegs = Realloc (solidsegs, MaxSegs * sizeof(cliprange_t));
|
||||
newend = &solidsegs[MaxSegs - 8];
|
||||
start = &solidsegs[i];
|
||||
lastsolidseg = &solidsegs[MaxSegs];
|
||||
DPrintf ("MaxSegs increased to %d\n", MaxSegs);
|
||||
}
|
||||
next = newend;
|
||||
newend++;
|
||||
|
||||
while (next != start)
|
||||
{
|
||||
*next = *(next-1);
|
||||
next--;
|
||||
}
|
||||
next->first = first;
|
||||
next->last = last;
|
||||
// 1/11/98 killough: performance tuning using fast memmove
|
||||
memmove(start+1,start,(++newend-start)*sizeof(*start));
|
||||
start->first = first;
|
||||
start->last = last;
|
||||
return;
|
||||
}
|
||||
|
||||
// There is a fragment above *start.
|
||||
R_StoreWallRange (first, start->first - 1);
|
||||
|
||||
// Now adjust the clip size.
|
||||
start->first = first;
|
||||
}
|
||||
|
@ -168,8 +150,7 @@ R_ClipSolidWallSegment
|
|||
|
||||
if (last <= next->last)
|
||||
{
|
||||
// Bottom is contained in next.
|
||||
// Adjust the clip size.
|
||||
// Bottom is contained in next. Adjust the clip size.
|
||||
start->last = next->last;
|
||||
goto crunch;
|
||||
}
|
||||
|
@ -208,12 +189,9 @@ R_ClipSolidWallSegment
|
|||
// Does handle windows,
|
||||
// e.g. LineDefs with upper and lower texture.
|
||||
//
|
||||
void
|
||||
R_ClipPassWallSegment
|
||||
( int first,
|
||||
int last )
|
||||
void R_ClipPassWallSegment (int first, int last)
|
||||
{
|
||||
cliprange_t* start;
|
||||
cliprange_t *start;
|
||||
|
||||
// Find the first range that touches the range
|
||||
// (adjacent pixels are touching).
|
||||
|
@ -264,13 +242,144 @@ void R_ClearClipSegs (void)
|
|||
solidsegs = Malloc (MaxSegs * sizeof(cliprange_t));
|
||||
lastsolidseg = &solidsegs[MaxSegs];
|
||||
}
|
||||
solidsegs[0].first = -0x7fffffff;
|
||||
solidsegs[0].first = -0x7fff; // new short limit -- killough
|
||||
solidsegs[0].last = -1;
|
||||
solidsegs[1].first = viewwidth;
|
||||
solidsegs[1].last = 0x7fffffff;
|
||||
solidsegs[1].last = 0x7fff; // new short limit -- killough
|
||||
newend = solidsegs+2;
|
||||
}
|
||||
|
||||
// killough 1/18/98 -- This function is used to fix the automap bug which
|
||||
// showed lines behind closed doors simply because the door had a dropoff.
|
||||
//
|
||||
// It assumes that Doom has already ruled out a door being closed because
|
||||
// of front-back closure (e.g. front floor is taller than back ceiling).
|
||||
|
||||
int R_DoorClosed(void)
|
||||
{
|
||||
return
|
||||
|
||||
// if door is closed because back is shut:
|
||||
backsector->ceilingheight <= backsector->floorheight
|
||||
|
||||
// preserve a kind of transparent door/lift special effect:
|
||||
&& (backsector->ceilingheight >= frontsector->ceilingheight ||
|
||||
curline->sidedef->toptexture)
|
||||
|
||||
&& (backsector->floorheight <= frontsector->floorheight ||
|
||||
curline->sidedef->bottomtexture)
|
||||
|
||||
// properly render skies (consider door "open" if both ceilings are sky):
|
||||
&& (backsector->ceilingpic !=skyflatnum ||
|
||||
frontsector->ceilingpic!=skyflatnum);
|
||||
}
|
||||
|
||||
//
|
||||
// killough 3/7/98: Hack floor/ceiling heights for deep water etc.
|
||||
//
|
||||
// If player's view height is underneath fake floor, lower the
|
||||
// drawn ceiling to be just under the floor height, and replace
|
||||
// the drawn floor and ceiling textures, and light level, with
|
||||
// the control sector's.
|
||||
//
|
||||
// Similar for ceiling, only reflected.
|
||||
//
|
||||
// killough 4/11/98, 4/13/98: fix bugs, add 'back' parameter
|
||||
//
|
||||
|
||||
sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec,
|
||||
int *floorlightlevel, int *ceilinglightlevel,
|
||||
BOOL back)
|
||||
{
|
||||
if (floorlightlevel)
|
||||
*floorlightlevel = sec->floorlightsec == -1 ?
|
||||
sec->lightlevel : sectors[sec->floorlightsec].lightlevel;
|
||||
|
||||
if (ceilinglightlevel)
|
||||
*ceilinglightlevel = sec->ceilinglightsec == -1 ? // killough 4/11/98
|
||||
sec->lightlevel : sectors[sec->ceilinglightsec].lightlevel;
|
||||
|
||||
if (sec->heightsec != -1)
|
||||
{
|
||||
const sector_t *s = §ors[sec->heightsec];
|
||||
int heightsec = viewplayer->mo->subsector->sector->heightsec;
|
||||
int underwater = heightsec!=-1 && viewz<=sectors[heightsec].floorheight;
|
||||
|
||||
// Replace sector being drawn, with a copy to be hacked
|
||||
*tempsec = *sec;
|
||||
|
||||
// Replace floor and ceiling height with other sector's heights.
|
||||
tempsec->floorheight = s->floorheight;
|
||||
tempsec->ceilingheight = s->ceilingheight;
|
||||
|
||||
if ((underwater && (tempsec-> floorheight = sec->floorheight,
|
||||
tempsec->ceilingheight = s->floorheight-1,
|
||||
!back)) || viewz <= s->floorheight)
|
||||
{ // head-below-floor hack
|
||||
tempsec->floorpic = s->floorpic;
|
||||
tempsec->floor_xoffs = s->floor_xoffs;
|
||||
tempsec->floor_yoffs = s->floor_yoffs;
|
||||
|
||||
if (underwater)
|
||||
if (s->ceilingpic == skyflatnum)
|
||||
{
|
||||
tempsec->floorheight = tempsec->ceilingheight+1;
|
||||
tempsec->ceilingpic = tempsec->floorpic;
|
||||
tempsec->ceiling_xoffs = tempsec->floor_xoffs;
|
||||
tempsec->ceiling_yoffs = tempsec->floor_yoffs;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempsec->ceilingpic = s->ceilingpic;
|
||||
tempsec->ceiling_xoffs = s->ceiling_xoffs;
|
||||
tempsec->ceiling_yoffs = s->ceiling_yoffs;
|
||||
}
|
||||
|
||||
tempsec->lightlevel = s->lightlevel;
|
||||
|
||||
if (floorlightlevel)
|
||||
*floorlightlevel = s->floorlightsec == -1 ? s->lightlevel :
|
||||
sectors[s->floorlightsec].lightlevel; // killough 3/16/98
|
||||
|
||||
if (ceilinglightlevel)
|
||||
*ceilinglightlevel = s->ceilinglightsec == -1 ? s->lightlevel :
|
||||
sectors[s->ceilinglightsec].lightlevel; // killough 4/11/98
|
||||
}
|
||||
else
|
||||
if (heightsec != -1 && viewz >= sectors[heightsec].ceilingheight &&
|
||||
sec->ceilingheight > s->ceilingheight)
|
||||
{ // Above-ceiling hack
|
||||
tempsec->ceilingheight = s->ceilingheight;
|
||||
tempsec->floorheight = s->ceilingheight + 1;
|
||||
|
||||
tempsec->floorpic = tempsec->ceilingpic = s->ceilingpic;
|
||||
tempsec->floor_xoffs = tempsec->ceiling_xoffs = s->ceiling_xoffs;
|
||||
tempsec->floor_yoffs = tempsec->ceiling_yoffs = s->ceiling_yoffs;
|
||||
|
||||
if (s->floorpic != skyflatnum)
|
||||
{
|
||||
tempsec->ceilingheight = sec->ceilingheight;
|
||||
tempsec->floorpic = s->floorpic;
|
||||
tempsec->floor_xoffs = s->floor_xoffs;
|
||||
tempsec->floor_yoffs = s->floor_yoffs;
|
||||
}
|
||||
|
||||
tempsec->lightlevel = s->lightlevel;
|
||||
|
||||
if (floorlightlevel)
|
||||
*floorlightlevel = s->floorlightsec == -1 ? s->lightlevel :
|
||||
sectors[s->floorlightsec].lightlevel; // killough 3/16/98
|
||||
|
||||
if (ceilinglightlevel)
|
||||
*ceilinglightlevel = s->ceilinglightsec == -1 ? s->lightlevel :
|
||||
sectors[s->ceilinglightsec].lightlevel; // killough 4/11/98
|
||||
}
|
||||
sec = tempsec; // Use other sector
|
||||
}
|
||||
return sec;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// R_AddLine
|
||||
// Clips the given segment
|
||||
|
@ -284,6 +393,7 @@ void R_AddLine (seg_t* line)
|
|||
angle_t angle2;
|
||||
angle_t span;
|
||||
angle_t tspan;
|
||||
static sector_t tempsec; // killough 3/8/98: ceiling/water hack
|
||||
|
||||
curline = line;
|
||||
|
||||
|
@ -330,11 +440,13 @@ void R_AddLine (seg_t* line)
|
|||
// but not necessarily visible.
|
||||
angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT;
|
||||
angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT;
|
||||
|
||||
// killough 1/31/98: Here is where "slime trails" can SOMETIMES occur:
|
||||
x1 = viewangletox[angle1];
|
||||
x2 = viewangletox[angle2];
|
||||
|
||||
// Does not cross a pixel?
|
||||
if (x1 == x2)
|
||||
if (x1 >= x2) // killough 1/31/98 -- change == to >= for robustness
|
||||
return;
|
||||
|
||||
backsector = line->backsector;
|
||||
|
@ -343,11 +455,21 @@ void R_AddLine (seg_t* line)
|
|||
if (!backsector)
|
||||
goto clipsolid;
|
||||
|
||||
// killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water
|
||||
backsector = R_FakeFlat (backsector, &tempsec, NULL, NULL, true);
|
||||
|
||||
doorclosed = 0; // killough 4/16/98
|
||||
|
||||
// Closed door.
|
||||
if (backsector->ceilingheight <= frontsector->floorheight
|
||||
|| backsector->floorheight >= frontsector->ceilingheight)
|
||||
goto clipsolid;
|
||||
|
||||
// This fixes the automap floor height bug -- killough 1/18/98:
|
||||
// killough 4/7/98: optimize: save result in doorclosed for use in r_segs.c
|
||||
if ((doorclosed = R_DoorClosed()))
|
||||
goto clipsolid;
|
||||
|
||||
// Window.
|
||||
if (backsector->ceilingheight != frontsector->ceilingheight
|
||||
|| backsector->floorheight != frontsector->floorheight)
|
||||
|
@ -361,7 +483,18 @@ void R_AddLine (seg_t* line)
|
|||
if (backsector->ceilingpic == frontsector->ceilingpic
|
||||
&& backsector->floorpic == frontsector->floorpic
|
||||
&& backsector->lightlevel == frontsector->lightlevel
|
||||
&& curline->sidedef->midtexture == 0)
|
||||
&& curline->sidedef->midtexture == 0
|
||||
|
||||
// killough 3/7/98: Take flats offsets into account:
|
||||
&& backsector->floor_xoffs == frontsector->floor_xoffs
|
||||
&& backsector->floor_yoffs == frontsector->floor_yoffs
|
||||
&& backsector->ceiling_xoffs == frontsector->ceiling_xoffs
|
||||
&& backsector->ceiling_yoffs == frontsector->ceiling_yoffs
|
||||
|
||||
// killough 4/16/98: consider altered lighting
|
||||
&& backsector->floorlightsec == frontsector->floorlightsec
|
||||
&& backsector->ceilinglightsec == frontsector->ceilinglightsec
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -382,7 +515,7 @@ void R_AddLine (seg_t* line)
|
|||
// Returns true
|
||||
// if some part of the bbox might be visible.
|
||||
//
|
||||
int checkcoord[12][4] =
|
||||
static const int checkcoord[12][4] = // killough -- static const
|
||||
{
|
||||
{3,0,2,1},
|
||||
{3,0,2,0},
|
||||
|
@ -398,7 +531,7 @@ int checkcoord[12][4] =
|
|||
};
|
||||
|
||||
|
||||
BOOL R_CheckBBox (fixed_t* bspcoord)
|
||||
static BOOL R_CheckBBox (fixed_t *bspcoord) // killough 1/28/98: static
|
||||
{
|
||||
int boxx;
|
||||
int boxy;
|
||||
|
@ -518,39 +651,48 @@ void R_Subsector (int num)
|
|||
{
|
||||
int count;
|
||||
seg_t* line;
|
||||
subsector_t* sub;
|
||||
subsector_t *sub;
|
||||
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);
|
||||
I_Error ("R_Subsector: ss %i with numss = %i", num, numsubsectors);
|
||||
#endif
|
||||
|
||||
sscount++;
|
||||
sub = &subsectors[num];
|
||||
frontsector = sub->sector;
|
||||
count = sub->numlines;
|
||||
line = &segs[sub->firstline];
|
||||
|
||||
if (frontsector->floorheight < viewz)
|
||||
{
|
||||
floorplane = R_FindPlane (frontsector->floorheight,
|
||||
frontsector->floorpic,
|
||||
frontsector->lightlevel);
|
||||
}
|
||||
else
|
||||
floorplane = NULL;
|
||||
// killough 3/8/98, 4/4/98: Deep water / fake ceiling effect
|
||||
frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel,
|
||||
&ceilinglightlevel, false); // killough 4/11/98
|
||||
|
||||
if (frontsector->ceilingheight > viewz
|
||||
|| frontsector->ceilingpic == skyflatnum)
|
||||
{
|
||||
ceilingplane = R_FindPlane (frontsector->ceilingheight,
|
||||
// killough 3/7/98: Add (x,y) offsets to flats, add deep water check
|
||||
// killough 3/16/98: add floorlightlevel
|
||||
|
||||
floorplane = frontsector->floorheight < viewz || // killough 3/7/98
|
||||
(frontsector->heightsec != -1 &&
|
||||
sectors[frontsector->heightsec].ceilingpic == skyflatnum) ?
|
||||
R_FindPlane(frontsector->floorheight,
|
||||
frontsector->floorpic,
|
||||
floorlightlevel, // killough 3/16/98
|
||||
frontsector->floor_xoffs, // killough 3/7/98
|
||||
frontsector->floor_yoffs
|
||||
) : NULL;
|
||||
|
||||
ceilingplane = frontsector->ceilingheight > viewz ||
|
||||
frontsector->ceilingpic == skyflatnum ||
|
||||
(frontsector->heightsec != -1 &&
|
||||
sectors[frontsector->heightsec].floorpic == skyflatnum) ?
|
||||
R_FindPlane(frontsector->ceilingheight, // killough 3/8/98
|
||||
frontsector->ceilingpic,
|
||||
frontsector->lightlevel);
|
||||
}
|
||||
else
|
||||
ceilingplane = NULL;
|
||||
ceilinglightlevel, // killough 4/11/98
|
||||
frontsector->ceiling_xoffs, // killough 3/7/98
|
||||
frontsector->ceiling_yoffs
|
||||
) : NULL;
|
||||
|
||||
R_AddSprites (frontsector);
|
||||
|
||||
|
@ -569,32 +711,26 @@ void R_Subsector (int num)
|
|||
// Renders all subsectors below a given node,
|
||||
// traversing subtree recursively.
|
||||
// Just call with BSP root.
|
||||
void R_RenderBSPNode (int bspnum)
|
||||
// killough 5/2/98: reformatted, removed tail recursion
|
||||
|
||||
void R_RenderBSPNode(int bspnum)
|
||||
{
|
||||
node_t* bsp;
|
||||
int side;
|
||||
|
||||
// Found a subsector?
|
||||
if (bspnum & NF_SUBSECTOR)
|
||||
while (!(bspnum & NF_SUBSECTOR)) // Found a subsector?
|
||||
{
|
||||
if (bspnum == -1)
|
||||
R_Subsector (0);
|
||||
else
|
||||
R_Subsector (bspnum&(~NF_SUBSECTOR));
|
||||
return;
|
||||
}
|
||||
|
||||
bsp = &nodes[bspnum];
|
||||
node_t *bsp = &nodes[bspnum];
|
||||
|
||||
// Decide which side the view point is on.
|
||||
side = R_PointOnSide (viewx, viewy, bsp);
|
||||
int side = R_PointOnSide(viewx, viewy, bsp);
|
||||
|
||||
// Recursively divide front space.
|
||||
R_RenderBSPNode (bsp->children[side]);
|
||||
R_RenderBSPNode(bsp->children[side]);
|
||||
|
||||
// Possibly divide back space.
|
||||
if (R_CheckBBox (bsp->bbox[side^1]))
|
||||
R_RenderBSPNode (bsp->children[side^1]);
|
||||
|
||||
if (!R_CheckBBox(bsp->bbox[side^1]))
|
||||
return;
|
||||
|
||||
bspnum = bsp->children[side^1];
|
||||
}
|
||||
R_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR);
|
||||
}
|
||||
|
||||
|
||||
|
|
10
code/R_bsp.h
10
code/R_bsp.h
|
@ -44,10 +44,6 @@ extern BOOL skymap;
|
|||
extern drawseg_t *drawsegs;
|
||||
extern drawseg_t* ds_p;
|
||||
|
||||
extern lighttable_t** hscalelight;
|
||||
extern lighttable_t** vscalelight;
|
||||
extern lighttable_t** dscalelight;
|
||||
|
||||
|
||||
typedef void (*drawfunc_t) (int start, int stop);
|
||||
|
||||
|
@ -55,9 +51,11 @@ typedef void (*drawfunc_t) (int start, int stop);
|
|||
// BSP?
|
||||
void R_ClearClipSegs (void);
|
||||
void R_ClearDrawSegs (void);
|
||||
|
||||
|
||||
void R_RenderBSPNode (int bspnum);
|
||||
int R_DoorClosed(void); // killough 1/17/98
|
||||
|
||||
// killough 4/13/98: fake floors/ceilings for deep water / fake ceilings:
|
||||
sector_t *R_FakeFlat(sector_t *, sector_t *, int *, int *, BOOL);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
278
code/R_data.c
278
code/R_data.c
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "i_system.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_alloc.h"
|
||||
|
||||
#include "m_swap.h"
|
||||
|
||||
|
@ -84,7 +85,7 @@ typedef struct
|
|||
BOOL masked;
|
||||
short width;
|
||||
short height;
|
||||
void **columndirectory; // OBSOLETE
|
||||
byte pad[4]; // OBSOLETE (was short **columndirectory)
|
||||
short patchcount;
|
||||
mappatch_t patches[1];
|
||||
} maptexture_t;
|
||||
|
@ -146,7 +147,7 @@ static byte* textureheightmask; // [RH] Tutti-Frutti fix
|
|||
fixed_t* textureheight; // needed for texture pegging
|
||||
static int* texturecompositesize;
|
||||
static short** texturecolumnlump;
|
||||
static unsigned short**texturecolumnofs;
|
||||
static unsigned **texturecolumnofs; // killough 4/9/98: make 32-bit
|
||||
static byte** texturecomposite;
|
||||
|
||||
// for global animation
|
||||
|
@ -175,12 +176,11 @@ fixed_t* spritetopoffset;
|
|||
|
||||
|
||||
|
||||
// Rewritten by Lee Killough for performance and to fix Medusa bug
|
||||
//
|
||||
// R_DrawColumnInCache
|
||||
// Clip and draw a column
|
||||
// from a patch into a cached post.
|
||||
//
|
||||
void R_DrawColumnInCache (column_t *patch, byte *cache, int originy, int cacheheight)
|
||||
|
||||
void R_DrawColumnInCache (const column_t *patch, byte *cache,
|
||||
int originy, int cacheheight, byte *marks)
|
||||
{
|
||||
while (patch->topdelta != 0xff)
|
||||
{
|
||||
|
@ -197,151 +197,192 @@ void R_DrawColumnInCache (column_t *patch, byte *cache, int originy, int cachehe
|
|||
count = cacheheight - position;
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
memcpy (cache + position, (byte *)patch + 3, count);
|
||||
|
||||
patch = (column_t *)( (byte *)patch + patch->length + 4);
|
||||
// killough 4/9/98: remember which cells in column have been drawn,
|
||||
// so that column can later be converted into a series of posts, to
|
||||
// fix the Medusa bug.
|
||||
|
||||
memset (marks + position, 0xff, count);
|
||||
}
|
||||
|
||||
patch = (column_t *)((byte *) patch + patch->length + 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// R_GenerateComposite
|
||||
// Using the texture definition,
|
||||
// the composite texture is created from the patches,
|
||||
// and each column is cached.
|
||||
//
|
||||
// Rewritten by Lee Killough for performance and to fix Medusa bug
|
||||
|
||||
void R_GenerateComposite (int texnum)
|
||||
{
|
||||
byte* block;
|
||||
texture_t* texture;
|
||||
texpatch_t* patch;
|
||||
int i;
|
||||
column_t* patchcol;
|
||||
short* collump;
|
||||
unsigned short* colofs;
|
||||
|
||||
texture = textures[texnum];
|
||||
|
||||
block = Z_Malloc (texturecompositesize[texnum], PU_STATIC,
|
||||
&texturecomposite[texnum]);
|
||||
|
||||
collump = texturecolumnlump[texnum];
|
||||
colofs = texturecolumnofs[texnum];
|
||||
|
||||
byte *block = Z_Malloc(texturecompositesize[texnum], PU_STATIC,
|
||||
(void **) &texturecomposite[texnum]);
|
||||
texture_t *texture = textures[texnum];
|
||||
// Composite the columns together.
|
||||
patch = texture->patches;
|
||||
texpatch_t *patch = texture->patches;
|
||||
short *collump = texturecolumnlump[texnum];
|
||||
unsigned *colofs = texturecolumnofs[texnum]; // killough 4/9/98: make 32-bit
|
||||
int i = texture->patchcount;
|
||||
// killough 4/9/98: marks to identify transparent regions in merged textures
|
||||
byte *marks = Calloc(texture->width, texture->height), *source;
|
||||
|
||||
for (i = texture->patchcount, patch = texture->patches; i > 0; i--, patch++)
|
||||
for (; --i >=0; patch++)
|
||||
{
|
||||
patch_t *realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
|
||||
int x1 = patch->originx;
|
||||
int x2 = x1 + SHORT(realpatch->width);
|
||||
int x = (x1 < 0) ? 0 : x1;
|
||||
|
||||
patch_t *realpatch = W_CacheLumpNum(patch->patch, PU_CACHE);
|
||||
int x1 = patch->originx, x2 = x1 + SHORT(realpatch->width);
|
||||
const int *cofs = realpatch->columnofs-x1;
|
||||
if (x1<0)
|
||||
x1 = 0;
|
||||
if (x2 > texture->width)
|
||||
x2 = texture->width;
|
||||
for (; x1<x2 ; x1++)
|
||||
if (collump[x1] == -1) // Column has multiple patches?
|
||||
// killough 1/25/98, 4/9/98: Fix medusa bug.
|
||||
R_DrawColumnInCache((column_t*)((byte*)realpatch+LONG(cofs[x1])),
|
||||
block+colofs[x1],patch->originy,texture->height,
|
||||
marks + x1 * texture->height);
|
||||
}
|
||||
|
||||
for ( ; x < x2; x++)
|
||||
// killough 4/9/98: Next, convert multipatched columns into true columns,
|
||||
// to fix Medusa bug while still allowing for transparent regions.
|
||||
|
||||
source = malloc(texture->height); // temporary column
|
||||
for (i=0; i < texture->width; i++)
|
||||
if (collump[i] == -1) // process only multipatched columns
|
||||
{
|
||||
// Column does not have multiple patches?
|
||||
if (collump[x] >= 0)
|
||||
continue;
|
||||
column_t *col = (column_t *)(block + colofs[i] - 3); // cached column
|
||||
const byte *mark = marks + i * texture->height;
|
||||
int j = 0;
|
||||
|
||||
patchcol = (column_t *)((byte *)realpatch
|
||||
+ LONG(realpatch->columnofs[x-x1]));
|
||||
R_DrawColumnInCache (patchcol,
|
||||
block + colofs[x],
|
||||
patch->originy,
|
||||
texture->height);
|
||||
}
|
||||
// save column in temporary so we can shuffle it around
|
||||
memcpy(source, (byte *) col + 3, texture->height);
|
||||
|
||||
for (;;) // reconstruct the column by scanning transparency marks
|
||||
{
|
||||
while (j < texture->height && !mark[j]) // skip transparent cells
|
||||
j++;
|
||||
if (j >= texture->height) // if at end of column
|
||||
{
|
||||
col->topdelta = -1; // end-of-column marker
|
||||
break;
|
||||
}
|
||||
col->topdelta = j; // starting offset of post
|
||||
for (col->length=0; j < texture->height && mark[j]; j++)
|
||||
col->length++; // count opaque cells
|
||||
// copy opaque cells from the temporary back into the column
|
||||
memcpy((byte *) col + 3, source + col->topdelta, col->length);
|
||||
col = (column_t *)((byte *) col + col->length + 4); // next post
|
||||
}
|
||||
}
|
||||
free(source); // free temporary column
|
||||
free(marks); // free transparency marks
|
||||
|
||||
// Now that the texture has been built in column cache,
|
||||
// it is purgable from zone memory.
|
||||
Z_ChangeTag (block, PU_CACHE);
|
||||
|
||||
Z_ChangeTag(block, PU_CACHE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// R_GenerateLookup
|
||||
//
|
||||
void R_GenerateLookup (int texnum)
|
||||
{
|
||||
texture_t* texture;
|
||||
byte* patchcount; // patchcount[texture->width]
|
||||
texpatch_t* patch;
|
||||
int i;
|
||||
short* collump;
|
||||
unsigned short* colofs;
|
||||
// Rewritten by Lee Killough for performance and to fix Medusa bug
|
||||
//
|
||||
|
||||
texture = textures[texnum];
|
||||
static void R_GenerateLookup(int texnum, int *const errors)
|
||||
{
|
||||
const texture_t *texture = textures[texnum];
|
||||
|
||||
// Composited texture not created yet.
|
||||
texturecomposite[texnum] = 0;
|
||||
|
||||
texturecompositesize[texnum] = 0;
|
||||
collump = texturecolumnlump[texnum];
|
||||
colofs = texturecolumnofs[texnum];
|
||||
short *collump = texturecolumnlump[texnum];
|
||||
unsigned *colofs = texturecolumnofs[texnum]; // killough 4/9/98: make 32-bit
|
||||
|
||||
// killough 4/9/98: keep count of posts in addition to patches.
|
||||
// Part of fix for medusa bug for multipatched 2s normals.
|
||||
|
||||
struct {
|
||||
unsigned short patches, posts;
|
||||
} *count = Calloc(sizeof *count, texture->width);
|
||||
|
||||
{
|
||||
int i = texture->patchcount;
|
||||
const texpatch_t *patch = texture->patches;
|
||||
|
||||
while (--i >= 0)
|
||||
{
|
||||
int pat = patch->patch;
|
||||
const patch_t *realpatch = W_CacheLumpNum(pat, PU_CACHE);
|
||||
int x1 = patch++->originx, x2 = x1 + SHORT(realpatch->width), x = x1;
|
||||
const int *cofs = realpatch->columnofs-x1;
|
||||
|
||||
if (x2 > texture->width)
|
||||
x2 = texture->width;
|
||||
if (x1 < 0)
|
||||
x = 0;
|
||||
for ( ; x<x2 ; x++)
|
||||
{
|
||||
// killough 4/9/98: keep a count of the number of posts in column,
|
||||
// to fix Medusa bug while allowing for transparent multipatches.
|
||||
|
||||
const column_t *col = (column_t*)((byte*)realpatch+LONG(cofs[x]));
|
||||
for (;col->topdelta != 0xff; count[x].posts++)
|
||||
col = (column_t *)((byte *) col + col->length + 4);
|
||||
count[x].patches++;
|
||||
collump[x] = pat;
|
||||
colofs[x] = LONG(cofs[x])+3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now count the number of columns
|
||||
// that are covered by more than one patch.
|
||||
// Fill in the lump / offset, so columns
|
||||
// with only a single patch are all done.
|
||||
patchcount = (byte *)Z_Malloc (texture->width, PU_STATIC, 0);
|
||||
memset (patchcount, 0, texture->width);
|
||||
patch = texture->patches;
|
||||
|
||||
for (i = texture->patchcount, patch = texture->patches; i > 0; i--, patch++)
|
||||
texturecomposite[texnum] = 0;
|
||||
|
||||
{
|
||||
patch_t *realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
|
||||
int x1 = patch->originx;
|
||||
int x2 = x1 + SHORT(realpatch->width);
|
||||
int x = (x1 < 0) ? 0 : x1;
|
||||
int x = texture->width;
|
||||
int height = texture->height;
|
||||
int csize = 0;
|
||||
|
||||
if (x2 > texture->width)
|
||||
x2 = texture->width;
|
||||
|
||||
for ( ; x < x2 ; x++)
|
||||
while (--x >= 0)
|
||||
{
|
||||
patchcount[x]++;
|
||||
collump[x] = (short)patch->patch;
|
||||
colofs[x] = (short)(LONG(realpatch->columnofs[x-x1])+3);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < texture->width; i++)
|
||||
if (!count[x].patches) // killough 4/9/98
|
||||
{
|
||||
if (!patchcount[i])
|
||||
Printf("\nR_GenerateLookup: Column %d is without a patch in texture %.8s",
|
||||
x, texture->name);
|
||||
++*errors;
|
||||
}
|
||||
if (count[x].patches > 1) // killough 4/9/98
|
||||
{
|
||||
char namet[9];
|
||||
strncpy (namet, texture->name, 8);
|
||||
namet[8] = 0;
|
||||
// I_Error ("R_GenerateLookup: column without a patch");
|
||||
Printf ("R_GenerateLookup: column without a patch (%s)\n", namet);
|
||||
return;
|
||||
}
|
||||
// killough 1/25/98, 4/9/98:
|
||||
//
|
||||
// Fix Medusa bug, by adding room for column header
|
||||
// and trailer bytes for each post in merged column.
|
||||
// For now, just allocate conservatively 4 bytes
|
||||
// per post per patch per column, since we don't
|
||||
// yet know how many posts the merged column will
|
||||
// require, and it's bounded above by this limit.
|
||||
|
||||
if (patchcount[i] > 1)
|
||||
{
|
||||
// Use the cached block.
|
||||
collump[i] = -1;
|
||||
colofs[i] = (short)texturecompositesize[texnum];
|
||||
|
||||
if (texturecompositesize[texnum] > 0x10000-texture->height)
|
||||
I_Error ("R_GenerateLookup: texture %i is >64k", texnum);
|
||||
|
||||
texturecompositesize[texnum] += texture->height;
|
||||
collump[x] = -1; // mark lump as multipatched
|
||||
colofs[x] = csize + 3; // three header bytes in a column
|
||||
csize += 4*count[x].posts+1; // 1 stop byte plus 4 bytes per post
|
||||
}
|
||||
csize += height; // height bytes of texture data
|
||||
}
|
||||
Z_Free (patchcount);
|
||||
texturecompositesize[texnum] = csize;
|
||||
}
|
||||
free(count); // killough 4/9/98
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// R_GetColumn
|
||||
//
|
||||
|
@ -398,6 +439,8 @@ void R_InitTextures (void)
|
|||
|
||||
int* directory;
|
||||
|
||||
int errors = 0;
|
||||
|
||||
|
||||
// Load the patch names from pnames.lmp.
|
||||
{
|
||||
|
@ -407,9 +450,20 @@ void R_InitTextures (void)
|
|||
nummappatches = LONG ( *((int *)names) );
|
||||
patchlookup = Z_Malloc (nummappatches*sizeof(*patchlookup), PU_STATIC, 0);
|
||||
|
||||
for (i = 0; i < nummappatches; i++)
|
||||
patchlookup[i] = W_CheckNumForName (name_p + i * 8);
|
||||
for (i = 0; i < nummappatches; i++) {
|
||||
patchlookup[i] = W_CheckNumForName (name_p + i*8);
|
||||
if (patchlookup[i] == -1) {
|
||||
// killough 4/17/98:
|
||||
// Some wads use sprites as wall patches, so repeat check and
|
||||
// look for sprites this time, but only if there were no wall
|
||||
// patches found. This is the same as allowing for both, except
|
||||
// that wall patches always win over sprites, even when they
|
||||
// appear first in a wad. This is a kludgy solution to the wad
|
||||
// lump namespace problem.
|
||||
|
||||
patchlookup[i] = (W_CheckNumForName)(name_p + i*8, ns_sprites);
|
||||
}
|
||||
}
|
||||
Z_Free (names);
|
||||
}
|
||||
|
||||
|
@ -504,8 +558,8 @@ void R_InitTextures (void)
|
|||
patch->patch = patchlookup[SHORT(mpatch->patch)];
|
||||
if (patch->patch == -1)
|
||||
{
|
||||
I_Error ("R_InitTextures: Missing patch in texture %s",
|
||||
texture->name);
|
||||
Printf ("R_InitTextures: Missing patch in texture %s\n", texture->name);
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
texturecolumnlump[i] = Z_Malloc (texture->width*sizeof(**texturecolumnlump), PU_STATIC,0);
|
||||
|
@ -534,6 +588,9 @@ void R_InitTextures (void)
|
|||
if (maptex2)
|
||||
Z_Free (maptex2);
|
||||
|
||||
if (errors)
|
||||
I_Error ("%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
|
||||
// of the last (thus mimicing the original behavior
|
||||
|
@ -549,7 +606,10 @@ void R_InitTextures (void)
|
|||
|
||||
// Precalculate whatever possible.
|
||||
for (i = 0; i < numtextures; i++)
|
||||
R_GenerateLookup (i);
|
||||
R_GenerateLookup (i, &errors);
|
||||
|
||||
if (errors)
|
||||
I_Error ("%d errors encountered during texture generation.", errors);
|
||||
|
||||
// Create translation table for global animation.
|
||||
texturetranslation = Z_Malloc ((numtextures+1)*sizeof(*texturetranslation), PU_STATIC, 0);
|
||||
|
@ -662,10 +722,10 @@ void R_InitData (void)
|
|||
//
|
||||
int R_FlatNumForName (const char* name)
|
||||
{
|
||||
int i = W_CheckNumForName (name);
|
||||
int i = (W_CheckNumForName) (name, ns_flats);
|
||||
|
||||
if (i == -1)
|
||||
i = W_CheckNumForName ("-NOFLAT-");
|
||||
if (i == -1) // [RH] Default flat for not found ones
|
||||
i = (W_CheckNumForName) ("-NOFLAT-", ns_flats);
|
||||
|
||||
if (i == -1) {
|
||||
char namet[9];
|
||||
|
|
|
@ -104,29 +104,39 @@ struct sector_s
|
|||
short special;
|
||||
short tag;
|
||||
|
||||
// 0 = untraversed, 1,2 = sndlines -1
|
||||
int soundtraversed;
|
||||
|
||||
// thing that made a sound (or null)
|
||||
mobj_t* soundtarget;
|
||||
|
||||
// mapblock bounding box for height changes
|
||||
int blockbox[4];
|
||||
|
||||
// origin for any sounds played by the sector
|
||||
degenmobj_t soundorg;
|
||||
|
||||
// if == validcount, already checked
|
||||
int validcount;
|
||||
|
||||
// list of mobjs in sector
|
||||
mobj_t* thinglist;
|
||||
int soundtraversed; // 0 = untraversed, 1,2 = sndlines -1
|
||||
mobj_t* soundtarget; // thing that made a sound (or null)
|
||||
int blockbox[4]; // mapblock bounding box for height changes
|
||||
degenmobj_t soundorg; // origin for any sounds played by the sector
|
||||
int validcount; // if == validcount, already checked
|
||||
mobj_t* thinglist; // list of mobjs in sector
|
||||
|
||||
// thinker_t for reversable actions
|
||||
void* specialdata;
|
||||
void *floordata; // jff 2/22/98 make thinkers on
|
||||
void *ceilingdata; // floors, ceilings, lighting,
|
||||
void *lightingdata; // independent of one another
|
||||
|
||||
// jff 2/26/98 lockout machinery for stairbuilding
|
||||
int stairlock; // -2 on first locked -1 after thinker done 0 normally
|
||||
int prevsec; // -1 or number of sector for previous step
|
||||
int nextsec; // -1 or number of next step sector
|
||||
|
||||
// killough 3/7/98: floor and ceiling texture offsets
|
||||
fixed_t floor_xoffs, floor_yoffs;
|
||||
fixed_t ceiling_xoffs, ceiling_yoffs;
|
||||
|
||||
// killough 3/7/98: support flat heights drawn at another sector's heights
|
||||
int heightsec; // other sector, or -1 if no other sector
|
||||
|
||||
// killough 4/11/98: support for lightlevels coming from another sector
|
||||
int floorlightsec, ceilinglightsec;
|
||||
|
||||
// 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
|
||||
|
||||
int linecount;
|
||||
struct line_s** lines; // [linecount] size
|
||||
struct line_s **lines; // [linecount] size
|
||||
|
||||
};
|
||||
typedef struct sector_s sector_t;
|
||||
|
@ -186,6 +196,7 @@ struct line_s
|
|||
short flags;
|
||||
short special;
|
||||
short tag;
|
||||
byte args[5]; // [RH] Hexen-style arguments
|
||||
|
||||
// Visual appearance: SideDefs.
|
||||
// sidenum[1] will be -1 if one sided
|
||||
|
@ -229,6 +240,32 @@ struct subsector_s
|
|||
};
|
||||
typedef struct subsector_s subsector_t;
|
||||
|
||||
// phares 3/14/98
|
||||
//
|
||||
// Sector list node showing all sectors an object appears in.
|
||||
//
|
||||
// There are two threads that flow through these nodes. The first thread
|
||||
// starts at touching_thinglist in a sector_t and flows through the m_snext
|
||||
// links to find all mobjs that are entirely or partially in the sector.
|
||||
// The second thread starts at touching_sectorlist in an mobj_t and flows
|
||||
// through the m_tnext links to find all sectors a thing touches. This is
|
||||
// useful when applying friction or push effects to sectors. These effects
|
||||
// can be done as thinkers that act upon all objects touching their sectors.
|
||||
// As an mobj moves through the world, these nodes are created and
|
||||
// destroyed, with the links changed appropriately.
|
||||
//
|
||||
// For the links, NULL means top or end of list.
|
||||
|
||||
typedef struct msecnode_s
|
||||
{
|
||||
sector_t *m_sector; // a sector containing this object
|
||||
struct mobj_s *m_thing; // this object
|
||||
struct msecnode_s *m_tprev; // prev msecnode_t for this thing
|
||||
struct msecnode_s *m_tnext; // next msecnode_t for this thing
|
||||
struct msecnode_s *m_sprev; // prev msecnode_t for this sector
|
||||
struct msecnode_s *m_snext; // next msecnode_t for this sector
|
||||
BOOL visited; // killough 4/4/98, 4/7/98: used in search algorithms
|
||||
} msecnode_t;
|
||||
|
||||
//
|
||||
// The LineSeg.
|
||||
|
@ -403,6 +440,9 @@ struct vissprite_s
|
|||
// Currently this is just a translation table and not a palette.
|
||||
struct palette_s *palette;
|
||||
|
||||
// killough 3/27/98: height sector for underwater/fake ceiling support
|
||||
int heightsec;
|
||||
|
||||
};
|
||||
typedef struct vissprite_s vissprite_t;
|
||||
|
||||
|
@ -459,6 +499,8 @@ struct visplane_s
|
|||
fixed_t height;
|
||||
int picnum;
|
||||
int lightlevel;
|
||||
fixed_t xoffs;
|
||||
fixed_t yoffs;
|
||||
int minx;
|
||||
int maxx;
|
||||
|
||||
|
|
|
@ -876,24 +876,14 @@ void R_FillBackScreen (void)
|
|||
int y;
|
||||
patch_t* patch;
|
||||
|
||||
// DOOM border patch.
|
||||
//char name1[] = "FLOOR7_2";
|
||||
|
||||
// DOOM II border patch.
|
||||
//char name2[] = "GRNROCK";
|
||||
|
||||
char* name;
|
||||
|
||||
// [RH] Always draws something now.
|
||||
|
||||
if ( gamemode == commercial)
|
||||
name = "GRNROCK";
|
||||
else
|
||||
name = "FLOOR7_2";
|
||||
|
||||
V_LockScreen (&screens[1]);
|
||||
|
||||
V_FlatFill (0,0,screens[1].width,screens[1].height,&screens[1],W_CacheLumpName (name, PU_CACHE));
|
||||
{
|
||||
int lump = R_FlatNumForName ((gamemode == commercial) ? "GRNROCK" : "FLOOR7_2");
|
||||
V_FlatFill (0,0,screens[1].width,screens[1].height,&screens[1],
|
||||
W_CacheLumpNum (lump + firstflat, PU_CACHE));
|
||||
}
|
||||
|
||||
|
||||
if (realviewwidth != screens[0].width) {
|
||||
patch = W_CacheLumpName ("brdr_b",PU_CACHE);
|
||||
|
|
|
@ -77,7 +77,6 @@ fixed_t skytopfrac;
|
|||
// just for profiling purposes
|
||||
int framecount;
|
||||
|
||||
int sscount;
|
||||
int linecount;
|
||||
int loopcount;
|
||||
|
||||
|
@ -394,38 +393,6 @@ R_PointToAngle2
|
|||
}
|
||||
|
||||
|
||||
fixed_t
|
||||
R_PointToDist
|
||||
( fixed_t x,
|
||||
fixed_t y )
|
||||
{
|
||||
int angle;
|
||||
fixed_t dx;
|
||||
fixed_t dy;
|
||||
fixed_t temp;
|
||||
fixed_t dist;
|
||||
|
||||
dx = abs(x - viewx);
|
||||
dy = abs(y - viewy);
|
||||
|
||||
if (dy>dx)
|
||||
{
|
||||
temp = dx;
|
||||
dx = dy;
|
||||
dy = temp;
|
||||
}
|
||||
|
||||
angle = (tantoangle[ FixedDiv(dy,dx)>>DBITS ]+ANG90) >> ANGLETOFINESHIFT;
|
||||
|
||||
// use as cosine
|
||||
dist = FixedDiv (dx, finesine[angle] );
|
||||
|
||||
return dist;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// R_InitPointToAngle
|
||||
//
|
||||
|
@ -930,8 +897,6 @@ void R_SetupFrame (player_t* player)
|
|||
viewsin = finesine[viewangle>>ANGLETOFINESHIFT];
|
||||
viewcos = finecosine[viewangle>>ANGLETOFINESHIFT];
|
||||
|
||||
sscount = 0;
|
||||
|
||||
if (player->fixedcolormap)
|
||||
{
|
||||
fixedcolormap =
|
||||
|
|
|
@ -55,7 +55,7 @@ visplane_t *floorplane;
|
|||
visplane_t *ceilingplane;
|
||||
|
||||
// ?
|
||||
#define MAXOPENINGS (screens[0].width*64)
|
||||
size_t maxopenings;
|
||||
short *openings;
|
||||
short *lastopening;
|
||||
|
||||
|
@ -86,6 +86,7 @@ fixed_t *yslope;
|
|||
fixed_t *distscale;
|
||||
fixed_t basexscale;
|
||||
fixed_t baseyscale;
|
||||
static fixed_t xoffs, yoffs; // killough 2/28/98: flat offsets
|
||||
|
||||
fixed_t *cachedheight;
|
||||
fixed_t *cacheddistance;
|
||||
|
@ -151,6 +152,8 @@ static void GetMoreVisPlanes (visplane_t **toupdate)
|
|||
// baseyscale
|
||||
// viewx
|
||||
// viewy
|
||||
// xoffs
|
||||
// yoffs
|
||||
//
|
||||
// BASIC PRIMITIVE
|
||||
//
|
||||
|
@ -186,8 +189,10 @@ void R_MapPlane (int y, int x1, int x2)
|
|||
|
||||
length = FixedMul (distance,distscale[x1]);
|
||||
angle = (viewangle + xtoviewangle[x1])>>ANGLETOFINESHIFT;
|
||||
ds_xfrac = viewx + FixedMul(finecosine[angle], length);
|
||||
ds_yfrac = -viewy - FixedMul(finesine[angle], length);
|
||||
|
||||
// killough 2/28/98: Add offsets
|
||||
ds_xfrac = viewx + FixedMul(finecosine[angle], length) + xoffs;
|
||||
ds_yfrac = -viewy - FixedMul(finesine[angle], length) + yoffs;
|
||||
|
||||
if (fixedcolormap)
|
||||
ds_colormap = fixedcolormap;
|
||||
|
@ -246,27 +251,29 @@ void R_ClearPlanes (void)
|
|||
//
|
||||
// R_FindPlane
|
||||
//
|
||||
visplane_t *R_FindPlane (fixed_t height, int picnum, int lightlevel)
|
||||
// killough 2/28/98: Add offsets
|
||||
|
||||
visplane_t *R_FindPlane (fixed_t height, int picnum, int lightlevel,
|
||||
fixed_t xoffs, fixed_t yoffs)
|
||||
{
|
||||
visplane_t* check;
|
||||
visplane_t *check;
|
||||
|
||||
if (picnum == skyflatnum)
|
||||
{
|
||||
height = 0; // all skys map together
|
||||
lightlevel = 0;
|
||||
}
|
||||
height = lightlevel = 0; // all skys map together
|
||||
|
||||
for (check=visplanes; check<lastvisplane; check++)
|
||||
{
|
||||
if (height == check->height
|
||||
&& picnum == check->picnum
|
||||
&& lightlevel == check->lightlevel)
|
||||
&& lightlevel == check->lightlevel
|
||||
&& xoffs == check->xoffs
|
||||
&& yoffs == check->yoffs
|
||||
)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (check < lastvisplane)
|
||||
return check;
|
||||
|
||||
|
@ -278,6 +285,8 @@ visplane_t *R_FindPlane (fixed_t height, int picnum, int lightlevel)
|
|||
check->height = height;
|
||||
check->picnum = picnum;
|
||||
check->lightlevel = lightlevel;
|
||||
check->xoffs = xoffs; // killough 2/28/98: Save offsets
|
||||
check->yoffs = yoffs;
|
||||
check->minx = screens[0].width;
|
||||
check->maxx = -1;
|
||||
|
||||
|
@ -341,6 +350,8 @@ visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop)
|
|||
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++;
|
||||
|
||||
|
@ -405,7 +416,7 @@ static void R_DrawMaskedSky (int skytexture, int skypos, fixed_t scale, fixed_t
|
|||
for (x=pl->minx ; x <= pl->maxx ; x++)
|
||||
{
|
||||
dc_x = x;
|
||||
angle = ((((viewangle + xtoviewangle[x])>>(ANGLETOSKYSHIFT-16)) + skypos)>>16)&0xff;
|
||||
angle = ((((viewangle + xtoviewangle[x])>>(ANGLETOSKYSHIFT-16)) + skypos)>>16);
|
||||
column = (column_t *) ((byte *)R_GetColumn(skytexture, angle) - 3);
|
||||
|
||||
if (column->topdelta == 0xff)
|
||||
|
@ -467,7 +478,7 @@ static void R_DrawSky (int skytexture, int skypos, visplane_t *pl)
|
|||
dc_yh = pl->bottom[x];
|
||||
|
||||
if (dc_yl <= dc_yh) {
|
||||
angle = ((((viewangle + xtoviewangle[x])>>(ANGLETOSKYSHIFT-16)) + skypos)>>16)&0xff;
|
||||
angle = ((((viewangle + xtoviewangle[x])>>(ANGLETOSKYSHIFT-16)) + skypos)>>16);
|
||||
dc_x = x;
|
||||
dc_source = R_GetColumn(skytexture, angle);
|
||||
colfunc ();
|
||||
|
@ -524,6 +535,8 @@ void R_DrawPlanes (void)
|
|||
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;
|
||||
|
||||
|
@ -554,7 +567,6 @@ void R_DrawPlanes (void)
|
|||
|
||||
BOOL R_PlaneInitData (void)
|
||||
{
|
||||
if (openings) free (openings);
|
||||
if (floorclip) free (floorclip);
|
||||
if (ceilingclip) free (ceilingclip);
|
||||
if (spanstart) free (spanstart);
|
||||
|
@ -565,7 +577,6 @@ BOOL R_PlaneInitData (void)
|
|||
if (cachedxstep) free (cachedxstep);
|
||||
if (cachedystep) free (cachedystep);
|
||||
|
||||
openings = Calloc (MAXOPENINGS, sizeof(short));
|
||||
floorclip = Calloc (screens[0].width, sizeof(short));
|
||||
ceilingclip = Calloc (screens[0].width, sizeof(short));
|
||||
|
||||
|
|
|
@ -66,7 +66,9 @@ visplane_t*
|
|||
R_FindPlane
|
||||
( fixed_t height,
|
||||
int picnum,
|
||||
int lightlevel );
|
||||
int lightlevel,
|
||||
fixed_t xoffs, // killough 2/28/98: add x-y offsets
|
||||
fixed_t yoffs);
|
||||
|
||||
visplane_t*
|
||||
R_CheckPlane
|
||||
|
|
349
code/R_segs.c
349
code/R_segs.c
|
@ -36,62 +36,56 @@
|
|||
|
||||
#include "r_local.h"
|
||||
#include "r_sky.h"
|
||||
|
||||
#include "v_video.h"
|
||||
|
||||
// OPTIMIZE: closed two sided lines as single sided
|
||||
|
||||
// True if any of the segs textures might be visible.
|
||||
BOOL segtextured;
|
||||
// killough 1/6/98: replaced globals with statics where appropriate
|
||||
|
||||
// False if the back side is the same plane.
|
||||
BOOL markfloor;
|
||||
BOOL markceiling;
|
||||
|
||||
BOOL maskedtexture;
|
||||
int toptexture;
|
||||
int bottomtexture;
|
||||
int midtexture;
|
||||
static BOOL segtextured; // True if any of the segs textures might be visible.
|
||||
static BOOL markfloor; // False if the back side is the same plane.
|
||||
static BOOL markceiling;
|
||||
static BOOL maskedtexture;
|
||||
static int toptexture;
|
||||
static int bottomtexture;
|
||||
static int midtexture;
|
||||
|
||||
|
||||
angle_t rw_normalangle;
|
||||
// angle to line origin
|
||||
angle_t rw_normalangle; // angle to line origin
|
||||
int rw_angle1;
|
||||
fixed_t rw_distance;
|
||||
lighttable_t** walllights;
|
||||
|
||||
//
|
||||
// regular wall
|
||||
//
|
||||
int rw_x;
|
||||
int rw_stopx;
|
||||
angle_t rw_centerangle;
|
||||
fixed_t rw_offset;
|
||||
fixed_t rw_distance;
|
||||
fixed_t rw_scale;
|
||||
fixed_t rw_scalestep;
|
||||
fixed_t rw_midtexturemid;
|
||||
fixed_t rw_toptexturemid;
|
||||
fixed_t rw_bottomtexturemid;
|
||||
static int rw_x;
|
||||
static int rw_stopx;
|
||||
static angle_t rw_centerangle;
|
||||
static fixed_t rw_offset;
|
||||
static fixed_t rw_scale;
|
||||
static fixed_t rw_scalestep;
|
||||
static fixed_t rw_midtexturemid;
|
||||
static fixed_t rw_toptexturemid;
|
||||
static fixed_t rw_bottomtexturemid;
|
||||
|
||||
int worldtop;
|
||||
int worldbottom;
|
||||
int worldhigh;
|
||||
int worldlow;
|
||||
static int worldtop;
|
||||
static int worldbottom;
|
||||
static int worldhigh;
|
||||
static int worldlow;
|
||||
|
||||
fixed_t pixhigh;
|
||||
fixed_t pixlow;
|
||||
fixed_t pixhighstep;
|
||||
fixed_t pixlowstep;
|
||||
static fixed_t pixhigh;
|
||||
static fixed_t pixlow;
|
||||
static fixed_t pixhighstep;
|
||||
static fixed_t pixlowstep;
|
||||
|
||||
fixed_t topfrac;
|
||||
fixed_t topstep;
|
||||
static fixed_t topfrac;
|
||||
static fixed_t topstep;
|
||||
|
||||
fixed_t bottomfrac;
|
||||
fixed_t bottomstep;
|
||||
|
||||
|
||||
lighttable_t** walllights;
|
||||
|
||||
short* maskedtexturecol;
|
||||
static fixed_t bottomfrac;
|
||||
static fixed_t bottomstep;
|
||||
|
||||
static short *maskedtexturecol;
|
||||
|
||||
|
||||
//
|
||||
|
@ -99,33 +93,33 @@ short* maskedtexturecol;
|
|||
//
|
||||
void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
||||
{
|
||||
unsigned index;
|
||||
column_t* col;
|
||||
int lightnum;
|
||||
int texnum;
|
||||
sector_t tempsec; // killough 4/13/98
|
||||
|
||||
// Calculate light table.
|
||||
// Use different light tables
|
||||
// for horizontal / vertical / diagonal. Diagonal?
|
||||
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
|
||||
curline = ds->curline;
|
||||
|
||||
frontsector = curline->frontsector;
|
||||
backsector = curline->backsector;
|
||||
|
||||
texnum = texturetranslation[curline->sidedef->midtexture];
|
||||
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
|
||||
// killough 4/13/98: get correct lightlevel for 2s normal textures
|
||||
lightnum = (R_FakeFlat(frontsector, &tempsec, NULL, NULL, false)
|
||||
->lightlevel >> LIGHTSEGSHIFT)+extralight;
|
||||
|
||||
if (curline->v1->y == curline->v2->y)
|
||||
lightnum--;
|
||||
else if (curline->v1->x == curline->v2->x)
|
||||
lightnum++;
|
||||
|
||||
if (lightnum < 0)
|
||||
walllights = scalelight[0];
|
||||
else if (lightnum >= LIGHTLEVELS)
|
||||
walllights = scalelight[LIGHTLEVELS-1];
|
||||
else
|
||||
walllights = scalelight[lightnum];
|
||||
walllights = lightnum >= LIGHTLEVELS ? scalelight[LIGHTLEVELS-1] :
|
||||
lightnum < 0 ? scalelight[0] : scalelight[lightnum];
|
||||
|
||||
maskedtexturecol = ds->maskedtexturecol;
|
||||
|
||||
|
@ -155,22 +149,48 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
|||
// draw the columns
|
||||
for (dc_x = x1 ; dc_x <= x2 ; dc_x++)
|
||||
{
|
||||
// calculate lighting
|
||||
if (maskedtexturecol[dc_x] != MAXSHORT)
|
||||
{
|
||||
// calculate lighting
|
||||
if (!fixedcolormap)
|
||||
{
|
||||
index = spryscale>>LIGHTSCALESHIFT;
|
||||
unsigned index = spryscale>>LIGHTSCALESHIFT;
|
||||
|
||||
if (index >= MAXLIGHTSCALE )
|
||||
if (index >= MAXLIGHTSCALE)
|
||||
index = MAXLIGHTSCALE-1;
|
||||
|
||||
dc_colormap = walllights[index];
|
||||
}
|
||||
|
||||
sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
|
||||
// killough 3/2/98:
|
||||
//
|
||||
// This calculation used to overflow and cause crashes in Doom:
|
||||
//
|
||||
// sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
|
||||
//
|
||||
// This code fixes it, by using double-precision intermediate
|
||||
// arithmetic and by skipping the drawing of 2s normals whose
|
||||
// mapping to screen coordinates is totally out of range:
|
||||
|
||||
{
|
||||
__int64 t = ((__int64) centeryfrac << FRACBITS) -
|
||||
(__int64) dc_texturemid * spryscale;
|
||||
// [RH] This doesn't work properly as-is with freelook
|
||||
// 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
|
||||
sprtopscreen = (long)(t >> FRACBITS);
|
||||
}
|
||||
dc_iscale = 0xffffffffu / (unsigned)spryscale;
|
||||
|
||||
// killough 1/25/98: here's where Medusa came in, because
|
||||
// it implicitly assumed that the column was all one patch.
|
||||
// Originally, Doom did not construct complete columns for
|
||||
// multipatched textures, so there were no header or trailer
|
||||
// bytes in the column referred to below, which explains
|
||||
// the Medusa effect. The fix is to construct true columns
|
||||
// when forming multipatched textures (see r_data.c).
|
||||
|
||||
// draw the texture
|
||||
col = (column_t *)(
|
||||
(byte *)R_GetColumn(texnum,maskedtexturecol[dc_x]) -3);
|
||||
|
@ -357,7 +377,23 @@ void R_RenderSegLoop (void)
|
|||
}
|
||||
}
|
||||
|
||||
// killough 5/2/98: move from r_main.c, made static, simplified
|
||||
|
||||
static fixed_t R_PointToDist(fixed_t x, fixed_t y)
|
||||
{
|
||||
fixed_t dx = abs(x - viewx);
|
||||
fixed_t dy = abs(y - viewy);
|
||||
|
||||
if (dy > dx)
|
||||
{
|
||||
fixed_t t = dx;
|
||||
dx = dy;
|
||||
dy = t;
|
||||
}
|
||||
|
||||
return FixedDiv(dx, finesine[(tantoangle[FixedDiv(dy,dx) >> DBITS]
|
||||
+ ANG90) >> ANGLETOFINESHIFT]);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
|
@ -365,6 +401,9 @@ void R_RenderSegLoop (void)
|
|||
// A wall segment will be drawn
|
||||
// between start and stop pixels (inclusive).
|
||||
//
|
||||
extern short *openings;
|
||||
extern size_t maxopenings;
|
||||
|
||||
void R_StoreWallRange (int start, int stop)
|
||||
{
|
||||
fixed_t hyp;
|
||||
|
@ -373,20 +412,21 @@ void R_StoreWallRange (int start, int stop)
|
|||
fixed_t vtop;
|
||||
int lightnum;
|
||||
|
||||
// don't overflow and crash
|
||||
if (ds_p == &drawsegs[MaxDrawSegs]) {
|
||||
// [RH] Grab some more drawsegs
|
||||
MaxDrawSegs += 32;
|
||||
drawsegs = Realloc (drawsegs, MaxDrawSegs * sizeof(drawseg_t));
|
||||
ds_p = &drawsegs[MaxDrawSegs - 32];
|
||||
DPrintf ("MaxDrawSegs increased to %d\n", MaxDrawSegs);
|
||||
}
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (start >=viewwidth || start > stop)
|
||||
I_Error ("Bad R_RenderWallRange: %i to %i", start , stop);
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
DPrintf ("MaxDrawSegs increased to %d\n", MaxDrawSegs);
|
||||
}
|
||||
|
||||
sidedef = curline->sidedef;
|
||||
linedef = curline->linedef;
|
||||
|
||||
|
@ -411,6 +451,36 @@ void R_StoreWallRange (int start, int 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;
|
||||
size_t need = (rw_stopx - start)*4 + pos;
|
||||
|
||||
if (need > maxopenings)
|
||||
{
|
||||
drawseg_t *ds;
|
||||
short *oldopenings = openings;
|
||||
short *oldlast = lastopening;
|
||||
|
||||
do
|
||||
maxopenings = maxopenings ? maxopenings*2 : 16384;
|
||||
while (need > maxopenings);
|
||||
openings = Realloc(openings, maxopenings * sizeof(*openings));
|
||||
lastopening = openings + pos;
|
||||
DPrintf ("MaxOpenings increased to %u\n", maxopenings);
|
||||
|
||||
// [RH] We also need to adjust the openings pointers that
|
||||
// were already stored in drawsegs.
|
||||
for (ds = drawsegs; ds < ds_p; ds++) {
|
||||
#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast)\
|
||||
ds->p = ds->p - oldopenings + openings;
|
||||
ADJUST (maskedtexturecol);
|
||||
ADJUST (sprtopclip);
|
||||
ADJUST (sprbottomclip);
|
||||
}
|
||||
#undef ADJUST
|
||||
}
|
||||
} // killough: end of code to remove limits on openings
|
||||
|
||||
// calculate scale at both ends and step
|
||||
ds_p->scale1 = rw_scale =
|
||||
R_ScaleFromGlobalAngle (viewangle + xtoviewangle[start]);
|
||||
|
@ -423,21 +493,6 @@ void R_StoreWallRange (int start, int stop)
|
|||
}
|
||||
else
|
||||
{
|
||||
// UNUSED: try to fix the stretched line bug
|
||||
#if 0
|
||||
if (rw_distance < FRACUNIT/2)
|
||||
{
|
||||
fixed_t trx,try;
|
||||
fixed_t gxt,gyt;
|
||||
|
||||
trx = curline->v1->x - viewx;
|
||||
try = curline->v1->y - viewy;
|
||||
|
||||
gxt = FixedMul(trx,viewcos);
|
||||
gyt = -FixedMul(try,viewsin);
|
||||
ds_p->scale1 = FixedDiv(projection, gxt-gyt);
|
||||
}
|
||||
#endif
|
||||
ds_p->scale2 = ds_p->scale1;
|
||||
}
|
||||
|
||||
|
@ -453,8 +508,10 @@ void R_StoreWallRange (int start, int stop)
|
|||
{
|
||||
// single sided line
|
||||
midtexture = texturetranslation[sidedef->midtexture];
|
||||
|
||||
// a single sided line is terminal, so it must mark ends
|
||||
markfloor = markceiling = true;
|
||||
|
||||
if (linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{
|
||||
vtop = frontsector->floorheight +
|
||||
|
@ -467,8 +524,18 @@ void R_StoreWallRange (int start, int stop)
|
|||
// top of texture at top
|
||||
rw_midtexturemid = worldtop;
|
||||
}
|
||||
|
||||
rw_midtexturemid += sidedef->rowoffset;
|
||||
|
||||
{ // killough 3/27/98: reduce offset
|
||||
/* [RH] Not necessary unless I do BOOM's fix for wrapping
|
||||
* textures of any height
|
||||
fixed_t h = textureheight[sidedef->midtexture];
|
||||
if (h & (h-FRACUNIT))
|
||||
rw_midtexturemid %= h;
|
||||
*/
|
||||
}
|
||||
|
||||
ds_p->silhouette = SIL_BOTH;
|
||||
ds_p->sprtopclip = screenheightarray;
|
||||
ds_p->sprbottomclip = negonearray;
|
||||
|
@ -490,7 +557,6 @@ void R_StoreWallRange (int start, int stop)
|
|||
{
|
||||
ds_p->silhouette = SIL_BOTTOM;
|
||||
ds_p->bsilheight = MAXINT;
|
||||
// ds_p->sprbottomclip = negonearray;
|
||||
}
|
||||
|
||||
if (frontsector->ceilingheight < backsector->ceilingheight)
|
||||
|
@ -502,7 +568,6 @@ void R_StoreWallRange (int start, int stop)
|
|||
{
|
||||
ds_p->silhouette |= SIL_TOP;
|
||||
ds_p->tsilheight = MININT;
|
||||
// ds_p->sprtopclip = screenheightarray;
|
||||
}
|
||||
|
||||
if (backsector->ceilingheight <= frontsector->floorheight)
|
||||
|
@ -519,6 +584,30 @@ void R_StoreWallRange (int start, int stop)
|
|||
ds_p->silhouette |= SIL_TOP;
|
||||
}
|
||||
|
||||
// killough 1/17/98: this test is required if the fix
|
||||
// for the automap bug (r_bsp.c) is used, or else some
|
||||
// sprites will be displayed behind closed doors. That
|
||||
// fix prevents lines behind closed doors with dropoffs
|
||||
// from being displayed on the automap.
|
||||
//
|
||||
// killough 4/7/98: make doorclosed external variable
|
||||
|
||||
{
|
||||
extern int doorclosed; // killough 1/17/98, 2/8/98, 4/7/98
|
||||
if (doorclosed || backsector->ceilingheight<=frontsector->floorheight)
|
||||
{
|
||||
ds_p->sprbottomclip = negonearray;
|
||||
ds_p->bsilheight = MAXINT;
|
||||
ds_p->silhouette |= SIL_BOTTOM;
|
||||
}
|
||||
if (doorclosed || backsector->floorheight>=frontsector->ceilingheight)
|
||||
{ // killough 1/17/98, 2/8/98
|
||||
ds_p->sprtopclip = screenheightarray;
|
||||
ds_p->tsilheight = MININT;
|
||||
ds_p->silhouette |= SIL_TOP;
|
||||
}
|
||||
}
|
||||
|
||||
worldhigh = backsector->ceilingheight - viewz;
|
||||
worldlow = backsector->floorheight - viewz;
|
||||
|
||||
|
@ -530,30 +619,38 @@ void R_StoreWallRange (int start, int stop)
|
|||
}
|
||||
|
||||
|
||||
if (worldlow != worldbottom
|
||||
markfloor = worldlow != worldbottom
|
||||
|| backsector->floorpic != frontsector->floorpic
|
||||
|| backsector->lightlevel != frontsector->lightlevel)
|
||||
{
|
||||
markfloor = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// same plane on both sides
|
||||
markfloor = false;
|
||||
}
|
||||
|| backsector->lightlevel != frontsector->lightlevel
|
||||
|
||||
// killough 3/7/98: Add checks for (x,y) offsets
|
||||
|| backsector->floor_xoffs != frontsector->floor_xoffs
|
||||
|| backsector->floor_yoffs != frontsector->floor_yoffs
|
||||
|
||||
if (worldhigh != worldtop
|
||||
// killough 4/15/98: prevent 2s normals
|
||||
// from bleeding through deep water
|
||||
|| frontsector->heightsec != -1
|
||||
|
||||
// killough 4/17/98: draw floors if different light levels
|
||||
|| backsector->floorlightsec != frontsector->floorlightsec
|
||||
;
|
||||
|
||||
markceiling = worldhigh != worldtop
|
||||
|| backsector->ceilingpic != frontsector->ceilingpic
|
||||
|| backsector->lightlevel != frontsector->lightlevel)
|
||||
{
|
||||
markceiling = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// same plane on both sides
|
||||
markceiling = false;
|
||||
}
|
||||
|| backsector->lightlevel != frontsector->lightlevel
|
||||
|
||||
// killough 3/7/98: Add checks for (x,y) offsets
|
||||
|| backsector->ceiling_xoffs != frontsector->ceiling_xoffs
|
||||
|| backsector->ceiling_yoffs != frontsector->ceiling_yoffs
|
||||
|
||||
// killough 4/15/98: prevent 2s normals
|
||||
// from bleeding through fake ceilings
|
||||
|| (frontsector->heightsec != -1 &&
|
||||
frontsector->ceilingpic!=skyflatnum)
|
||||
|
||||
// killough 4/17/98: draw ceilings if different light levels
|
||||
|| backsector->ceilinglightsec != frontsector->ceilinglightsec
|
||||
;
|
||||
|
||||
if (backsector->ceilingheight <= frontsector->floorheight
|
||||
|| backsector->floorheight >= frontsector->ceilingheight)
|
||||
|
@ -597,8 +694,29 @@ void R_StoreWallRange (int start, int stop)
|
|||
rw_bottomtexturemid = worldlow;
|
||||
}
|
||||
rw_toptexturemid += sidedef->rowoffset;
|
||||
|
||||
// killough 3/27/98: reduce offset
|
||||
{
|
||||
/* [RH] Not necessary unless I do BOOM's fix for wrapping
|
||||
* textures of any height
|
||||
fixed_t h = textureheight[sidedef->toptexture];
|
||||
if (h & (h-FRACUNIT))
|
||||
rw_toptexturemid %= h;
|
||||
*/
|
||||
}
|
||||
|
||||
rw_bottomtexturemid += sidedef->rowoffset;
|
||||
|
||||
// killough 3/27/98: reduce offset
|
||||
{
|
||||
/* [RH] Not necessary unless I do BOOM's fix for wrapping
|
||||
* textures of any height
|
||||
fixed_t h = textureheight[sidedef->bottomtexture];
|
||||
if (h & (h-FRACUNIT))
|
||||
rw_bottomtexturemid %= h;
|
||||
*/
|
||||
}
|
||||
|
||||
// allocate space for masked texture tables
|
||||
if (sidedef->midtexture)
|
||||
{
|
||||
|
@ -657,20 +775,16 @@ void R_StoreWallRange (int start, int stop)
|
|||
// and doesn't need to be marked.
|
||||
|
||||
|
||||
if (frontsector->floorheight >= viewz)
|
||||
// killough 3/7/98: add deep water check
|
||||
if (frontsector->heightsec == -1)
|
||||
{
|
||||
// above view plane
|
||||
if (frontsector->floorheight >= viewz) // above view plane
|
||||
markfloor = false;
|
||||
}
|
||||
|
||||
if (frontsector->ceilingheight <= viewz
|
||||
&& frontsector->ceilingpic != skyflatnum)
|
||||
{
|
||||
// below view plane
|
||||
if (frontsector->ceilingheight <= viewz &&
|
||||
frontsector->ceilingpic != skyflatnum) // below view plane
|
||||
markceiling = false;
|
||||
}
|
||||
|
||||
|
||||
// calculate incremental stepping values for texture edges
|
||||
worldtop >>= 4;
|
||||
worldbottom >>= 4;
|
||||
|
@ -701,41 +815,46 @@ void R_StoreWallRange (int start, int stop)
|
|||
|
||||
// render it
|
||||
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 (floorplane) // killough 4/11/98: add NULL ptr checks
|
||||
floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1);
|
||||
else
|
||||
markfloor = 0;
|
||||
|
||||
R_RenderSegLoop ();
|
||||
|
||||
|
||||
// save sprite clipping info
|
||||
if ( ((ds_p->silhouette & SIL_TOP) || maskedtexture)
|
||||
&& !ds_p->sprtopclip)
|
||||
if ( ((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip)
|
||||
{
|
||||
memcpy (lastopening, ceilingclip+start, 2*(rw_stopx-start));
|
||||
memcpy (lastopening, ceilingclip+start, sizeof(*lastopening)*(rw_stopx-start));
|
||||
ds_p->sprtopclip = lastopening - start;
|
||||
lastopening += rw_stopx - start;
|
||||
}
|
||||
|
||||
if ( ((ds_p->silhouette & SIL_BOTTOM) || maskedtexture)
|
||||
&& !ds_p->sprbottomclip)
|
||||
if ( ((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip)
|
||||
{
|
||||
memcpy (lastopening, floorclip+start, 2*(rw_stopx-start));
|
||||
memcpy (lastopening, floorclip+start, sizeof(*lastopening)*(rw_stopx-start));
|
||||
ds_p->sprbottomclip = lastopening - start;
|
||||
lastopening += rw_stopx - start;
|
||||
}
|
||||
|
||||
if (maskedtexture && !(ds_p->silhouette&SIL_TOP))
|
||||
if (maskedtexture && !(ds_p->silhouette & SIL_TOP))
|
||||
{
|
||||
ds_p->silhouette |= SIL_TOP;
|
||||
ds_p->tsilheight = MININT;
|
||||
}
|
||||
if (maskedtexture && !(ds_p->silhouette&SIL_BOTTOM))
|
||||
if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM))
|
||||
{
|
||||
ds_p->silhouette |= SIL_BOTTOM;
|
||||
ds_p->bsilheight = MAXINT;
|
||||
}
|
||||
|
||||
ds_p++;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ fixed_t sky2pos=0, sky2speed=0;
|
|||
// [RH] Stretch sky texture if not taller than 128 pixels?
|
||||
cvar_t *r_stretchsky;
|
||||
|
||||
char SKYFLATNAME[8] = "F_SKY1";
|
||||
|
||||
//
|
||||
// R_InitSkyMap
|
||||
|
|
134
code/R_things.c
134
code/R_things.c
|
@ -467,6 +467,7 @@ void R_ProjectSprite (mobj_t* thing)
|
|||
fixed_t gxt;
|
||||
fixed_t gyt;
|
||||
|
||||
fixed_t gzt; // killough 3/27/98
|
||||
fixed_t tx;
|
||||
fixed_t tz;
|
||||
|
||||
|
@ -490,6 +491,9 @@ void R_ProjectSprite (mobj_t* thing)
|
|||
angle_t ang;
|
||||
fixed_t iscale;
|
||||
|
||||
int heightsec; // killough 3/27/98
|
||||
|
||||
|
||||
// [RH] Andy Baker's stealth monsters
|
||||
if (thing->invisible == true)
|
||||
return;
|
||||
|
@ -565,14 +569,47 @@ void R_ProjectSprite (mobj_t* thing)
|
|||
if (x2 < 0)
|
||||
return;
|
||||
|
||||
gzt = thing->z + spritetopoffset[lump];
|
||||
|
||||
// killough 4/9/98: clip things which are out of view due to height
|
||||
// [RH] This doesn't work too well with freelook
|
||||
// if (thing->z > viewz + FixedDiv(centeryfrac, yscale) ||
|
||||
// gzt < viewz - FixedDiv(centeryfrac-viewheight, yscale))
|
||||
// return;
|
||||
|
||||
// killough 3/27/98: exclude things totally separated
|
||||
// from the viewer, by either water or fake ceilings
|
||||
// killough 4/11/98: improve sprite clipping for underwater/fake ceilings
|
||||
|
||||
heightsec = thing->subsector->sector->heightsec;
|
||||
|
||||
if (heightsec != -1) // only clip things which are in special sectors
|
||||
{
|
||||
int phs = viewplayer->mo->subsector->sector->heightsec;
|
||||
|
||||
if (phs != -1 && viewz < sectors[phs].floorheight ?
|
||||
thing->z >= sectors[heightsec].floorheight :
|
||||
gzt < sectors[heightsec].floorheight)
|
||||
return;
|
||||
if (phs != -1 && viewz > sectors[phs].ceilingheight ?
|
||||
gzt < sectors[heightsec].ceilingheight &&
|
||||
viewz >= sectors[heightsec].ceilingheight :
|
||||
thing->z >= sectors[heightsec].ceilingheight)
|
||||
return;
|
||||
}
|
||||
|
||||
// store information in a vissprite
|
||||
vis = R_NewVisSprite ();
|
||||
|
||||
// killough 3/27/98: save sector for special clipping later
|
||||
vis->heightsec = heightsec;
|
||||
|
||||
vis->mobjflags = thing->flags;
|
||||
vis->scale = yscale;
|
||||
vis->gx = thing->x;
|
||||
vis->gy = thing->y;
|
||||
vis->gz = thing->z;
|
||||
vis->gzt = thing->z + spritetopoffset[lump];
|
||||
vis->gzt = gzt; // killough 3/27/98
|
||||
vis->texturemid = vis->gzt - viewz;
|
||||
vis->x1 = x1 < 0 ? 0 : x1;
|
||||
vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2;
|
||||
|
@ -876,21 +913,25 @@ void R_DrawSprite (vissprite_t* spr)
|
|||
int r2;
|
||||
fixed_t scale;
|
||||
fixed_t lowscale;
|
||||
int silhouette;
|
||||
|
||||
for (x = spr->x1 ; x<=spr->x2 ; x++)
|
||||
r_dsclipbot[x] = r_dscliptop[x] = -2;
|
||||
|
||||
// Scan drawsegs from end to start for obscuring segs.
|
||||
// The first drawseg that has a greater scale
|
||||
// is the clip seg.
|
||||
for (ds=ds_p-1 ; ds >= drawsegs ; ds--)
|
||||
// The first drawseg that has a greater scale is the clip seg.
|
||||
|
||||
// Modified by Lee Killough:
|
||||
// (pointer check was originally nonportable
|
||||
// and buggy, by going past LEFT end of array):
|
||||
|
||||
// for (ds=ds_p-1 ; ds >= drawsegs ; ds--) old buggy code
|
||||
|
||||
for (ds = ds_p ; ds-- > drawsegs ; ) // new -- killough
|
||||
{
|
||||
// determine if the drawseg obscures the sprite
|
||||
if (ds->x1 > spr->x2
|
||||
|| ds->x2 < spr->x1
|
||||
|| (!ds->silhouette
|
||||
&& !ds->maskedtexturecol) )
|
||||
|| (!ds->silhouette && !ds->maskedtexturecol) )
|
||||
{
|
||||
// does not cover sprite
|
||||
continue;
|
||||
|
@ -923,41 +964,61 @@ void R_DrawSprite (vissprite_t* spr)
|
|||
|
||||
|
||||
// clip this piece of the sprite
|
||||
silhouette = ds->silhouette;
|
||||
// killough 3/27/98: optimized and made much shorter
|
||||
|
||||
if (spr->gz >= ds->bsilheight)
|
||||
silhouette &= ~SIL_BOTTOM;
|
||||
|
||||
if (spr->gzt <= ds->tsilheight)
|
||||
silhouette &= ~SIL_TOP;
|
||||
|
||||
if (silhouette == 1)
|
||||
{
|
||||
// bottom sil
|
||||
if (ds->silhouette&SIL_BOTTOM && spr->gz < ds->bsilheight) //bottom sil
|
||||
for (x=r1 ; x<=r2 ; x++)
|
||||
if (r_dsclipbot[x] == -2)
|
||||
r_dsclipbot[x] = ds->sprbottomclip[x];
|
||||
}
|
||||
else if (silhouette == 2)
|
||||
{
|
||||
// top sil
|
||||
|
||||
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];
|
||||
}
|
||||
else if (silhouette == 3)
|
||||
{
|
||||
// both
|
||||
for (x=r1 ; x<=r2 ; x++)
|
||||
{
|
||||
if (r_dsclipbot[x] == -2)
|
||||
r_dsclipbot[x] = ds->sprbottomclip[x];
|
||||
if (r_dscliptop[x] == -2)
|
||||
r_dscliptop[x] = ds->sprtopclip[x];
|
||||
}
|
||||
}
|
||||
|
||||
// killough 3/27/98:
|
||||
// Clip the sprite against deep water and/or fake ceilings.
|
||||
// killough 4/9/98: optimize by adding mh
|
||||
// killough 4/11/98: improve sprite clipping for underwater/fake ceilings
|
||||
|
||||
if (spr->heightsec != -1) // only things in specially marked sectors
|
||||
{
|
||||
fixed_t h,mh;
|
||||
int phs = viewplayer->mo->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;
|
||||
}
|
||||
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 &&
|
||||
(h >>= FRACBITS) < viewheight)
|
||||
{
|
||||
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])
|
||||
r_dsclipbot[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;
|
||||
}
|
||||
}
|
||||
}
|
||||
// killough 3/27/98: end special clipping for deep water / fake ceilings
|
||||
|
||||
// all clipping has been performed, so draw the sprite
|
||||
|
||||
|
@ -1043,7 +1104,14 @@ void R_DrawMasked (void)
|
|||
}
|
||||
|
||||
// render any remaining masked mid textures
|
||||
for (ds=ds_p-1 ; ds >= drawsegs ; ds--)
|
||||
|
||||
// Modified by Lee Killough:
|
||||
// (pointer check was originally nonportable
|
||||
// and buggy, by going past LEFT end of array):
|
||||
|
||||
// for (ds=ds_p-1 ; ds >= drawsegs ; ds--) old buggy code
|
||||
|
||||
for (ds=ds_p ; ds-- > drawsegs ; ) // new -- killough
|
||||
if (ds->maskedtexturecol)
|
||||
R_RenderMaskedSegRange (ds, ds->x1, ds->x2);
|
||||
|
||||
|
|
|
@ -1,4 +1,83 @@
|
|||
July 26, 1998
|
||||
- If FONTA?? is available, it is now used in deference to STCFN??? (i.e.
|
||||
-file heretic)
|
||||
- Renamed all the WICHAR?? in zdoom.wad to FONTB?? to match the naming
|
||||
convention used by Heretic and Hexen.
|
||||
|
||||
July 23, 1998
|
||||
- I must be an idiot! I took a fix from BOOM for freeing the lnames array too
|
||||
soon and stuck it into ZDoom without really thinking about it. In BOOM (and
|
||||
DOOM) lnames[] is dynamically allocated. In ZDoom, it's static since it
|
||||
only needs to contain two items (the patch of the level just left and the
|
||||
patch of the level being entered).
|
||||
- Using the changemap command no longer says you are leaving the map you're
|
||||
entering when no title patch is provided. (Unless they're one and the same.)
|
||||
|
||||
July 22, 1998
|
||||
- Added a z parameter to P_TeleportMove() to properly handle checks in the
|
||||
third dimension. Previously, I was checking for this, too, but against the
|
||||
thing's original position. Now I check against the desired z location. This
|
||||
prevents monsters from teleporting inside of each other.
|
||||
|
||||
July 19, 1998
|
||||
- Improved handling of international keymaps (such as the French one) by
|
||||
moving all responsibility for determining the shifted state of keys into
|
||||
i_input.c. C_consol.c no longer maintains a ShiftLOT since .data3 of the
|
||||
key event will contain a character that is sensitive of the current state
|
||||
of modifier keys. (i.e. .data3 contains 'a' when the A key is pressed and
|
||||
'A' when SHIFT-A is pressed.)
|
||||
- Made some changes to D_DoAdvanceDemo() and G_CheckDemoStatus() so that
|
||||
using the player setup menu during demo playback is now safe.
|
||||
- Added a check to C_BackupCVars() so that it doesn't back up CVAR_LATCH
|
||||
cvars are not saved. This is unnecessary since they don't actually
|
||||
change until a new game anyway. The primary advantage of this is that
|
||||
starting a new game during demo playback now uses the selected skill
|
||||
level (again).
|
||||
- Anything spawned by a boss shooter will now always telefrag even if
|
||||
LEVEL_MONSTERSTELEFRAG is not set.
|
||||
- Modifed PIT_RadiusAttack() (again) so that when a barrel is doing the
|
||||
exploding, the original damage code is used.
|
||||
- Removed the bitwise and against 0xff for angle in R_DrawSky() and
|
||||
R_DrawMaskedSky(). Some skies in various PWADs are wider than this, and
|
||||
R_GetColumn() masks it to the proper width for us anyway.
|
||||
|
||||
July 18, 1998
|
||||
- Changed the unknown thing to have no gravity so that it stays at the
|
||||
height it was spawned at (useful with Hexen).
|
||||
- Discovered the source of a memory leak: When I added the thing_list code
|
||||
from BOOM, I left out some from P_UnsetThingPosition(), so
|
||||
P_SetThingPosition() was always creating a new thing_list and letting the
|
||||
old one waste space. Conveyors even work now! Yay!
|
||||
- Removed support for repeating the left and right arrow keys in m_menu.c
|
||||
since some people had trouble with it.
|
||||
- Changed D_DoServerInfoChange() so that it doesn't print messages in
|
||||
single player games.
|
||||
|
||||
July 16, 1998
|
||||
- Added entries for Heretic to SWITCHES and ANIMATED lumps (because I can).
|
||||
- Did equivalent things for BOOM SWITCHES lumps.
|
||||
- Removed MAXANIMS limit by scanning through the AnimDefs array to find out
|
||||
how many entries it contains and then allocating that many anim_t's. Also
|
||||
added support for BOOM ANIMATED lumps.
|
||||
- Reduced the Revenant's height from 80 back to 56 to fix a problem with a
|
||||
trap on DOOM2 MAP27. The new height caused the revenants heads to get
|
||||
stuck in the ceiling, so the platforms they were on wouldn't lower. Since
|
||||
there are probably other situations like this elsewhere, I went and gave
|
||||
all the monsters their original heights back.
|
||||
- Fixed a problem with BOOM's openings limit removal. Pointers to openings
|
||||
get stored in drawsegs, and the realloc() of the openings didn't bother
|
||||
to adjust those pointers. A simple fix in r_segs.c once I figured out what
|
||||
the problem was.
|
||||
- Incorporated BOOM's Medusa fix.
|
||||
|
||||
July 15, 1998
|
||||
- Added Lee Killough's generalized scrollers from BOOM.
|
||||
- Added Rand Phares' thing list stuff from BOOM.
|
||||
- Finished support for BOOM's multiple sector thinkers and threw in the
|
||||
elevator code in the process (but nothing that calls it).
|
||||
|
||||
July 14, 1998
|
||||
- Started adding support for BOOM's multiple actions per sector.
|
||||
- Uploaded the 1.14 binaries and source to notgod.com.
|
||||
- Fixed bug that caused the bunny scroller to crash: Using 0 instead of
|
||||
&screens[0] in the calls to F_DrawPatchCol().
|
||||
|
|
|
@ -854,12 +854,22 @@ void S_ParseSndInfo (void)
|
|||
int lastlump, lump;
|
||||
char *sndinfo;
|
||||
char *logicalname;
|
||||
char *data;
|
||||
|
||||
lastlump = 0;
|
||||
while ((lump = W_FindLump ("SNDINFO", &lastlump)) != -1) {
|
||||
sndinfo = W_CacheLumpNum (lump, PU_CACHE);
|
||||
|
||||
while ( (sndinfo = COM_Parse (sndinfo)) ) {
|
||||
while ( (data = COM_Parse (sndinfo)) ) {
|
||||
if (com_token[0] == ';') {
|
||||
// Handle comments from Hexen MAPINFO lumps
|
||||
while (*sndinfo && *sndinfo != ';')
|
||||
sndinfo++;
|
||||
while (*sndinfo && *sndinfo != '\n')
|
||||
sndinfo++;
|
||||
continue;
|
||||
}
|
||||
sndinfo = data;
|
||||
if (com_token[0] == '$') {
|
||||
// com_token is a command
|
||||
|
||||
|
@ -924,6 +934,16 @@ void S_ParseSndInfo (void)
|
|||
ambient->volume = 255;
|
||||
else if (ambient->volume < 0)
|
||||
ambient->volume = 0;
|
||||
} else if (!stricmp (com_token + 1, "map")) {
|
||||
// Hexen-style $MAP command
|
||||
level_info_t *info;
|
||||
|
||||
sndinfo = COM_Parse (sndinfo);
|
||||
sprintf (com_token, "MAP%02d", atoi (com_token));
|
||||
info = FindLevelInfo (com_token);
|
||||
sndinfo = COM_Parse (sndinfo);
|
||||
if (info->mapname[0])
|
||||
uppercopy (info->music, com_token);
|
||||
} else {
|
||||
Printf ("Unknown SNDINFO command %s\n", com_token);
|
||||
while (*sndinfo != '\n' && *sndinfo != '\0')
|
||||
|
|
|
@ -48,7 +48,7 @@ void ST_initNew (void)
|
|||
}
|
||||
*/
|
||||
for (i = 0; i < 4; i++) {
|
||||
if ((lump = W_CheckNumForName (ammopatches[i])) != -1)
|
||||
if ((lump = (W_CheckNumForName) (ammopatches[i], ns_sprites)) != -1)
|
||||
ammos[i] = W_CacheLumpNum (lump, PU_STATIC);
|
||||
}
|
||||
|
||||
|
|
31
code/W_wad.c
31
code/W_wad.c
|
@ -190,7 +190,7 @@ void W_AddFile (char *filename)
|
|||
//
|
||||
void W_InitMultipleFiles (char** filenames)
|
||||
{
|
||||
int size;
|
||||
int i;
|
||||
|
||||
// open all the files, load headers, and count lumps
|
||||
numlumps = 0;
|
||||
|
@ -204,20 +204,25 @@ void W_InitMultipleFiles (char** filenames)
|
|||
if (!numlumps)
|
||||
I_Error ("W_InitFiles: no files found");
|
||||
|
||||
// [RH] Set namespace markers to global for everything
|
||||
for (i = 0; i < numlumps; i++)
|
||||
lumpinfo[i].namespc = ns_global;
|
||||
|
||||
// [RH] Merge sprite and flat groups.
|
||||
// (We don't need to bother with patches, since
|
||||
// Doom doesn't use markers to identify them.)
|
||||
|
||||
W_MergeLumps ("S_START", "S_END");
|
||||
W_MergeLumps ("F_START", "F_END");
|
||||
W_MergeLumps ("S_START", "S_END", ns_sprites);
|
||||
W_MergeLumps ("F_START", "F_END", ns_flats);
|
||||
W_MergeLumps ("C_START", "C_END", ns_colormaps);
|
||||
|
||||
// [RH] Set up hash table
|
||||
W_InitHashChains ();
|
||||
|
||||
// set up caching
|
||||
size = numlumps * sizeof(*lumpcache);
|
||||
lumpcache = Malloc (size);
|
||||
memset (lumpcache, 0, size);
|
||||
i = numlumps * sizeof(*lumpcache);
|
||||
lumpcache = Z_Malloc (i, PU_STATIC, 0);
|
||||
memset (lumpcache, 0, i);
|
||||
}
|
||||
|
||||
|
||||
|
@ -229,7 +234,7 @@ void W_InitMultipleFiles (char** filenames)
|
|||
//
|
||||
void W_InitFile (char* filename)
|
||||
{
|
||||
char* names[2];
|
||||
char *names[2];
|
||||
|
||||
names[0] = filename;
|
||||
names[1] = NULL;
|
||||
|
@ -253,8 +258,9 @@ int W_NumLumps (void)
|
|||
// Returns -1 if name not found.
|
||||
//
|
||||
// [RH] Changed to use hash lookup ala BOOM instead of a linear search
|
||||
// and namespace parameter
|
||||
//
|
||||
int W_CheckNumForName (const char *name)
|
||||
int (W_CheckNumForName) (const char *name, int space)
|
||||
{
|
||||
char uname[8];
|
||||
int i;
|
||||
|
@ -263,7 +269,7 @@ int W_CheckNumForName (const char *name)
|
|||
i = lumpinfo[W_LumpNameHash (uname) % (unsigned)numlumps].index;
|
||||
|
||||
while (i != -1) {
|
||||
if (!strncmp (lumpinfo[i].name, uname, 8))
|
||||
if (!strncmp (lumpinfo[i].name, uname, 8) && lumpinfo[i].namespc == space)
|
||||
break;
|
||||
i = lumpinfo[i].next;
|
||||
}
|
||||
|
@ -429,7 +435,7 @@ static BOOL IsMarker (const char *name, const char *marker)
|
|||
//
|
||||
// Basically from Boom, too, although I tried to write
|
||||
// it independently.
|
||||
void W_MergeLumps (const char *start, const char *end)
|
||||
void W_MergeLumps (const char *start, const char *end, int space)
|
||||
{
|
||||
char ustart[8], uend[8];
|
||||
lumpinfo_t *newlumpinfos;
|
||||
|
@ -460,6 +466,7 @@ void W_MergeLumps (const char *start, const char *end)
|
|||
newlumpinfos[0].handle =
|
||||
newlumpinfos[0].position =
|
||||
newlumpinfos[0].size = 0;
|
||||
newlumpinfos[0].namespc = ns_global;
|
||||
}
|
||||
} else {
|
||||
// Copy lumpinfo down this list
|
||||
|
@ -473,7 +480,8 @@ void W_MergeLumps (const char *start, const char *end)
|
|||
haveEndMarker = true;
|
||||
insideBlock = false;
|
||||
} else {
|
||||
newlumpinfos[newlumps++] = lumpinfo[i];
|
||||
newlumpinfos[newlumps] = lumpinfo[i];
|
||||
newlumpinfos[newlumps++].namespc = space;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -487,6 +495,7 @@ void W_MergeLumps (const char *start, const char *end)
|
|||
newlumpinfos[newlumps].handle =
|
||||
newlumpinfos[newlumps].position =
|
||||
newlumpinfos[newlumps].size = 0;
|
||||
newlumpinfos[newlumps].namespc = ns_global;
|
||||
newlumps++;
|
||||
}
|
||||
|
||||
|
|
|
@ -440,7 +440,7 @@ static int WI_DrawName (char *str, int x, int y)
|
|||
char charname[9];
|
||||
|
||||
while (*str) {
|
||||
sprintf (charname, "WICHAR%02x", toupper(*str));
|
||||
sprintf (charname, "FONTB%02u", toupper(*str) - 32);
|
||||
lump = W_CheckNumForName (charname);
|
||||
if (lump != -1) {
|
||||
p = W_CacheLumpNum (lump, PU_CACHE);
|
||||
|
@ -452,7 +452,8 @@ static int WI_DrawName (char *str, int x, int y)
|
|||
str++;
|
||||
}
|
||||
|
||||
return p ? (5*SHORT(p->height))/4 : 0;
|
||||
p = W_CacheLumpName ("FONTB39", PU_CACHE);
|
||||
return (5*(SHORT(p->height)-SHORT(p->topoffset)))/4;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1630,7 +1631,7 @@ static int WI_CalcWidth (char *str)
|
|||
return 0;
|
||||
|
||||
while (*str) {
|
||||
sprintf (charname, "WICHAR%02x", toupper(*str));
|
||||
sprintf (charname, "FONTB%02u", toupper(*str) - 32);
|
||||
lump = W_CheckNumForName (charname);
|
||||
if (lump != -1) {
|
||||
p = W_CacheLumpNum (lump, PU_CACHE);
|
||||
|
@ -1683,11 +1684,6 @@ void WI_loadData(void)
|
|||
for (i = 0; i < 2; i++) {
|
||||
char *lname = (i == 0 ? wbs->lname0 : wbs->lname1);
|
||||
|
||||
if (lnames[i]) {
|
||||
Z_Free (lnames[i]);
|
||||
lnames[i] = NULL;
|
||||
}
|
||||
|
||||
if (lname)
|
||||
j = W_CheckNumForName (lname);
|
||||
else
|
||||
|
@ -1821,6 +1817,13 @@ void WI_unloadData(void)
|
|||
for (i=0 ; i<10 ; i++)
|
||||
Z_ChangeTag(num[i], PU_CACHE);
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (lnames[i]) {
|
||||
Z_ChangeTag (lnames[i], PU_CACHE);
|
||||
lnames[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (gamemode != commercial)
|
||||
{
|
||||
Z_ChangeTag(yah[0], PU_CACHE);
|
||||
|
|
|
@ -348,6 +348,7 @@ void Cmd_Limits (player_t *plyr, int argc, char **argv)
|
|||
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");
|
||||
|
|
|
@ -33,7 +33,7 @@ extern int gametic;
|
|||
extern BOOL automapactive; // in AM_map.c
|
||||
|
||||
typedef enum cstate_t {
|
||||
up=0, down, falling, rising
|
||||
up=0, down=1, falling=2, rising=3
|
||||
} constate;
|
||||
|
||||
|
||||
|
@ -43,7 +43,7 @@ BOOL vidactive = false, gotconback = false;
|
|||
BOOL cursoron = false;
|
||||
int ShowRows, SkipRows, ConsoleTicker, ConBottom, ConScroll, RowAdjust;
|
||||
int CursorTicker, ScrollState = 0;
|
||||
constate ConsoleState = up;
|
||||
int ConsoleState = up;
|
||||
char VersionString[8];
|
||||
|
||||
event_t RepeatEvent; // always type ev_keydown
|
||||
|
@ -81,15 +81,6 @@ static int HistSize;
|
|||
cvar_t *NotifyTime;
|
||||
static byte NotifyStrings[4][256];
|
||||
|
||||
static char ShiftLOT[] = {
|
||||
'\"', '(', ')', '*', '+', '<', '_', '>', '?', // 9 39->
|
||||
')', '!', '@', '#', '$', '%', '^', '&', '*', '(', ':', ':', '<', '+', // 14 ->61
|
||||
|
||||
'{', '|', '}', '^', '_', '~', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 14 91->
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', // 14 ...
|
||||
'W', 'X', 'Y', 'Z' // 4 ->122
|
||||
};
|
||||
|
||||
FILE *Logfile = NULL;
|
||||
|
||||
|
||||
|
@ -752,7 +743,7 @@ void C_HandleKey (event_t *ev, byte *buffer, int len)
|
|||
buffer[0] = buffer[1] = buffer[len+4] = 0;
|
||||
AddCommandString (&buffer[2]);
|
||||
TabbedLast = false;
|
||||
} else if (ev->data3 == '`' || ev->data1 == KEY_ESCAPE) {
|
||||
} else if (ev->data2 == '`' || ev->data1 == KEY_ESCAPE) {
|
||||
// Close console, both ` and ESC clear command line
|
||||
|
||||
buffer[0] = buffer[1] = buffer[len+4] = 0;
|
||||
|
@ -766,13 +757,6 @@ void C_HandleKey (event_t *ev, byte *buffer, int len)
|
|||
if (buffer[0] < len) {
|
||||
char data = ev->data3;
|
||||
|
||||
if (KeysShifted) {
|
||||
if (data >= 39 && data <= 61)
|
||||
data = ShiftLOT[data-39];
|
||||
else if (data >= 91 && data <= 122)
|
||||
data = ShiftLOT[data-68];
|
||||
}
|
||||
|
||||
if (buffer[1] == buffer[0]) {
|
||||
buffer[buffer[0] + 2] = data;
|
||||
} else {
|
||||
|
|
|
@ -102,7 +102,7 @@ void D_DoServerInfoChange (byte **stream)
|
|||
if ( (breakpt = strchr (value, '\\')) )
|
||||
*breakpt = 0;
|
||||
|
||||
if (SetServerVar (ptr, value))
|
||||
if (SetServerVar (ptr, value) && netgame)
|
||||
Printf ("%s changed to %s\n", ptr, value);
|
||||
|
||||
*(value - 1) = '\\';
|
||||
|
|
|
@ -741,7 +741,8 @@ BOOL M_OptResponder (event_t *ev)
|
|||
}
|
||||
|
||||
if (item->type == bitflag && flagsvar &&
|
||||
(ch == KEY_LEFTARROW || ch == KEY_RIGHTARROW || ch == KEY_ENTER)) {
|
||||
(ch == KEY_LEFTARROW || ch == KEY_RIGHTARROW || ch == KEY_ENTER)
|
||||
&& !demoplayback) {
|
||||
int newflags = *item->e.flagint ^ item->a.flagmask;
|
||||
char val[16];
|
||||
|
||||
|
|
|
@ -169,10 +169,7 @@ void T_MoveCeiling (ceiling_t* ceiling)
|
|||
// EV_DoCeiling
|
||||
// Move a ceiling up/down and all around!
|
||||
//
|
||||
int
|
||||
EV_DoCeiling
|
||||
( line_t* line,
|
||||
ceiling_e type )
|
||||
int EV_DoCeiling (line_t *line, ceiling_e type)
|
||||
{
|
||||
int secnum;
|
||||
int rtn;
|
||||
|
@ -183,6 +180,7 @@ EV_DoCeiling
|
|||
rtn = 0;
|
||||
|
||||
// Reactivate in-stasis ceilings...for certain types.
|
||||
// This restarts a crusher after it has been stopped
|
||||
switch(type)
|
||||
{
|
||||
case fastCrushAndRaise:
|
||||
|
@ -193,17 +191,19 @@ EV_DoCeiling
|
|||
break;
|
||||
}
|
||||
|
||||
// affects all sectors with the same tag as the linedef
|
||||
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
if (sec->specialdata)
|
||||
// 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->specialdata = ceiling;
|
||||
sec->ceilingdata = ceiling; //jff 2/22/98
|
||||
ceiling->thinker.function.acp1 = (actionf_p1)T_MoveCeiling;
|
||||
ceiling->sector = sec;
|
||||
ceiling->crush = false;
|
||||
|
@ -283,7 +283,7 @@ void P_RemoveActiveCeiling(ceiling_t* c)
|
|||
{
|
||||
if (activeceilings[i] == c)
|
||||
{
|
||||
activeceilings[i]->sector->specialdata = NULL;
|
||||
activeceilings[i]->sector->ceilingdata = NULL; // [RH]
|
||||
P_RemoveThinker (&activeceilings[i]->thinker);
|
||||
activeceilings[i] = NULL;
|
||||
break;
|
||||
|
|
|
@ -210,7 +210,7 @@ P_SpawnStrobeFlash
|
|||
//
|
||||
// Start strobing lights (usually from a trigger)
|
||||
//
|
||||
void EV_StartLightStrobing(line_t* line)
|
||||
void EV_StartLightStrobing (line_t *line)
|
||||
{
|
||||
int secnum;
|
||||
sector_t* sec;
|
||||
|
@ -219,7 +219,7 @@ void EV_StartLightStrobing(line_t* line)
|
|||
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
if (sec->specialdata)
|
||||
if (P_SectorActive (lighting_special, sec)) //jff 2/22/98
|
||||
continue;
|
||||
|
||||
P_SpawnStrobeFlash (sec,SLOWDARK, 0);
|
||||
|
|
|
@ -136,11 +136,7 @@ void T_PlatRaise(plat_t* plat)
|
|||
// Do Platforms
|
||||
// "amount" is only used for SOME platforms.
|
||||
//
|
||||
int
|
||||
EV_DoPlat
|
||||
( line_t* line,
|
||||
plattype_e type,
|
||||
int amount )
|
||||
int EV_DoPlat (line_t *line, plattype_e type, int amount)
|
||||
{
|
||||
plat_t* plat;
|
||||
int secnum;
|
||||
|
@ -150,9 +146,8 @@ EV_DoPlat
|
|||
secnum = -1;
|
||||
rtn = 0;
|
||||
|
||||
|
||||
// Activate all <type> plats that are in_stasis
|
||||
switch(type)
|
||||
switch (type)
|
||||
{
|
||||
case perpetualRaise:
|
||||
P_ActivateInStasis(line->tag);
|
||||
|
@ -166,7 +161,7 @@ EV_DoPlat
|
|||
{
|
||||
sec = §ors[secnum];
|
||||
|
||||
if (sec->specialdata)
|
||||
if (P_SectorActive (floor_special, sec)) //jff 2/23/98 multiple thinkers
|
||||
continue;
|
||||
|
||||
// Find lowest & highest floors around sector
|
||||
|
@ -176,11 +171,15 @@ EV_DoPlat
|
|||
|
||||
plat->type = type;
|
||||
plat->sector = sec;
|
||||
plat->sector->specialdata = plat;
|
||||
plat->sector->floordata = plat; //jff 2/23/98 multiple thinkers
|
||||
plat->thinker.function.acp1 = (actionf_p1) T_PlatRaise;
|
||||
plat->crush = false;
|
||||
plat->tag = line->tag;
|
||||
|
||||
//jff 1/26/98 Avoid raise plat bouncing a head off a ceiling and then
|
||||
//going down forever -- default low to plat height when triggered
|
||||
plat->low = sec->floorheight;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case raiseToNearestAndChange:
|
||||
|
@ -309,10 +308,11 @@ void P_AddActivePlat(plat_t* plat)
|
|||
void P_RemoveActivePlat(plat_t* plat)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0;i < MaxPlats;i++)
|
||||
if (plat == activeplats[i])
|
||||
{
|
||||
(activeplats[i])->sector->specialdata = NULL;
|
||||
(activeplats[i])->sector->floordata = NULL; // [RH]
|
||||
P_RemoveThinker(&(activeplats[i])->thinker);
|
||||
activeplats[i] = NULL;
|
||||
|
||||
|
|
|
@ -64,7 +64,6 @@ int EV_Teleport (line_t *line, int side, mobj_t *thing)
|
|||
if (side == 1)
|
||||
return 0;
|
||||
|
||||
|
||||
tag = line->tag;
|
||||
for (i = 0; i < numsectors; i++)
|
||||
{
|
||||
|
@ -94,10 +93,9 @@ int EV_Teleport (line_t *line, int side, mobj_t *thing)
|
|||
oldy = thing->y;
|
||||
oldz = thing->z;
|
||||
|
||||
if (!P_TeleportMove (thing, m->x, m->y))
|
||||
if (!P_TeleportMove (thing, m->x, m->y, m->z, false))
|
||||
return 0;
|
||||
|
||||
thing->z = thing->floorz; //fixme: not needed?
|
||||
if (thing->player)
|
||||
thing->player->viewz = thing->z+thing->player->viewheight;
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "c_cvars.h"
|
||||
|
||||
// SKY, store the number for name.
|
||||
#define SKYFLATNAME "F_SKY1"
|
||||
extern char SKYFLATNAME[8];
|
||||
|
||||
// The sky map is 256*128*4 maps.
|
||||
#define ANGLETOSKYSHIFT 22
|
||||
|
|
|
@ -118,8 +118,6 @@ extern angle_t rw_normalangle;
|
|||
// angle to line origin
|
||||
extern int rw_angle1;
|
||||
|
||||
// Segs count?
|
||||
extern int sscount;
|
||||
|
||||
extern visplane_t* floorplane;
|
||||
extern visplane_t* ceilingplane;
|
||||
|
|
16
code/w_wad.h
16
code/w_wad.h
|
@ -68,9 +68,16 @@ typedef struct lumpinfo_s
|
|||
int next;
|
||||
int index;
|
||||
|
||||
int pad; // [RH] Pad to 32 bytes
|
||||
int namespc;
|
||||
} lumpinfo_t;
|
||||
|
||||
// [RH] Namespaces from BOOM.
|
||||
typedef enum {
|
||||
ns_global = 0,
|
||||
ns_sprites,
|
||||
ns_flats,
|
||||
ns_colormaps
|
||||
} namespace_t;
|
||||
|
||||
extern void** lumpcache;
|
||||
extern lumpinfo_t* lumpinfo;
|
||||
|
@ -78,7 +85,8 @@ extern int numlumps;
|
|||
|
||||
void W_InitMultipleFiles (char** filenames);
|
||||
|
||||
int W_CheckNumForName (const char *name);
|
||||
#define W_CheckNumForName(name) (W_CheckNumForName)(name, ns_global)
|
||||
int (W_CheckNumForName) (const char *name, int);
|
||||
int W_GetNumForName (const char *name);
|
||||
|
||||
int W_LumpLength (int lump);
|
||||
|
@ -88,7 +96,7 @@ void *W_CacheLumpNum (int lump, int tag);
|
|||
|
||||
// [RH] W_CacheLumpName() is now a macro
|
||||
#define W_CacheLumpName(name,tag) \
|
||||
W_CacheLumpNum (W_GetNumForName(name), tag)
|
||||
W_CacheLumpNum (W_GetNumForName(name), (tag))
|
||||
|
||||
void W_Profile (void);
|
||||
|
||||
|
@ -99,7 +107,7 @@ unsigned W_LumpNameHash (const char *name); // [RH] Create hash key from an 8
|
|||
void W_InitHashChains (void); // [RH] Set up the lumpinfo hashing
|
||||
|
||||
// [RH] Combine multiple marked ranges of lumps into one.
|
||||
void W_MergeLumps (const char *start, const char *end);
|
||||
void W_MergeLumps (const char *start, const char *end, int);
|
||||
|
||||
// Copy an 8-char string and uppercase it.
|
||||
void uppercopy (char *to, const char *from);
|
||||
|
|
18
readme.14a.txt
Normal file
18
readme.14a.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
This archive contains a unified diff that will patch the source code for
|
||||
ZDoom version 1.14 to 1.14a. To use it, you need to have already downloaded
|
||||
the archive zdoom114-src.zip and extracted its contains. Then extract
|
||||
patch.diff from this archive into your source code directory and apply it
|
||||
with the command:
|
||||
|
||||
patch -F 3 -i patch.diff
|
||||
|
||||
(You need to have kept the patch.exe included with zdoom114-src.zip.)
|
||||
|
||||
Note that there was another version of this archive from July. The only
|
||||
difference between that one and this one is that this one fixes the
|
||||
savegame loading bug. If you already installed that patch, you can do the
|
||||
fix yourself by changing one string in G_DoLoadGame() in g_game.c. The
|
||||
string "version %i" should be changed to "version %ia".
|
||||
|
||||
Randy Heit
|
||||
rheit@usa.net
|
Loading…
Add table
Add a link
Reference in a new issue