as re-released 2008-09-04
This commit is contained in:
commit
3ae84e87c6
87 changed files with 80377 additions and 0 deletions
107
Hexen Source/AM_DATA.H
Normal file
107
Hexen Source/AM_DATA.H
Normal file
|
@ -0,0 +1,107 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** am_data.h : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: am_data.h,v $
|
||||
//** $Revision: 1.2 $
|
||||
//** $Date: 96/01/06 18:37:22 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#ifndef __AMDATA_H__
|
||||
#define __AMDATA_H__
|
||||
|
||||
#pragma once
|
||||
|
||||
// a line drawing of the player pointing right, starting from the middle.
|
||||
|
||||
#define R ((8*PLAYERRADIUS)/7)
|
||||
|
||||
mline_t player_arrow[] = {
|
||||
{ { -R+R/4, 0 }, { 0, 0} }, // center line.
|
||||
{ { -R+R/4, R/8 }, { R, 0} }, // blade
|
||||
{ { -R+R/4, -R/8 }, { R, 0 } },
|
||||
{ { -R+R/4, -R/4 }, { -R+R/4, R/4 } }, // crosspiece
|
||||
{ { -R+R/8, -R/4 }, { -R+R/8, R/4 } },
|
||||
{ { -R+R/8, -R/4 }, { -R+R/4, -R/4} }, //crosspiece connectors
|
||||
{ { -R+R/8, R/4 }, { -R+R/4, R/4} },
|
||||
{ { -R-R/4, R/8 }, { -R-R/4, -R/8 } }, //pommel
|
||||
{ { -R-R/4, R/8 }, { -R+R/8, R/8 } },
|
||||
{ { -R-R/4, -R/8}, { -R+R/8, -R/8 } }
|
||||
};
|
||||
|
||||
/*
|
||||
mline_t keysquare[] = {
|
||||
{ { 0, 0 }, { R/4, -R/2 } },
|
||||
{ { R/4, -R/2 }, { R/2, -R/2 } },
|
||||
{ { R/2, -R/2 }, { R/2, R/2 } },
|
||||
{ { R/2, R/2 }, { R/4, R/2 } },
|
||||
{ { R/4, R/2 }, { 0, 0 } }, // handle part type thing
|
||||
{ { 0, 0 }, { -R, 0 } }, // stem
|
||||
{ { -R, 0 }, { -R, -R/2 } }, // end lockpick part
|
||||
{ { -3*R/4, 0 }, { -3*R/4, -R/4 } }
|
||||
};
|
||||
*/
|
||||
|
||||
/*mline_t player_arrow[] = {
|
||||
{ { -R+R/8, 0 }, { R, 0 } }, // -----
|
||||
{ { R, 0 }, { R-R/2, R/4 } }, // ----->
|
||||
{ { R, 0 }, { R-R/2, -R/4 } },
|
||||
{ { -R+R/8, 0 }, { -R-R/8, R/4 } }, // >---->
|
||||
{ { -R+R/8, 0 }, { -R-R/8, -R/4 } },
|
||||
{ { -R+3*R/8, 0 }, { -R+R/8, R/4 } }, // >>--->
|
||||
{ { -R+3*R/8, 0 }, { -R+R/8, -R/4 } }
|
||||
};
|
||||
*/
|
||||
#undef R
|
||||
#define NUMPLYRLINES (sizeof(player_arrow)/sizeof(mline_t))
|
||||
#define NUMKEYSQUARELINES (sizeof(keysquare)/sizeof(mline_t))
|
||||
|
||||
/*
|
||||
#define R ((8*PLAYERRADIUS)/7)
|
||||
mline_t cheat_player_arrow[] = {
|
||||
{ { -R+R/8, 0 }, { R, 0 } }, // -----
|
||||
{ { R, 0 }, { R-R/2, R/6 } }, // ----->
|
||||
{ { R, 0 }, { R-R/2, -R/6 } },
|
||||
{ { -R+R/8, 0 }, { -R-R/8, R/6 } }, // >----->
|
||||
{ { -R+R/8, 0 }, { -R-R/8, -R/6 } },
|
||||
{ { -R+3*R/8, 0 }, { -R+R/8, R/6 } }, // >>----->
|
||||
{ { -R+3*R/8, 0 }, { -R+R/8, -R/6 } },
|
||||
{ { -R/2, 0 }, { -R/2, -R/6 } }, // >>-d--->
|
||||
{ { -R/2, -R/6 }, { -R/2+R/6, -R/6 } },
|
||||
{ { -R/2+R/6, -R/6 }, { -R/2+R/6, R/4 } },
|
||||
{ { -R/6, 0 }, { -R/6, -R/6 } }, // >>-dd-->
|
||||
{ { -R/6, -R/6 }, { 0, -R/6 } },
|
||||
{ { 0, -R/6 }, { 0, R/4 } },
|
||||
{ { R/6, R/4 }, { R/6, -R/7 } }, // >>-ddt->
|
||||
{ { R/6, -R/7 }, { R/6+R/32, -R/7-R/32 } },
|
||||
{ { R/6+R/32, -R/7-R/32 }, { R/6+R/10, -R/7 } }
|
||||
};
|
||||
#undef R
|
||||
#define NUMCHEATPLYRLINES (sizeof(cheat_player_arrow)/sizeof(mline_t))
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
#define R (FRACUNIT)
|
||||
mline_t triangle_guy[] = {
|
||||
{ { -.867*R, -.5*R }, { .867*R, -.5*R } },
|
||||
{ { .867*R, -.5*R } , { 0, R } },
|
||||
{ { 0, R }, { -.867*R, -.5*R } }
|
||||
};
|
||||
#undef R
|
||||
#define NUMTRIANGLEGUYLINES (sizeof(triangle_guy)/sizeof(mline_t))
|
||||
*/
|
||||
|
||||
#define R (FRACUNIT)
|
||||
mline_t thintriangle_guy[] = {
|
||||
{ { -.5*R, -.7*R }, { R, 0 } },
|
||||
{ { R, 0 }, { -.5*R, .7*R } },
|
||||
{ { -.5*R, .7*R }, { -.5*R, -.7*R } }
|
||||
};
|
||||
#undef R
|
||||
#define NUMTHINTRIANGLEGUYLINES (sizeof(thintriangle_guy)/sizeof(mline_t))
|
||||
|
||||
#endif
|
1400
Hexen Source/AM_MAP.C
Normal file
1400
Hexen Source/AM_MAP.C
Normal file
File diff suppressed because it is too large
Load diff
143
Hexen Source/AM_MAP.H
Normal file
143
Hexen Source/AM_MAP.H
Normal file
|
@ -0,0 +1,143 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** am_map.h : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: am_map.h,v $
|
||||
//** $Revision: 1.3 $
|
||||
//** $Date: 95/12/31 19:47:21 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#ifndef __AMMAP_H__
|
||||
#define __AMMAP_H__
|
||||
|
||||
#pragma once
|
||||
|
||||
// For use if I do walls with outsides/insides
|
||||
#define REDS 12*8
|
||||
#define REDRANGE 1//16
|
||||
#define BLUES (256-4*16+8)
|
||||
#define BLUERANGE 1//8
|
||||
#define GREENS (33*8)
|
||||
#define GREENRANGE 1//16
|
||||
#define GRAYS (5*8)
|
||||
#define GRAYSRANGE 1//16
|
||||
#define BROWNS (14*8)
|
||||
#define BROWNRANGE 1//16
|
||||
#define YELLOWS 10*8
|
||||
#define YELLOWRANGE 1
|
||||
#define BLACK 0
|
||||
#define WHITE 4*8
|
||||
#define PARCH 13*8-1
|
||||
#define BLOODRED 177
|
||||
#define BLUEKEY 157
|
||||
#define YELLOWKEY 137
|
||||
#define GREENKEY 198
|
||||
|
||||
// Automap colors
|
||||
|
||||
#define AM_PLR1_COLOR 157 // Blue
|
||||
#define AM_PLR2_COLOR 177 // Red
|
||||
#define AM_PLR3_COLOR 137 // Yellow
|
||||
#define AM_PLR4_COLOR 198 // Green
|
||||
#define AM_PLR5_COLOR 215 // Jade
|
||||
#define AM_PLR6_COLOR 32 // White
|
||||
#define AM_PLR7_COLOR 106 // Hazel
|
||||
#define AM_PLR8_COLOR 234 // Purple
|
||||
|
||||
#define BACKGROUND PARCH
|
||||
#define YOURCOLORS WHITE
|
||||
#define YOURRANGE 0
|
||||
#define WALLCOLORS REDS
|
||||
#define WALLRANGE REDRANGE
|
||||
#define TSWALLCOLORS GRAYS
|
||||
#define TSWALLRANGE GRAYSRANGE
|
||||
#define FDWALLCOLORS BROWNS
|
||||
#define FDWALLRANGE BROWNRANGE
|
||||
#define CDWALLCOLORS YELLOWS
|
||||
#define CDWALLRANGE YELLOWRANGE
|
||||
#define THINGCOLORS GREENS
|
||||
#define THINGRANGE GREENRANGE
|
||||
#define SECRETWALLCOLORS WALLCOLORS
|
||||
#define SECRETWALLRANGE WALLRANGE
|
||||
#define GRIDCOLORS (GRAYS + GRAYSRANGE/2)
|
||||
#define GRIDRANGE 0
|
||||
#define XHAIRCOLORS GRAYS
|
||||
|
||||
// drawing stuff
|
||||
#define FB 0
|
||||
|
||||
#define KEY_TAB 9
|
||||
#define AM_PANDOWNKEY KEY_DOWNARROW
|
||||
#define AM_PANUPKEY KEY_UPARROW
|
||||
#define AM_PANRIGHTKEY KEY_RIGHTARROW
|
||||
#define AM_PANLEFTKEY KEY_LEFTARROW
|
||||
//#define AM_PANDOWNKEY SC_DOWNARROW
|
||||
//#define AM_PANUPKEY SC_UPARROW
|
||||
//#define AM_PANRIGHTKEY SC_RIGHTARROW
|
||||
//#define AM_PANLEFTKEY SC_LEFTARROW
|
||||
|
||||
#define AM_ZOOMINKEY '='
|
||||
//#define AM_ZOOMINKEY 13
|
||||
//#define AM_ZOOMOUTKEY 12
|
||||
#define AM_ZOOMOUTKEY '-'
|
||||
#define AM_STARTKEY KEY_TAB
|
||||
#define AM_ENDKEY KEY_TAB
|
||||
#define AM_GOBIGKEY '0'
|
||||
//#define AM_GOBIGKEY 11
|
||||
//#define AM_FOLLOWKEY 33
|
||||
//#define AM_GRIDKEY 34
|
||||
#define AM_FOLLOWKEY 'f'
|
||||
#define AM_GRIDKEY 'g'
|
||||
|
||||
#define AM_NUMMARKPOINTS 10
|
||||
|
||||
#define AM_MSGHEADER (('a'<<24)+('m'<<16))
|
||||
#define AM_MSGENTERED (AM_MSGHEADER | ('e'<<8))
|
||||
#define AM_MSGEXITED (AM_MSGHEADER | ('x'<<8))
|
||||
|
||||
#define INITSCALEMTOF (.2*FRACUNIT) // scale on entry
|
||||
// how much the automap moves window per tic in frame-buffer coordinates
|
||||
#define F_PANINC 4 // moves 140 pixels in 1 second
|
||||
// how much zoom-in per tic
|
||||
#define M_ZOOMIN ((int) (1.02*FRACUNIT)) // goes to 2x in 1 second
|
||||
// how much zoom-out per tic
|
||||
#define M_ZOOMOUT ((int) (FRACUNIT/1.02)) // pulls out to 0.5x in 1 second
|
||||
|
||||
// translates between frame-buffer and map distances
|
||||
#define FTOM(x) FixedMul(((x)<<16),scale_ftom)
|
||||
#define MTOF(x) (FixedMul((x),scale_mtof)>>16)
|
||||
// translates between frame-buffer and map coordinates
|
||||
#define CXMTOF(x) (f_x + MTOF((x)-m_x))
|
||||
#define CYMTOF(y) (f_y + (f_h - MTOF((y)-m_y)))
|
||||
|
||||
// the following is crap
|
||||
#define LINE_NEVERSEE ML_DONTDRAW
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x, y;
|
||||
} fpoint_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fpoint_t a, b;
|
||||
} fline_t;
|
||||
|
||||
typedef vertex_t mpoint_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mpoint_t a, b;
|
||||
} mline_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fixed_t slp, islp;
|
||||
} islope_t;
|
||||
|
||||
// extern int f_x, f_y, f_w, f_h;
|
||||
|
||||
#endif
|
1319
Hexen Source/A_ACTION.C
Normal file
1319
Hexen Source/A_ACTION.C
Normal file
File diff suppressed because it is too large
Load diff
497
Hexen Source/CT_CHAT.C
Normal file
497
Hexen Source/CT_CHAT.C
Normal file
|
@ -0,0 +1,497 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** ct_chat.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: ct_chat.c,v $
|
||||
//** $Revision: 1.12 $
|
||||
//** $Date: 96/01/16 10:35:26 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
#include "soundst.h"
|
||||
|
||||
#define NUMKEYS 256
|
||||
|
||||
#define QUEUESIZE 128
|
||||
#define MESSAGESIZE 128
|
||||
#define MESSAGELEN 265
|
||||
|
||||
// 8-player note: Change this stuff (CT_PLR_*, and the key mappings)
|
||||
enum
|
||||
{
|
||||
CT_PLR_BLUE = 1,
|
||||
CT_PLR_RED,
|
||||
CT_PLR_YELLOW,
|
||||
CT_PLR_GREEN,
|
||||
CT_PLR_PLAYER5,
|
||||
CT_PLR_PLAYER6,
|
||||
CT_PLR_PLAYER7,
|
||||
CT_PLR_PLAYER8,
|
||||
CT_PLR_ALL
|
||||
};
|
||||
|
||||
#define CT_KEY_BLUE 'b'
|
||||
#define CT_KEY_RED 'r'
|
||||
#define CT_KEY_YELLOW 'y'
|
||||
#define CT_KEY_GREEN 'g'
|
||||
#define CT_KEY_PLAYER5 'j' // Jade
|
||||
#define CT_KEY_PLAYER6 'w' // White
|
||||
#define CT_KEY_PLAYER7 'h' // Hazel
|
||||
#define CT_KEY_PLAYER8 'p' // Purple
|
||||
#define CT_KEY_ALL 't'
|
||||
#define CT_ESCAPE 6
|
||||
|
||||
// Public data
|
||||
|
||||
void CT_Init(void);
|
||||
void CT_Drawer(void);
|
||||
boolean CT_Responder(event_t *ev);
|
||||
void CT_Ticker(void);
|
||||
char CT_dequeueChatChar(void);
|
||||
|
||||
boolean chatmodeon;
|
||||
|
||||
// Private data
|
||||
|
||||
void CT_queueChatChar(char ch);
|
||||
void CT_ClearChatMessage(int player);
|
||||
void CT_AddChar(int player, char c);
|
||||
void CT_BackSpace(int player);
|
||||
|
||||
int head;
|
||||
int tail;
|
||||
byte ChatQueue[QUEUESIZE];
|
||||
int chat_dest[MAXPLAYERS];
|
||||
char chat_msg[MAXPLAYERS][MESSAGESIZE];
|
||||
char plr_lastmsg[MAXPLAYERS][MESSAGESIZE+9];
|
||||
int msgptr[MAXPLAYERS];
|
||||
int msglen[MAXPLAYERS];
|
||||
|
||||
boolean cheated;
|
||||
|
||||
static int FontABaseLump;
|
||||
|
||||
char *CT_FromPlrText[MAXPLAYERS] =
|
||||
{
|
||||
"BLUE: ",
|
||||
"RED: ",
|
||||
"YELLOW: ",
|
||||
"GREEN: ",
|
||||
"JADE: ",
|
||||
"WHITE: ",
|
||||
"HAZEL: ",
|
||||
"PURPLE: "
|
||||
};
|
||||
|
||||
char *chat_macros[10];
|
||||
|
||||
boolean altdown;
|
||||
boolean shiftdown;
|
||||
|
||||
extern boolean usearti;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CT_Init
|
||||
//
|
||||
// Initialize chat mode data
|
||||
//===========================================================================
|
||||
|
||||
void CT_Init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
head = 0; //initialize the queue index
|
||||
tail = 0;
|
||||
chatmodeon = false;
|
||||
memset(ChatQueue, 0, QUEUESIZE);
|
||||
for(i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
chat_dest[i] = 0;
|
||||
msgptr[i] = 0;
|
||||
memset(plr_lastmsg[i], 0, MESSAGESIZE);
|
||||
memset(chat_msg[i], 0, MESSAGESIZE);
|
||||
}
|
||||
FontABaseLump = W_GetNumForName("FONTA_S")+1;
|
||||
return;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CT_Stop
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void CT_Stop(void)
|
||||
{
|
||||
chatmodeon = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CT_Responder
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
boolean CT_Responder(event_t *ev)
|
||||
{
|
||||
char *macro;
|
||||
|
||||
int sendto;
|
||||
|
||||
if(!netgame)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(ev->data1 == KEY_RALT)
|
||||
{
|
||||
altdown = (ev->type == ev_keydown);
|
||||
return false;
|
||||
}
|
||||
if(ev->data1 == KEY_RSHIFT)
|
||||
{
|
||||
shiftdown = (ev->type == ev_keydown);
|
||||
return false;
|
||||
}
|
||||
if(gamestate != GS_LEVEL || ev->type != ev_keydown)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(!chatmodeon)
|
||||
{
|
||||
sendto = 0;
|
||||
if(ev->data1 == CT_KEY_ALL)
|
||||
{
|
||||
sendto = CT_PLR_ALL;
|
||||
}
|
||||
else if(ev->data1 == CT_KEY_GREEN)
|
||||
{
|
||||
sendto = CT_PLR_GREEN;
|
||||
}
|
||||
else if(ev->data1 == CT_KEY_YELLOW)
|
||||
{
|
||||
sendto = CT_PLR_YELLOW;
|
||||
}
|
||||
else if(ev->data1 == CT_KEY_RED)
|
||||
{
|
||||
sendto = CT_PLR_RED;
|
||||
}
|
||||
else if(ev->data1 == CT_KEY_BLUE)
|
||||
{
|
||||
sendto = CT_PLR_BLUE;
|
||||
}
|
||||
else if(ev->data1 == CT_KEY_PLAYER5)
|
||||
{
|
||||
sendto = CT_PLR_PLAYER5;
|
||||
}
|
||||
else if(ev->data1 == CT_KEY_PLAYER6)
|
||||
{
|
||||
sendto = CT_PLR_PLAYER6;
|
||||
}
|
||||
else if(ev->data1 == CT_KEY_PLAYER7)
|
||||
{
|
||||
sendto = CT_PLR_PLAYER7;
|
||||
}
|
||||
else if(ev->data1 == CT_KEY_PLAYER8)
|
||||
{
|
||||
sendto = CT_PLR_PLAYER8;
|
||||
}
|
||||
if(sendto == 0 || (sendto != CT_PLR_ALL && !playeringame[sendto-1])
|
||||
|| sendto == consoleplayer+1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
CT_queueChatChar(sendto);
|
||||
chatmodeon = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(altdown)
|
||||
{
|
||||
if(ev->data1 >= '0' && ev->data1 <= '9')
|
||||
{
|
||||
if(ev->data1 == '0')
|
||||
{ // macro 0 comes after macro 9
|
||||
ev->data1 = '9'+1;
|
||||
}
|
||||
macro = chat_macros[ev->data1-'1'];
|
||||
CT_queueChatChar(KEY_ENTER); //send old message
|
||||
CT_queueChatChar(chat_dest[consoleplayer]); // chose the dest.
|
||||
while(*macro)
|
||||
{
|
||||
CT_queueChatChar(toupper(*macro++));
|
||||
}
|
||||
CT_queueChatChar(KEY_ENTER); //send it off...
|
||||
CT_Stop();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(ev->data1 == KEY_ENTER)
|
||||
{
|
||||
CT_queueChatChar(KEY_ENTER);
|
||||
usearti = false;
|
||||
CT_Stop();
|
||||
return true;
|
||||
}
|
||||
else if(ev->data1 == KEY_ESCAPE)
|
||||
{
|
||||
CT_queueChatChar(CT_ESCAPE);
|
||||
CT_Stop();
|
||||
return true;
|
||||
}
|
||||
else if(ev->data1 >= 'a' && ev->data1 <= 'z')
|
||||
{
|
||||
CT_queueChatChar(ev->data1-32);
|
||||
return true;
|
||||
}
|
||||
else if(shiftdown)
|
||||
{
|
||||
if(ev->data1 == '1')
|
||||
{
|
||||
CT_queueChatChar('!');
|
||||
return true;
|
||||
}
|
||||
else if(ev->data1 == '/')
|
||||
{
|
||||
CT_queueChatChar('?');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(ev->data1 == ' ' || ev->data1 == ',' || ev->data1 == '.'
|
||||
|| (ev->data1 >= '0' && ev->data1 <= '9') || ev->data1 == '\''
|
||||
|| ev->data1 == KEY_BACKSPACE || ev->data1 == '-' || ev->data1 == '=')
|
||||
{
|
||||
CT_queueChatChar(ev->data1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CT_Ticker
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void CT_Ticker(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
char c;
|
||||
int numplayers;
|
||||
|
||||
for(i=0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if(!playeringame[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if((c = players[i].cmd.chatchar) != 0)
|
||||
{
|
||||
if(c <= CT_PLR_ALL)
|
||||
{
|
||||
chat_dest[i] = c;
|
||||
continue;
|
||||
}
|
||||
else if(c == CT_ESCAPE)
|
||||
{
|
||||
CT_ClearChatMessage(i);
|
||||
}
|
||||
else if(c == KEY_ENTER)
|
||||
{
|
||||
numplayers = 0;
|
||||
for(j = 0; j < MAXPLAYERS; j++)
|
||||
{
|
||||
numplayers += playeringame[j];
|
||||
}
|
||||
CT_AddChar(i, 0); // set the end of message character
|
||||
if(numplayers > 2)
|
||||
{
|
||||
strcpy(plr_lastmsg[i], CT_FromPlrText[i]);
|
||||
strcat(plr_lastmsg[i], chat_msg[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(plr_lastmsg[i], chat_msg[i]);
|
||||
}
|
||||
if(i != consoleplayer && (chat_dest[i] == consoleplayer+1
|
||||
|| chat_dest[i] == CT_PLR_ALL) && *chat_msg[i])
|
||||
{
|
||||
P_SetMessage(&players[consoleplayer], plr_lastmsg[i],
|
||||
true);
|
||||
S_StartSound(NULL, SFX_CHAT);
|
||||
}
|
||||
else if(i == consoleplayer && (*chat_msg[i]))
|
||||
{
|
||||
if(numplayers <= 1)
|
||||
{
|
||||
P_SetMessage(&players[consoleplayer],
|
||||
"THERE ARE NO OTHER PLAYERS IN THE GAME!", true);
|
||||
S_StartSound(NULL, SFX_CHAT);
|
||||
}
|
||||
}
|
||||
CT_ClearChatMessage(i);
|
||||
}
|
||||
else if(c == KEY_BACKSPACE)
|
||||
{
|
||||
CT_BackSpace(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
CT_AddChar(i, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CT_Drawer
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void CT_Drawer(void)
|
||||
{
|
||||
int i;
|
||||
int x;
|
||||
patch_t *patch;
|
||||
|
||||
if(chatmodeon)
|
||||
{
|
||||
x = 25;
|
||||
for(i = 0; i < msgptr[consoleplayer]; i++)
|
||||
{
|
||||
if(chat_msg[consoleplayer][i] < 33)
|
||||
{
|
||||
x += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
patch=W_CacheLumpNum(FontABaseLump+
|
||||
chat_msg[consoleplayer][i]-33, PU_CACHE);
|
||||
V_DrawPatch(x, 10, patch);
|
||||
x += patch->width;
|
||||
}
|
||||
}
|
||||
V_DrawPatch(x, 10, W_CacheLumpName("FONTA59", PU_CACHE));
|
||||
BorderTopRefresh = true;
|
||||
UpdateState |= I_MESSAGES;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CT_queueChatChar
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void CT_queueChatChar(char ch)
|
||||
{
|
||||
if((tail+1)&(QUEUESIZE-1) == head)
|
||||
{ // the queue is full
|
||||
return;
|
||||
}
|
||||
ChatQueue[tail] = ch;
|
||||
tail = (tail+1)&(QUEUESIZE-1);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CT_dequeueChatChar
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
char CT_dequeueChatChar(void)
|
||||
{
|
||||
byte temp;
|
||||
|
||||
if(head == tail)
|
||||
{ // queue is empty
|
||||
return 0;
|
||||
}
|
||||
temp = ChatQueue[head];
|
||||
head = (head+1)&(QUEUESIZE-1);
|
||||
return temp;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CT_AddChar
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void CT_AddChar(int player, char c)
|
||||
{
|
||||
patch_t *patch;
|
||||
|
||||
if(msgptr[player]+1 >= MESSAGESIZE || msglen[player] >= MESSAGELEN)
|
||||
{ // full.
|
||||
return;
|
||||
}
|
||||
chat_msg[player][msgptr[player]] = c;
|
||||
msgptr[player]++;
|
||||
if(c < 33)
|
||||
{
|
||||
msglen[player] += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
patch = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
|
||||
msglen[player] += patch->width;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CT_BackSpace
|
||||
//
|
||||
// Backs up a space, when the user hits (obviously) backspace
|
||||
//===========================================================================
|
||||
|
||||
void CT_BackSpace(int player)
|
||||
{
|
||||
patch_t *patch;
|
||||
char c;
|
||||
|
||||
if(msgptr[player] == 0)
|
||||
{ // message is already blank
|
||||
return;
|
||||
}
|
||||
msgptr[player]--;
|
||||
c = chat_msg[player][msgptr[player]];
|
||||
if(c < 33)
|
||||
{
|
||||
msglen[player] -= 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
patch = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
|
||||
msglen[player] -= patch->width;
|
||||
}
|
||||
chat_msg[player][msgptr[player]] = 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CT_ClearChatMessage
|
||||
//
|
||||
// Clears out the data for the chat message, but the player's message
|
||||
// is still saved in plrmsg.
|
||||
//===========================================================================
|
||||
|
||||
void CT_ClearChatMessage(int player)
|
||||
{
|
||||
memset(chat_msg[player], 0, MESSAGESIZE);
|
||||
msgptr[player] = 0;
|
||||
msglen[player] = 0;
|
||||
}
|
15
Hexen Source/CT_CHAT.H
Normal file
15
Hexen Source/CT_CHAT.H
Normal file
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// Chat mode stuff
|
||||
//
|
||||
|
||||
#define CT_PLR_GREEN 1
|
||||
#define CT_PLR_YELLOW 2
|
||||
#define CT_PLR_RED 3
|
||||
#define CT_PLR_BLUE 4
|
||||
#define CT_PLR_ALL 5
|
||||
|
||||
#define CT_KEY_GREEN 'g'
|
||||
#define CT_KEY_YELLOW 'y'
|
||||
#define CT_KEY_RED 'r'
|
||||
#define CT_KEY_BLUE 'b'
|
||||
#define CT_KEY_ALL 't'
|
52
Hexen Source/DEFS.INC
Normal file
52
Hexen Source/DEFS.INC
Normal file
|
@ -0,0 +1,52 @@
|
|||
SKIPPRIMITIVES = 0 ; set to 1 to skip unwound drawing
|
||||
|
||||
|
||||
SCREEN = 0a0000h
|
||||
SCREENWIDTH = 320
|
||||
SCREENHEIGHT = 200
|
||||
PLANEWIDTH = 80
|
||||
PLANESIZE = 80*200
|
||||
|
||||
PEL_WRITE_ADR = 03c8h
|
||||
PEL_DATA = 03c9h
|
||||
|
||||
SC_INDEX = 03C4h
|
||||
SC_MAPMASK = 2
|
||||
|
||||
OP_RET = 0c3h
|
||||
OP_MOVAL = 08ah
|
||||
OP_MOVDEST = 088h
|
||||
|
||||
|
||||
.DATA
|
||||
|
||||
EXTRN _dc_colormap:DWORD
|
||||
EXTRN _tinttable:DWORD
|
||||
EXTRN _dc_x:DWORD
|
||||
EXTRN _dc_yl:DWORD
|
||||
EXTRN _dc_yh:DWORD
|
||||
EXTRN _dc_iscale:DWORD
|
||||
EXTRN _dc_texturemid:DWORD
|
||||
EXTRN _dc_source:DWORD
|
||||
|
||||
EXTRN _ylookup:DWORD
|
||||
EXTRN _columnofs:DWORD
|
||||
|
||||
|
||||
EXTRN _ds_y:DWORD
|
||||
EXTRN _ds_x1:DWORD
|
||||
EXTRN _ds_x2:DWORD
|
||||
EXTRN _ds_colormap:DWORD
|
||||
EXTRN _ds_xfrac:DWORD
|
||||
EXTRN _ds_yfrac:DWORD
|
||||
EXTRN _ds_xstep:DWORD
|
||||
EXTRN _ds_ystep:DWORD
|
||||
EXTRN _ds_source:DWORD
|
||||
|
||||
PUSHR MACRO
|
||||
pushad
|
||||
ENDM
|
||||
|
||||
POPR MACRO
|
||||
popad
|
||||
ENDM
|
29
Hexen Source/DRCOORD.H
Normal file
29
Hexen Source/DRCOORD.H
Normal file
|
@ -0,0 +1,29 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** DRCoord.h : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: DRCoord.h,v $
|
||||
//** $Revision: 1.1 $
|
||||
//** $Date: 95/05/11 00:19:30 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#import <appkit/appkit.h>
|
||||
|
||||
@interface DRCoord:Object
|
||||
{
|
||||
id players_i;
|
||||
id console_i;
|
||||
id skill_i;
|
||||
id episode_i;
|
||||
id map_i;
|
||||
}
|
||||
|
||||
- newGame: sender;
|
||||
- scale1: sender;
|
||||
- scale2: sender;
|
||||
- scale4: sender;
|
||||
|
||||
@end
|
205
Hexen Source/DSTRINGS.H
Normal file
205
Hexen Source/DSTRINGS.H
Normal file
|
@ -0,0 +1,205 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** DStrings.H
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// MN_menu.c ---------------------------------------------------------------
|
||||
|
||||
#define PRESSKEY "press a key."
|
||||
#define PRESSYN "press y or n."
|
||||
#define TXT_PAUSED "PAUSED"
|
||||
#define QUITMSG "are you sure you want to\nquit this great game?"
|
||||
#define LOADNET "you can't do load while in a net game!\n\n"PRESSKEY
|
||||
#define QLOADNET "you can't quickload during a netgame!\n\n"PRESSKEY
|
||||
#define QSAVESPOT "you haven't picked a quicksave slot yet!\n\n"PRESSKEY
|
||||
#define SAVEDEAD "you can't save if you aren't playing!\n\n"PRESSKEY
|
||||
#define QSPROMPT "quicksave over your game named\n\n'%s'?\n\n"PRESSYN
|
||||
#define QLPROMPT "do you want to quickload the game named"\
|
||||
"\n\n'%s'?\n\n"PRESSYN
|
||||
#define NEWGAME "you can't start a new game\n"\
|
||||
"while in a network game.\n\n"PRESSKEY
|
||||
#define NIGHTMARE "are you sure? this skill level\n"\
|
||||
"isn't even remotely fair.\n\n"PRESSYN
|
||||
#define SWSTRING "this is the shareware version of doom.\n\n"\
|
||||
"you need to order the entire trilogy.\n\n"PRESSKEY
|
||||
#define MSGOFF "Messages OFF"
|
||||
#define MSGON "Messages ON"
|
||||
#define NETEND "you can't end a netgame!\n\n"PRESSKEY
|
||||
#define ENDGAME "are you sure you want to end the game?\n\n"PRESSYN
|
||||
#define DOSY "(press y to quit to dos.)"
|
||||
#define DETAILHI "High detail"
|
||||
#define DETAILLO "Low detail"
|
||||
#define GAMMALVL0 "Gamma correction OFF"
|
||||
#define GAMMALVL1 "Gamma correction level 1"
|
||||
#define GAMMALVL2 "Gamma correction level 2"
|
||||
#define GAMMALVL3 "Gamma correction level 3"
|
||||
#define GAMMALVL4 "Gamma correction level 4"
|
||||
#define EMPTYSTRING "empty slot"
|
||||
|
||||
// P_inter.c ---------------------------------------------------------------
|
||||
|
||||
// Keys
|
||||
|
||||
#define TXT_GOTBLUEKEY "BLUE KEY"
|
||||
#define TXT_GOTYELLOWKEY "YELLOW KEY"
|
||||
#define TXT_GOTGREENKEY "GREEN KEY"
|
||||
|
||||
// Artifacts
|
||||
|
||||
#define TXT_ARTIHEALTH "QUARTZ FLASK"
|
||||
#define TXT_ARTIFLY "WINGS OF WRATH"
|
||||
#define TXT_ARTIINVULNERABILITY "RING OF INVINCIBILITY"
|
||||
#define TXT_ARTITOMEOFPOWER "TOME OF POWER"
|
||||
#define TXT_ARTIINVISIBILITY "SHADOWSPHERE"
|
||||
#define TXT_ARTIEGG "MORPH OVUM"
|
||||
#define TXT_ARTISUPERHEALTH "MYSTIC URN"
|
||||
#define TXT_ARTITORCH "TORCH"
|
||||
#define TXT_ARTIFIREBOMB "TIME BOMB OF THE ANCIENTS"
|
||||
#define TXT_ARTITELEPORT "CHAOS DEVICE"
|
||||
|
||||
// Items
|
||||
|
||||
#define TXT_ITEMHEALTH "CRYSTAL VIAL"
|
||||
#define TXT_ITEMBAGOFHOLDING "BAG OF HOLDING"
|
||||
#define TXT_ITEMSHIELD1 "SILVER SHIELD"
|
||||
#define TXT_ITEMSHIELD2 "ENCHANTED SHIELD"
|
||||
#define TXT_ITEMSUPERMAP "MAP SCROLL"
|
||||
|
||||
// Ammo
|
||||
|
||||
#define TXT_AMMOGOLDWAND1 "WAND CRYSTAL"
|
||||
#define TXT_AMMOGOLDWAND2 "CRYSTAL GEODE"
|
||||
#define TXT_AMMOMACE1 "MACE SPHERES"
|
||||
#define TXT_AMMOMACE2 "PILE OF MACE SPHERES"
|
||||
#define TXT_AMMOCROSSBOW1 "ETHEREAL ARROWS"
|
||||
#define TXT_AMMOCROSSBOW2 "QUIVER OF ETHEREAL ARROWS"
|
||||
#define TXT_AMMOBLASTER1 "CLAW ORB"
|
||||
#define TXT_AMMOBLASTER2 "ENERGY ORB"
|
||||
#define TXT_AMMOSKULLROD1 "LESSER RUNES"
|
||||
#define TXT_AMMOSKULLROD2 "GREATER RUNES"
|
||||
#define TXT_AMMOPHOENIXROD1 "FLAME ORB"
|
||||
#define TXT_AMMOPHOENIXROD2 "INFERNO ORB"
|
||||
|
||||
// Weapons
|
||||
|
||||
#define TXT_WPNMACE "FIREMACE"
|
||||
#define TXT_WPNCROSSBOW "ETHEREAL CROSSBOW"
|
||||
#define TXT_WPNBLASTER "DRAGON CLAW"
|
||||
#define TXT_WPNSKULLROD "HELLSTAFF"
|
||||
#define TXT_WPNPHOENIXROD "PHOENIX ROD"
|
||||
#define TXT_WPNGAUNTLETS "GAUNTLETS OF THE NECROMANCER"
|
||||
|
||||
// SB_bar.c ----------------------------------------------------------------
|
||||
|
||||
#define TXT_CHEATGODON "GOD MODE ON"
|
||||
#define TXT_CHEATGODOFF "GOD MODE OFF"
|
||||
#define TXT_CHEATNOCLIPON "NO CLIPPING ON"
|
||||
#define TXT_CHEATNOCLIPOFF "NO CLIPPING OFF"
|
||||
#define TXT_CHEATWEAPONS "ALL WEAPONS"
|
||||
#define TXT_CHEATFLIGHTON "FLIGHT ON"
|
||||
#define TXT_CHEATFLIGHTOFF "FLIGHT OFF"
|
||||
#define TXT_CHEATPOWERON "POWER ON"
|
||||
#define TXT_CHEATPOWEROFF "POWER OFF"
|
||||
#define TXT_CHEATHEALTH "FULL HEALTH"
|
||||
#define TXT_CHEATKEYS "ALL KEYS"
|
||||
#define TXT_CHEATSOUNDON "SOUND DEBUG ON"
|
||||
#define TXT_CHEATSOUNDOFF "SOUND DEBUG OFF"
|
||||
#define TXT_CHEATTICKERON "TICKER ON"
|
||||
#define TXT_CHEATTICKEROFF "TICKER OFF"
|
||||
#define TXT_CHEATARTIFACTS1 "CHOOSE AN ARTIFACT ( A - J )"
|
||||
#define TXT_CHEATARTIFACTS2 "HOW MANY ( 1 - 9 )"
|
||||
#define TXT_CHEATARTIFACTS3 "YOU GOT IT"
|
||||
#define TXT_CHEATARTIFACTSFAIL "BAD INPUT"
|
||||
#define TXT_CHEATWARP "LEVEL WARP"
|
||||
#define TXT_CHEATSCREENSHOT "SCREENSHOT"
|
||||
#define TXT_CHEATCHICKENON "CHICKEN ON"
|
||||
#define TXT_CHEATCHICKENOFF "CHICKEN OFF"
|
||||
#define TXT_CHEATMASSACRE "MASSACRE"
|
||||
#define TXT_CHEATIDDQD "TRYING TO CHEAT, EH? NOW YOU DIE!"
|
||||
#define TXT_CHEATIDKFA "CHEATER - YOU DON'T DESERVE WEAPONS"
|
||||
|
||||
// P_doors.c ---------------------------------------------------------------
|
||||
|
||||
#define TXT_NEEDBLUEKEY "YOU NEED A BLUE KEY TO OPEN THIS DOOR"
|
||||
#define TXT_NEEDGREENKEY "YOU NEED A GREEN KEY TO OPEN THIS DOOR"
|
||||
#define TXT_NEEDYELLOWKEY "YOU NEED A YELLOW KEY TO OPEN THIS DOOR"
|
||||
|
||||
// G_game.c ----------------------------------------------------------------
|
||||
|
||||
#define TXT_GAMESAVED "GAME SAVED"
|
||||
|
||||
// M_misc.c ----------------------------------------------------------------
|
||||
|
||||
#define HUSTR_CHATMACRO1 "I'm ready to kick butt!"
|
||||
#define HUSTR_CHATMACRO2 "I'm OK."
|
||||
#define HUSTR_CHATMACRO3 "I'm not looking too good!"
|
||||
#define HUSTR_CHATMACRO4 "Help!"
|
||||
#define HUSTR_CHATMACRO5 "You suck!"
|
||||
#define HUSTR_CHATMACRO6 "Next time, scumbag..."
|
||||
#define HUSTR_CHATMACRO7 "Come here!"
|
||||
#define HUSTR_CHATMACRO8 "I'll take care of it."
|
||||
#define HUSTR_CHATMACRO9 "Yes"
|
||||
#define HUSTR_CHATMACRO0 "No"
|
||||
|
||||
// AM_map.c ----------------------------------------------------------------
|
||||
|
||||
#define AMSTR_FOLLOWON "FOLLOW MODE ON"
|
||||
#define AMSTR_FOLLOWOFF "FOLLOW MODE OFF"
|
||||
|
||||
// F_finale.c --------------------------------------------------------------
|
||||
|
||||
#define E1TEXT "with the destruction of the iron\n"\
|
||||
"liches and their minions, the last\n"\
|
||||
"of the undead are cleared from this\n"\
|
||||
"plane of existence.\n\n"\
|
||||
"those creatures had to come from\n"\
|
||||
"somewhere, though, and you have the\n"\
|
||||
"sneaky suspicion that the fiery\n"\
|
||||
"portal of hell's maw opens onto\n"\
|
||||
"their home dimension.\n\n"\
|
||||
"to make sure that more undead\n"\
|
||||
"(or even worse things) don't come\n"\
|
||||
"through, you'll have to seal hell's\n"\
|
||||
"maw from the other side. of course\n"\
|
||||
"this means you may get stuck in a\n"\
|
||||
"very unfriendly world, but no one\n"\
|
||||
"ever said being a Heretic was easy!"
|
||||
|
||||
#define E2TEXT "the mighty maulotaurs have proved\n"\
|
||||
"to be no match for you, and as\n"\
|
||||
"their steaming corpses slide to the\n"\
|
||||
"ground you feel a sense of grim\n"\
|
||||
"satisfaction that they have been\n"\
|
||||
"destroyed.\n\n"\
|
||||
"the gateways which they guarded\n"\
|
||||
"have opened, revealing what you\n"\
|
||||
"hope is the way home. but as you\n"\
|
||||
"step through, mocking laughter\n"\
|
||||
"rings in your ears.\n\n"\
|
||||
"was some other force controlling\n"\
|
||||
"the maulotaurs? could there be even\n"\
|
||||
"more horrific beings through this\n"\
|
||||
"gate? the sweep of a crystal dome\n"\
|
||||
"overhead where the sky should be is\n"\
|
||||
"certainly not a good sign...."
|
||||
|
||||
#define E3TEXT "the death of d'sparil has loosed\n"\
|
||||
"the magical bonds holding his\n"\
|
||||
"creatures on this plane, their\n"\
|
||||
"dying screams overwhelming his own\n"\
|
||||
"cries of agony.\n\n"\
|
||||
"your oath of vengeance fulfilled,\n"\
|
||||
"you enter the portal to your own\n"\
|
||||
"world, mere moments before the dome\n"\
|
||||
"shatters into a million pieces.\n\n"\
|
||||
"but if d'sparil's power is broken\n"\
|
||||
"forever, why don't you feel safe?\n"\
|
||||
"was it that last shout just before\n"\
|
||||
"his death, the one that sounded\n"\
|
||||
"like a curse? or a summoning? you\n"\
|
||||
"can't really be sure, but it might\n"\
|
||||
"just have been a scream.\n\n"\
|
||||
"then again, what about the other\n"\
|
||||
"serpent riders?"
|
927
Hexen Source/D_NET.C
Normal file
927
Hexen Source/D_NET.C
Normal file
|
@ -0,0 +1,927 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** d_net.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: d_net.c,v $
|
||||
//** $Revision: 1.16 $
|
||||
//** $Date: 96/01/01 03:39:44 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//** This version has the fixed ticdup code.
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
#include <stdlib.h> // for atoi()
|
||||
|
||||
#define NCMD_EXIT 0x80000000
|
||||
#define NCMD_RETRANSMIT 0x40000000
|
||||
#define NCMD_SETUP 0x20000000
|
||||
#define NCMD_KILL 0x10000000 // kill game
|
||||
#define NCMD_CHECKSUM 0x0fffffff
|
||||
|
||||
|
||||
doomcom_t *doomcom;
|
||||
doomdata_t *netbuffer; // points inside doomcom
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
NETWORKING
|
||||
|
||||
gametic is the tic about to (or currently being) run
|
||||
maketic is the tick that hasn't had control made for it yet
|
||||
nettics[] has the maketics for all players
|
||||
|
||||
a gametic cannot be run until nettics[] > gametic for all players
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#define RESENDCOUNT 10
|
||||
#define PL_DRONE 0x80 // bit flag in doomdata->player
|
||||
|
||||
ticcmd_t localcmds[BACKUPTICS];
|
||||
|
||||
ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS];
|
||||
int nettics[MAXNETNODES];
|
||||
boolean nodeingame[MAXNETNODES]; // set false as nodes leave game
|
||||
boolean remoteresend[MAXNETNODES]; // set when local needs tics
|
||||
int resendto[MAXNETNODES]; // set when remote needs tics
|
||||
int resendcount[MAXNETNODES];
|
||||
|
||||
int nodeforplayer[MAXPLAYERS];
|
||||
|
||||
int maketic;
|
||||
int lastnettic, skiptics;
|
||||
int ticdup;
|
||||
int maxsend; // BACKUPTICS/(2*ticdup)-1
|
||||
|
||||
void H2_ProcessEvents (void);
|
||||
void G_BuildTiccmd (ticcmd_t *cmd);
|
||||
void H2_DoAdvanceDemo (void);
|
||||
extern void ST_NetProgress(void);
|
||||
extern void ST_NetDone(void);
|
||||
|
||||
boolean reboundpacket;
|
||||
doomdata_t reboundstore;
|
||||
|
||||
|
||||
int NetbufferSize (void)
|
||||
{
|
||||
return (int)&(((doomdata_t *)0)->cmds[netbuffer->numtics]);
|
||||
}
|
||||
|
||||
unsigned NetbufferChecksum (void)
|
||||
{
|
||||
unsigned c;
|
||||
int i,l;
|
||||
|
||||
c = 0x1234567;
|
||||
|
||||
#if defined(NeXT) || defined(NORMALUNIX)
|
||||
return 0; // byte order problems
|
||||
#endif
|
||||
|
||||
l = (NetbufferSize () - (int)&(((doomdata_t *)0)->retransmitfrom))/4;
|
||||
for (i=0 ; i<l ; i++)
|
||||
c += ((unsigned *)&netbuffer->retransmitfrom)[i] * (i+1);
|
||||
|
||||
return c & NCMD_CHECKSUM;
|
||||
}
|
||||
|
||||
int ExpandTics (int low)
|
||||
{
|
||||
int delta;
|
||||
|
||||
delta = low - (maketic&0xff);
|
||||
|
||||
if (delta >= -64 && delta <= 64)
|
||||
return (maketic&~0xff) + low;
|
||||
if (delta > 64)
|
||||
return (maketic&~0xff) - 256 + low;
|
||||
if (delta < -64)
|
||||
return (maketic&~0xff) + 256 + low;
|
||||
|
||||
I_Error ("ExpandTics: strange value %i at maketic %i",low,maketic);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
=
|
||||
= HSendPacket
|
||||
=
|
||||
==============
|
||||
*/
|
||||
|
||||
void HSendPacket (int node, int flags)
|
||||
{
|
||||
netbuffer->checksum = NetbufferChecksum () | flags;
|
||||
|
||||
if (!node)
|
||||
{
|
||||
reboundstore = *netbuffer;
|
||||
reboundpacket = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (demoplayback)
|
||||
return;
|
||||
|
||||
if (!netgame)
|
||||
I_Error ("Tried to transmit to another node");
|
||||
|
||||
doomcom->command = CMD_SEND;
|
||||
doomcom->remotenode = node;
|
||||
doomcom->datalength = NetbufferSize ();
|
||||
|
||||
if (debugfile)
|
||||
{
|
||||
int i;
|
||||
int realretrans;
|
||||
if (netbuffer->checksum & NCMD_RETRANSMIT)
|
||||
realretrans = ExpandTics (netbuffer->retransmitfrom);
|
||||
else
|
||||
realretrans = -1;
|
||||
fprintf (debugfile,"send (%i + %i, R %i) [%i] "
|
||||
,ExpandTics(netbuffer->starttic),netbuffer->numtics, realretrans, doomcom->datalength);
|
||||
for (i=0 ; i<doomcom->datalength ; i++)
|
||||
fprintf (debugfile,"%i ",((byte *)netbuffer)[i]);
|
||||
fprintf (debugfile,"\n");
|
||||
}
|
||||
|
||||
I_NetCmd ();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// NET_SendFrags
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void NET_SendFrags(player_t *player)
|
||||
{
|
||||
int i;
|
||||
int frags;
|
||||
|
||||
netbuffer->checksum = NetbufferChecksum();
|
||||
|
||||
if (demoplayback)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!netgame)
|
||||
{
|
||||
I_Error ("Tried to transmit to another node");
|
||||
}
|
||||
|
||||
frags = 0;
|
||||
for(i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
frags += player->frags[i];
|
||||
}
|
||||
doomcom->command = CMD_FRAG;
|
||||
doomcom->remotenode = frags;
|
||||
doomcom->datalength = NetbufferSize ();
|
||||
|
||||
I_NetCmd ();
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
=
|
||||
= HGetPacket
|
||||
=
|
||||
= Returns false if no packet is waiting
|
||||
=
|
||||
==============
|
||||
*/
|
||||
|
||||
boolean HGetPacket (void)
|
||||
{
|
||||
if (reboundpacket)
|
||||
{
|
||||
*netbuffer = reboundstore;
|
||||
doomcom->remotenode = 0;
|
||||
reboundpacket = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!netgame)
|
||||
return false;
|
||||
if (demoplayback)
|
||||
return false;
|
||||
|
||||
doomcom->command = CMD_GET;
|
||||
I_NetCmd ();
|
||||
if (doomcom->remotenode == -1)
|
||||
return false;
|
||||
|
||||
if (doomcom->datalength != NetbufferSize ())
|
||||
{
|
||||
if (debugfile)
|
||||
fprintf (debugfile,"bad packet length %i\n",doomcom->datalength);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NetbufferChecksum () != (netbuffer->checksum&NCMD_CHECKSUM) )
|
||||
{
|
||||
if (debugfile)
|
||||
fprintf (debugfile,"bad packet checksum\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (debugfile)
|
||||
{
|
||||
int realretrans;
|
||||
int i;
|
||||
|
||||
if (netbuffer->checksum & NCMD_SETUP)
|
||||
fprintf (debugfile,"setup packet\n");
|
||||
else
|
||||
{
|
||||
if (netbuffer->checksum & NCMD_RETRANSMIT)
|
||||
realretrans = ExpandTics (netbuffer->retransmitfrom);
|
||||
else
|
||||
realretrans = -1;
|
||||
fprintf (debugfile,"get %i = (%i + %i, R %i)[%i] ",doomcom->remotenode,
|
||||
ExpandTics(netbuffer->starttic),netbuffer->numtics, realretrans, doomcom->datalength);
|
||||
for (i=0 ; i<doomcom->datalength ; i++)
|
||||
fprintf (debugfile,"%i ",((byte *)netbuffer)[i]);
|
||||
fprintf (debugfile,"\n");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
=
|
||||
= GetPackets
|
||||
=
|
||||
===================
|
||||
*/
|
||||
|
||||
char exitmsg[80];
|
||||
|
||||
void GetPackets (void)
|
||||
{
|
||||
int netconsole;
|
||||
int netnode;
|
||||
ticcmd_t *src, *dest;
|
||||
int realend;
|
||||
int realstart;
|
||||
|
||||
while (HGetPacket ())
|
||||
{
|
||||
if (netbuffer->checksum & NCMD_SETUP)
|
||||
continue; // extra setup packet
|
||||
|
||||
netconsole = netbuffer->player & ~PL_DRONE;
|
||||
netnode = doomcom->remotenode;
|
||||
//
|
||||
// to save bytes, only the low byte of tic numbers are sent
|
||||
// Figure out what the rest of the bytes are
|
||||
//
|
||||
realstart = ExpandTics (netbuffer->starttic);
|
||||
realend = (realstart+netbuffer->numtics);
|
||||
|
||||
//
|
||||
// check for exiting the game
|
||||
//
|
||||
if (netbuffer->checksum & NCMD_EXIT)
|
||||
{
|
||||
if (!nodeingame[netnode])
|
||||
continue;
|
||||
nodeingame[netnode] = false;
|
||||
playeringame[netconsole] = false;
|
||||
strcpy (exitmsg, "PLAYER 1 LEFT THE GAME");
|
||||
exitmsg[7] += netconsole;
|
||||
P_SetMessage(&players[consoleplayer], exitmsg, true);
|
||||
S_StartSound(NULL, SFX_CHAT);
|
||||
// players[consoleplayer].message = exitmsg;
|
||||
// if (demorecording)
|
||||
// G_CheckDemoStatus ();
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// check for a remote game kill
|
||||
//
|
||||
if (netbuffer->checksum & NCMD_KILL)
|
||||
I_Error ("Killed by network driver");
|
||||
|
||||
nodeforplayer[netconsole] = netnode;
|
||||
|
||||
//
|
||||
// check for retransmit request
|
||||
//
|
||||
if ( resendcount[netnode] <= 0
|
||||
&& (netbuffer->checksum & NCMD_RETRANSMIT) )
|
||||
{
|
||||
resendto[netnode] = ExpandTics(netbuffer->retransmitfrom);
|
||||
if (debugfile)
|
||||
fprintf (debugfile,"retransmit from %i\n", resendto[netnode]);
|
||||
resendcount[netnode] = RESENDCOUNT;
|
||||
}
|
||||
else
|
||||
resendcount[netnode]--;
|
||||
|
||||
//
|
||||
// check for out of order / duplicated packet
|
||||
//
|
||||
if (realend == nettics[netnode])
|
||||
continue;
|
||||
|
||||
if (realend < nettics[netnode])
|
||||
{
|
||||
if (debugfile)
|
||||
fprintf (debugfile,"out of order packet (%i + %i)\n" ,realstart,netbuffer->numtics);
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// check for a missed packet
|
||||
//
|
||||
if (realstart > nettics[netnode])
|
||||
{
|
||||
// stop processing until the other system resends the missed tics
|
||||
if (debugfile)
|
||||
fprintf (debugfile,"missed tics from %i (%i - %i)\n", netnode, realstart, nettics[netnode]);
|
||||
remoteresend[netnode] = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// update command store from the packet
|
||||
//
|
||||
{
|
||||
int start;
|
||||
|
||||
remoteresend[netnode] = false;
|
||||
|
||||
start = nettics[netnode] - realstart;
|
||||
src = &netbuffer->cmds[start];
|
||||
|
||||
while (nettics[netnode] < realend)
|
||||
{
|
||||
dest = &netcmds[netconsole][nettics[netnode]%BACKUPTICS];
|
||||
nettics[netnode]++;
|
||||
*dest = *src;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
=
|
||||
= NetUpdate
|
||||
=
|
||||
= Builds ticcmds for console player
|
||||
= sends out a packet
|
||||
=============
|
||||
*/
|
||||
|
||||
int gametime;
|
||||
|
||||
void NetUpdate (void)
|
||||
{
|
||||
int nowtime;
|
||||
int newtics;
|
||||
int i,j;
|
||||
int realstart;
|
||||
int gameticdiv;
|
||||
|
||||
//
|
||||
// check time
|
||||
//
|
||||
nowtime = I_GetTime ()/ticdup;
|
||||
newtics = nowtime - gametime;
|
||||
gametime = nowtime;
|
||||
|
||||
if (newtics <= 0) // nothing new to update
|
||||
goto listen;
|
||||
|
||||
if (skiptics <= newtics)
|
||||
{
|
||||
newtics -= skiptics;
|
||||
skiptics = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
skiptics -= newtics;
|
||||
newtics = 0;
|
||||
}
|
||||
|
||||
|
||||
netbuffer->player = consoleplayer;
|
||||
|
||||
//
|
||||
// build new ticcmds for console player
|
||||
//
|
||||
gameticdiv = gametic/ticdup;
|
||||
for (i=0 ; i<newtics ; i++)
|
||||
{
|
||||
I_StartTic ();
|
||||
H2_ProcessEvents ();
|
||||
if (maketic - gameticdiv >= BACKUPTICS/2-1)
|
||||
break; // can't hold any more
|
||||
//printf ("mk:%i ",maketic);
|
||||
G_BuildTiccmd (&localcmds[maketic%BACKUPTICS]);
|
||||
maketic++;
|
||||
}
|
||||
|
||||
|
||||
if (singletics)
|
||||
return; // singletic update is syncronous
|
||||
|
||||
//
|
||||
// send the packet to the other nodes
|
||||
//
|
||||
for (i=0 ; i<doomcom->numnodes ; i++)
|
||||
if (nodeingame[i])
|
||||
{
|
||||
netbuffer->starttic = realstart = resendto[i];
|
||||
netbuffer->numtics = maketic - realstart;
|
||||
if (netbuffer->numtics > BACKUPTICS)
|
||||
I_Error ("NetUpdate: netbuffer->numtics > BACKUPTICS");
|
||||
|
||||
resendto[i] = maketic - doomcom->extratics;
|
||||
|
||||
for (j=0 ; j< netbuffer->numtics ; j++)
|
||||
netbuffer->cmds[j] =
|
||||
localcmds[(realstart+j)%BACKUPTICS];
|
||||
|
||||
if (remoteresend[i])
|
||||
{
|
||||
netbuffer->retransmitfrom = nettics[i];
|
||||
HSendPacket (i, NCMD_RETRANSMIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
netbuffer->retransmitfrom = 0;
|
||||
HSendPacket (i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// listen for other packets
|
||||
//
|
||||
listen:
|
||||
|
||||
GetPackets ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
=
|
||||
= CheckAbort
|
||||
=
|
||||
=====================
|
||||
*/
|
||||
|
||||
void CheckAbort (void)
|
||||
{
|
||||
event_t *ev;
|
||||
int stoptic;
|
||||
|
||||
stoptic = I_GetTime () + 2;
|
||||
while (I_GetTime() < stoptic)
|
||||
I_StartTic ();
|
||||
|
||||
I_StartTic ();
|
||||
for ( ; eventtail != eventhead
|
||||
; eventtail = (++eventtail)&(MAXEVENTS-1) )
|
||||
{
|
||||
ev = &events[eventtail];
|
||||
if (ev->type == ev_keydown && ev->data1 == KEY_ESCAPE)
|
||||
I_Error ("Network game synchronization aborted.");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
=
|
||||
= D_ArbitrateNetStart
|
||||
=
|
||||
=====================
|
||||
*/
|
||||
|
||||
void D_ArbitrateNetStart (void)
|
||||
{
|
||||
int i;
|
||||
boolean gotinfo[MAXNETNODES];
|
||||
boolean gotClass[MAXNETNODES];
|
||||
#ifdef __WATCOMC__
|
||||
int nextTic;
|
||||
extern volatile int ticcount;
|
||||
|
||||
nextTic = ticcount+8;
|
||||
#endif
|
||||
|
||||
autostart = true;
|
||||
|
||||
memset (gotClass,0,sizeof(gotClass));
|
||||
memset (gotinfo,0,sizeof(gotinfo));
|
||||
gotClass[doomcom->consoleplayer] = true;
|
||||
do
|
||||
{
|
||||
i = 0;
|
||||
|
||||
CheckAbort();
|
||||
while(HGetPacket())
|
||||
{ // Check for any incoming packets
|
||||
if(netbuffer->checksum&NCMD_SETUP && netbuffer->starttic >= 64)
|
||||
{
|
||||
|
||||
PlayerClass[netbuffer->player] = netbuffer->starttic&0x3f;
|
||||
if(!gotClass[netbuffer->player])
|
||||
{
|
||||
gotClass[netbuffer->player] = true;
|
||||
ST_NetProgress();
|
||||
ST_Message("\n");
|
||||
}
|
||||
if(netbuffer->retransmitfrom)
|
||||
{ // that node has received info from all other nodes
|
||||
gotinfo[netbuffer->player] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef __WATCOMC__
|
||||
if(ticcount <= nextTic)
|
||||
{ // only send packets every half second
|
||||
continue;
|
||||
}
|
||||
nextTic = ticcount+8;
|
||||
#endif
|
||||
// Keep sending out packets containing the console class
|
||||
for(i = 0; i < doomcom->numnodes; i++)
|
||||
{
|
||||
netbuffer->player = doomcom->consoleplayer;
|
||||
netbuffer->starttic = PlayerClass[doomcom->consoleplayer]+64;
|
||||
netbuffer->retransmitfrom = gotinfo[doomcom->consoleplayer];
|
||||
netbuffer->numtics = 0;
|
||||
HSendPacket(i, NCMD_SETUP);
|
||||
}
|
||||
for(i = 0; i < doomcom->numnodes; i++)
|
||||
{ // Make sure that all nodes have sent class info
|
||||
if (!gotClass[i])
|
||||
{
|
||||
ST_Message(".");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i < doomcom->numnodes)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{ // consoleplayer has received all player classes
|
||||
if(gotinfo[doomcom->consoleplayer])
|
||||
{
|
||||
CheckAbort();
|
||||
}
|
||||
else
|
||||
{
|
||||
gotinfo[doomcom->consoleplayer] = true;
|
||||
ST_Message("All player classes received, ready to proceed\n");
|
||||
ST_NetDone();
|
||||
}
|
||||
}
|
||||
for (i = 0; i < doomcom->numnodes; i++)
|
||||
{ // Make sure that all nodes are ready to proceed
|
||||
if (!gotinfo[i])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(i < doomcom->numnodes);
|
||||
|
||||
memset (gotinfo,0,sizeof(gotinfo));
|
||||
|
||||
if (doomcom->consoleplayer)
|
||||
{ // listen for setup info from key player
|
||||
// ST_Message ("listening for network start info...\n");
|
||||
while (1)
|
||||
{
|
||||
CheckAbort ();
|
||||
if (!HGetPacket ())
|
||||
continue;
|
||||
if(netbuffer->checksum & NCMD_SETUP && netbuffer->starttic < 64)
|
||||
{
|
||||
if (netbuffer->player != VERSION)
|
||||
I_Error ("Different HEXEN versions cannot play a net game!");
|
||||
startskill = netbuffer->retransmitfrom & 15;
|
||||
deathmatch = (netbuffer->retransmitfrom & 0xc0) >> 6;
|
||||
nomonsters = (netbuffer->retransmitfrom & 0x20) > 0;
|
||||
respawnparm = (netbuffer->retransmitfrom & 0x10) > 0;
|
||||
startmap = netbuffer->starttic & 0x3f;
|
||||
startepisode = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // key player, send the setup info
|
||||
// ST_Message ("sending network start info...\n");
|
||||
do
|
||||
{
|
||||
CheckAbort ();
|
||||
for (i=0 ; i<doomcom->numnodes ; i++)
|
||||
{
|
||||
netbuffer->retransmitfrom = startskill;
|
||||
if (deathmatch)
|
||||
netbuffer->retransmitfrom |= (deathmatch<<6);
|
||||
if (nomonsters)
|
||||
netbuffer->retransmitfrom |= 0x20;
|
||||
if (respawnparm)
|
||||
netbuffer->retransmitfrom |= 0x10;
|
||||
netbuffer->starttic = startmap&0x3f;
|
||||
netbuffer->player = VERSION;
|
||||
netbuffer->numtics = 0;
|
||||
HSendPacket (i, NCMD_SETUP);
|
||||
}
|
||||
|
||||
#if 1
|
||||
for(i = 10 ; i && HGetPacket(); --i)
|
||||
{
|
||||
if((netbuffer->player&0x7f) < MAXNETNODES)
|
||||
gotinfo[netbuffer->player&0x7f] = true;
|
||||
}
|
||||
#else
|
||||
while (HGetPacket ())
|
||||
{
|
||||
gotinfo[netbuffer->player&0x7f] = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i=1 ; i<doomcom->numnodes ; i++)
|
||||
if (!gotinfo[i])
|
||||
break;
|
||||
} while (i < doomcom->numnodes);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
=
|
||||
= D_CheckNetGame
|
||||
=
|
||||
= Works out player numbers among the net participants
|
||||
===================
|
||||
*/
|
||||
|
||||
extern int viewangleoffset;
|
||||
|
||||
void D_CheckNetGame (void)
|
||||
{
|
||||
int i;
|
||||
int pClass;
|
||||
|
||||
for (i=0 ; i<MAXNETNODES ; i++)
|
||||
{
|
||||
nodeingame[i] = false;
|
||||
nettics[i] = 0;
|
||||
remoteresend[i] = false; // set when local needs tics
|
||||
resendto[i] = 0; // which tic to start sending
|
||||
}
|
||||
|
||||
// I_InitNetwork sets doomcom and netgame
|
||||
I_InitNetwork ();
|
||||
if (doomcom->id != DOOMCOM_ID)
|
||||
I_Error ("Doomcom buffer invalid!");
|
||||
netbuffer = &doomcom->data;
|
||||
consoleplayer = displayplayer = doomcom->consoleplayer;
|
||||
pClass = PCLASS_FIGHTER;
|
||||
if(i = M_CheckParm("-class"))
|
||||
{
|
||||
pClass = atoi(myargv[i+1]);
|
||||
if(pClass > PCLASS_MAGE || pClass < PCLASS_FIGHTER)
|
||||
{
|
||||
I_Error("Invalid player class: %d\n", pClass);
|
||||
}
|
||||
ST_Message("\nPlayer Class: %d\n", pClass);
|
||||
}
|
||||
PlayerClass[consoleplayer] = pClass;
|
||||
if (netgame)
|
||||
D_ArbitrateNetStart ();
|
||||
//ST_Message ("startskill %i deathmatch: %i startmap: %i startepisode: %i\n", startskill, deathmatch, startmap, startepisode);
|
||||
|
||||
// read values out of doomcom
|
||||
ticdup = doomcom->ticdup;
|
||||
maxsend = BACKUPTICS/(2*ticdup)-1;
|
||||
if (maxsend<1)
|
||||
maxsend = 1;
|
||||
|
||||
for (i=0 ; i<doomcom->numplayers ; i++)
|
||||
playeringame[i] = true;
|
||||
for (i=0 ; i<doomcom->numnodes ; i++)
|
||||
nodeingame[i] = true;
|
||||
|
||||
//ST_Message ("player %i of %i (%i nodes)\n", consoleplayer+1, doomcom->numplayers, doomcom->numnodes);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
=
|
||||
= D_QuitNetGame
|
||||
=
|
||||
= Called before quitting to leave a net game without hanging the
|
||||
= other players
|
||||
=
|
||||
==================
|
||||
*/
|
||||
|
||||
void D_QuitNetGame (void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (debugfile)
|
||||
fclose (debugfile);
|
||||
|
||||
if (!netgame || !usergame || consoleplayer == -1 || demoplayback)
|
||||
return;
|
||||
|
||||
// send a bunch of packets for security
|
||||
netbuffer->player = consoleplayer;
|
||||
netbuffer->numtics = 0;
|
||||
for (i=0 ; i<4 ; i++)
|
||||
{
|
||||
for (j=1 ; j<doomcom->numnodes ; j++)
|
||||
if (nodeingame[j])
|
||||
HSendPacket (j, NCMD_EXIT);
|
||||
I_WaitVBL (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
=
|
||||
= TryRunTics
|
||||
=
|
||||
===============
|
||||
*/
|
||||
|
||||
int frametics[4], frameon;
|
||||
int frameskip[4];
|
||||
int oldnettics;
|
||||
extern boolean advancedemo;
|
||||
|
||||
void TryRunTics (void)
|
||||
{
|
||||
int i;
|
||||
int lowtic;
|
||||
int entertic;
|
||||
static int oldentertics;
|
||||
int realtics, availabletics;
|
||||
int counts;
|
||||
int numplaying;
|
||||
|
||||
//
|
||||
// get real tics
|
||||
//
|
||||
entertic = I_GetTime ()/ticdup;
|
||||
realtics = entertic - oldentertics;
|
||||
oldentertics = entertic;
|
||||
|
||||
//
|
||||
// get available tics
|
||||
//
|
||||
NetUpdate ();
|
||||
|
||||
lowtic = MAXINT;
|
||||
numplaying = 0;
|
||||
for (i=0 ; i<doomcom->numnodes ; i++)
|
||||
if (nodeingame[i])
|
||||
{
|
||||
numplaying++;
|
||||
if (nettics[i] < lowtic)
|
||||
lowtic = nettics[i];
|
||||
}
|
||||
availabletics = lowtic - gametic/ticdup;
|
||||
|
||||
|
||||
//
|
||||
// decide how many tics to run
|
||||
//
|
||||
if (realtics < availabletics-1)
|
||||
counts = realtics+1;
|
||||
else if (realtics < availabletics)
|
||||
counts = realtics;
|
||||
else
|
||||
counts = availabletics;
|
||||
if (counts < 1)
|
||||
counts = 1;
|
||||
|
||||
frameon++;
|
||||
|
||||
if (debugfile)
|
||||
fprintf (debugfile,"=======real: %i avail: %i game: %i\n",realtics, availabletics,counts);
|
||||
|
||||
if (!demoplayback)
|
||||
{
|
||||
//=============================================================================
|
||||
//
|
||||
// ideally nettics[0] should be 1 - 3 tics above lowtic
|
||||
// if we are consistantly slower, speed up time
|
||||
//
|
||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
||||
if (playeringame[i])
|
||||
break;
|
||||
if (consoleplayer == i)
|
||||
{ // the key player does not adapt
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nettics[0] <= nettics[nodeforplayer[i]])
|
||||
{
|
||||
gametime--;
|
||||
// printf ("-");
|
||||
}
|
||||
frameskip[frameon&3] = (oldnettics > nettics[nodeforplayer[i]]);
|
||||
oldnettics = nettics[0];
|
||||
if (frameskip[0] && frameskip[1] && frameskip[2] && frameskip[3])
|
||||
{
|
||||
skiptics = 1;
|
||||
// printf ("+");
|
||||
}
|
||||
}
|
||||
//=============================================================================
|
||||
} // demoplayback
|
||||
|
||||
//
|
||||
// wait for new tics if needed
|
||||
//
|
||||
while (lowtic < gametic/ticdup + counts)
|
||||
{
|
||||
|
||||
NetUpdate ();
|
||||
lowtic = MAXINT;
|
||||
|
||||
for (i=0 ; i<doomcom->numnodes ; i++)
|
||||
if (nodeingame[i] && nettics[i] < lowtic)
|
||||
lowtic = nettics[i];
|
||||
|
||||
if (lowtic < gametic/ticdup)
|
||||
I_Error ("TryRunTics: lowtic < gametic");
|
||||
|
||||
// don't stay in here forever -- give the menu a chance to work
|
||||
if (I_GetTime ()/ticdup - entertic >= 20)
|
||||
{
|
||||
MN_Ticker ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// run the count * ticdup dics
|
||||
//
|
||||
while (counts--)
|
||||
{
|
||||
for (i=0 ; i<ticdup ; i++)
|
||||
{
|
||||
if (gametic/ticdup > lowtic)
|
||||
I_Error ("gametic>lowtic");
|
||||
if (advancedemo)
|
||||
H2_DoAdvanceDemo ();
|
||||
MN_Ticker ();
|
||||
G_Ticker ();
|
||||
gametic++;
|
||||
//
|
||||
// modify command for duplicated tics
|
||||
//
|
||||
if (i != ticdup-1)
|
||||
{
|
||||
ticcmd_t *cmd;
|
||||
int buf;
|
||||
int j;
|
||||
|
||||
buf = (gametic/ticdup)%BACKUPTICS;
|
||||
for (j=0 ; j<MAXPLAYERS ; j++)
|
||||
{
|
||||
cmd = &netcmds[j][buf];
|
||||
cmd->chatchar = 0;
|
||||
if (cmd->buttons & BT_SPECIAL)
|
||||
cmd->buttons = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
NetUpdate (); // check for new console commands
|
||||
}
|
||||
}
|
376
Hexen Source/F_FINALE.C
Normal file
376
Hexen Source/F_FINALE.C
Normal file
|
@ -0,0 +1,376 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** f_finale.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: f_finale.c,v $
|
||||
//** $Revision: 1.7 $
|
||||
//** $Date: 96/01/05 23:33:26 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include "h2def.h"
|
||||
#include "soundst.h"
|
||||
#include "p_local.h"
|
||||
#include <ctype.h>
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
#define TEXTSPEED 3
|
||||
#define TEXTWAIT 250
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static void TextWrite(void);
|
||||
static void DrawPic(void);
|
||||
static void InitializeFade(boolean fadeIn);
|
||||
static void DeInitializeFade(void);
|
||||
static void FadePic(void);
|
||||
static char *GetFinaleText(int sequence);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
extern boolean automapactive;
|
||||
extern boolean viewactive;
|
||||
|
||||
// PUBLIC DATA DECLARATIONS ------------------------------------------------
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static int FinaleStage;
|
||||
static int FinaleCount;
|
||||
static int FinaleEndCount;
|
||||
static int FinaleLumpNum;
|
||||
static int FontABaseLump;
|
||||
static char *FinaleText;
|
||||
|
||||
static fixed_t *Palette;
|
||||
static fixed_t *PaletteDelta;
|
||||
static byte *RealPalette;
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// F_StartFinale
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void F_StartFinale (void)
|
||||
{
|
||||
gameaction = ga_nothing;
|
||||
gamestate = GS_FINALE;
|
||||
viewactive = false;
|
||||
automapactive = false;
|
||||
P_ClearMessage(&players[consoleplayer]);
|
||||
|
||||
FinaleStage = 0;
|
||||
FinaleCount = 0;
|
||||
FinaleText = GetFinaleText(0);
|
||||
FinaleEndCount = 70;
|
||||
FinaleLumpNum = W_GetNumForName("FINALE1");
|
||||
FontABaseLump = W_GetNumForName("FONTA_S")+1;
|
||||
InitializeFade(1);
|
||||
|
||||
// S_ChangeMusic(mus_victor, true);
|
||||
S_StartSongName("hall", false); // don't loop the song
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// F_Responder
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
boolean F_Responder(event_t *event)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// F_Ticker
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void F_Ticker (void)
|
||||
{
|
||||
FinaleCount++;
|
||||
if(FinaleStage < 5 && FinaleCount >= FinaleEndCount)
|
||||
{
|
||||
FinaleCount = 0;
|
||||
FinaleStage++;
|
||||
switch(FinaleStage)
|
||||
{
|
||||
case 1: // Text 1
|
||||
FinaleEndCount = strlen(FinaleText)*TEXTSPEED+TEXTWAIT;
|
||||
break;
|
||||
case 2: // Pic 2, Text 2
|
||||
FinaleText = GetFinaleText(1);
|
||||
FinaleEndCount = strlen(FinaleText)*TEXTSPEED+TEXTWAIT;
|
||||
FinaleLumpNum = W_GetNumForName("FINALE2");
|
||||
S_StartSongName("orb", false);
|
||||
break;
|
||||
case 3: // Pic 2 -- Fade out
|
||||
FinaleEndCount = 70;
|
||||
DeInitializeFade();
|
||||
InitializeFade(0);
|
||||
break;
|
||||
case 4: // Pic 3 -- Fade in
|
||||
FinaleLumpNum = W_GetNumForName("FINALE3");
|
||||
FinaleEndCount = 71;
|
||||
DeInitializeFade();
|
||||
InitializeFade(1);
|
||||
S_StartSongName("chess", true);
|
||||
break;
|
||||
case 5: // Pic 3 , Text 3
|
||||
FinaleText = GetFinaleText(2);
|
||||
DeInitializeFade();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(FinaleStage == 0 || FinaleStage == 3 || FinaleStage == 4)
|
||||
{
|
||||
FadePic();
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// TextWrite
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static void TextWrite (void)
|
||||
{
|
||||
int count;
|
||||
char *ch;
|
||||
int c;
|
||||
int cx, cy;
|
||||
patch_t *w;
|
||||
|
||||
memcpy(screen, W_CacheLumpNum(FinaleLumpNum, PU_CACHE),
|
||||
SCREENWIDTH*SCREENHEIGHT);
|
||||
if(FinaleStage == 5)
|
||||
{ // Chess pic, draw the correct character graphic
|
||||
if(netgame)
|
||||
{
|
||||
V_DrawPatch(20, 0, W_CacheLumpName("chessall", PU_CACHE));
|
||||
}
|
||||
else if(PlayerClass[consoleplayer])
|
||||
{
|
||||
V_DrawPatch(60, 0, W_CacheLumpNum(W_GetNumForName("chessc")
|
||||
+PlayerClass[consoleplayer]-1, PU_CACHE));
|
||||
}
|
||||
}
|
||||
// Draw the actual text
|
||||
if(FinaleStage == 5)
|
||||
{
|
||||
cy = 135;
|
||||
}
|
||||
else
|
||||
{
|
||||
cy = 5;
|
||||
}
|
||||
cx = 20;
|
||||
ch = FinaleText;
|
||||
count = (FinaleCount-10)/TEXTSPEED;
|
||||
if (count < 0)
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
for(; count; count--)
|
||||
{
|
||||
c = *ch++;
|
||||
if(!c)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(c == '\n')
|
||||
{
|
||||
cx = 20;
|
||||
cy += 9;
|
||||
continue;
|
||||
}
|
||||
if(c < 32)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
c = toupper(c);
|
||||
if(c == 32)
|
||||
{
|
||||
cx += 5;
|
||||
continue;
|
||||
}
|
||||
w = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
|
||||
if(cx+w->width > SCREENWIDTH)
|
||||
{
|
||||
break;
|
||||
}
|
||||
V_DrawPatch(cx, cy, w);
|
||||
cx += w->width;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// InitializeFade
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static void InitializeFade(boolean fadeIn)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
Palette = Z_Malloc(768*sizeof(fixed_t), PU_STATIC, 0);
|
||||
PaletteDelta = Z_Malloc(768*sizeof(fixed_t), PU_STATIC, 0);
|
||||
RealPalette = Z_Malloc(768*sizeof(byte), PU_STATIC, 0);
|
||||
|
||||
if(fadeIn)
|
||||
{
|
||||
memset(RealPalette, 0, 768*sizeof(byte));
|
||||
for(i = 0; i < 768; i++)
|
||||
{
|
||||
Palette[i] = 0;
|
||||
PaletteDelta[i] = FixedDiv((*((byte *)W_CacheLumpName("playpal",
|
||||
PU_CACHE)+i))<<FRACBITS, 70*FRACUNIT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0; i < 768; i++)
|
||||
{
|
||||
RealPalette[i] = *((byte *)W_CacheLumpName("playpal", PU_CACHE)+i);
|
||||
Palette[i] = RealPalette[i]<<FRACBITS;
|
||||
PaletteDelta[i] = FixedDiv(Palette[i], -70*FRACUNIT);
|
||||
}
|
||||
}
|
||||
I_SetPalette(RealPalette);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// DeInitializeFade
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static void DeInitializeFade(void)
|
||||
{
|
||||
Z_Free(Palette);
|
||||
Z_Free(PaletteDelta);
|
||||
Z_Free(RealPalette);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FadePic
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static void FadePic(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for(i = 0; i < 768; i++)
|
||||
{
|
||||
Palette[i] += PaletteDelta[i];
|
||||
RealPalette[i] = Palette[i]>>FRACBITS;
|
||||
}
|
||||
I_SetPalette(RealPalette);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// DrawPic
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static void DrawPic(void)
|
||||
{
|
||||
memcpy(screen, W_CacheLumpNum(FinaleLumpNum, PU_CACHE),
|
||||
SCREENWIDTH*SCREENHEIGHT);
|
||||
if(FinaleStage == 4 || FinaleStage == 5)
|
||||
{ // Chess pic, draw the correct character graphic
|
||||
if(netgame)
|
||||
{
|
||||
V_DrawPatch(20, 0, W_CacheLumpName("chessall", PU_CACHE));
|
||||
}
|
||||
else if(PlayerClass[consoleplayer])
|
||||
{
|
||||
V_DrawPatch(60, 0, W_CacheLumpNum(W_GetNumForName("chessc")
|
||||
+PlayerClass[consoleplayer]-1, PU_CACHE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// F_Drawer
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void F_Drawer(void)
|
||||
{
|
||||
switch(FinaleStage)
|
||||
{
|
||||
case 0: // Fade in initial finale screen
|
||||
DrawPic();
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
TextWrite();
|
||||
break;
|
||||
case 3: // Fade screen out
|
||||
DrawPic();
|
||||
break;
|
||||
case 4: // Fade in chess screen
|
||||
DrawPic();
|
||||
break;
|
||||
case 5:
|
||||
TextWrite();
|
||||
break;
|
||||
}
|
||||
UpdateState |= I_FULLSCRN;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetFinaleText
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static char *GetFinaleText(int sequence)
|
||||
{
|
||||
char *msgLumpName;
|
||||
int msgSize;
|
||||
int msgLump;
|
||||
static char *winMsgLumpNames[] =
|
||||
{
|
||||
"win1msg",
|
||||
"win2msg",
|
||||
"win3msg"
|
||||
};
|
||||
|
||||
msgLumpName = winMsgLumpNames[sequence];
|
||||
msgLump = W_GetNumForName(msgLumpName);
|
||||
msgSize = W_LumpLength(msgLump);
|
||||
if(msgSize >= MAX_INTRMSN_MESSAGE_SIZE)
|
||||
{
|
||||
I_Error("Finale message too long (%s)", msgLumpName);
|
||||
}
|
||||
W_ReadLump(msgLump, ClusterMessage);
|
||||
ClusterMessage[msgSize] = 0; // Append terminator
|
||||
return ClusterMessage;
|
||||
}
|
2014
Hexen Source/G_GAME.C
Normal file
2014
Hexen Source/G_GAME.C
Normal file
File diff suppressed because it is too large
Load diff
1459
Hexen Source/H2DEF.H
Normal file
1459
Hexen Source/H2DEF.H
Normal file
File diff suppressed because it is too large
Load diff
934
Hexen Source/H2_MAIN.C
Normal file
934
Hexen Source/H2_MAIN.C
Normal file
|
@ -0,0 +1,934 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** h2_main.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: h2_main.c,v $
|
||||
//** $Revision: 1.50 $
|
||||
//** $Date: 96/01/16 13:02:28 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
#include <dos.h>
|
||||
#include <sys\types.h>
|
||||
#include <direct.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
#include "soundst.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
#define CONFIG_FILE_NAME "hexen.cfg"
|
||||
#define MAXWADFILES 20
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
void (*func)(char **args, int tag);
|
||||
int requiredArgs;
|
||||
int tag;
|
||||
} execOpt_t;
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
void R_ExecuteSetViewSize(void);
|
||||
void D_CheckNetGame(void);
|
||||
void G_BuildTiccmd(ticcmd_t *cmd);
|
||||
void F_Drawer(void);
|
||||
boolean F_Responder(event_t *ev);
|
||||
void I_StartupKeyboard(void);
|
||||
void I_StartupJoystick(void);
|
||||
void I_ShutdownKeyboard(void);
|
||||
void S_InitScript(void);
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
void H2_ProcessEvents(void);
|
||||
void H2_DoAdvanceDemo(void);
|
||||
void H2_AdvanceDemo(void);
|
||||
void H2_StartTitle(void);
|
||||
void H2_PageTicker(void);
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static void DrawMessage(void);
|
||||
static void PageDrawer(void);
|
||||
static void HandleArgs(void);
|
||||
static void CheckRecordFrom(void);
|
||||
static void AddWADFile(char *file);
|
||||
static void DrawAndBlit(void);
|
||||
static void ExecOptionFILE(char **args, int tag);
|
||||
static void ExecOptionSCRIPTS(char **args, int tag);
|
||||
static void ExecOptionDEVMAPS(char **args, int tag);
|
||||
static void ExecOptionSKILL(char **args, int tag);
|
||||
static void ExecOptionPLAYDEMO(char **args, int tag);
|
||||
static void ExecOptionMAXZONE(char **args, int tag);
|
||||
static void CreateSavePath(void);
|
||||
static void WarpCheck(void);
|
||||
|
||||
#ifdef TIMEBOMB
|
||||
static void DoTimeBomb(void);
|
||||
#endif
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
extern boolean automapactive;
|
||||
extern boolean MenuActive;
|
||||
extern boolean askforquit;
|
||||
extern char *SavePath;
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
boolean DevMaps; // true = Map development mode
|
||||
char *DevMapsDir = ""; // development maps directory
|
||||
boolean shareware; // true if only episode 1 present
|
||||
boolean nomonsters; // checkparm of -nomonsters
|
||||
boolean respawnparm; // checkparm of -respawn
|
||||
boolean randomclass; // checkparm of -randclass
|
||||
boolean debugmode; // checkparm of -debug
|
||||
boolean ravpic; // checkparm of -ravpic
|
||||
boolean cdrom; // true if cd-rom mode active
|
||||
boolean cmdfrag; // true if a CMD_FRAG packet should be sent out
|
||||
boolean singletics; // debug flag to cancel adaptiveness
|
||||
boolean artiskip; // whether shift-enter skips an artifact
|
||||
int maxzone = 0x800000; // Maximum allocated for zone heap (8meg default)
|
||||
skill_t startskill;
|
||||
int startepisode;
|
||||
int startmap;
|
||||
boolean autostart;
|
||||
boolean advancedemo;
|
||||
FILE *debugfile;
|
||||
event_t events[MAXEVENTS];
|
||||
int eventhead;
|
||||
int eventtail;
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static int WarpMap;
|
||||
static int demosequence;
|
||||
static int pagetic;
|
||||
static char *pagename;
|
||||
#ifdef __NeXT__
|
||||
static char *wadfiles[MAXWADFILES] =
|
||||
{
|
||||
"/Novell/H2/source/hexen.wad"
|
||||
};
|
||||
#else
|
||||
static char *wadfiles[MAXWADFILES] =
|
||||
{
|
||||
"hexen.wad"
|
||||
};
|
||||
#endif
|
||||
static execOpt_t ExecOptions[] =
|
||||
{
|
||||
{ "-file", ExecOptionFILE, 1, 0 },
|
||||
{ "-scripts", ExecOptionSCRIPTS, 1, 0 },
|
||||
{ "-devmaps", ExecOptionDEVMAPS, 1, 0 },
|
||||
{ "-skill", ExecOptionSKILL, 1, 0 },
|
||||
{ "-playdemo", ExecOptionPLAYDEMO, 1, 0 },
|
||||
{ "-timedemo", ExecOptionPLAYDEMO, 1, 0 },
|
||||
{ "-maxzone", ExecOptionMAXZONE, 1, 0 },
|
||||
{ NULL, NULL, 0, 0 } // Terminator
|
||||
};
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// H2_Main
|
||||
//
|
||||
//==========================================================================
|
||||
void InitMapMusicInfo(void);
|
||||
|
||||
void H2_Main(void)
|
||||
{
|
||||
int p;
|
||||
|
||||
M_FindResponseFile();
|
||||
setbuf(stdout, NULL);
|
||||
startepisode = 1;
|
||||
autostart = false;
|
||||
startskill = sk_medium;
|
||||
startmap = 1;
|
||||
shareware = false; // Always false for Hexen
|
||||
|
||||
HandleArgs();
|
||||
|
||||
// Initialize subsystems
|
||||
|
||||
ST_Message("V_Init: allocate screens.\n");
|
||||
V_Init();
|
||||
|
||||
// Load defaults before initing other systems
|
||||
ST_Message("M_LoadDefaults: Load system defaults.\n");
|
||||
M_LoadDefaults(CONFIG_FILE_NAME);
|
||||
|
||||
// Now that the savedir is loaded from .CFG, make sure it exists
|
||||
CreateSavePath();
|
||||
|
||||
// HEXEN MODIFICATION:
|
||||
// There is a realloc() in W_AddFile() that might fail if the zone
|
||||
// heap has been previously allocated, so we need to initialize the
|
||||
// WAD files BEFORE the zone memory initialization.
|
||||
ST_Message("W_Init: Init WADfiles.\n");
|
||||
W_InitMultipleFiles(wadfiles);
|
||||
|
||||
#ifdef TIMEBOMB
|
||||
DoTimeBomb();
|
||||
#endif
|
||||
|
||||
ST_Message("Z_Init: Init zone memory allocation daemon.\n");
|
||||
Z_Init();
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
I_StartupKeyboard();
|
||||
I_StartupJoystick();
|
||||
#endif
|
||||
|
||||
ST_Message("MN_Init: Init menu system.\n");
|
||||
MN_Init();
|
||||
|
||||
ST_Message("CT_Init: Init chat mode data.\n");
|
||||
CT_Init();
|
||||
|
||||
InitMapMusicInfo(); // Init music fields in mapinfo
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
ST_Message("S_InitScript\n");
|
||||
S_InitScript();
|
||||
#endif
|
||||
|
||||
ST_Message("SN_InitSequenceScript: Registering sound sequences.\n");
|
||||
SN_InitSequenceScript();
|
||||
ST_Message("I_Init: Setting up machine state.\n");
|
||||
I_Init();
|
||||
|
||||
ST_Message("ST_Init: Init startup screen.\n");
|
||||
ST_Init();
|
||||
|
||||
S_StartSongName("orb", true);
|
||||
|
||||
// Show version message now, so it's visible during R_Init()
|
||||
ST_Message("Executable: "VERSIONTEXT".\n");
|
||||
|
||||
ST_Message("R_Init: Init Hexen refresh daemon");
|
||||
R_Init();
|
||||
ST_Message("\n");
|
||||
|
||||
if (M_CheckParm("-net")) ST_NetProgress(); // Console player found
|
||||
|
||||
ST_Message("P_Init: Init Playloop state.\n");
|
||||
P_Init();
|
||||
|
||||
// Check for command line warping. Follows P_Init() because the
|
||||
// MAPINFO.TXT script must be already processed.
|
||||
WarpCheck();
|
||||
|
||||
if(autostart)
|
||||
{
|
||||
ST_Message("Warp to Map %d (\"%s\":%d), Skill %d\n",
|
||||
WarpMap, P_GetMapName(startmap), startmap, startskill+1);
|
||||
}
|
||||
|
||||
ST_Message("D_CheckNetGame: Checking network game status.\n");
|
||||
D_CheckNetGame();
|
||||
|
||||
ST_Message("SB_Init: Loading patches.\n");
|
||||
SB_Init();
|
||||
|
||||
CheckRecordFrom();
|
||||
|
||||
p = M_CheckParm("-record");
|
||||
if(p && p < myargc-1)
|
||||
{
|
||||
G_RecordDemo(startskill, 1, startepisode, startmap, myargv[p+1]);
|
||||
H2_GameLoop(); // Never returns
|
||||
}
|
||||
|
||||
p = M_CheckParm("-playdemo");
|
||||
if(p && p < myargc-1)
|
||||
{
|
||||
singledemo = true; // Quit after one demo
|
||||
G_DeferedPlayDemo(myargv[p+1]);
|
||||
H2_GameLoop(); // Never returns
|
||||
}
|
||||
|
||||
p = M_CheckParm("-timedemo");
|
||||
if(p && p < myargc-1)
|
||||
{
|
||||
G_TimeDemo(myargv[p+1]);
|
||||
H2_GameLoop(); // Never returns
|
||||
}
|
||||
|
||||
p = M_CheckParm("-loadgame");
|
||||
if(p && p < myargc-1)
|
||||
{
|
||||
G_LoadGame(atoi(myargv[p+1]));
|
||||
}
|
||||
|
||||
if(gameaction != ga_loadgame)
|
||||
{
|
||||
UpdateState |= I_FULLSCRN;
|
||||
BorderNeedRefresh = true;
|
||||
if(autostart || netgame)
|
||||
{
|
||||
G_StartNewInit();
|
||||
G_InitNew(startskill, startepisode, startmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
H2_StartTitle();
|
||||
}
|
||||
}
|
||||
H2_GameLoop(); // Never returns
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// HandleArgs
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void HandleArgs(void)
|
||||
{
|
||||
int p;
|
||||
execOpt_t *opt;
|
||||
|
||||
nomonsters = M_ParmExists("-nomonsters");
|
||||
respawnparm = M_ParmExists("-respawn");
|
||||
randomclass = M_ParmExists("-randclass");
|
||||
ravpic = M_ParmExists("-ravpic");
|
||||
artiskip = M_ParmExists("-artiskip");
|
||||
debugmode = M_ParmExists("-debug");
|
||||
deathmatch = M_ParmExists("-deathmatch");
|
||||
cdrom = M_ParmExists("-cdrom");
|
||||
cmdfrag = M_ParmExists("-cmdfrag");
|
||||
|
||||
// Process command line options
|
||||
for(opt = ExecOptions; opt->name != NULL; opt++)
|
||||
{
|
||||
p = M_CheckParm(opt->name);
|
||||
if(p && p < myargc-opt->requiredArgs)
|
||||
{
|
||||
opt->func(&myargv[p], opt->tag);
|
||||
}
|
||||
}
|
||||
|
||||
// Look for an external device driver
|
||||
I_CheckExternDriver();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// WarpCheck
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void WarpCheck(void)
|
||||
{
|
||||
int p;
|
||||
int map;
|
||||
|
||||
p = M_CheckParm("-warp");
|
||||
if(p && p < myargc-1)
|
||||
{
|
||||
WarpMap = atoi(myargv[p+1]);
|
||||
map = P_TranslateMap(WarpMap);
|
||||
if(map == -1)
|
||||
{ // Couldn't find real map number
|
||||
startmap = 1;
|
||||
ST_Message("-WARP: Invalid map number.\n");
|
||||
}
|
||||
else
|
||||
{ // Found a valid startmap
|
||||
startmap = map;
|
||||
autostart = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WarpMap = 1;
|
||||
startmap = P_TranslateMap(1);
|
||||
if(startmap == -1)
|
||||
{
|
||||
startmap = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ExecOptionSKILL
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ExecOptionSKILL(char **args, int tag)
|
||||
{
|
||||
startskill = args[1][0]-'1';
|
||||
autostart = true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ExecOptionFILE
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ExecOptionFILE(char **args, int tag)
|
||||
{
|
||||
int p;
|
||||
|
||||
p = M_CheckParm("-file");
|
||||
while(++p != myargc && myargv[p][0] != '-')
|
||||
{
|
||||
AddWADFile(myargv[p]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ExecOptionPLAYDEMO
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ExecOptionPLAYDEMO(char **args, int tag)
|
||||
{
|
||||
char file[256];
|
||||
|
||||
sprintf(file, "%s.lmp", args[1]);
|
||||
AddWADFile(file);
|
||||
ST_Message("Playing demo %s.lmp.\n", args[1]);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ExecOptionSCRIPTS
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ExecOptionSCRIPTS(char **args, int tag)
|
||||
{
|
||||
sc_FileScripts = true;
|
||||
sc_ScriptsDir = args[1];
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ExecOptionDEVMAPS
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ExecOptionDEVMAPS(char **args, int tag)
|
||||
{
|
||||
DevMaps = true;
|
||||
ST_Message("Map development mode enabled:\n");
|
||||
ST_Message("[config ] = %s\n", args[1]);
|
||||
SC_OpenFileCLib(args[1]);
|
||||
SC_MustGetStringName("mapsdir");
|
||||
SC_MustGetString();
|
||||
ST_Message("[mapsdir ] = %s\n", sc_String);
|
||||
DevMapsDir = malloc(strlen(sc_String)+1);
|
||||
strcpy(DevMapsDir, sc_String);
|
||||
SC_MustGetStringName("scriptsdir");
|
||||
SC_MustGetString();
|
||||
ST_Message("[scriptsdir] = %s\n", sc_String);
|
||||
sc_FileScripts = true;
|
||||
sc_ScriptsDir = malloc(strlen(sc_String)+1);
|
||||
strcpy(sc_ScriptsDir, sc_String);
|
||||
while(SC_GetString())
|
||||
{
|
||||
if(SC_Compare("file"))
|
||||
{
|
||||
SC_MustGetString();
|
||||
AddWADFile(sc_String);
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_ScriptError(NULL);
|
||||
}
|
||||
}
|
||||
SC_Close();
|
||||
}
|
||||
|
||||
|
||||
long superatol(char *s)
|
||||
{
|
||||
long int n=0, r=10, x, mul=1;
|
||||
char *c=s;
|
||||
|
||||
for (; *c; c++)
|
||||
{
|
||||
x = (*c & 223) - 16;
|
||||
|
||||
if (x == -3)
|
||||
{
|
||||
mul = -mul;
|
||||
}
|
||||
else if (x == 72 && r == 10)
|
||||
{
|
||||
n -= (r=n);
|
||||
if (!r) r=16;
|
||||
if (r<2 || r>36) return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x>10) x-=39;
|
||||
if (x >= r) return -1;
|
||||
n = (n*r) + x;
|
||||
}
|
||||
}
|
||||
return(mul*n);
|
||||
}
|
||||
|
||||
|
||||
static void ExecOptionMAXZONE(char **args, int tag)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = superatol(args[1]);
|
||||
if (size < MINIMUM_HEAP_SIZE) size = MINIMUM_HEAP_SIZE;
|
||||
if (size > MAXIMUM_HEAP_SIZE) size = MAXIMUM_HEAP_SIZE;
|
||||
maxzone = size;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// H2_GameLoop
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void H2_GameLoop(void)
|
||||
{
|
||||
if(M_CheckParm("-debugfile"))
|
||||
{
|
||||
char filename[20];
|
||||
sprintf(filename, "debug%i.txt", consoleplayer);
|
||||
debugfile = fopen(filename,"w");
|
||||
}
|
||||
I_InitGraphics();
|
||||
while(1)
|
||||
{
|
||||
// Frame syncronous IO operations
|
||||
I_StartFrame();
|
||||
|
||||
// Process one or more tics
|
||||
if(singletics)
|
||||
{
|
||||
I_StartTic();
|
||||
H2_ProcessEvents();
|
||||
G_BuildTiccmd(&netcmds[consoleplayer][maketic%BACKUPTICS]);
|
||||
if(advancedemo)
|
||||
{
|
||||
H2_DoAdvanceDemo();
|
||||
}
|
||||
G_Ticker();
|
||||
gametic++;
|
||||
maketic++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Will run at least one tic
|
||||
TryRunTics();
|
||||
}
|
||||
|
||||
// Move positional sounds
|
||||
S_UpdateSounds(players[displayplayer].mo);
|
||||
|
||||
DrawAndBlit();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// H2_ProcessEvents
|
||||
//
|
||||
// Send all the events of the given timestamp down the responder chain.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void H2_ProcessEvents(void)
|
||||
{
|
||||
event_t *ev;
|
||||
|
||||
for(; eventtail != eventhead; eventtail = (++eventtail)&(MAXEVENTS-1))
|
||||
{
|
||||
ev = &events[eventtail];
|
||||
if(F_Responder(ev))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(MN_Responder(ev))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
G_Responder(ev);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// H2_PostEvent
|
||||
//
|
||||
// Called by the I/O functions when input is detected.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void H2_PostEvent(event_t *ev)
|
||||
{
|
||||
events[eventhead] = *ev;
|
||||
eventhead = (++eventhead)&(MAXEVENTS-1);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DrawAndBlit
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void DrawAndBlit(void)
|
||||
{
|
||||
// Change the view size if needed
|
||||
if(setsizeneeded)
|
||||
{
|
||||
R_ExecuteSetViewSize();
|
||||
}
|
||||
|
||||
// Do buffered drawing
|
||||
switch(gamestate)
|
||||
{
|
||||
case GS_LEVEL:
|
||||
if(!gametic)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(automapactive)
|
||||
{
|
||||
AM_Drawer();
|
||||
}
|
||||
else
|
||||
{
|
||||
R_RenderPlayerView(&players[displayplayer]);
|
||||
}
|
||||
CT_Drawer();
|
||||
UpdateState |= I_FULLVIEW;
|
||||
SB_Drawer();
|
||||
break;
|
||||
case GS_INTERMISSION:
|
||||
IN_Drawer();
|
||||
break;
|
||||
case GS_FINALE:
|
||||
F_Drawer();
|
||||
break;
|
||||
case GS_DEMOSCREEN:
|
||||
PageDrawer();
|
||||
break;
|
||||
}
|
||||
|
||||
if(paused && !MenuActive && !askforquit)
|
||||
{
|
||||
if(!netgame)
|
||||
{
|
||||
V_DrawPatch(160, viewwindowy+5, W_CacheLumpName("PAUSED",
|
||||
PU_CACHE));
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawPatch(160, 70, W_CacheLumpName("PAUSED",
|
||||
PU_CACHE));
|
||||
}
|
||||
}
|
||||
|
||||
// Draw current message
|
||||
DrawMessage();
|
||||
|
||||
// Draw Menu
|
||||
MN_Drawer();
|
||||
|
||||
// Send out any new accumulation
|
||||
NetUpdate();
|
||||
|
||||
// Flush buffered stuff to screen
|
||||
I_Update();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DrawMessage
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void DrawMessage(void)
|
||||
{
|
||||
player_t *player;
|
||||
|
||||
player = &players[consoleplayer];
|
||||
if(player->messageTics <= 0 || !player->message)
|
||||
{ // No message
|
||||
return;
|
||||
}
|
||||
if(player->yellowMessage)
|
||||
{
|
||||
MN_DrTextAYellow(player->message,
|
||||
160-MN_TextAWidth(player->message)/2, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
MN_DrTextA(player->message, 160-MN_TextAWidth(player->message)/2, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// H2_PageTicker
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void H2_PageTicker(void)
|
||||
{
|
||||
if(--pagetic < 0)
|
||||
{
|
||||
H2_AdvanceDemo();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PageDrawer
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void PageDrawer(void)
|
||||
{
|
||||
V_DrawRawScreen(W_CacheLumpName(pagename, PU_CACHE));
|
||||
if(demosequence == 1)
|
||||
{
|
||||
V_DrawPatch(4, 160, W_CacheLumpName("ADVISOR", PU_CACHE));
|
||||
}
|
||||
UpdateState |= I_FULLSCRN;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// H2_AdvanceDemo
|
||||
//
|
||||
// Called after each demo or intro demosequence finishes.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void H2_AdvanceDemo(void)
|
||||
{
|
||||
advancedemo = true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// H2_DoAdvanceDemo
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void H2_DoAdvanceDemo(void)
|
||||
{
|
||||
players[consoleplayer].playerstate = PST_LIVE; // don't reborn
|
||||
advancedemo = false;
|
||||
usergame = false; // can't save/end game here
|
||||
paused = false;
|
||||
gameaction = ga_nothing;
|
||||
demosequence = (demosequence+1)%7;
|
||||
switch(demosequence)
|
||||
{
|
||||
case 0:
|
||||
pagetic = 280;
|
||||
gamestate = GS_DEMOSCREEN;
|
||||
pagename = "TITLE";
|
||||
S_StartSongName("hexen", true);
|
||||
break;
|
||||
case 1:
|
||||
pagetic = 210;
|
||||
gamestate = GS_DEMOSCREEN;
|
||||
pagename = "TITLE";
|
||||
break;
|
||||
case 2:
|
||||
BorderNeedRefresh = true;
|
||||
UpdateState |= I_FULLSCRN;
|
||||
G_DeferedPlayDemo("demo1");
|
||||
break;
|
||||
case 3:
|
||||
pagetic = 200;
|
||||
gamestate = GS_DEMOSCREEN;
|
||||
pagename = "CREDIT";
|
||||
break;
|
||||
case 4:
|
||||
BorderNeedRefresh = true;
|
||||
UpdateState |= I_FULLSCRN;
|
||||
G_DeferedPlayDemo("demo2");
|
||||
break;
|
||||
case 5:
|
||||
pagetic = 200;
|
||||
gamestate = GS_DEMOSCREEN;
|
||||
pagename = "CREDIT";
|
||||
break;
|
||||
case 6:
|
||||
BorderNeedRefresh = true;
|
||||
UpdateState |= I_FULLSCRN;
|
||||
G_DeferedPlayDemo("demo3");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// H2_StartTitle
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void H2_StartTitle(void)
|
||||
{
|
||||
gameaction = ga_nothing;
|
||||
demosequence = -1;
|
||||
H2_AdvanceDemo();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CheckRecordFrom
|
||||
//
|
||||
// -recordfrom <savegame num> <demoname>
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void CheckRecordFrom(void)
|
||||
{
|
||||
int p;
|
||||
|
||||
p = M_CheckParm("-recordfrom");
|
||||
if(!p || p > myargc-2)
|
||||
{ // Bad args
|
||||
return;
|
||||
}
|
||||
G_LoadGame(atoi(myargv[p+1]));
|
||||
G_DoLoadGame(); // Load the gameskill etc info from savegame
|
||||
G_RecordDemo(gameskill, 1, gameepisode, gamemap, myargv[p+2]);
|
||||
H2_GameLoop(); // Never returns
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// AddWADFile
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void AddWADFile(char *file)
|
||||
{
|
||||
int i;
|
||||
char *new;
|
||||
|
||||
ST_Message("Adding external file: %s\n", file);
|
||||
i = 0;
|
||||
while(wadfiles[i])
|
||||
{
|
||||
i++;
|
||||
}
|
||||
new = malloc(strlen(file)+1);
|
||||
strcpy(new, file);
|
||||
wadfiles[i] = new;
|
||||
}
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
/*
|
||||
void CleanExit(void)
|
||||
{
|
||||
union REGS regs;
|
||||
|
||||
I_ShutdownKeyboard();
|
||||
regs.x.eax = 0x3;
|
||||
int386(0x10, ®s, ®s);
|
||||
printf("Exited from HEXEN: Beyond Heretic.\n");
|
||||
exit(1);
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FixedDiv
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
fixed_t FixedDiv(fixed_t a, fixed_t b)
|
||||
{
|
||||
if((abs(a)>>14) >= abs(b))
|
||||
{
|
||||
return((a^b)<0 ? MININT : MAXINT);
|
||||
}
|
||||
return(FixedDiv2(a, b));
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CreateSavePath
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void CreateSavePath(void)
|
||||
{
|
||||
char creationPath[121];
|
||||
int len;
|
||||
|
||||
if(cdrom == true)
|
||||
{
|
||||
SavePath = "c:\\hexndata\\";
|
||||
}
|
||||
len = strlen(SavePath);
|
||||
if (len >= 120) I_Error("Save path too long\n");
|
||||
strcpy(creationPath, SavePath);
|
||||
#ifdef __WATCOMC__
|
||||
creationPath[len-1] = 0;
|
||||
mkdir(creationPath);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef TIMEBOMB
|
||||
//==========================================================================
|
||||
//
|
||||
// DoTimeBomb
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void DoTimeBomb(void)
|
||||
{
|
||||
#ifdef __WATCOMC__
|
||||
time_t timeOfDay;
|
||||
struct tm timeBuffer;
|
||||
|
||||
timeOfDay = time(NULL);
|
||||
_localtime(&timeOfDay, &timeBuffer);
|
||||
if(timeBuffer.tm_year != TIMEBOMB_YEAR
|
||||
|| timeBuffer.tm_yday < TIMEBOMB_STARTDATE
|
||||
|| timeBuffer.tm_yday > TIMEBOMB_ENDDATE)
|
||||
{
|
||||
I_Error("W_InitWadfiles: Wad file doesn't have IWAD or PWAD id\n");
|
||||
}
|
||||
|
||||
printf("\n===============================================================================\n");
|
||||
printf(" Hexen: Beyond Heretic\n\n");
|
||||
printf(" Beta -- Do Not Distribute!\n");
|
||||
printf(" Press any key to continue.\n");
|
||||
printf("===============================================================================\n");
|
||||
|
||||
getch();
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
#endif
|
73
Hexen Source/HEX.LNK
Normal file
73
Hexen Source/HEX.LNK
Normal file
|
@ -0,0 +1,73 @@
|
|||
|
||||
# HEX.EXE Linker directive file
|
||||
|
||||
option quiet
|
||||
option map
|
||||
option statics
|
||||
option stack=65536
|
||||
option stub=wstub
|
||||
debug all
|
||||
libpath %WATCOM%\lib386
|
||||
libpath %WATCOM%\lib386\dos
|
||||
lib noemu387.lib
|
||||
lib dmx
|
||||
format os2 le
|
||||
name hex
|
||||
|
||||
file i_cyber.obj
|
||||
file i_ibm.obj
|
||||
file i_ibm_a.obj
|
||||
file i_sound.obj
|
||||
file i_cdmus.obj
|
||||
file linear.obj
|
||||
|
||||
file am_map.obj
|
||||
file a_action.obj
|
||||
file ct_chat.obj
|
||||
file d_net.obj
|
||||
file f_finale.obj
|
||||
file g_game.obj
|
||||
file h2_main.obj
|
||||
file info.obj
|
||||
file in_lude.obj
|
||||
file mn_menu.obj
|
||||
file m_misc.obj
|
||||
file p_acs.obj
|
||||
file p_anim.obj
|
||||
file p_ceilng.obj
|
||||
file p_doors.obj
|
||||
file p_enemy.obj
|
||||
file p_floor.obj
|
||||
file p_inter.obj
|
||||
file p_lights.obj
|
||||
file p_map.obj
|
||||
file p_maputl.obj
|
||||
file p_mobj.obj
|
||||
file p_plats.obj
|
||||
file p_pspr.obj
|
||||
file p_setup.obj
|
||||
file p_sight.obj
|
||||
file p_spec.obj
|
||||
file p_switch.obj
|
||||
file p_telept.obj
|
||||
file p_tick.obj
|
||||
file p_things.obj
|
||||
file p_user.obj
|
||||
file po_man.obj
|
||||
file r_bsp.obj
|
||||
file r_data.obj
|
||||
file r_draw.obj
|
||||
file r_main.obj
|
||||
file r_plane.obj
|
||||
file r_segs.obj
|
||||
file r_things.obj
|
||||
file sb_bar.obj
|
||||
file sc_man.obj
|
||||
file sn_sonix.obj
|
||||
file st_start.obj
|
||||
file sv_save.obj
|
||||
file sounds.obj
|
||||
file tables.obj
|
||||
file v_video.obj
|
||||
file w_wad.obj
|
||||
file z_zone.obj
|
13862
Hexen Source/INFO.C
Normal file
13862
Hexen Source/INFO.C
Normal file
File diff suppressed because it is too large
Load diff
3601
Hexen Source/INFO.H
Normal file
3601
Hexen Source/INFO.H
Normal file
File diff suppressed because it is too large
Load diff
597
Hexen Source/IN_LUDE.C
Normal file
597
Hexen Source/IN_LUDE.C
Normal file
|
@ -0,0 +1,597 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** in_lude.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: in_lude.c,v $
|
||||
//** $Revision: 1.19 $
|
||||
//** $Date: 96/01/05 23:33:19 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
#include <ctype.h>
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
#define TEXTSPEED 3
|
||||
#define TEXTWAIT 140
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SINGLE,
|
||||
COOPERATIVE,
|
||||
DEATHMATCH
|
||||
} gametype_t;
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
void IN_Start(void);
|
||||
void IN_Ticker(void);
|
||||
void IN_Drawer(void);
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static void WaitStop(void);
|
||||
static void Stop(void);
|
||||
static void LoadPics(void);
|
||||
static void UnloadPics(void);
|
||||
static void CheckForSkip(void);
|
||||
static void InitStats(void);
|
||||
static void DrDeathTally(void);
|
||||
static void DrNumber(int val, int x, int y, int wrapThresh);
|
||||
static void DrNumberBold(int val, int x, int y, int wrapThresh);
|
||||
static void DrawHubText(void);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
// PUBLIC DATA DECLARATIONS ------------------------------------------------
|
||||
|
||||
boolean intermission;
|
||||
char ClusterMessage[MAX_INTRMSN_MESSAGE_SIZE];
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static boolean skipintermission;
|
||||
static int interstate = 0;
|
||||
static int intertime = -1;
|
||||
static gametype_t gametype;
|
||||
static int cnt;
|
||||
static int slaughterboy; // in DM, the player with the most kills
|
||||
static patch_t *patchINTERPIC;
|
||||
static patch_t *FontBNumbers[10];
|
||||
static patch_t *FontBNegative;
|
||||
static patch_t *FontBSlash;
|
||||
static patch_t *FontBPercent;
|
||||
static int FontABaseLump;
|
||||
static int FontBLump;
|
||||
static int FontBLumpBase;
|
||||
|
||||
static signed int totalFrags[MAXPLAYERS];
|
||||
|
||||
static int HubCount;
|
||||
static char *HubText;
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//========================================================================
|
||||
//
|
||||
// IN_Start
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
extern void AM_Stop (void);
|
||||
|
||||
void IN_Start(void)
|
||||
{
|
||||
int i;
|
||||
I_SetPalette(W_CacheLumpName("PLAYPAL", PU_CACHE));
|
||||
InitStats();
|
||||
LoadPics();
|
||||
intermission = true;
|
||||
interstate = 0;
|
||||
skipintermission = false;
|
||||
intertime = 0;
|
||||
AM_Stop();
|
||||
for(i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
players[i].messageTics = 0;
|
||||
players[i].message[0] = 0;
|
||||
}
|
||||
SN_StopAllSequences();
|
||||
}
|
||||
|
||||
//========================================================================
|
||||
//
|
||||
// WaitStop
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
void WaitStop(void)
|
||||
{
|
||||
if(!--cnt)
|
||||
{
|
||||
Stop();
|
||||
// gamestate = GS_LEVEL;
|
||||
// G_DoLoadLevel();
|
||||
gameaction = ga_leavemap;
|
||||
// G_WorldDone();
|
||||
}
|
||||
}
|
||||
|
||||
//========================================================================
|
||||
//
|
||||
// Stop
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
static void Stop(void)
|
||||
{
|
||||
intermission = false;
|
||||
UnloadPics();
|
||||
SB_state = -1;
|
||||
BorderNeedRefresh = true;
|
||||
}
|
||||
|
||||
//========================================================================
|
||||
//
|
||||
// InitStats
|
||||
//
|
||||
// Initializes the stats for single player mode
|
||||
//========================================================================
|
||||
|
||||
static char *ClusMsgLumpNames[] =
|
||||
{
|
||||
"clus1msg",
|
||||
"clus2msg",
|
||||
"clus3msg",
|
||||
"clus4msg",
|
||||
"clus5msg"
|
||||
};
|
||||
|
||||
static void InitStats(void)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int oldCluster;
|
||||
signed int slaughterfrags;
|
||||
int posnum;
|
||||
int slaughtercount;
|
||||
int playercount;
|
||||
char *msgLumpName;
|
||||
int msgSize;
|
||||
int msgLump;
|
||||
|
||||
extern int LeaveMap;
|
||||
|
||||
if(!deathmatch)
|
||||
{
|
||||
gametype = SINGLE;
|
||||
HubCount = 0;
|
||||
oldCluster = P_GetMapCluster(gamemap);
|
||||
if(oldCluster != P_GetMapCluster(LeaveMap))
|
||||
{
|
||||
if(oldCluster >= 1 && oldCluster <= 5)
|
||||
{
|
||||
msgLumpName = ClusMsgLumpNames[oldCluster-1];
|
||||
msgLump = W_GetNumForName(msgLumpName);
|
||||
msgSize = W_LumpLength(msgLump);
|
||||
if(msgSize >= MAX_INTRMSN_MESSAGE_SIZE)
|
||||
{
|
||||
I_Error("Cluster message too long (%s)", msgLumpName);
|
||||
}
|
||||
W_ReadLump(msgLump, ClusterMessage);
|
||||
ClusterMessage[msgSize] = 0; // Append terminator
|
||||
HubText = ClusterMessage;
|
||||
HubCount = strlen(HubText)*TEXTSPEED+TEXTWAIT;
|
||||
S_StartSongName("hub", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gametype = DEATHMATCH;
|
||||
slaughterboy = 0;
|
||||
slaughterfrags = -9999;
|
||||
posnum = 0;
|
||||
playercount = 0;
|
||||
slaughtercount = 0;
|
||||
for(i=0; i<MAXPLAYERS; i++)
|
||||
{
|
||||
totalFrags[i] = 0;
|
||||
if(playeringame[i])
|
||||
{
|
||||
playercount++;
|
||||
for(j=0; j<MAXPLAYERS; j++)
|
||||
{
|
||||
if(playeringame[j])
|
||||
{
|
||||
totalFrags[i] += players[i].frags[j];
|
||||
}
|
||||
}
|
||||
posnum++;
|
||||
}
|
||||
if(totalFrags[i] > slaughterfrags)
|
||||
{
|
||||
slaughterboy = 1<<i;
|
||||
slaughterfrags = totalFrags[i];
|
||||
slaughtercount = 1;
|
||||
}
|
||||
else if(totalFrags[i] == slaughterfrags)
|
||||
{
|
||||
slaughterboy |= 1<<i;
|
||||
slaughtercount++;
|
||||
}
|
||||
}
|
||||
if(playercount == slaughtercount)
|
||||
{ // don't do the slaughter stuff if everyone is equal
|
||||
slaughterboy = 0;
|
||||
}
|
||||
S_StartSongName("hub", true);
|
||||
}
|
||||
}
|
||||
|
||||
//========================================================================
|
||||
//
|
||||
// LoadPics
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
static void LoadPics(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(HubCount || gametype == DEATHMATCH)
|
||||
{
|
||||
patchINTERPIC = W_CacheLumpName("INTERPIC", PU_STATIC);
|
||||
FontBLumpBase = W_GetNumForName("FONTB16");
|
||||
for(i=0; i<10; i++)
|
||||
{
|
||||
FontBNumbers[i] = W_CacheLumpNum(FontBLumpBase+i, PU_STATIC);
|
||||
}
|
||||
FontBLump = W_GetNumForName("FONTB_S")+1;
|
||||
FontBNegative = W_CacheLumpName("FONTB13", PU_STATIC);
|
||||
FontABaseLump = W_GetNumForName("FONTA_S")+1;
|
||||
|
||||
FontBSlash = W_CacheLumpName("FONTB15", PU_STATIC);
|
||||
FontBPercent = W_CacheLumpName("FONTB05", PU_STATIC);
|
||||
}
|
||||
}
|
||||
|
||||
//========================================================================
|
||||
//
|
||||
// UnloadPics
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
static void UnloadPics(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(HubCount || gametype == DEATHMATCH)
|
||||
{
|
||||
Z_ChangeTag(patchINTERPIC, PU_CACHE);
|
||||
for(i=0; i<10; i++)
|
||||
{
|
||||
Z_ChangeTag(FontBNumbers[i], PU_CACHE);
|
||||
}
|
||||
Z_ChangeTag(FontBNegative, PU_CACHE);
|
||||
Z_ChangeTag(FontBSlash, PU_CACHE);
|
||||
Z_ChangeTag(FontBPercent, PU_CACHE);
|
||||
}
|
||||
}
|
||||
|
||||
//========================================================================
|
||||
//
|
||||
// IN_Ticker
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
void IN_Ticker(void)
|
||||
{
|
||||
if(!intermission)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(interstate)
|
||||
{
|
||||
WaitStop();
|
||||
return;
|
||||
}
|
||||
skipintermission = false;
|
||||
CheckForSkip();
|
||||
intertime++;
|
||||
if(skipintermission || (gametype == SINGLE && !HubCount))
|
||||
{
|
||||
interstate = 1;
|
||||
cnt = 10;
|
||||
skipintermission = false;
|
||||
//S_StartSound(NULL, sfx_dorcls);
|
||||
}
|
||||
}
|
||||
|
||||
//========================================================================
|
||||
//
|
||||
// CheckForSkip
|
||||
//
|
||||
// Check to see if any player hit a key
|
||||
//========================================================================
|
||||
|
||||
static void CheckForSkip(void)
|
||||
{
|
||||
int i;
|
||||
player_t *player;
|
||||
static boolean triedToSkip;
|
||||
|
||||
for(i = 0, player = players; i < MAXPLAYERS; i++, player++)
|
||||
{
|
||||
if(playeringame[i])
|
||||
{
|
||||
if(player->cmd.buttons&BT_ATTACK)
|
||||
{
|
||||
if(!player->attackdown)
|
||||
{
|
||||
skipintermission = 1;
|
||||
}
|
||||
player->attackdown = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->attackdown = false;
|
||||
}
|
||||
if(player->cmd.buttons&BT_USE)
|
||||
{
|
||||
if(!player->usedown)
|
||||
{
|
||||
skipintermission = 1;
|
||||
}
|
||||
player->usedown = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->usedown = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(deathmatch && intertime < 140)
|
||||
{ // wait for 4 seconds before allowing a skip
|
||||
if(skipintermission == 1)
|
||||
{
|
||||
triedToSkip = true;
|
||||
skipintermission = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(triedToSkip)
|
||||
{
|
||||
skipintermission = 1;
|
||||
triedToSkip = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//========================================================================
|
||||
//
|
||||
// IN_Drawer
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
void IN_Drawer(void)
|
||||
{
|
||||
if(!intermission)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(interstate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
UpdateState |= I_FULLSCRN;
|
||||
memcpy(screen, (byte *)patchINTERPIC, SCREENWIDTH*SCREENHEIGHT);
|
||||
|
||||
if(gametype == SINGLE)
|
||||
{
|
||||
if(HubCount)
|
||||
{
|
||||
DrawHubText();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DrDeathTally();
|
||||
}
|
||||
}
|
||||
|
||||
//========================================================================
|
||||
//
|
||||
// DrDeathTally
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#define TALLY_EFFECT_TICKS 20
|
||||
#define TALLY_FINAL_X_DELTA (23*FRACUNIT)
|
||||
#define TALLY_FINAL_Y_DELTA (13*FRACUNIT)
|
||||
#define TALLY_START_XPOS (178*FRACUNIT)
|
||||
#define TALLY_STOP_XPOS (90*FRACUNIT)
|
||||
#define TALLY_START_YPOS (132*FRACUNIT)
|
||||
#define TALLY_STOP_YPOS (83*FRACUNIT)
|
||||
#define TALLY_TOP_X 85
|
||||
#define TALLY_TOP_Y 9
|
||||
#define TALLY_LEFT_X 7
|
||||
#define TALLY_LEFT_Y 71
|
||||
#define TALLY_TOTALS_X 291
|
||||
|
||||
static void DrDeathTally(void)
|
||||
{
|
||||
int i, j;
|
||||
fixed_t xPos, yPos;
|
||||
fixed_t xDelta, yDelta;
|
||||
fixed_t xStart, scale;
|
||||
int x, y;
|
||||
boolean bold;
|
||||
static boolean showTotals;
|
||||
int temp;
|
||||
|
||||
V_DrawPatch(TALLY_TOP_X, TALLY_TOP_Y,
|
||||
W_CacheLumpName("tallytop", PU_CACHE));
|
||||
V_DrawPatch(TALLY_LEFT_X, TALLY_LEFT_Y,
|
||||
W_CacheLumpName("tallylft", PU_CACHE));
|
||||
if(intertime < TALLY_EFFECT_TICKS)
|
||||
{
|
||||
showTotals = false;
|
||||
scale = (intertime*FRACUNIT)/TALLY_EFFECT_TICKS;
|
||||
xDelta = FixedMul(scale, TALLY_FINAL_X_DELTA);
|
||||
yDelta = FixedMul(scale, TALLY_FINAL_Y_DELTA);
|
||||
xStart = TALLY_START_XPOS-FixedMul(scale,
|
||||
TALLY_START_XPOS-TALLY_STOP_XPOS);
|
||||
yPos = TALLY_START_YPOS-FixedMul(scale,
|
||||
TALLY_START_YPOS-TALLY_STOP_YPOS);
|
||||
}
|
||||
else
|
||||
{
|
||||
xDelta = TALLY_FINAL_X_DELTA;
|
||||
yDelta = TALLY_FINAL_Y_DELTA;
|
||||
xStart = TALLY_STOP_XPOS;
|
||||
yPos = TALLY_STOP_YPOS;
|
||||
}
|
||||
if(intertime >= TALLY_EFFECT_TICKS && showTotals == false)
|
||||
{
|
||||
showTotals = true;
|
||||
S_StartSound(NULL, SFX_PLATFORM_STOP);
|
||||
}
|
||||
y = yPos>>FRACBITS;
|
||||
for(i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
xPos = xStart;
|
||||
for(j = 0; j < MAXPLAYERS; j++, xPos += xDelta)
|
||||
{
|
||||
x = xPos>>FRACBITS;
|
||||
bold = (i == consoleplayer || j == consoleplayer);
|
||||
if(playeringame[i] && playeringame[j])
|
||||
{
|
||||
if(bold)
|
||||
{
|
||||
DrNumberBold(players[i].frags[j], x, y, 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrNumber(players[i].frags[j], x, y, 100);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp = MN_TextAWidth("--")/2;
|
||||
if(bold)
|
||||
{
|
||||
MN_DrTextAYellow("--", x-temp, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
MN_DrTextA("--", x-temp, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(showTotals && playeringame[i]
|
||||
&& !((slaughterboy&(1<<i)) && !(intertime&16)))
|
||||
{
|
||||
DrNumber(totalFrags[i], TALLY_TOTALS_X, y, 1000);
|
||||
}
|
||||
yPos += yDelta;
|
||||
y = yPos>>FRACBITS;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DrNumber
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void DrNumber(int val, int x, int y, int wrapThresh)
|
||||
{
|
||||
char buff[8] = "XX";
|
||||
|
||||
if(!(val < -9 && wrapThresh < 1000))
|
||||
{
|
||||
sprintf(buff, "%d", val >= wrapThresh ? val%wrapThresh : val);
|
||||
}
|
||||
MN_DrTextA(buff, x-MN_TextAWidth(buff)/2, y);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DrNumberBold
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void DrNumberBold(int val, int x, int y, int wrapThresh)
|
||||
{
|
||||
char buff[8] = "XX";
|
||||
|
||||
if(!(val < -9 && wrapThresh < 1000))
|
||||
{
|
||||
sprintf(buff, "%d", val >= wrapThresh ? val%wrapThresh : val);
|
||||
}
|
||||
MN_DrTextAYellow(buff, x-MN_TextAWidth(buff)/2, y);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// DrawHubText
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
static void DrawHubText(void)
|
||||
{
|
||||
int count;
|
||||
char *ch;
|
||||
int c;
|
||||
int cx, cy;
|
||||
patch_t *w;
|
||||
|
||||
cy = 5;
|
||||
cx = 10;
|
||||
ch = HubText;
|
||||
count = (intertime-10)/TEXTSPEED;
|
||||
if (count < 0)
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
for(; count; count--)
|
||||
{
|
||||
c = *ch++;
|
||||
if(!c)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(c == '\n')
|
||||
{
|
||||
cx = 10;
|
||||
cy += 9;
|
||||
continue;
|
||||
}
|
||||
if(c < 32)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
c = toupper(c);
|
||||
if(c == 32)
|
||||
{
|
||||
cx += 5;
|
||||
continue;
|
||||
}
|
||||
w = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
|
||||
if(cx+w->width > SCREENWIDTH)
|
||||
{
|
||||
break;
|
||||
}
|
||||
V_DrawPatch(cx, cy, w);
|
||||
cx += w->width;
|
||||
}
|
||||
}
|
1023
Hexen Source/I_CDMUS.C
Normal file
1023
Hexen Source/I_CDMUS.C
Normal file
File diff suppressed because it is too large
Load diff
26
Hexen Source/I_CDMUS.H
Normal file
26
Hexen Source/I_CDMUS.H
Normal file
|
@ -0,0 +1,26 @@
|
|||
|
||||
// i_cdmus.h
|
||||
|
||||
#ifndef __ICDMUS__
|
||||
#define __ICDMUS__
|
||||
|
||||
#define CDERR_NOTINSTALLED 10 // MSCDEX not installed
|
||||
#define CDERR_NOAUDIOSUPPORT 11 // CD-ROM Doesn't support audio
|
||||
#define CDERR_NOAUDIOTRACKS 12 // Current CD has no audio tracks
|
||||
#define CDERR_BADDRIVE 20 // Bad drive number
|
||||
#define CDERR_BADTRACK 21 // Bad track number
|
||||
#define CDERR_IOCTLBUFFMEM 22 // Not enough low memory for IOCTL
|
||||
#define CDERR_DEVREQBASE 100 // DevReq errors
|
||||
|
||||
extern int cd_Error;
|
||||
|
||||
int I_CDMusInit(void);
|
||||
int I_CDMusPlay(int track);
|
||||
int I_CDMusStop(void);
|
||||
int I_CDMusResume(void);
|
||||
int I_CDMusSetVolume(int volume);
|
||||
int I_CDMusFirstTrack(void);
|
||||
int I_CDMusLastTrack(void);
|
||||
int I_CDMusTrackLength(int track);
|
||||
|
||||
#endif
|
277
Hexen Source/I_CYBER.C
Normal file
277
Hexen Source/I_CYBER.C
Normal file
|
@ -0,0 +1,277 @@
|
|||
// I_cyber.c
|
||||
|
||||
#include <dos.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "st_start.h" // For ST_Message()
|
||||
|
||||
|
||||
// Prototypes
|
||||
unsigned char *I_AllocLow (int length);
|
||||
|
||||
|
||||
/*
|
||||
====================================================
|
||||
|
||||
Doom control structure
|
||||
|
||||
The keybaord and joystick will add to the values set by the cyberman,
|
||||
to a maximum of 0x19000 for forwardmove and sidemove. Angleturn is
|
||||
not bounded at all.
|
||||
|
||||
parm normal fast
|
||||
----- ------ ----
|
||||
forwardmove 0xc800 0x19000
|
||||
sidemove 0xc000 0x14000
|
||||
angleturn 0x2800000 0x5000000
|
||||
|
||||
The keyboard and joystick have a 1/3 second slow turn of 0x1400000 under
|
||||
normal speed to help aiming.
|
||||
|
||||
|
||||
|
||||
====================================================
|
||||
*/
|
||||
/* old ticcmd_t
|
||||
typedef struct
|
||||
{
|
||||
char forwardmove; // *2048 for move
|
||||
char sidemove; // *2048 for move
|
||||
short angleturn; // <<16 for angle delta
|
||||
short consistancy; // checks for net game
|
||||
unsigned char chatchar;
|
||||
unsigned char buttons;
|
||||
} ticcmd_t;
|
||||
*/
|
||||
// ticcmd_t as it appears in h2def.h
|
||||
typedef struct
|
||||
{
|
||||
char forwardmove;
|
||||
char sidemove;
|
||||
short angleturn;
|
||||
short consistancy;
|
||||
unsigned char chatchar;
|
||||
unsigned char buttons;
|
||||
unsigned char lookfly;
|
||||
unsigned char arti;
|
||||
}ticcmd_t;
|
||||
|
||||
|
||||
#define BT_ATTACK 1
|
||||
#define BT_USE 2
|
||||
#define BT_CHANGE 4 // if true, the next 3 bits hold weapon num
|
||||
#define BT_WEAPONMASK (8+16+32)
|
||||
#define BT_WEAPONSHIFT 3
|
||||
|
||||
//==================================================
|
||||
//
|
||||
// CyberMan detection and usage info
|
||||
//
|
||||
//==================================================
|
||||
#define DPMI_INT 0x31
|
||||
#define MOUSE_INT 0x33
|
||||
|
||||
#define DOSMEMSIZE 64 // enough for any SWIFT structure
|
||||
|
||||
typedef struct {
|
||||
short x;
|
||||
short y;
|
||||
short z;
|
||||
short pitch;
|
||||
short roll;
|
||||
short yaw;
|
||||
short buttons;
|
||||
} SWIFT_3DStatus;
|
||||
|
||||
// DPMI real mode interrupt structure
|
||||
static struct rminfo {
|
||||
long EDI;
|
||||
long ESI;
|
||||
long EBP;
|
||||
long reserved_by_system;
|
||||
long EBX;
|
||||
long EDX;
|
||||
long ECX;
|
||||
long EAX;
|
||||
short flags;
|
||||
short ES,DS,FS,GS,IP,CS,SP,SS;
|
||||
} RMI;
|
||||
|
||||
typedef struct {
|
||||
unsigned char deviceType;
|
||||
unsigned char majorVersion;
|
||||
unsigned char minorVersion;
|
||||
unsigned char absRelFlags;
|
||||
unsigned char centeringFlags;
|
||||
unsigned char reserved[5];
|
||||
} StaticDeviceData;
|
||||
|
||||
// values for deviceType:
|
||||
#define DEVTYPE_CYBERMAN 1
|
||||
|
||||
short selector;
|
||||
unsigned short segment; // segment of DOS memory block
|
||||
SWIFT_3DStatus *cyberstat;
|
||||
int isCyberPresent; // is CyberMan present?
|
||||
|
||||
|
||||
static union REGS regs;
|
||||
static struct SREGS sregs;
|
||||
|
||||
|
||||
extern int mousepresent;
|
||||
|
||||
//===========================================================
|
||||
//
|
||||
// I_StartupCyberMan
|
||||
//
|
||||
// If a cyberman is present, init it and set isCyberPresent to 1
|
||||
//===========================================================
|
||||
void I_StartupCyberMan(void)
|
||||
{
|
||||
StaticDeviceData *pbuf;
|
||||
|
||||
ST_Message(" CyberMan: ");
|
||||
isCyberPresent = 0;
|
||||
|
||||
cyberstat = (SWIFT_3DStatus *)I_AllocLow (DOSMEMSIZE);
|
||||
segment = (int)cyberstat>>4;
|
||||
|
||||
pbuf = (StaticDeviceData *)cyberstat;
|
||||
memset(pbuf, 0, sizeof (StaticDeviceData));
|
||||
|
||||
|
||||
// Use DPMI call 300h to issue mouse interrupt
|
||||
memset(&RMI, 0, sizeof(RMI));
|
||||
RMI.EAX = 0x53C1; // SWIFT: Get Static Device Data
|
||||
RMI.ES = segment;
|
||||
RMI.EDX = 0;
|
||||
memset(&sregs, 0, sizeof (sregs));
|
||||
regs.w.ax = 0x0300; // DPMI: simulate interrupt
|
||||
regs.w.bx = MOUSE_INT;
|
||||
regs.w.cx = 0;
|
||||
regs.x.edi = FP_OFF(&RMI);
|
||||
sregs.es = FP_SEG(&RMI);
|
||||
int386x( DPMI_INT, ®s, ®s, &sregs );
|
||||
|
||||
if ((short)RMI.EAX != 1)
|
||||
{
|
||||
// SWIFT functions not present
|
||||
ST_Message("Wrong mouse driver - no SWIFT support (AX=%04x).\n",
|
||||
(unsigned)(short)RMI.EAX);
|
||||
}
|
||||
else if (pbuf->deviceType != DEVTYPE_CYBERMAN)
|
||||
{
|
||||
// no SWIFT device, or not CyberMan
|
||||
if (pbuf->deviceType == 0)
|
||||
{
|
||||
ST_Message("no SWIFT device connected.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
ST_Message("SWIFT device is not a CyberMan! (type=%d)\n",
|
||||
pbuf->deviceType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ST_Message("CyberMan %d.%02d connected.\n",
|
||||
pbuf->majorVersion, pbuf->minorVersion);
|
||||
isCyberPresent = 1;
|
||||
mousepresent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
=
|
||||
= I_ReadCyberCmds
|
||||
=
|
||||
===============
|
||||
*/
|
||||
|
||||
|
||||
int oldpos;
|
||||
|
||||
void I_ReadCyberCmd (ticcmd_t *cmd)
|
||||
{
|
||||
int delta;
|
||||
|
||||
// Use DPMI call 300h to issue mouse interrupt
|
||||
memset(&RMI, 0, sizeof(RMI));
|
||||
RMI.EAX = 0x5301; // SWIFT: Get Position and Buttons
|
||||
RMI.ES = segment;
|
||||
RMI.EDX = 0;
|
||||
memset(&sregs, 0, sizeof (sregs));
|
||||
regs.w.ax = 0x0300; // DPMI: simulate interrupt
|
||||
regs.w.bx = MOUSE_INT;
|
||||
regs.w.cx = 0;
|
||||
regs.x.edi = FP_OFF(&RMI);
|
||||
sregs.es = FP_SEG(&RMI);
|
||||
int386x( DPMI_INT, ®s, ®s, &sregs );
|
||||
|
||||
if (cyberstat->y < -7900)
|
||||
cmd->forwardmove = 0xc800/2048;
|
||||
else if (cyberstat->y > 7900)
|
||||
cmd->forwardmove = -0xc800/2048;
|
||||
|
||||
if (cyberstat->buttons & 4)
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
if (cyberstat->buttons & 2)
|
||||
cmd->buttons |= BT_USE;
|
||||
|
||||
delta = cyberstat->x - oldpos;
|
||||
oldpos = cyberstat->x;
|
||||
|
||||
if (cyberstat->buttons & 1)
|
||||
{ // strafe
|
||||
if (cyberstat->x < -7900)
|
||||
cmd->sidemove = -0xc800/2048;
|
||||
else if (cyberstat->x > 7900)
|
||||
cmd->sidemove = 0xc800/2048;
|
||||
else
|
||||
cmd->sidemove = delta*40/2048;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cyberstat->x < -7900)
|
||||
cmd->angleturn = 0x280;
|
||||
else if (cyberstat->x > 7900)
|
||||
cmd->angleturn = -0x280;
|
||||
else
|
||||
cmd->angleturn = -delta*0xa/16;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void I_Tactile (int on, int off, int total)
|
||||
{
|
||||
if (!isCyberPresent)
|
||||
return;
|
||||
|
||||
on /= 5;
|
||||
off /= 5;
|
||||
total /= 40;
|
||||
if (on > 255)
|
||||
on = 255;
|
||||
if (off > 255)
|
||||
off = 255;
|
||||
if (total > 255)
|
||||
total = 255;
|
||||
|
||||
memset(&RMI, 0, sizeof(RMI));
|
||||
RMI.EAX = 0x5330; // SWIFT: Get Position and Buttons
|
||||
RMI.EBX = on*256+off;
|
||||
RMI.ECX = total;
|
||||
memset(&sregs, 0, sizeof (sregs));
|
||||
regs.w.ax = 0x0300; // DPMI: simulate interrupt
|
||||
regs.w.bx = MOUSE_INT;
|
||||
regs.w.cx = 0;
|
||||
regs.x.edi = FP_OFF(&RMI);
|
||||
sregs.es = FP_SEG(&RMI);
|
||||
int386x( DPMI_INT, ®s, ®s, &sregs );
|
||||
}
|
77
Hexen Source/I_HEADER.H
Normal file
77
Hexen Source/I_HEADER.H
Normal file
|
@ -0,0 +1,77 @@
|
|||
#ifndef __I_HEADER_H__
|
||||
#define __I_HEADER_H__
|
||||
|
||||
#include "h2def.h"
|
||||
|
||||
//--------
|
||||
//SOUND IO
|
||||
//--------
|
||||
#define FREQ_LOW 0x40
|
||||
#define FREQ_NORM 0x80
|
||||
#define FREQ_HIGH 0xff
|
||||
|
||||
void I_SetMasterVolume(int volume);
|
||||
|
||||
void I_TurnOffSfx(void);
|
||||
void I_TurnOnSfx(void);
|
||||
void I_TurnOffMusic(void);
|
||||
void I_TurnOnMusic(void);
|
||||
|
||||
// MUSIC I/O
|
||||
//
|
||||
|
||||
int I_RegisterSong(void *songdata);
|
||||
// called by anything that wants to register a song lump with the sound lib
|
||||
// calls Paul's function of the similar name to register music only.
|
||||
// note that the song data is the same for any sound card and is paul's
|
||||
// MUS format. Returns a handle which will be passed to all other music
|
||||
// functions.
|
||||
|
||||
void I_UnregisterSong(int handle);
|
||||
// called by anything which is finished with a song and no longer needs
|
||||
// the sound library to be aware of it. All songs should be stopped
|
||||
// before calling this, but it will double check and stop it if necessary.
|
||||
|
||||
void I_LoopSong(int handle);
|
||||
// called by anything that wishes to start music.
|
||||
// plays a song, and when the song is done, starts playing it again in
|
||||
// an endless loop. the start is faded in over three seconds.
|
||||
|
||||
void I_FadeOutSong(int handle, int fotime);
|
||||
// called by anything that wishes to stop music.
|
||||
// fades out the song over <fotime> milliseconds.
|
||||
|
||||
void I_StopSong(int handle);
|
||||
// called by anything that wishes to stop music.
|
||||
// stops a song abruptly.
|
||||
|
||||
// SFX I/O
|
||||
//
|
||||
|
||||
void *I_GetSoundEffect (char *soundname);
|
||||
// called by routines which wish to play a sound effect at some later
|
||||
// time. Pass it the lump name of a sound effect WITHOUT the sfx
|
||||
// prefix. This means the maximum name length is 7 letters/digits.
|
||||
// The prefixes for different sound cards are 'S','M','A', and 'P'.
|
||||
// They refer to the card type. The routine will cache in the
|
||||
// appropriate sound effect when it is played.
|
||||
|
||||
void I_UngetSoundEffect (void *soundset);
|
||||
// called by routines which wish to no longer use the sounds at all
|
||||
// frees up the associated structure. It stops any currently playing
|
||||
// sound effects.
|
||||
|
||||
void I_StartSound (channel_t *c, int vol, int sep, int pitch, int priority);
|
||||
// Starts a sound in a particular sound channel
|
||||
|
||||
void I_UpdateSoundParams(channel_t *c, int vol, int sep, int pitch);
|
||||
// Updates the volume, separation, and pitch of a sound channel
|
||||
|
||||
void I_StopSound(channel_t *c);
|
||||
// Stops a sound channel
|
||||
|
||||
int I_SoundIsPlaying(channel_t *c);
|
||||
// called by S_*()'s to see if a channel is still playing. Returns 0
|
||||
// if no longer playing, 1 if playing.
|
||||
|
||||
#endif
|
2782
Hexen Source/I_IBM.C
Normal file
2782
Hexen Source/I_IBM.C
Normal file
File diff suppressed because it is too large
Load diff
135
Hexen Source/I_IBM_A.ASM
Normal file
135
Hexen Source/I_IBM_A.ASM
Normal file
|
@ -0,0 +1,135 @@
|
|||
.386
|
||||
.MODEL small
|
||||
|
||||
.DATA
|
||||
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
IF 0
|
||||
#define PEL_WRITE_ADR 0x3c8
|
||||
#define PEL_READ_ADR 0x3c7
|
||||
#define PEL_DATA 0x3c9
|
||||
ENDIF
|
||||
|
||||
;================
|
||||
;
|
||||
; I_DivException
|
||||
;
|
||||
;================
|
||||
|
||||
PROC I_DivException_
|
||||
PUBLIC I_DivException_
|
||||
mov edx,03c9h
|
||||
mov al,63
|
||||
out dx,al
|
||||
|
||||
mov ebx,0ffffffh
|
||||
mov eax,[ebx]
|
||||
retf
|
||||
ENDP
|
||||
|
||||
;================
|
||||
;
|
||||
; I_SetDivException
|
||||
;
|
||||
;================
|
||||
|
||||
PROC I_SetDivException_
|
||||
PUBLIC I_SetDivException_
|
||||
pusha
|
||||
|
||||
mov eax,0212h
|
||||
mov ebx,0
|
||||
mov ecx,cs
|
||||
mov edx,OFFSET I_DivException_
|
||||
int 31h
|
||||
jnc good
|
||||
|
||||
popa
|
||||
mov eax,0
|
||||
ret
|
||||
|
||||
good:
|
||||
popa
|
||||
mov eax,1
|
||||
ret
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
;================
|
||||
;
|
||||
; I_ReadJoystick
|
||||
;
|
||||
; Read the absolute joystick values
|
||||
; returns false if not connected
|
||||
;================
|
||||
|
||||
.data
|
||||
|
||||
_joystickx dd 0
|
||||
_joysticky dd 0
|
||||
PUBLIC _joystickx, _joysticky
|
||||
|
||||
.code
|
||||
|
||||
PROC I_ReadJoystick_
|
||||
PUBLIC I_ReadJoystick_
|
||||
pushad
|
||||
pushf ; state of interrupt flag
|
||||
cli
|
||||
|
||||
mov dx,0201h
|
||||
in al,dx
|
||||
out dx,al ; Clear the resistors
|
||||
|
||||
mov ah,1 ; Get masks into registers
|
||||
mov ch,2
|
||||
|
||||
xor esi,esi ; Clear count registers
|
||||
xor edi,edi
|
||||
xor ebx,ebx ; Clear high byte of bx for later
|
||||
|
||||
mov ebp,10000 ; joystick is disconnected if value is this big
|
||||
|
||||
jloop:
|
||||
in al,dx ; Get bits indicating whether all are finished
|
||||
|
||||
dec ebp ; Check bounding register
|
||||
jz bad ; We have a silly value - abort
|
||||
|
||||
mov bl,al ; Duplicate the bits
|
||||
and bl,ah ; Mask off useless bits (in [xb])
|
||||
add esi,ebx ; Possibly increment count register
|
||||
mov cl,bl ; Save for testing later
|
||||
|
||||
mov bl,al
|
||||
and bl,ch ; [yb]
|
||||
add edi,ebx
|
||||
|
||||
add cl,bl
|
||||
jnz jloop ; If both bits were 0, drop out
|
||||
|
||||
done:
|
||||
mov [_joystickx],esi
|
||||
shr edi,1 ; because 2s were added
|
||||
mov [_joysticky],edi
|
||||
|
||||
popf ; restore interrupt flag
|
||||
popad
|
||||
mov eax,1 ; read was ok
|
||||
ret
|
||||
|
||||
bad:
|
||||
popf ; restore interrupt flag
|
||||
popad
|
||||
xor eax, eax ; read was bad
|
||||
ret
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
END
|
||||
|
369
Hexen Source/I_SOUND.C
Normal file
369
Hexen Source/I_SOUND.C
Normal file
|
@ -0,0 +1,369 @@
|
|||
|
||||
// I_SOUND.C
|
||||
|
||||
#include <stdio.h>
|
||||
#include "h2def.h"
|
||||
#include "dmx.h"
|
||||
#include "sounds.h"
|
||||
#include "i_sound.h"
|
||||
|
||||
/*
|
||||
===============
|
||||
=
|
||||
= I_StartupTimer
|
||||
=
|
||||
===============
|
||||
*/
|
||||
|
||||
int tsm_ID = -1;
|
||||
|
||||
void I_StartupTimer (void)
|
||||
{
|
||||
#ifndef NOTIMER
|
||||
extern int I_TimerISR(void);
|
||||
|
||||
ST_Message(" I_StartupTimer()\n");
|
||||
// installs master timer. Must be done before StartupTimer()!
|
||||
TSM_Install(SND_TICRATE);
|
||||
tsm_ID = TSM_NewService (I_TimerISR, 35, 255, 0); // max priority
|
||||
if (tsm_ID == -1)
|
||||
{
|
||||
I_Error("Can't register 35 Hz timer w/ DMX library");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void I_ShutdownTimer (void)
|
||||
{
|
||||
TSM_DelService(tsm_ID);
|
||||
TSM_Remove();
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* SOUND HEADER & DATA
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
// sound information
|
||||
#if 0
|
||||
const char *dnames[] = {"None",
|
||||
"PC_Speaker",
|
||||
"Adlib",
|
||||
"Sound_Blaster",
|
||||
"ProAudio_Spectrum16",
|
||||
"Gravis_Ultrasound",
|
||||
"MPU",
|
||||
"AWE32"
|
||||
};
|
||||
#endif
|
||||
|
||||
const char snd_prefixen[] = { 'P', 'P', 'A', 'S', 'S', 'S', 'M',
|
||||
'M', 'M', 'S' };
|
||||
|
||||
int snd_Channels;
|
||||
int snd_DesiredMusicDevice, snd_DesiredSfxDevice;
|
||||
int snd_MusicDevice, // current music card # (index to dmxCodes)
|
||||
snd_SfxDevice, // current sfx card # (index to dmxCodes)
|
||||
snd_MaxVolume, // maximum volume for sound
|
||||
snd_MusicVolume; // maximum volume for music
|
||||
int dmxCodes[NUM_SCARDS]; // the dmx code for a given card
|
||||
|
||||
int snd_SBport, snd_SBirq, snd_SBdma; // sound blaster variables
|
||||
int snd_Mport; // midi variables
|
||||
|
||||
extern boolean snd_MusicAvail, // whether music is available
|
||||
snd_SfxAvail; // whether sfx are available
|
||||
|
||||
void I_PauseSong(int handle)
|
||||
{
|
||||
MUS_PauseSong(handle);
|
||||
}
|
||||
|
||||
void I_ResumeSong(int handle)
|
||||
{
|
||||
MUS_ResumeSong(handle);
|
||||
}
|
||||
|
||||
void I_SetMusicVolume(int volume)
|
||||
{
|
||||
MUS_SetMasterVolume(volume*8);
|
||||
// snd_MusicVolume = volume;
|
||||
}
|
||||
|
||||
void I_SetSfxVolume(int volume)
|
||||
{
|
||||
snd_MaxVolume = volume; // THROW AWAY?
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* SONG API
|
||||
*
|
||||
*/
|
||||
|
||||
int I_RegisterSong(void *data)
|
||||
{
|
||||
int rc = MUS_RegisterSong(data);
|
||||
#ifdef SNDDEBUG
|
||||
if (rc<0) ST_Message(" MUS_Reg() returned %d\n", rc);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
void I_UnRegisterSong(int handle)
|
||||
{
|
||||
int rc = MUS_UnregisterSong(handle);
|
||||
#ifdef SNDDEBUG
|
||||
if (rc < 0) ST_Message(" MUS_Unreg() returned %d\n", rc);
|
||||
#endif
|
||||
}
|
||||
|
||||
int I_QrySongPlaying(int handle)
|
||||
{
|
||||
int rc = MUS_QrySongPlaying(handle);
|
||||
#ifdef SNDDEBUG
|
||||
if (rc < 0) ST_Message(" MUS_QrySP() returned %d\n", rc);
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Stops a song. MUST be called before I_UnregisterSong().
|
||||
|
||||
void I_StopSong(int handle)
|
||||
{
|
||||
int rc;
|
||||
rc = MUS_StopSong(handle);
|
||||
#ifdef SNDDEBUG
|
||||
if (rc < 0) ST_Message(" MUS_StopSong() returned %d\n", rc);
|
||||
#endif
|
||||
/*
|
||||
// Fucking kluge pause
|
||||
{
|
||||
int s;
|
||||
extern volatile int ticcount;
|
||||
for (s=ticcount ; ticcount - s < 10 ; );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void I_PlaySong(int handle, boolean looping)
|
||||
{
|
||||
int rc;
|
||||
rc = MUS_ChainSong(handle, looping ? handle : -1);
|
||||
#ifdef SNDDEBUG
|
||||
if (rc < 0) ST_Message(" MUS_ChainSong() returned %d\n", rc);
|
||||
#endif
|
||||
rc = MUS_PlaySong(handle, snd_MusicVolume);
|
||||
#ifdef SNDDEBUG
|
||||
if (rc < 0) ST_Message(" MUS_PlaySong() returned %d\n", rc);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* SOUND FX API
|
||||
*
|
||||
*/
|
||||
|
||||
// Gets lump nums of the named sound. Returns pointer which will be
|
||||
// passed to I_StartSound() when you want to start an SFX. Must be
|
||||
// sure to pass this to UngetSoundEffect() so that they can be
|
||||
// freed!
|
||||
|
||||
|
||||
int I_GetSfxLumpNum(sfxinfo_t *sound)
|
||||
{
|
||||
return W_GetNumForName(sound->lumpname);
|
||||
|
||||
}
|
||||
|
||||
int I_StartSound (int id, void *data, int vol, int sep, int pitch, int priority)
|
||||
{
|
||||
return SFX_PlayPatch(data, pitch, sep, vol, 0, 0);
|
||||
}
|
||||
|
||||
void I_StopSound(int handle)
|
||||
{
|
||||
// extern volatile long gDmaCount;
|
||||
// long waittocount;
|
||||
SFX_StopPatch(handle);
|
||||
// waittocount = gDmaCount + 2;
|
||||
// while (gDmaCount < waittocount) ;
|
||||
}
|
||||
|
||||
int I_SoundIsPlaying(int handle)
|
||||
{
|
||||
return SFX_Playing(handle);
|
||||
}
|
||||
|
||||
void I_UpdateSoundParams(int handle, int vol, int sep, int pitch)
|
||||
{
|
||||
SFX_SetOrigin(handle, pitch, sep, vol);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* SOUND STARTUP STUFF
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
//
|
||||
// Why PC's Suck, Reason #8712
|
||||
//
|
||||
|
||||
void I_sndArbitrateCards(void)
|
||||
{
|
||||
char tmp[160];
|
||||
boolean gus, adlib, pc, sb, midi;
|
||||
int i, rc, mputype, p, opltype, wait, dmxlump;
|
||||
|
||||
snd_MusicDevice = snd_DesiredMusicDevice;
|
||||
snd_SfxDevice = snd_DesiredSfxDevice;
|
||||
|
||||
// check command-line parameters- overrides config file
|
||||
//
|
||||
if (M_CheckParm("-nosound")) snd_MusicDevice = snd_SfxDevice = snd_none;
|
||||
if (M_CheckParm("-nosfx")) snd_SfxDevice = snd_none;
|
||||
if (M_CheckParm("-nomusic")) snd_MusicDevice = snd_none;
|
||||
|
||||
if (snd_MusicDevice > snd_MPU && snd_MusicDevice <= snd_MPU3)
|
||||
snd_MusicDevice = snd_MPU;
|
||||
if (snd_MusicDevice == snd_SB)
|
||||
snd_MusicDevice = snd_Adlib;
|
||||
if (snd_MusicDevice == snd_PAS)
|
||||
snd_MusicDevice = snd_Adlib;
|
||||
|
||||
// figure out what i've got to initialize
|
||||
//
|
||||
gus = snd_MusicDevice == snd_GUS || snd_SfxDevice == snd_GUS;
|
||||
sb = snd_SfxDevice == snd_SB || snd_MusicDevice == snd_SB;
|
||||
adlib = snd_MusicDevice == snd_Adlib ;
|
||||
pc = snd_SfxDevice == snd_PC;
|
||||
midi = snd_MusicDevice == snd_MPU;
|
||||
|
||||
// initialize whatever i've got
|
||||
//
|
||||
if (gus)
|
||||
{
|
||||
if (GF1_Detect()) ST_Message(" Dude. The GUS ain't responding.\n");
|
||||
else
|
||||
{
|
||||
dmxlump = W_GetNumForName("dmxgus");
|
||||
GF1_SetMap(W_CacheLumpNum(dmxlump, PU_CACHE), lumpinfo[dmxlump].size);
|
||||
}
|
||||
|
||||
}
|
||||
if (sb)
|
||||
{
|
||||
if(debugmode)
|
||||
{
|
||||
ST_Message(" Sound cfg p=0x%x, i=%d, d=%d\n",
|
||||
snd_SBport, snd_SBirq, snd_SBdma);
|
||||
}
|
||||
if (SB_Detect(&snd_SBport, &snd_SBirq, &snd_SBdma, 0))
|
||||
{
|
||||
ST_Message(" SB isn't responding at p=0x%x, i=%d, d=%d\n",
|
||||
snd_SBport, snd_SBirq, snd_SBdma);
|
||||
}
|
||||
else SB_SetCard(snd_SBport, snd_SBirq, snd_SBdma);
|
||||
|
||||
if(debugmode)
|
||||
{
|
||||
ST_Message(" SB_Detect returned p=0x%x, i=%d, d=%d\n",
|
||||
snd_SBport, snd_SBirq, snd_SBdma);
|
||||
}
|
||||
}
|
||||
|
||||
if (adlib)
|
||||
{
|
||||
if (AL_Detect(&wait,0))
|
||||
{
|
||||
ST_Message(" Dude. The Adlib isn't responding.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
AL_SetCard(wait, W_CacheLumpName("genmidi", PU_STATIC));
|
||||
}
|
||||
}
|
||||
|
||||
if (midi)
|
||||
{
|
||||
if (debugmode)
|
||||
{
|
||||
ST_Message(" cfg p=0x%x\n", snd_Mport);
|
||||
}
|
||||
|
||||
if (MPU_Detect(&snd_Mport, &i))
|
||||
{
|
||||
ST_Message(" The MPU-401 isn't reponding @ p=0x%x.\n", snd_Mport);
|
||||
}
|
||||
else MPU_SetCard(snd_Mport);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// inits all sound stuff
|
||||
|
||||
void I_StartupSound (void)
|
||||
{
|
||||
int rc, i;
|
||||
|
||||
if (debugmode)
|
||||
ST_Message("I_StartupSound: Hope you hear a pop.\n");
|
||||
|
||||
// initialize dmxCodes[]
|
||||
dmxCodes[0] = 0;
|
||||
dmxCodes[snd_PC] = AHW_PC_SPEAKER;
|
||||
dmxCodes[snd_Adlib] = AHW_ADLIB;
|
||||
dmxCodes[snd_SB] = AHW_SOUND_BLASTER;
|
||||
dmxCodes[snd_PAS] = AHW_MEDIA_VISION;
|
||||
dmxCodes[snd_GUS] = AHW_ULTRA_SOUND;
|
||||
dmxCodes[snd_MPU] = AHW_MPU_401;
|
||||
dmxCodes[snd_MPU2] = AHW_MPU_401;
|
||||
dmxCodes[snd_MPU3] = AHW_MPU_401;
|
||||
dmxCodes[snd_AWE] = AHW_AWE32;
|
||||
dmxCodes[snd_CDMUSIC] = 0;
|
||||
|
||||
// inits sound library timer stuff
|
||||
I_StartupTimer();
|
||||
|
||||
// pick the sound cards i'm going to use
|
||||
//
|
||||
I_sndArbitrateCards();
|
||||
|
||||
if (debugmode)
|
||||
{
|
||||
ST_Message(" Music device #%d & dmxCode=%d,", snd_MusicDevice,
|
||||
dmxCodes[snd_MusicDevice]);
|
||||
ST_Message(" Sfx device #%d & dmxCode=%d\n", snd_SfxDevice,
|
||||
dmxCodes[snd_SfxDevice]);
|
||||
}
|
||||
|
||||
// inits DMX sound library
|
||||
ST_Message(" Calling DMX_Init...");
|
||||
rc = DMX_Init(SND_TICRATE, SND_MAXSONGS, dmxCodes[snd_MusicDevice],
|
||||
dmxCodes[snd_SfxDevice]);
|
||||
|
||||
if (debugmode)
|
||||
{
|
||||
ST_Message(" DMX_Init() returned %d\n", rc);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// shuts down all sound stuff
|
||||
|
||||
void I_ShutdownSound (void)
|
||||
{
|
||||
DMX_DeInit();
|
||||
I_ShutdownTimer();
|
||||
}
|
||||
|
||||
void I_SetChannels(int channels)
|
||||
{
|
||||
WAV_PlayMode(channels, SND_SAMPLERATE);
|
||||
}
|
68
Hexen Source/I_SOUND.H
Normal file
68
Hexen Source/I_SOUND.H
Normal file
|
@ -0,0 +1,68 @@
|
|||
#ifndef __SOUND__
|
||||
#define __SOUND__
|
||||
|
||||
#define SND_TICRATE 140 // tic rate for updating sound
|
||||
#define SND_MAXSONGS 40 // max number of songs in game
|
||||
#define SND_SAMPLERATE 11025 // sample rate of sound effects
|
||||
|
||||
typedef enum
|
||||
{
|
||||
snd_none,
|
||||
snd_PC,
|
||||
snd_Adlib,
|
||||
snd_SB,
|
||||
snd_PAS,
|
||||
snd_GUS,
|
||||
snd_MPU,
|
||||
snd_MPU2,
|
||||
snd_MPU3,
|
||||
snd_AWE,
|
||||
snd_CDMUSIC,
|
||||
NUM_SCARDS
|
||||
} cardenum_t;
|
||||
|
||||
void I_PauseSong(int handle);
|
||||
void I_ResumeSong(int handle);
|
||||
void I_SetMusicVolume(int volume);
|
||||
void I_SetSfxVolume(int volume);
|
||||
int I_RegisterSong(void *data);
|
||||
void I_UnRegisterSong(int handle);
|
||||
int I_QrySongPlaying(int handle);
|
||||
void I_StopSong(int handle);
|
||||
void I_PlaySong(int handle, int looping);
|
||||
int I_GetSfxLumpNum(sfxinfo_t *sound);
|
||||
int I_StartSound (int id, void *data, int vol, int sep, int pitch, int priority);
|
||||
void I_StopSound(int handle);
|
||||
int I_SoundIsPlaying(int handle);
|
||||
void I_UpdateSoundParams(int handle, int vol, int sep, int pitch);
|
||||
void I_sndArbitrateCards(void);
|
||||
void I_StartupSound (void);
|
||||
void I_ShutdownSound (void);
|
||||
void I_SetChannels(int channels);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ICDMUS__
|
||||
#define __ICDMUS__
|
||||
|
||||
#define CDERR_NOTINSTALLED 10 // MSCDEX not installed
|
||||
#define CDERR_NOAUDIOSUPPORT 11 // CD-ROM Doesn't support audio
|
||||
#define CDERR_NOAUDIOTRACKS 12 // Current CD has no audio tracks
|
||||
#define CDERR_BADDRIVE 20 // Bad drive number
|
||||
#define CDERR_BADTRACK 21 // Bad track number
|
||||
#define CDERR_IOCTLBUFFMEM 22 // Not enough low memory for IOCTL
|
||||
#define CDERR_DEVREQBASE 100 // DevReq errors
|
||||
|
||||
extern int cd_Error;
|
||||
|
||||
int I_CDMusInit(void);
|
||||
int I_CDMusPlay(int track);
|
||||
int I_CDMusStop(void);
|
||||
int I_CDMusResume(void);
|
||||
int I_CDMusSetVolume(int volume);
|
||||
int I_CDMusFirstTrack(void);
|
||||
int I_CDMusLastTrack(void);
|
||||
int I_CDMusTrackLength(int track);
|
||||
|
||||
#endif
|
||||
|
349
Hexen Source/LINEAR.ASM
Normal file
349
Hexen Source/LINEAR.ASM
Normal file
|
@ -0,0 +1,349 @@
|
|||
.386
|
||||
.MODEL small
|
||||
INCLUDE defs.inc
|
||||
|
||||
|
||||
;============================================================================
|
||||
;
|
||||
; unwound vertical scaling code
|
||||
;
|
||||
; eax light table pointer, 0 lowbyte overwritten
|
||||
; ebx all 0, low byte overwritten
|
||||
; ecx fractional step value
|
||||
; edx fractional scale value
|
||||
; esi start of source pixels
|
||||
; edi bottom pixel in screenbuffer to blit into
|
||||
;
|
||||
; ebx should be set to 0 0 0 dh to feed the pipeline
|
||||
;
|
||||
; The graphics wrap vertically at 128 pixels
|
||||
;============================================================================
|
||||
|
||||
.DATA
|
||||
|
||||
EXTRN _centery:DWORD
|
||||
|
||||
SCALEDEFINE MACRO number
|
||||
dd vscale&number
|
||||
ENDM
|
||||
|
||||
ALIGN 4
|
||||
scalecalls LABEL
|
||||
LINE = 0
|
||||
REPT SCREENHEIGHT+1
|
||||
SCALEDEFINE %LINE
|
||||
LINE = LINE+1
|
||||
ENDM
|
||||
|
||||
FUZZSCALEDEFINE MACRO number
|
||||
dd fuzzvscale&number
|
||||
ENDM
|
||||
|
||||
ALIGN 4
|
||||
fuzzscalecalls LABEL
|
||||
LINE = 0
|
||||
REPT SCREENHEIGHT+1
|
||||
FUZZSCALEDEFINE %LINE
|
||||
LINE = LINE+1
|
||||
ENDM
|
||||
|
||||
calladdr dd ?
|
||||
|
||||
;=================================
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
;================
|
||||
;
|
||||
; R_DrawColumn
|
||||
;
|
||||
;================
|
||||
|
||||
PROC R_DrawColumn_
|
||||
PUBLIC R_DrawColumn_
|
||||
PUSHR
|
||||
|
||||
mov ebp,[_dc_yh]
|
||||
mov ebx,ebp
|
||||
mov edi,[_ylookup+ebx*4]
|
||||
mov ebx,[_dc_x]
|
||||
add edi,[_columnofs + ebx*4]
|
||||
|
||||
mov eax,[_dc_yl]
|
||||
sub ebp,eax ; ebp = pixel count
|
||||
or ebp,ebp
|
||||
js done
|
||||
|
||||
mov ecx,[_dc_iscale]
|
||||
|
||||
sub eax,[_centery]
|
||||
imul ecx
|
||||
mov edx,[_dc_texturemid]
|
||||
add edx,eax
|
||||
shl edx,9 ; 7 significant bits, 25 frac
|
||||
|
||||
shl ecx,9 ; 7 significant bits, 25 frac
|
||||
mov esi,[_dc_source]
|
||||
|
||||
mov eax,[_dc_colormap]
|
||||
|
||||
xor ebx,ebx
|
||||
shld ebx,edx,7 ; get address of first location
|
||||
call [scalecalls+4+ebp*4]
|
||||
|
||||
done:
|
||||
POPR
|
||||
ret
|
||||
|
||||
;============ HIGH DETAIL ============
|
||||
|
||||
SCALELABEL MACRO number
|
||||
vscale&number:
|
||||
ENDM
|
||||
|
||||
LINE = SCREENHEIGHT
|
||||
REPT SCREENHEIGHT-1
|
||||
SCALELABEL %LINE
|
||||
mov al,[esi+ebx] ; get source pixel
|
||||
add edx,ecx ; calculate next location
|
||||
mov al,[eax] ; translate the color
|
||||
; xor ebx,ebx
|
||||
; shld ebx,edx,7 ; get address of next location
|
||||
mov ebx,edx
|
||||
shr ebx,25
|
||||
mov [edi-(LINE-1)*SCREENWIDTH],al ; draw a pixel to the buffer
|
||||
LINE = LINE-1
|
||||
ENDM
|
||||
vscale1:
|
||||
mov al,[esi+ebx]
|
||||
mov al,[eax]
|
||||
mov [edi],al
|
||||
vscale0:
|
||||
ret
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
;================
|
||||
;
|
||||
; R_DrawFuzz
|
||||
;
|
||||
;================
|
||||
|
||||
PROC R_DrawFuzzColumn_
|
||||
PUBLIC R_DrawFuzzColumn_
|
||||
PUSHR
|
||||
|
||||
mov ebp,[_dc_yh]
|
||||
mov ebx,ebp
|
||||
mov edi,[_ylookup+ebx*4]
|
||||
mov ebx,[_dc_x]
|
||||
add edi,[_columnofs + ebx*4]
|
||||
|
||||
mov eax,[_dc_yl]
|
||||
sub ebp,eax ; ebp = pixel count
|
||||
or ebp,ebp
|
||||
js fuzzdone
|
||||
|
||||
mov ecx,[_dc_iscale]
|
||||
|
||||
sub eax,[_centery]
|
||||
imul ecx
|
||||
mov edx,[_dc_texturemid]
|
||||
add edx,eax
|
||||
shl edx,9 ; 7 significant bits, 25 frac
|
||||
|
||||
shl ecx,9 ; 7 significant bits, 25 frac
|
||||
mov esi,[_dc_source]
|
||||
mov eax,[_dc_colormap]
|
||||
xor ebx,ebx
|
||||
shld ebx,edx,7 ;get address of first location
|
||||
|
||||
mov ebp, [fuzzscalecalls+4+ebp*4]
|
||||
mov calladdr, ebp
|
||||
mov ebp, ecx
|
||||
xor ecx, ecx
|
||||
|
||||
call [calladdr]
|
||||
|
||||
fuzzdone:
|
||||
POPR
|
||||
ret
|
||||
|
||||
|
||||
FUZZSCALELABEL MACRO number
|
||||
fuzzvscale&number:
|
||||
ENDM
|
||||
|
||||
LINE = SCREENHEIGHT
|
||||
REPT SCREENHEIGHT-1
|
||||
FUZZSCALELABEL %LINE
|
||||
mov al, byte ptr [esi+ebx] ; get source pixel
|
||||
add edx, ebp ; calculate next location
|
||||
|
||||
mov cl, byte ptr [edi-(LINE-1)*SCREENWIDTH]
|
||||
mov ch, [eax]
|
||||
add ecx, [_tinttable]
|
||||
mov ebx, edx
|
||||
shr ebx, 25
|
||||
mov al, [ecx]
|
||||
mov [edi-(LINE-1)*SCREENWIDTH],al ; draw a pixel to the buffer
|
||||
xor ecx, ecx
|
||||
LINE = LINE-1
|
||||
ENDM
|
||||
fuzzvscale1:
|
||||
mov al,[esi+ebx]
|
||||
mov cl, byte ptr [edi-(LINE-1)*SCREENWIDTH]
|
||||
mov ch, [eax]
|
||||
add ecx, [_tinttable]
|
||||
mov al, [ecx]
|
||||
mov [edi],al
|
||||
fuzzvscale0:
|
||||
ret
|
||||
|
||||
ENDP
|
||||
|
||||
;============================================================================
|
||||
;
|
||||
; unwound horizontal texture mapping code
|
||||
;
|
||||
; eax lighttable
|
||||
; ebx scratch register
|
||||
; ecx position 6.10 bits x, 6.10 bits y
|
||||
; edx step 6.10 bits x, 6.10 bits y
|
||||
; esi start of block
|
||||
; edi dest
|
||||
; ebp fff to mask bx
|
||||
;
|
||||
; ebp should by preset from ebx / ecx before calling
|
||||
;============================================================================
|
||||
|
||||
OP_SHLD = 0fh
|
||||
|
||||
|
||||
.DATA
|
||||
|
||||
|
||||
MAPDEFINE MACRO number
|
||||
dd hmap&number
|
||||
ENDM
|
||||
|
||||
ALIGN 4
|
||||
mapcalls LABEL
|
||||
LINE = 0
|
||||
REPT SCREENWIDTH+1
|
||||
MAPDEFINE %LINE
|
||||
LINE = LINE+1
|
||||
ENDM
|
||||
|
||||
|
||||
callpoint dd 0
|
||||
returnpoint dd 0
|
||||
|
||||
|
||||
.CODE
|
||||
|
||||
;================
|
||||
;
|
||||
; R_DrawSpan
|
||||
;
|
||||
; Horizontal texture mapping
|
||||
;
|
||||
;================
|
||||
|
||||
|
||||
PROC R_DrawSpan_
|
||||
PUBLIC R_DrawSpan_
|
||||
PUSHR
|
||||
|
||||
IFE SKIPPRIMITIVES
|
||||
|
||||
mov eax,[_ds_x1]
|
||||
mov ebx,[_ds_x2]
|
||||
mov eax,[mapcalls+eax*4]
|
||||
mov [callpoint],eax ; spot to jump into unwound
|
||||
mov eax,[mapcalls+4+ebx*4]
|
||||
mov [returnpoint],eax ; spot to patch a ret at
|
||||
mov BYTE PTR [eax], OP_RET
|
||||
|
||||
;
|
||||
; build composite position
|
||||
;
|
||||
mov ecx,[_ds_xfrac]
|
||||
shl ecx,10
|
||||
and ecx,0ffff0000h
|
||||
mov eax,[_ds_yfrac]
|
||||
shr eax,6
|
||||
and eax,0ffffh
|
||||
or ecx,eax
|
||||
|
||||
;
|
||||
; build composite step
|
||||
;
|
||||
mov edx,[_ds_xstep]
|
||||
shl edx,10
|
||||
and edx,0ffff0000h
|
||||
mov eax,[_ds_ystep]
|
||||
shr eax,6
|
||||
and eax,0ffffh
|
||||
or edx,eax
|
||||
|
||||
mov esi,[_ds_source]
|
||||
|
||||
mov edi,[_ds_y]
|
||||
mov edi,[_ylookup+edi*4]
|
||||
add edi,[_columnofs]
|
||||
|
||||
mov eax,[_ds_colormap]
|
||||
|
||||
;
|
||||
; feed the pipeline and jump in
|
||||
;
|
||||
mov ebp,0fffh ; used to mask off slop high bits from position
|
||||
shld ebx,ecx,22 ; shift y units in
|
||||
shld ebx,ecx,6 ; shift x units in
|
||||
and ebx,ebp ; mask off slop bits
|
||||
call [callpoint]
|
||||
|
||||
mov ebx,[returnpoint]
|
||||
mov BYTE PTR [ebx],OP_MOVAL ; remove the ret patched in
|
||||
|
||||
ENDIF
|
||||
POPR
|
||||
ret
|
||||
|
||||
|
||||
;============= HIGH DETAIL ============
|
||||
|
||||
.CODE
|
||||
|
||||
MAPLABEL MACRO number
|
||||
hmap&number:
|
||||
ENDM
|
||||
|
||||
LINE = 0
|
||||
PCOL = 0
|
||||
REPT SCREENWIDTH/4
|
||||
PLANE = 0
|
||||
REPT 4
|
||||
MAPLABEL %LINE
|
||||
LINE = LINE + 1
|
||||
|
||||
mov al,[esi+ebx] ; get source pixel
|
||||
shld ebx,ecx,22 ; shift y units in
|
||||
shld ebx,ecx,6 ; shift x units in
|
||||
mov al,[eax] ; translate color
|
||||
and ebx,ebp ; mask off slop bits
|
||||
add ecx,edx ; position += step
|
||||
mov [edi+PLANE+PCOL*4],al ; write pixel
|
||||
PLANE = PLANE + 1
|
||||
ENDM
|
||||
PCOL = PCOL + 1
|
||||
ENDM
|
||||
hmap320:
|
||||
ret
|
||||
|
||||
ENDP
|
||||
|
||||
END
|
50
Hexen Source/M.BAT
Normal file
50
Hexen Source/M.BAT
Normal file
|
@ -0,0 +1,50 @@
|
|||
@REM Hexen make batch
|
||||
@echo off
|
||||
|
||||
if "%1"=="/?" goto usage
|
||||
if "%1"=="f" goto final
|
||||
if "%1"=="F" goto final
|
||||
if "%1"=="d" goto debug
|
||||
if "%1"=="D" goto debug
|
||||
goto normal
|
||||
|
||||
:usage
|
||||
echo.
|
||||
echo Hexen make batch
|
||||
echo Usage: M [/?] [build-type]
|
||||
echo.
|
||||
echo build-type f = Final build (no RANGECHECK)
|
||||
echo build-type d = Debug build (include debugging info)
|
||||
echo.
|
||||
goto end
|
||||
|
||||
:final
|
||||
echo.
|
||||
echo.
|
||||
echo *** Building Hexen FINAL executable
|
||||
echo.
|
||||
echo.
|
||||
shift
|
||||
wmake hex.exe EXTERNOPT=/dNORANGECHECKING %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||||
goto end
|
||||
|
||||
:debug
|
||||
echo.
|
||||
echo.
|
||||
echo *** Building Hexen DEBUG executable
|
||||
echo.
|
||||
echo.
|
||||
shift
|
||||
wmake hex.exe EXTERNOPT=/d2 %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||||
goto end
|
||||
|
||||
:normal
|
||||
echo.
|
||||
echo.
|
||||
echo *** Building Hexen DEVELOPMENT executable
|
||||
echo.
|
||||
echo.
|
||||
wmake hex.exe %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||||
goto end
|
||||
|
||||
:end
|
1
Hexen Source/MAKE.BAT
Normal file
1
Hexen Source/MAKE.BAT
Normal file
|
@ -0,0 +1 @@
|
|||
wmake
|
120
Hexen Source/MAKEFILE
Normal file
120
Hexen Source/MAKEFILE
Normal file
|
@ -0,0 +1,120 @@
|
|||
|
||||
# --------------------------------------------------------------------------
|
||||
#
|
||||
# WCC386 Options:
|
||||
#
|
||||
# 4r use 80486 timings and register argument passing
|
||||
# c compile only
|
||||
# d1 include line number debugging information
|
||||
# d2 include full sybolic debugging information
|
||||
# ei force enums to be of type int
|
||||
# j change char default from unsigned to signed
|
||||
# oa relax aliasing checking
|
||||
# od do not optimize
|
||||
# oe[=#] expand functions inline, # = quads (default 20)
|
||||
# oi use the inline library functions
|
||||
# om generate inline 80x87 code for math functions
|
||||
# ot optimize for time
|
||||
# ox maximum optimization
|
||||
# s remove stack overflow checks
|
||||
# zp1 align structures on bytes
|
||||
# zq use quiet mode
|
||||
# /i=dir add include directories
|
||||
#
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
LOCOBJS = &
|
||||
i_cdmus.obj &
|
||||
i_cyber.obj &
|
||||
i_ibm.obj &
|
||||
i_ibm_a.obj &
|
||||
i_sound.obj &
|
||||
linear.obj
|
||||
|
||||
GLOBOBJS = &
|
||||
am_map.obj &
|
||||
a_action.obj &
|
||||
ct_chat.obj &
|
||||
d_net.obj &
|
||||
f_finale.obj &
|
||||
g_game.obj &
|
||||
h2_main.obj &
|
||||
info.obj &
|
||||
in_lude.obj &
|
||||
mn_menu.obj &
|
||||
m_misc.obj &
|
||||
p_acs.obj &
|
||||
p_anim.obj &
|
||||
p_ceilng.obj &
|
||||
p_doors.obj &
|
||||
p_enemy.obj &
|
||||
p_floor.obj &
|
||||
p_inter.obj &
|
||||
p_lights.obj &
|
||||
p_map.obj &
|
||||
p_maputl.obj &
|
||||
p_mobj.obj &
|
||||
p_plats.obj &
|
||||
p_pspr.obj &
|
||||
p_setup.obj &
|
||||
p_sight.obj &
|
||||
p_spec.obj &
|
||||
p_switch.obj &
|
||||
p_telept.obj &
|
||||
p_tick.obj &
|
||||
p_things.obj &
|
||||
p_user.obj &
|
||||
po_man.obj &
|
||||
r_bsp.obj &
|
||||
r_data.obj &
|
||||
r_draw.obj &
|
||||
r_main.obj &
|
||||
r_plane.obj &
|
||||
r_segs.obj &
|
||||
r_things.obj &
|
||||
sb_bar.obj &
|
||||
sc_man.obj &
|
||||
sn_sonix.obj &
|
||||
st_start.obj &
|
||||
sv_save.obj &
|
||||
sounds.obj &
|
||||
tables.obj &
|
||||
v_video.obj &
|
||||
w_wad.obj &
|
||||
z_zone.obj
|
||||
|
||||
default: .SYMBOLIC
|
||||
@echo.
|
||||
@echo You must use M.BAT to build Hexen.
|
||||
@echo Type "M /?" for help.
|
||||
@echo.
|
||||
|
||||
#
|
||||
# DEBUG Build:
|
||||
#
|
||||
# The EXTERNOPT macro should be set to /d2
|
||||
#
|
||||
# FINAL Build:
|
||||
#
|
||||
# The EXTERNOPT macro should be set to /dNORANGECHECKING
|
||||
#
|
||||
|
||||
VERSION_ID = BCP
|
||||
|
||||
VERSIONOPT = /dVER_ID="$(VERSION_ID)"
|
||||
|
||||
CCOPTS = $(EXTERNOPT) $(VERSIONOPT) /omaxet /zp1 /4r /ei /j /zq /i=dmx
|
||||
|
||||
hex.exe : $(LOCOBJS) $(GLOBOBJS)
|
||||
wlink @hex.lnk
|
||||
ncopy hex.exe striphex.exe
|
||||
wstrip striphex.exe
|
||||
4gwbind 4gwpro.exe striphex.exe hexen.exe -V
|
||||
ncopy hex.map v_$(VERSION_ID).map
|
||||
prsucc
|
||||
|
||||
.c.obj :
|
||||
wcc386 $(CCOPTS) $[*
|
||||
|
||||
.asm.obj :
|
||||
tasm /mx $[*
|
1743
Hexen Source/MN_MENU.C
Normal file
1743
Hexen Source/MN_MENU.C
Normal file
File diff suppressed because it is too large
Load diff
878
Hexen Source/M_MISC.C
Normal file
878
Hexen Source/M_MISC.C
Normal file
|
@ -0,0 +1,878 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** m_misc.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: m_misc.c,v $
|
||||
//** $Revision: 1.18 $
|
||||
//** $Date: 96/01/07 16:51:18 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#ifdef __NeXT__
|
||||
#include <libc.h>
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <direct.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <io.h>
|
||||
#include <conio.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
#include "soundst.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
#define MALLOC_CLIB 1
|
||||
#define MALLOC_ZONE 2
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static int ReadFile(char const *name, byte **buffer, int mallocType);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
extern char *SavePath;
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
int myargc;
|
||||
char **myargv;
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// M_CheckParm
|
||||
//
|
||||
// Checks for the given parameter in the program's command line arguments.
|
||||
// Returns the argument number (1 to argc-1) or 0 if not present.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int M_CheckParm(char *check)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 1; i < myargc; i++)
|
||||
{
|
||||
if(!strcasecmp(check, myargv[i]))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// M_ParmExists
|
||||
//
|
||||
// Returns true if the given parameter exists in the program's command
|
||||
// line arguments, false if not.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
boolean M_ParmExists(char *check)
|
||||
{
|
||||
return M_CheckParm(check) != 0 ? true : false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// M_ExtractFileBase
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void M_ExtractFileBase(char *path, char *dest)
|
||||
{
|
||||
char *src;
|
||||
int length;
|
||||
|
||||
src = path+strlen(path)-1;
|
||||
|
||||
// Back up until a \ or the start
|
||||
while(src != path && *(src-1) != '\\' && *(src-1) != '/')
|
||||
{
|
||||
src--;
|
||||
}
|
||||
|
||||
// Copy up to eight characters
|
||||
memset(dest, 0, 8);
|
||||
length = 0;
|
||||
while(*src && *src != '.')
|
||||
{
|
||||
if(++length == 9)
|
||||
{
|
||||
I_Error("Filename base of %s > 8 chars", path);
|
||||
}
|
||||
*dest++ = toupper((int)*src++);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===============
|
||||
=
|
||||
= M_Random
|
||||
=
|
||||
= Returns a 0-255 number
|
||||
=
|
||||
===============
|
||||
*/
|
||||
|
||||
|
||||
// This is the new flat distribution table
|
||||
unsigned char rndtable[256] = {
|
||||
201, 1,243, 19, 18, 42,183,203,101,123,154,137, 34,118, 10,216,
|
||||
135,246, 0,107,133,229, 35,113,177,211,110, 17,139, 84,251,235,
|
||||
182,166,161,230,143, 91, 24, 81, 22, 94, 7, 51,232,104,122,248,
|
||||
175,138,127,171,222,213, 44, 16, 9, 33, 88,102,170,150,136,114,
|
||||
62, 3,142,237, 6,252,249, 56, 74, 30, 13, 21,180,199, 32,132,
|
||||
187,234, 78,210, 46,131,197, 8,206,244, 73, 4,236,178,195, 70,
|
||||
121, 97,167,217,103, 40,247,186,105, 39, 95,163, 99,149,253, 29,
|
||||
119, 83,254, 26,202, 65,130,155, 60, 64,184,106,221, 93,164,196,
|
||||
112,108,179,141, 54,109, 11,126, 75,165,191,227, 87,225,156, 15,
|
||||
98,162,116, 79,169,140,190,205,168,194, 41,250, 27, 20, 14,241,
|
||||
50,214, 72,192,220,233, 67,148, 96,185,176,181,215,207,172, 85,
|
||||
89, 90,209,128,124, 2, 55,173, 66,152, 47,129, 59, 43,159,240,
|
||||
239, 12,189,212,144, 28,200, 77,219,198,134,228, 45, 92,125,151,
|
||||
5, 53,255, 52, 68,245,160,158, 61, 86, 58, 82,117, 37,242,145,
|
||||
69,188,115, 76, 63,100, 49,111,153, 80, 38, 57,174,224, 71,231,
|
||||
23, 25, 48,218,120,147,208, 36,226,223,193,238,157,204,146, 31
|
||||
};
|
||||
|
||||
|
||||
int rndindex = 0;
|
||||
int prndindex = 0;
|
||||
|
||||
int M_Random (void)
|
||||
{
|
||||
rndindex = (rndindex+1)&0xff;
|
||||
return rndtable[rndindex];
|
||||
}
|
||||
|
||||
void M_ClearRandom (void)
|
||||
{
|
||||
rndindex = prndindex = 0;
|
||||
}
|
||||
|
||||
|
||||
void M_ClearBox (fixed_t *box)
|
||||
{
|
||||
box[BOXTOP] = box[BOXRIGHT] = MININT;
|
||||
box[BOXBOTTOM] = box[BOXLEFT] = MAXINT;
|
||||
}
|
||||
|
||||
void M_AddToBox (fixed_t *box, fixed_t x, fixed_t y)
|
||||
{
|
||||
if (x<box[BOXLEFT])
|
||||
box[BOXLEFT] = x;
|
||||
else if (x>box[BOXRIGHT])
|
||||
box[BOXRIGHT] = x;
|
||||
if (y<box[BOXBOTTOM])
|
||||
box[BOXBOTTOM] = y;
|
||||
else if (y>box[BOXTOP])
|
||||
box[BOXTOP] = y;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
=
|
||||
= M_WriteFile
|
||||
=
|
||||
==================
|
||||
*/
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
boolean M_WriteFile (char const *name, void *source, int length)
|
||||
{
|
||||
int handle, count;
|
||||
|
||||
handle = open (name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
|
||||
if (handle == -1)
|
||||
return false;
|
||||
count = write (handle, source, length);
|
||||
close (handle);
|
||||
|
||||
if (count < length)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// M_ReadFile
|
||||
//
|
||||
// Read a file into a buffer allocated using Z_Malloc().
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int M_ReadFile(char const *name, byte **buffer)
|
||||
{
|
||||
return ReadFile(name, buffer, MALLOC_ZONE);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// M_ReadFileCLib
|
||||
//
|
||||
// Read a file into a buffer allocated using malloc().
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int M_ReadFileCLib(char const *name, byte **buffer)
|
||||
{
|
||||
return ReadFile(name, buffer, MALLOC_CLIB);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ReadFile
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static int ReadFile(char const *name, byte **buffer, int mallocType)
|
||||
{
|
||||
int handle, count, length;
|
||||
struct stat fileinfo;
|
||||
byte *buf;
|
||||
|
||||
handle = open(name, O_RDONLY|O_BINARY, 0666);
|
||||
if(handle == -1)
|
||||
{
|
||||
I_Error("Couldn't read file %s", name);
|
||||
}
|
||||
if(fstat(handle, &fileinfo) == -1)
|
||||
{
|
||||
I_Error("Couldn't read file %s", name);
|
||||
}
|
||||
length = fileinfo.st_size;
|
||||
if(mallocType == MALLOC_ZONE)
|
||||
{ // Use zone memory allocation
|
||||
buf = Z_Malloc(length, PU_STATIC, NULL);
|
||||
}
|
||||
else
|
||||
{ // Use c library memory allocation
|
||||
buf = malloc(length);
|
||||
if(buf == NULL)
|
||||
{
|
||||
I_Error("Couldn't malloc buffer %d for file %s.",
|
||||
length, name);
|
||||
}
|
||||
}
|
||||
count = read(handle, buf, length);
|
||||
close(handle);
|
||||
if(count < length)
|
||||
{
|
||||
I_Error("Couldn't read file %s", name);
|
||||
}
|
||||
*buffer = buf;
|
||||
return length;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC M_FindResponseFile
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#define MAXARGVS 100
|
||||
|
||||
void M_FindResponseFile(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 1; i < myargc; i++)
|
||||
{
|
||||
if(myargv[i][0] == '@')
|
||||
{
|
||||
FILE *handle;
|
||||
int size;
|
||||
int k;
|
||||
int index;
|
||||
int indexinfile;
|
||||
char *infile;
|
||||
char *file;
|
||||
char *moreargs[20];
|
||||
char *firstargv;
|
||||
|
||||
// READ THE RESPONSE FILE INTO MEMORY
|
||||
handle = fopen(&myargv[i][1], "rb");
|
||||
if(!handle)
|
||||
{
|
||||
printf("\nNo such response file!");
|
||||
exit(1);
|
||||
}
|
||||
ST_Message("Found response file %s!\n",&myargv[i][1]);
|
||||
fseek (handle,0,SEEK_END);
|
||||
size = ftell(handle);
|
||||
fseek (handle,0,SEEK_SET);
|
||||
file = malloc (size);
|
||||
fread (file,size,1,handle);
|
||||
fclose (handle);
|
||||
|
||||
// KEEP ALL CMDLINE ARGS FOLLOWING @RESPONSEFILE ARG
|
||||
for (index = 0,k = i+1; k < myargc; k++)
|
||||
moreargs[index++] = myargv[k];
|
||||
|
||||
firstargv = myargv[0];
|
||||
myargv = malloc(sizeof(char *)*MAXARGVS);
|
||||
memset(myargv,0,sizeof(char *)*MAXARGVS);
|
||||
myargv[0] = firstargv;
|
||||
|
||||
infile = file;
|
||||
indexinfile = k = 0;
|
||||
indexinfile++; // SKIP PAST ARGV[0] (KEEP IT)
|
||||
do
|
||||
{
|
||||
myargv[indexinfile++] = infile+k;
|
||||
while(k < size &&
|
||||
|
||||
((*(infile+k)>= ' '+1) && (*(infile+k)<='z')))
|
||||
k++;
|
||||
*(infile+k) = 0;
|
||||
while(k < size &&
|
||||
((*(infile+k)<= ' ') || (*(infile+k)>'z')))
|
||||
k++;
|
||||
} while(k < size);
|
||||
|
||||
for (k = 0;k < index;k++)
|
||||
myargv[indexinfile++] = moreargs[k];
|
||||
myargc = indexinfile;
|
||||
// DISPLAY ARGS
|
||||
if(M_CheckParm("-debug"))
|
||||
{
|
||||
ST_Message("%d command-line args:\n", myargc);
|
||||
for(k = 1; k < myargc; k++)
|
||||
{
|
||||
ST_Message("%s\n", myargv[k]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC M_ForceUppercase
|
||||
//
|
||||
// Change string to uppercase.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void M_ForceUppercase(char *text)
|
||||
{
|
||||
char c;
|
||||
|
||||
while((c = *text) != 0)
|
||||
{
|
||||
if(c >= 'a' && c <= 'z')
|
||||
{
|
||||
*text++ = c-('a'-'A');
|
||||
}
|
||||
else
|
||||
{
|
||||
text++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
DEFAULTS
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
int usemouse;
|
||||
int usejoystick;
|
||||
|
||||
extern int key_right, key_left, key_up, key_down;
|
||||
extern int key_strafeleft, key_straferight, key_jump;
|
||||
extern int key_fire, key_use, key_strafe, key_speed;
|
||||
extern int key_flyup, key_flydown, key_flycenter;
|
||||
extern int key_lookup, key_lookdown, key_lookcenter;
|
||||
extern int key_invleft, key_invright, key_useartifact;
|
||||
|
||||
extern int mousebfire;
|
||||
extern int mousebstrafe;
|
||||
extern int mousebforward;
|
||||
extern int mousebjump;
|
||||
|
||||
extern int joybfire;
|
||||
extern int joybstrafe;
|
||||
extern int joybuse;
|
||||
extern int joybspeed;
|
||||
extern int joybjump;
|
||||
|
||||
extern boolean messageson;
|
||||
|
||||
extern int viewwidth, viewheight;
|
||||
|
||||
int mouseSensitivity;
|
||||
|
||||
extern int screenblocks;
|
||||
|
||||
extern char *chat_macros[10];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
int *location;
|
||||
int defaultvalue;
|
||||
int scantranslate; // PC scan code hack
|
||||
int untranslated; // lousy hack
|
||||
} default_t;
|
||||
|
||||
#ifndef __NeXT__
|
||||
extern int snd_Channels;
|
||||
extern int snd_DesiredMusicDevice, snd_DesiredSfxDevice;
|
||||
extern int snd_MusicDevice, // current music card # (index to dmxCodes)
|
||||
snd_SfxDevice; // current sfx card # (index to dmxCodes)
|
||||
|
||||
extern int snd_SBport, snd_SBirq, snd_SBdma; // sound blaster variables
|
||||
extern int snd_Mport; // midi variables
|
||||
#endif
|
||||
|
||||
default_t defaults[] =
|
||||
{
|
||||
{ "mouse_sensitivity", &mouseSensitivity, 5 },
|
||||
|
||||
#ifndef __NeXT__
|
||||
{ "sfx_volume", &snd_MaxVolume, 10},
|
||||
{ "music_volume", &snd_MusicVolume, 10},
|
||||
#endif
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
#define SC_UPARROW 0x48
|
||||
#define SC_DOWNARROW 0x50
|
||||
#define SC_LEFTARROW 0x4b
|
||||
#define SC_RIGHTARROW 0x4d
|
||||
#define SC_RCTRL 0x1d
|
||||
#define SC_RALT 0x38
|
||||
#define SC_RSHIFT 0x36
|
||||
#define SC_SPACE 0x39
|
||||
#define SC_COMMA 0x33
|
||||
#define SC_PERIOD 0x34
|
||||
#define SC_PAGEUP 0x49
|
||||
#define SC_INSERT 0x52
|
||||
#define SC_HOME 0x47
|
||||
#define SC_PAGEDOWN 0x51
|
||||
#define SC_DELETE 0x53
|
||||
#define SC_END 0x4f
|
||||
#define SC_ENTER 0x1c
|
||||
#define SC_SLASH 0X35
|
||||
|
||||
{ "key_right", &key_right, SC_RIGHTARROW, 1 },
|
||||
{ "key_left", &key_left, SC_LEFTARROW, 1 },
|
||||
{ "key_up", &key_up, SC_UPARROW, 1 },
|
||||
{ "key_down", &key_down, SC_DOWNARROW, 1 },
|
||||
{ "key_strafeleft", &key_strafeleft, SC_COMMA, 1 },
|
||||
{ "key_straferight", &key_straferight, SC_PERIOD, 1 },
|
||||
{ "key_jump", &key_jump, SC_SLASH, 1},
|
||||
{ "key_flyup", &key_flyup, SC_PAGEUP, 1 },
|
||||
{ "key_flydown", &key_flydown, SC_INSERT, 1 },
|
||||
{ "key_flycenter", &key_flycenter, SC_HOME, 1 },
|
||||
{ "key_lookup", &key_lookup, SC_PAGEDOWN, 1 },
|
||||
{ "key_lookdown", &key_lookdown, SC_DELETE, 1 },
|
||||
{ "key_lookcenter", &key_lookcenter, SC_END, 1 },
|
||||
{ "key_invleft", &key_invleft, 0x1a, 1 },
|
||||
{ "key_invright", &key_invright, 0x1b, 1 },
|
||||
{ "key_useartifact", &key_useartifact, SC_ENTER, 1 },
|
||||
|
||||
{ "key_fire", &key_fire, SC_RCTRL, 1 },
|
||||
{ "key_use", &key_use, SC_SPACE, 1 },
|
||||
{ "key_strafe", &key_strafe, SC_RALT, 1 },
|
||||
{ "key_speed", &key_speed, SC_RSHIFT, 1 },
|
||||
#endif
|
||||
|
||||
#ifdef __NeXT__
|
||||
{ "key_right", &key_right, KEY_RIGHTARROW },
|
||||
{ "key_left", &key_left, KEY_LEFTARROW },
|
||||
{ "key_up", &key_up, KEY_UPARROW },
|
||||
{ "key_down", &key_down, KEY_DOWNARROW },
|
||||
{ "key_strafeleft", &key_strafeleft, ',' },
|
||||
{ "key_straferight", &key_straferight, '.' },
|
||||
{ "key_jump", &key_jump, '/'},
|
||||
{ "key_flyup", &key_flyup, 'u' },
|
||||
{ "key_flydown", &key_flydown, 'j' },
|
||||
{ "key_flycenter", &key_flycenter, 'k' },
|
||||
{ "key_lookup", &key_lookup, 'm' },
|
||||
{ "key_lookdown", &key_lookdown, 'b' },
|
||||
{ "key_lookcenter", &key_lookcenter, 'n' },
|
||||
{ "key_invleft", &key_invleft, '[' },
|
||||
{ "key_invright", &key_invright, ']' },
|
||||
{ "key_useartifact", &key_useartifact, 13 },
|
||||
|
||||
{ "key_fire", &key_fire, ' ', 1 },
|
||||
{ "key_use", &key_use, 'x', 1 },
|
||||
{ "key_strafe", &key_strafe, 'c', 1 },
|
||||
{ "key_speed", &key_speed, 'z', 1 },
|
||||
#endif
|
||||
|
||||
{ "use_mouse", &usemouse, 1 },
|
||||
{ "mouseb_fire", &mousebfire, 0 },
|
||||
{ "mouseb_strafe", &mousebstrafe, 1 },
|
||||
{ "mouseb_forward", &mousebforward, 2 },
|
||||
{ "mouseb_jump", &mousebjump, -1 },
|
||||
|
||||
{ "use_joystick", &usejoystick, 0 },
|
||||
{ "joyb_fire", &joybfire, 0 },
|
||||
{ "joyb_strafe", &joybstrafe, 1 },
|
||||
{ "joyb_use", &joybuse, 3 },
|
||||
{ "joyb_speed", &joybspeed, 2 },
|
||||
{ "joyb_jump", &joybjump, -1 },
|
||||
|
||||
{ "screenblocks", &screenblocks, 10 },
|
||||
|
||||
#ifndef __NeXT__
|
||||
{ "snd_channels", &snd_Channels, 3 },
|
||||
{ "snd_musicdevice", &snd_DesiredMusicDevice, 0 },
|
||||
{ "snd_sfxdevice", &snd_DesiredSfxDevice, 0 },
|
||||
{ "snd_sbport", &snd_SBport, 544 },
|
||||
{ "snd_sbirq", &snd_SBirq, -1 },
|
||||
{ "snd_sbdma", &snd_SBdma, -1 },
|
||||
{ "snd_mport", &snd_Mport, -1 },
|
||||
#endif
|
||||
|
||||
{ "usegamma", &usegamma, 0 },
|
||||
|
||||
#ifdef __NeXT__
|
||||
#define DEFAULT_SAVEPATH "hexndata/"
|
||||
#endif
|
||||
#ifdef __WATCOMC__
|
||||
#define DEFAULT_SAVEPATH "hexndata\\"
|
||||
#endif
|
||||
{ "savedir", (int *) &SavePath, (int) DEFAULT_SAVEPATH },
|
||||
|
||||
{ "messageson", (int *) &messageson, 1 },
|
||||
|
||||
{ "chatmacro0", (int *) &chat_macros[0], (int) HUSTR_CHATMACRO0 },
|
||||
{ "chatmacro1", (int *) &chat_macros[1], (int) HUSTR_CHATMACRO1 },
|
||||
{ "chatmacro2", (int *) &chat_macros[2], (int) HUSTR_CHATMACRO2 },
|
||||
{ "chatmacro3", (int *) &chat_macros[3], (int) HUSTR_CHATMACRO3 },
|
||||
{ "chatmacro4", (int *) &chat_macros[4], (int) HUSTR_CHATMACRO4 },
|
||||
{ "chatmacro5", (int *) &chat_macros[5], (int) HUSTR_CHATMACRO5 },
|
||||
{ "chatmacro6", (int *) &chat_macros[6], (int) HUSTR_CHATMACRO6 },
|
||||
{ "chatmacro7", (int *) &chat_macros[7], (int) HUSTR_CHATMACRO7 },
|
||||
{ "chatmacro8", (int *) &chat_macros[8], (int) HUSTR_CHATMACRO8 },
|
||||
{ "chatmacro9", (int *) &chat_macros[9], (int) HUSTR_CHATMACRO9 }
|
||||
};
|
||||
|
||||
int numdefaults;
|
||||
char defaultfile[128];
|
||||
|
||||
/*
|
||||
==============
|
||||
=
|
||||
= M_SaveDefaults
|
||||
=
|
||||
==============
|
||||
*/
|
||||
|
||||
void M_SaveDefaults (void)
|
||||
{
|
||||
int i,v;
|
||||
FILE *f;
|
||||
|
||||
f = fopen (defaultfile, "w");
|
||||
if (!f)
|
||||
return; // can't write the file, but don't complain
|
||||
|
||||
for (i=0 ; i<numdefaults ; i++)
|
||||
{
|
||||
#ifdef __WATCOMC__
|
||||
if (defaults[i].scantranslate)
|
||||
defaults[i].location = &defaults[i].untranslated;
|
||||
#endif
|
||||
if (defaults[i].defaultvalue > -0xfff
|
||||
&& defaults[i].defaultvalue < 0xfff)
|
||||
{
|
||||
v = *defaults[i].location;
|
||||
fprintf (f,"%s\t\t%i\n",defaults[i].name,v);
|
||||
} else {
|
||||
fprintf (f,"%s\t\t\"%s\"\n",defaults[i].name,
|
||||
* (char **) (defaults[i].location));
|
||||
}
|
||||
}
|
||||
|
||||
fclose (f);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// M_LoadDefaults
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
extern byte scantokey[128];
|
||||
|
||||
void M_LoadDefaults(char *fileName)
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
FILE *f;
|
||||
char def[80];
|
||||
char strparm[100];
|
||||
char *newstring;
|
||||
int parm;
|
||||
boolean isstring;
|
||||
|
||||
// Set everything to base values
|
||||
numdefaults = sizeof(defaults)/sizeof(defaults[0]);
|
||||
for(i = 0; i < numdefaults; i++)
|
||||
{
|
||||
*defaults[i].location = defaults[i].defaultvalue;
|
||||
}
|
||||
|
||||
// Check for a custom config file
|
||||
i = M_CheckParm("-config");
|
||||
if(i && i < myargc-1)
|
||||
{
|
||||
strcpy(defaultfile, myargv[i+1]);
|
||||
ST_Message("config file: %s\n", defaultfile);
|
||||
}
|
||||
else if(cdrom)
|
||||
{
|
||||
sprintf(defaultfile, "c:\\hexndata\\%s", fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(defaultfile, fileName);
|
||||
}
|
||||
|
||||
// Scan the config file
|
||||
f = fopen(defaultfile, "r");
|
||||
if(f)
|
||||
{
|
||||
while(!feof(f))
|
||||
{
|
||||
isstring = false;
|
||||
if(fscanf(f, "%79s %[^\n]\n", def, strparm) == 2)
|
||||
{
|
||||
if(strparm[0] == '"')
|
||||
{
|
||||
// Get a string default
|
||||
isstring = true;
|
||||
len = strlen(strparm);
|
||||
newstring = (char *)malloc(len);
|
||||
if (newstring == NULL) I_Error("can't malloc newstring");
|
||||
strparm[len-1] = 0;
|
||||
strcpy(newstring, strparm+1);
|
||||
}
|
||||
else if(strparm[0] == '0' && strparm[1] == 'x')
|
||||
{
|
||||
sscanf(strparm+2, "%x", &parm);
|
||||
}
|
||||
else
|
||||
{
|
||||
sscanf(strparm, "%i", &parm);
|
||||
}
|
||||
for(i = 0; i < numdefaults; i++)
|
||||
{
|
||||
if(!strcmp(def, defaults[i].name))
|
||||
{
|
||||
if(!isstring)
|
||||
{
|
||||
*defaults[i].location = parm;
|
||||
}
|
||||
else
|
||||
{
|
||||
*defaults[i].location = (int)newstring;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose (f);
|
||||
}
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
// Translate the key scancodes
|
||||
for(i = 0; i < numdefaults; i++)
|
||||
{
|
||||
if(defaults[i].scantranslate)
|
||||
{
|
||||
parm = *defaults[i].location;
|
||||
defaults[i].untranslated = parm;
|
||||
*defaults[i].location = scantokey[parm];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
SCREEN SHOTS
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char manufacturer;
|
||||
char version;
|
||||
char encoding;
|
||||
char bits_per_pixel;
|
||||
unsigned short xmin,ymin,xmax,ymax;
|
||||
unsigned short hres,vres;
|
||||
unsigned char palette[48];
|
||||
char reserved;
|
||||
char color_planes;
|
||||
unsigned short bytes_per_line;
|
||||
unsigned short palette_type;
|
||||
char filler[58];
|
||||
unsigned char data; // unbounded
|
||||
} pcx_t;
|
||||
|
||||
/*
|
||||
==============
|
||||
=
|
||||
= WritePCXfile
|
||||
=
|
||||
==============
|
||||
*/
|
||||
|
||||
void WritePCXfile (char *filename, byte *data, int width, int height, byte *palette)
|
||||
{
|
||||
int i, length;
|
||||
pcx_t *pcx;
|
||||
byte *pack;
|
||||
|
||||
pcx = Z_Malloc (width*height*2+1000, PU_STATIC, NULL);
|
||||
|
||||
pcx->manufacturer = 0x0a; // PCX id
|
||||
pcx->version = 5; // 256 color
|
||||
pcx->encoding = 1; // uncompressed
|
||||
pcx->bits_per_pixel = 8; // 256 color
|
||||
pcx->xmin = 0;
|
||||
pcx->ymin = 0;
|
||||
pcx->xmax = SHORT(width-1);
|
||||
pcx->ymax = SHORT(height-1);
|
||||
pcx->hres = SHORT(width);
|
||||
pcx->vres = SHORT(height);
|
||||
memset (pcx->palette,0,sizeof(pcx->palette));
|
||||
pcx->color_planes = 1; // chunky image
|
||||
pcx->bytes_per_line = SHORT(width);
|
||||
pcx->palette_type = SHORT(2); // not a grey scale
|
||||
memset (pcx->filler,0,sizeof(pcx->filler));
|
||||
|
||||
//
|
||||
// pack the image
|
||||
//
|
||||
pack = &pcx->data;
|
||||
|
||||
for (i=0 ; i<width*height ; i++)
|
||||
if ( (*data & 0xc0) != 0xc0)
|
||||
*pack++ = *data++;
|
||||
else
|
||||
{
|
||||
*pack++ = 0xc1;
|
||||
*pack++ = *data++;
|
||||
}
|
||||
|
||||
//
|
||||
// write the palette
|
||||
//
|
||||
*pack++ = 0x0c; // palette ID byte
|
||||
for (i=0 ; i<768 ; i++)
|
||||
*pack++ = *palette++;
|
||||
|
||||
//
|
||||
// write output file
|
||||
//
|
||||
length = pack - (byte *)pcx;
|
||||
M_WriteFile (filename, pcx, length);
|
||||
|
||||
Z_Free (pcx);
|
||||
}
|
||||
|
||||
|
||||
//==============================================================================
|
||||
|
||||
/*
|
||||
==================
|
||||
=
|
||||
= M_ScreenShot
|
||||
=
|
||||
==================
|
||||
*/
|
||||
|
||||
void M_ScreenShot (void)
|
||||
{
|
||||
int i;
|
||||
byte *linear;
|
||||
char lbmname[12];
|
||||
byte *pal;
|
||||
|
||||
#ifdef _WATCOMC_
|
||||
extern byte *pcscreen;
|
||||
#endif
|
||||
//
|
||||
// munge planar buffer to linear
|
||||
//
|
||||
#ifdef _WATCOMC_
|
||||
linear = pcscreen;
|
||||
#else
|
||||
linear = screen;
|
||||
#endif
|
||||
//
|
||||
// find a file name to save it to
|
||||
//
|
||||
strcpy(lbmname,"HEXEN00.pcx");
|
||||
|
||||
for (i=0 ; i<=99 ; i++)
|
||||
{
|
||||
lbmname[5] = i/10 + '0';
|
||||
lbmname[6] = i%10 + '0';
|
||||
if (access(lbmname,0) == -1)
|
||||
break; // file doesn't exist
|
||||
}
|
||||
if (i==100)
|
||||
I_Error ("M_ScreenShot: Couldn't create a PCX");
|
||||
|
||||
//
|
||||
// save the pcx file
|
||||
//
|
||||
#ifdef __WATCOMC__
|
||||
pal = (byte *)Z_Malloc(768, PU_STATIC, NULL);
|
||||
outp(0x3c7, 0);
|
||||
for(i = 0; i < 768; i++)
|
||||
{
|
||||
*(pal+i) = inp(0x3c9)<<2;
|
||||
}
|
||||
#else
|
||||
pal = (byte *)W_CacheLumpName("PLAYPAL", PU_CACHE);
|
||||
#endif
|
||||
|
||||
WritePCXfile (lbmname, linear, SCREENWIDTH, SCREENHEIGHT
|
||||
, pal);
|
||||
|
||||
P_SetMessage(&players[consoleplayer], "SCREEN SHOT", false);
|
||||
#ifdef __WATCOMC__
|
||||
Z_Free(pal);
|
||||
#endif
|
||||
}
|
790
Hexen Source/OLDD_NET.C
Normal file
790
Hexen Source/OLDD_NET.C
Normal file
|
@ -0,0 +1,790 @@
|
|||
// I_pcnet.m
|
||||
|
||||
#include "DoomDef.h"
|
||||
|
||||
#define NCMD_EXIT 0x80000000
|
||||
#define NCMD_RETRANSMIT 0x40000000
|
||||
#define NCMD_SETUP 0x20000000
|
||||
#define NCMD_CHECKSUM 0x0fffffff
|
||||
|
||||
/*
|
||||
if more space needs to be crunched out of the protocol...
|
||||
|
||||
1 drone
|
||||
2 player
|
||||
8 tic
|
||||
5 numtics
|
||||
|
||||
#define NCMD_EXIT 0x80000000
|
||||
#define NCMD_RETRANSMIT 0x40000000 // a retransmit will have 0 tics
|
||||
#define NCMD_DRONE 0x20000000
|
||||
#define NCMD_PLAYER 0x18000000
|
||||
#define NCMD_PLAYERSHIFT 27
|
||||
#define NCMD_TIC 0x00ff0000
|
||||
#define NCMD_TICSHIFT 16
|
||||
#define NCMD_NUMTICS 0x0000ff00
|
||||
#define NCMD_NUMTICSSHIFT 8
|
||||
#define NCMD_CHECKSUM 0x000000ff
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
doomcom_t *doomcom;
|
||||
doomdata_t *netbuffer; // points inside doomcom
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
NETWORKING
|
||||
|
||||
gametic is the tic about to (or currently being) run
|
||||
maketic is the tick that hasn't had control made for it yet
|
||||
nettics[] has the maketics for all players
|
||||
|
||||
a gametic cannot be run until nettics[] > gametic for all players
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#define RESENDCOUNT 10
|
||||
#define PL_DRONE 0x80 // bit flag in doomdata->player
|
||||
|
||||
ticcmd_t localcmds[BACKUPTICS];
|
||||
|
||||
ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS];
|
||||
int nettics[MAXNETNODES];
|
||||
boolean nodeingame[MAXNETNODES]; // set false as nodes leave game
|
||||
boolean remoteresend[MAXNETNODES]; // set when local needs tics
|
||||
int resendto[MAXNETNODES]; // set when remote needs tics
|
||||
int resendcount[MAXNETNODES];
|
||||
|
||||
int nodeforplayer[MAXPLAYERS];
|
||||
|
||||
int gametime;
|
||||
int maketic;
|
||||
int lastnettic, skiptics;
|
||||
int ticdup;
|
||||
|
||||
void D_ProcessEvents (void);
|
||||
void G_BuildTiccmd (ticcmd_t *cmd);
|
||||
void D_DoAdvanceDemo (void);
|
||||
|
||||
boolean reboundpacket;
|
||||
doomdata_t reboundstore;
|
||||
|
||||
|
||||
int NetbufferSize (void)
|
||||
{
|
||||
return (int)&(((doomdata_t *)0)->cmds[netbuffer->numtics]);
|
||||
}
|
||||
|
||||
unsigned NetbufferChecksum (void)
|
||||
{
|
||||
unsigned c;
|
||||
int i,l;
|
||||
|
||||
c = 0x1234567;
|
||||
|
||||
#ifdef NeXT
|
||||
return 0; // byte order problems
|
||||
#endif
|
||||
|
||||
l = (NetbufferSize () - (int)&(((doomdata_t *)0)->retransmitfrom))/4;
|
||||
for (i=0 ; i<l ; i++)
|
||||
c += ((unsigned *)&netbuffer->retransmitfrom)[i] * (i+1);
|
||||
|
||||
return c & NCMD_CHECKSUM;
|
||||
}
|
||||
|
||||
int ExpandTics (int low)
|
||||
{
|
||||
int delta;
|
||||
|
||||
delta = low - (maketic&0xff);
|
||||
|
||||
if (delta >= -64 && delta <= 64)
|
||||
return (maketic&~0xff) + low;
|
||||
if (delta > 64)
|
||||
return (maketic&~0xff) - 256 + low;
|
||||
if (delta < -64)
|
||||
return (maketic&~0xff) + 256 + low;
|
||||
|
||||
I_Error ("ExpandTics: strange value %i at maketic %i",low,maketic);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
=
|
||||
= HSendPacket
|
||||
=
|
||||
==============
|
||||
*/
|
||||
|
||||
void HSendPacket (int node, int flags)
|
||||
{
|
||||
netbuffer->checksum = NetbufferChecksum () | flags;
|
||||
|
||||
if (!node)
|
||||
{
|
||||
reboundstore = *netbuffer;
|
||||
reboundpacket = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!netgame)
|
||||
I_Error ("Tried to transmit to another node");
|
||||
|
||||
doomcom->command = CMD_SEND;
|
||||
doomcom->remotenode = node;
|
||||
doomcom->datalength = NetbufferSize ();
|
||||
|
||||
if (debugfile)
|
||||
{
|
||||
int i;
|
||||
int realretrans;
|
||||
if (netbuffer->checksum & NCMD_RETRANSMIT)
|
||||
realretrans = ExpandTics (netbuffer->retransmitfrom);
|
||||
else
|
||||
realretrans = -1;
|
||||
fprintf (debugfile,"send (%i + %i, R %i) [%i] "
|
||||
,ExpandTics(netbuffer->starttic),netbuffer->numtics, realretrans, doomcom->datalength);
|
||||
for (i=0 ; i<doomcom->datalength ; i++)
|
||||
fprintf (debugfile,"%i ",((byte *)netbuffer)[i]);
|
||||
fprintf (debugfile,"\n");
|
||||
}
|
||||
|
||||
I_NetCmd ();
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
=
|
||||
= HGetPacket
|
||||
=
|
||||
= Returns false if no packet is waiting
|
||||
=
|
||||
==============
|
||||
*/
|
||||
|
||||
boolean HGetPacket (void)
|
||||
{
|
||||
if (reboundpacket)
|
||||
{
|
||||
*netbuffer = reboundstore;
|
||||
doomcom->remotenode = 0;
|
||||
reboundpacket = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!netgame)
|
||||
return false;
|
||||
|
||||
doomcom->command = CMD_GET;
|
||||
I_NetCmd ();
|
||||
if (doomcom->remotenode == -1)
|
||||
return false;
|
||||
|
||||
if (doomcom->datalength != NetbufferSize ())
|
||||
{
|
||||
if (debugfile)
|
||||
fprintf (debugfile,"bad packet length %i\n",doomcom->datalength);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NetbufferChecksum () != (netbuffer->checksum&NCMD_CHECKSUM) )
|
||||
{
|
||||
if (debugfile)
|
||||
fprintf (debugfile,"bad packet checksum\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (debugfile)
|
||||
{
|
||||
int realretrans;
|
||||
int i;
|
||||
|
||||
if (netbuffer->checksum & NCMD_SETUP)
|
||||
fprintf (debugfile,"setup packet\n");
|
||||
else
|
||||
{
|
||||
if (netbuffer->checksum & NCMD_RETRANSMIT)
|
||||
realretrans = ExpandTics (netbuffer->retransmitfrom);
|
||||
else
|
||||
realretrans = -1;
|
||||
fprintf (debugfile,"get %i = (%i + %i, R %i)[%i] ",doomcom->remotenode,
|
||||
ExpandTics(netbuffer->starttic),netbuffer->numtics, realretrans, doomcom->datalength);
|
||||
for (i=0 ; i<doomcom->datalength ; i++)
|
||||
fprintf (debugfile,"%i ",((byte *)netbuffer)[i]);
|
||||
fprintf (debugfile,"\n");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
=
|
||||
= GetPackets
|
||||
=
|
||||
===================
|
||||
*/
|
||||
|
||||
char exitmsg[80];
|
||||
|
||||
void GetPackets (void)
|
||||
{
|
||||
int netconsole;
|
||||
int netnode;
|
||||
int netdrone;
|
||||
int j;
|
||||
ticcmd_t *src, *dest;
|
||||
int dupedstart, dupedend;
|
||||
int skiptics;
|
||||
int realstart;
|
||||
|
||||
while (HGetPacket ())
|
||||
{
|
||||
if (netbuffer->checksum & NCMD_SETUP)
|
||||
continue; // extra setup packet
|
||||
|
||||
netdrone = netbuffer->player & PL_DRONE;
|
||||
netconsole = netbuffer->player & ~PL_DRONE;
|
||||
netnode = doomcom->remotenode;
|
||||
//
|
||||
// to save bytes, only the low byte of tic numbers are sent
|
||||
// Figure out what the rest of the bytes are
|
||||
//
|
||||
realstart = ExpandTics (netbuffer->starttic);
|
||||
dupedstart = realstart*doomcom->ticdup;
|
||||
dupedend = (realstart+netbuffer->numtics)*doomcom->ticdup;
|
||||
|
||||
//
|
||||
// check for exiting the game
|
||||
//
|
||||
if (netbuffer->checksum & NCMD_EXIT)
|
||||
{
|
||||
if (!nodeingame[netnode])
|
||||
continue;
|
||||
nodeingame[netnode] = false;
|
||||
if (!netdrone)
|
||||
{
|
||||
playeringame[netconsole] = false;
|
||||
strcpy (exitmsg, "Player 1 left the game");
|
||||
exitmsg[7] += netconsole;
|
||||
players[consoleplayer].message = exitmsg;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// drone packets are just notifications
|
||||
//
|
||||
if (netdrone)
|
||||
{
|
||||
nettics[netnode] = dupedend;
|
||||
continue;
|
||||
}
|
||||
|
||||
nodeforplayer[netconsole] = netnode;
|
||||
|
||||
//
|
||||
// check for retransmit request
|
||||
//
|
||||
if ( resendcount[netnode] <= 0
|
||||
&& (netbuffer->checksum & NCMD_RETRANSMIT) )
|
||||
{
|
||||
resendto[netnode] = ExpandTics(netbuffer->retransmitfrom);
|
||||
if (debugfile)
|
||||
fprintf (debugfile,"retransmit from %i\n", resendto[netnode]);
|
||||
resendcount[netnode] = RESENDCOUNT;
|
||||
}
|
||||
else
|
||||
resendcount[netnode]--;
|
||||
|
||||
//
|
||||
// check for out of order / duplicated packet
|
||||
//
|
||||
if (dupedend == nettics[netnode])
|
||||
continue;
|
||||
|
||||
if (dupedend < nettics[netnode])
|
||||
{
|
||||
if (debugfile)
|
||||
fprintf (debugfile,"out of order packet (%i + %i)\n" ,realstart,netbuffer->numtics);
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// check for a missed packet
|
||||
//
|
||||
if (dupedstart > nettics[netnode])
|
||||
{
|
||||
// stop processing until the other system resends the missed tics
|
||||
if (debugfile)
|
||||
fprintf (debugfile,"missed tics from %i (%i - %i)\n", netnode, dupedstart, nettics[netnode]);
|
||||
remoteresend[netnode] = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// update command store from the packet
|
||||
//
|
||||
remoteresend[netnode] = false;
|
||||
|
||||
skiptics = nettics[netnode]/doomcom->ticdup - realstart;
|
||||
src = &netbuffer->cmds[skiptics];
|
||||
|
||||
while (nettics[netnode] < dupedend)
|
||||
{
|
||||
for (j=0 ; j<doomcom->ticdup ; j++)
|
||||
{
|
||||
dest = &netcmds[netconsole][nettics[netnode]%BACKUPTICS];
|
||||
nettics[netnode]++;
|
||||
*dest = *src;
|
||||
src->chatchar = 0;
|
||||
if (src->buttons & BT_SPECIAL)
|
||||
src->buttons = 0;
|
||||
}
|
||||
src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
=
|
||||
= NetUpdate
|
||||
=
|
||||
= Builds ticcmds for console player
|
||||
= sends out a packet
|
||||
=============
|
||||
*/
|
||||
|
||||
void NetUpdate (void)
|
||||
{
|
||||
int nowtime;
|
||||
int newtics;
|
||||
int i,j;
|
||||
int gameticdiv;
|
||||
int realstart;
|
||||
|
||||
if (singletics)
|
||||
return; // singletic update is syncronous
|
||||
|
||||
//
|
||||
// check time
|
||||
//
|
||||
nowtime = I_GetTime ()/doomcom->ticdup;
|
||||
newtics = nowtime - gametime;
|
||||
gametime = nowtime;
|
||||
if (newtics <= 0) // nothing new to update
|
||||
goto listen;
|
||||
|
||||
if (skiptics <= newtics)
|
||||
{
|
||||
newtics -= skiptics;
|
||||
skiptics = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
skiptics -= newtics;
|
||||
newtics = 0;
|
||||
}
|
||||
|
||||
|
||||
netbuffer->player = consoleplayer;
|
||||
if (doomcom->drone)
|
||||
netbuffer->player |= PL_DRONE;
|
||||
|
||||
//
|
||||
// drone packets
|
||||
//
|
||||
if (doomcom->drone)
|
||||
{
|
||||
I_StartTic ();
|
||||
D_ProcessEvents ();
|
||||
goto sendit;
|
||||
}
|
||||
|
||||
//
|
||||
// build new ticcmds for console player
|
||||
//
|
||||
gameticdiv = (gametic+doomcom->ticdup-1)/doomcom->ticdup;
|
||||
for (i=0 ; i<newtics ; i++)
|
||||
{
|
||||
I_StartTic ();
|
||||
D_ProcessEvents ();
|
||||
if (maketic - gameticdiv >= BACKUPTICS/2 /* /doomcom->ticdup */- 1)
|
||||
{
|
||||
newtics = i;
|
||||
break; // can't hold any more
|
||||
}
|
||||
//printf ("mk:%i ",maketic);
|
||||
G_BuildTiccmd (&localcmds[maketic%BACKUPTICS]);
|
||||
maketic++;
|
||||
}
|
||||
|
||||
//
|
||||
// send the packet to the other nodes
|
||||
//
|
||||
sendit:
|
||||
for (i=0 ; i<doomcom->numnodes ; i++)
|
||||
if (nodeingame[i])
|
||||
{
|
||||
if (doomcom->drone)
|
||||
{
|
||||
netbuffer->starttic = realstart = maketic + BACKUPTICS/2;
|
||||
netbuffer->numtics = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
netbuffer->starttic = realstart = resendto[i];
|
||||
netbuffer->numtics = maketic - realstart;
|
||||
resendto[i] = maketic - doomcom->extratics;
|
||||
}
|
||||
|
||||
if (netbuffer->numtics > BACKUPTICS)
|
||||
I_Error ("NetUpdate: netbuffer->numtics > BACKUPTICS");
|
||||
|
||||
for (j=0 ; j< netbuffer->numtics ; j++)
|
||||
netbuffer->cmds[j] =
|
||||
localcmds[(realstart+j)%BACKUPTICS];
|
||||
|
||||
if (remoteresend[i])
|
||||
{
|
||||
netbuffer->retransmitfrom = nettics[i]/doomcom->ticdup;
|
||||
HSendPacket (i, NCMD_RETRANSMIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
netbuffer->retransmitfrom = 0;
|
||||
HSendPacket (i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// listen for other packets
|
||||
//
|
||||
listen:
|
||||
|
||||
GetPackets ();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
=
|
||||
= CheckAbort
|
||||
=
|
||||
=====================
|
||||
*/
|
||||
|
||||
void CheckAbort (void)
|
||||
{
|
||||
event_t *ev;
|
||||
|
||||
I_WaitVBL(2);
|
||||
|
||||
I_StartTic ();
|
||||
for ( ; eventtail != eventhead
|
||||
; eventtail = (++eventtail)&(MAXEVENTS-1) )
|
||||
{
|
||||
ev = &events[eventtail];
|
||||
if (ev->type == ev_keydown && ev->data1 == KEY_ESCAPE)
|
||||
I_Error ("Network game synchronization aborted.");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=====================
|
||||
=
|
||||
= D_ArbitrateNetStart
|
||||
=
|
||||
=====================
|
||||
*/
|
||||
|
||||
void D_ArbitrateNetStart (void)
|
||||
{
|
||||
int i;
|
||||
boolean gotinfo[MAXNETNODES];
|
||||
|
||||
autostart = true;
|
||||
memset (gotinfo,0,sizeof(gotinfo));
|
||||
|
||||
if (doomcom->consoleplayer)
|
||||
{ // listen for setup info from key player
|
||||
printf ("listening for network start info...\n");
|
||||
while (1)
|
||||
{
|
||||
CheckAbort ();
|
||||
if (!HGetPacket ())
|
||||
continue;
|
||||
if (netbuffer->checksum & NCMD_SETUP)
|
||||
{
|
||||
if (netbuffer->player != VERSION)
|
||||
I_Error ("Different DOOM versions cannot play a net game!");
|
||||
startskill = netbuffer->retransmitfrom & 15;
|
||||
deathmatch = (netbuffer->retransmitfrom & 0x80) > 0;
|
||||
nomonsters = (netbuffer->retransmitfrom & 0x40) > 0;
|
||||
respawnparm = (netbuffer->retransmitfrom & 0x20) > 0;
|
||||
startmap = netbuffer->starttic & 15;
|
||||
startepisode = netbuffer->starttic >> 4;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // key player, send the setup info
|
||||
printf ("sending network start info...\n");
|
||||
do
|
||||
{
|
||||
CheckAbort ();
|
||||
for (i=0 ; i<doomcom->numnodes ; i++)
|
||||
{
|
||||
netbuffer->retransmitfrom = startskill;
|
||||
if (deathmatch)
|
||||
netbuffer->retransmitfrom |= 0x80;
|
||||
if (nomonsters)
|
||||
netbuffer->retransmitfrom |= 0x40;
|
||||
if (respawnparm)
|
||||
netbuffer->retransmitfrom |= 0x20;
|
||||
netbuffer->starttic = startepisode * 16 + startmap;
|
||||
netbuffer->player = VERSION;
|
||||
netbuffer->numtics = 0;
|
||||
HSendPacket (i, NCMD_SETUP);
|
||||
}
|
||||
|
||||
while (HGetPacket ())
|
||||
{
|
||||
gotinfo[netbuffer->player&0x7f] = true;
|
||||
}
|
||||
|
||||
for (i=1 ; i<doomcom->numnodes ; i++)
|
||||
if (!gotinfo[i])
|
||||
break;
|
||||
} while (i < doomcom->numnodes);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
===================
|
||||
=
|
||||
= D_CheckNetGame
|
||||
=
|
||||
= Works out player numbers among the net participants
|
||||
===================
|
||||
*/
|
||||
|
||||
extern int viewangleoffset;
|
||||
|
||||
void D_CheckNetGame (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<MAXNETNODES ; i++)
|
||||
{
|
||||
nodeingame[i] = false;
|
||||
nettics[i] = 0;
|
||||
remoteresend[i] = false; // set when local needs tics
|
||||
resendto[i] = 0; // which tic to start sending
|
||||
}
|
||||
|
||||
// I_InitNetwork sets doomcom and netgame
|
||||
I_InitNetwork ();
|
||||
if (doomcom->id != DOOMCOM_ID)
|
||||
I_Error ("Doomcom buffer invalid!");
|
||||
netbuffer = &doomcom->data;
|
||||
consoleplayer = displayplayer = doomcom->consoleplayer;
|
||||
if (netgame)
|
||||
D_ArbitrateNetStart ();
|
||||
printf ("startskill %i deathmatch: %i startmap: %i startepisode: %i\n", startskill, deathmatch, startmap, startepisode);
|
||||
|
||||
// read values out of doomcom
|
||||
ticdup = doomcom->ticdup;
|
||||
|
||||
for (i=0 ; i<doomcom->numplayers ; i++)
|
||||
playeringame[i] = true;
|
||||
for (i=0 ; i<doomcom->numnodes ; i++)
|
||||
nodeingame[i] = true;
|
||||
|
||||
printf ("player %i of %i (%i nodes)\n", consoleplayer+1, doomcom->numplayers, doomcom->numnodes);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
=
|
||||
= D_QuitNetGame
|
||||
=
|
||||
= Called before quitting to leave a net game without hanging the
|
||||
= other players
|
||||
=
|
||||
==================
|
||||
*/
|
||||
|
||||
void D_QuitNetGame (void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (debugfile)
|
||||
fclose (debugfile);
|
||||
|
||||
if (!netgame || !usergame || consoleplayer == -1)
|
||||
return;
|
||||
|
||||
// send a bunch of packets for security
|
||||
netbuffer->player = consoleplayer;
|
||||
if (doomcom->drone)
|
||||
netbuffer->player |= PL_DRONE;
|
||||
netbuffer->numtics = 0;
|
||||
for (i=0 ; i<4 ; i++)
|
||||
{
|
||||
for (j=1 ; j<doomcom->numnodes ; j++)
|
||||
if (nodeingame[j])
|
||||
HSendPacket (j, NCMD_EXIT);
|
||||
I_WaitVBL (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
===============
|
||||
=
|
||||
= TryRunTics
|
||||
=
|
||||
===============
|
||||
*/
|
||||
|
||||
int frametics[4], frameon;
|
||||
int frameskip[4];
|
||||
int oldnettics;
|
||||
extern boolean advancedemo;
|
||||
|
||||
void TryRunTics (void)
|
||||
{
|
||||
int i;
|
||||
int lowtic, nextlowest;
|
||||
int entertic;
|
||||
int static oldentertics;
|
||||
int realtics, availabletics;
|
||||
int counts;
|
||||
int numplaying;
|
||||
|
||||
//
|
||||
// get real tics
|
||||
//
|
||||
entertic = I_GetTime ();
|
||||
realtics = entertic - oldentertics;
|
||||
oldentertics = entertic;
|
||||
|
||||
//
|
||||
// get available tics
|
||||
//
|
||||
NetUpdate ();
|
||||
|
||||
lowtic = nextlowest = MAXINT;
|
||||
numplaying = 0;
|
||||
for (i=0 ; i<doomcom->numnodes ; i++)
|
||||
if (nodeingame[i])
|
||||
{
|
||||
numplaying++;
|
||||
if (nettics[i] < lowtic)
|
||||
{
|
||||
nextlowest = lowtic;
|
||||
lowtic = nettics[i];
|
||||
}
|
||||
else if (nettics[i] < nextlowest)
|
||||
nextlowest = nettics[i];
|
||||
}
|
||||
availabletics = lowtic - gametic;
|
||||
|
||||
|
||||
//
|
||||
// decide how many tics to run
|
||||
//
|
||||
if (realtics < availabletics-1)
|
||||
counts = realtics+1;
|
||||
else if (realtics < availabletics)
|
||||
counts = realtics;
|
||||
else
|
||||
counts = availabletics;
|
||||
if (counts < 1)
|
||||
counts = 1;
|
||||
|
||||
frameon++;
|
||||
|
||||
if (debugfile)
|
||||
fprintf (debugfile,"=======real: %i avail: %i game: %i\n",realtics, availabletics,counts);
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// ideally nettics[0] should be 1 - 3 tics above lowtic
|
||||
// if we are consistantly slower, speed up time
|
||||
// drones should never hold up the other players
|
||||
//
|
||||
for (i=0 ; i<MAXPLAYERS ; i++)
|
||||
if (playeringame[i])
|
||||
break;
|
||||
if (consoleplayer == i)
|
||||
{ // the key player does not adapt
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nettics[0] <= nettics[nodeforplayer[i]])
|
||||
{
|
||||
gametime--;
|
||||
// printf ("-");
|
||||
}
|
||||
frameskip[frameon&3] = (oldnettics > nettics[nodeforplayer[i]]);
|
||||
oldnettics = nettics[0];
|
||||
if (frameskip[0] && frameskip[1] && frameskip[2] && frameskip[3])
|
||||
{
|
||||
skiptics = 1;
|
||||
// printf ("+");
|
||||
}
|
||||
}
|
||||
//=============================================================================
|
||||
|
||||
//
|
||||
// wait for new tics if needed
|
||||
//
|
||||
while (lowtic < gametic + counts)
|
||||
{
|
||||
|
||||
NetUpdate ();
|
||||
lowtic = MAXINT;
|
||||
|
||||
for (i=0 ; i<doomcom->numnodes ; i++)
|
||||
if (nodeingame[i] && nettics[i] < lowtic)
|
||||
lowtic = nettics[i];
|
||||
|
||||
if (lowtic < gametic)
|
||||
I_Error ("TryRunTics: lowtic < gametic");
|
||||
|
||||
// don't stay in here forever -- give the menu a chance to work
|
||||
if (I_GetTime () - entertic >= 20)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// run the tics
|
||||
//
|
||||
while (counts--)
|
||||
{
|
||||
G_Ticker ();
|
||||
NetUpdate (); // check for new console commands
|
||||
gametic++;
|
||||
}
|
||||
}
|
1482
Hexen Source/PO_MAN.C
Normal file
1482
Hexen Source/PO_MAN.C
Normal file
File diff suppressed because it is too large
Load diff
1782
Hexen Source/P_ACS.C
Normal file
1782
Hexen Source/P_ACS.C
Normal file
File diff suppressed because it is too large
Load diff
473
Hexen Source/P_ANIM.C
Normal file
473
Hexen Source/P_ANIM.C
Normal file
|
@ -0,0 +1,473 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** p_anim.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: p_anim.c,v $
|
||||
//** $Revision: 1.9 $
|
||||
//** $Date: 95/07/17 18:50:37 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
#define ANIM_SCRIPT_NAME "ANIMDEFS"
|
||||
#define MAX_ANIM_DEFS 20
|
||||
#define MAX_FRAME_DEFS 96
|
||||
#define ANIM_FLAT 0
|
||||
#define ANIM_TEXTURE 1
|
||||
#define SCI_FLAT "flat"
|
||||
#define SCI_TEXTURE "texture"
|
||||
#define SCI_PIC "pic"
|
||||
#define SCI_TICS "tics"
|
||||
#define SCI_RAND "rand"
|
||||
|
||||
#define LIGHTNING_SPECIAL 198
|
||||
#define LIGHTNING_SPECIAL2 199
|
||||
#define SKYCHANGE_SPECIAL 200
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int index;
|
||||
int tics;
|
||||
} frameDef_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int type;
|
||||
int index;
|
||||
int tics;
|
||||
int currentFrameDef;
|
||||
int startFrameDef;
|
||||
int endFrameDef;
|
||||
} animDef_t;
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static void P_LightningFlash(void);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
extern fixed_t Sky1ColumnOffset;
|
||||
extern fixed_t Sky2ColumnOffset;
|
||||
extern int Sky1Texture;
|
||||
extern boolean DoubleSky;
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
fixed_t Sky1ScrollDelta;
|
||||
fixed_t Sky2ScrollDelta;
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static animDef_t AnimDefs[MAX_ANIM_DEFS];
|
||||
static frameDef_t FrameDefs[MAX_FRAME_DEFS];
|
||||
static int AnimDefCount;
|
||||
static boolean LevelHasLightning;
|
||||
static int NextLightningFlash;
|
||||
static int LightningFlash;
|
||||
static int *LightningLightLevels;
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_AnimateSurfaces
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_AnimateSurfaces(void)
|
||||
{
|
||||
int i;
|
||||
animDef_t *ad;
|
||||
line_t *line;
|
||||
|
||||
// Animate flats and textures
|
||||
for(i = 0; i < AnimDefCount; i++)
|
||||
{
|
||||
ad = &AnimDefs[i];
|
||||
ad->tics--;
|
||||
if(ad->tics == 0)
|
||||
{
|
||||
if(ad->currentFrameDef == ad->endFrameDef)
|
||||
{
|
||||
ad->currentFrameDef = ad->startFrameDef;
|
||||
}
|
||||
else
|
||||
{
|
||||
ad->currentFrameDef++;
|
||||
}
|
||||
ad->tics = FrameDefs[ad->currentFrameDef].tics;
|
||||
if(ad->tics > 255)
|
||||
{ // Random tics
|
||||
ad->tics = (ad->tics>>16)
|
||||
+P_Random()%((ad->tics&0xff00)>>8);
|
||||
}
|
||||
if(ad->type == ANIM_FLAT)
|
||||
{
|
||||
flattranslation[ad->index] =
|
||||
FrameDefs[ad->currentFrameDef].index;
|
||||
}
|
||||
else
|
||||
{ // Texture
|
||||
texturetranslation[ad->index] =
|
||||
FrameDefs[ad->currentFrameDef].index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update scrolling textures
|
||||
for(i = 0; i < numlinespecials; i++)
|
||||
{
|
||||
line = linespeciallist[i];
|
||||
switch(line->special)
|
||||
{
|
||||
case 100: // Scroll_Texture_Left
|
||||
sides[line->sidenum[0]].textureoffset += line->arg1<<10;
|
||||
break;
|
||||
case 101: // Scroll_Texture_Right
|
||||
sides[line->sidenum[0]].textureoffset -= line->arg1<<10;
|
||||
break;
|
||||
case 102: // Scroll_Texture_Up
|
||||
sides[line->sidenum[0]].rowoffset += line->arg1<<10;
|
||||
break;
|
||||
case 103: // Scroll_Texture_Down
|
||||
sides[line->sidenum[0]].rowoffset -= line->arg1<<10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Update sky column offsets
|
||||
Sky1ColumnOffset += Sky1ScrollDelta;
|
||||
Sky2ColumnOffset += Sky2ScrollDelta;
|
||||
|
||||
if(LevelHasLightning)
|
||||
{
|
||||
if(!NextLightningFlash || LightningFlash)
|
||||
{
|
||||
P_LightningFlash();
|
||||
}
|
||||
else
|
||||
{
|
||||
NextLightningFlash--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_LightningFlash
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void P_LightningFlash(void)
|
||||
{
|
||||
int i;
|
||||
sector_t *tempSec;
|
||||
int *tempLight;
|
||||
boolean foundSec;
|
||||
int flashLight;
|
||||
|
||||
if(LightningFlash)
|
||||
{
|
||||
LightningFlash--;
|
||||
if(LightningFlash)
|
||||
{
|
||||
tempLight = LightningLightLevels;
|
||||
tempSec = sectors;
|
||||
for(i = 0; i < numsectors; i++, tempSec++)
|
||||
{
|
||||
if(tempSec->ceilingpic == skyflatnum
|
||||
|| tempSec->special == LIGHTNING_SPECIAL
|
||||
|| tempSec->special == LIGHTNING_SPECIAL2)
|
||||
{
|
||||
if(*tempLight < tempSec->lightlevel-4)
|
||||
{
|
||||
tempSec->lightlevel -= 4;
|
||||
}
|
||||
tempLight++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // remove the alternate lightning flash special
|
||||
tempLight = LightningLightLevels;
|
||||
tempSec = sectors;
|
||||
for(i = 0; i < numsectors; i++, tempSec++)
|
||||
{
|
||||
if(tempSec->ceilingpic == skyflatnum
|
||||
|| tempSec->special == LIGHTNING_SPECIAL
|
||||
|| tempSec->special == LIGHTNING_SPECIAL2)
|
||||
{
|
||||
tempSec->lightlevel = *tempLight;
|
||||
tempLight++;
|
||||
}
|
||||
}
|
||||
Sky1Texture = P_GetMapSky1Texture(gamemap);
|
||||
}
|
||||
return;
|
||||
}
|
||||
LightningFlash = (P_Random()&7)+8;
|
||||
flashLight = 200+(P_Random()&31);
|
||||
tempSec = sectors;
|
||||
tempLight = LightningLightLevels;
|
||||
foundSec = false;
|
||||
for(i = 0; i < numsectors; i++, tempSec++)
|
||||
{
|
||||
if(tempSec->ceilingpic == skyflatnum
|
||||
|| tempSec->special == LIGHTNING_SPECIAL
|
||||
|| tempSec->special == LIGHTNING_SPECIAL2)
|
||||
{
|
||||
*tempLight = tempSec->lightlevel;
|
||||
if(tempSec->special == LIGHTNING_SPECIAL)
|
||||
{
|
||||
tempSec->lightlevel += 64;
|
||||
if(tempSec->lightlevel > flashLight)
|
||||
{
|
||||
tempSec->lightlevel = flashLight;
|
||||
}
|
||||
}
|
||||
else if(tempSec->special == LIGHTNING_SPECIAL2)
|
||||
{
|
||||
tempSec->lightlevel += 32;
|
||||
if(tempSec->lightlevel > flashLight)
|
||||
{
|
||||
tempSec->lightlevel = flashLight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tempSec->lightlevel = flashLight;
|
||||
}
|
||||
if(tempSec->lightlevel < *tempLight)
|
||||
{
|
||||
tempSec->lightlevel = *tempLight;
|
||||
}
|
||||
tempLight++;
|
||||
foundSec = true;
|
||||
}
|
||||
}
|
||||
if(foundSec)
|
||||
{
|
||||
Sky1Texture = P_GetMapSky2Texture(gamemap); // set alternate sky
|
||||
S_StartSound(NULL, SFX_THUNDER_CRASH);
|
||||
}
|
||||
// Calculate the next lighting flash
|
||||
if(!NextLightningFlash)
|
||||
{
|
||||
if(P_Random() < 50)
|
||||
{ // Immediate Quick flash
|
||||
NextLightningFlash = (P_Random()&15)+16;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(P_Random() < 128 && !(leveltime&32))
|
||||
{
|
||||
NextLightningFlash = ((P_Random()&7)+2)*35;
|
||||
}
|
||||
else
|
||||
{
|
||||
NextLightningFlash = ((P_Random()&15)+5)*35;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_ForceLightning
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_ForceLightning(void)
|
||||
{
|
||||
NextLightningFlash = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_InitLightning
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_InitLightning(void)
|
||||
{
|
||||
int i;
|
||||
int secCount;
|
||||
|
||||
if(!P_GetMapLightning(gamemap))
|
||||
{
|
||||
LevelHasLightning = false;
|
||||
LightningFlash = 0;
|
||||
return;
|
||||
}
|
||||
LightningFlash = 0;
|
||||
secCount = 0;
|
||||
for(i = 0; i < numsectors; i++)
|
||||
{
|
||||
if(sectors[i].ceilingpic == skyflatnum
|
||||
|| sectors[i].special == LIGHTNING_SPECIAL
|
||||
|| sectors[i].special == LIGHTNING_SPECIAL2)
|
||||
{
|
||||
secCount++;
|
||||
}
|
||||
}
|
||||
if(secCount)
|
||||
{
|
||||
LevelHasLightning = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LevelHasLightning = false;
|
||||
return;
|
||||
}
|
||||
LightningLightLevels = (int *)Z_Malloc(secCount*sizeof(int), PU_LEVEL,
|
||||
NULL);
|
||||
NextLightningFlash = ((P_Random()&15)+5)*35; // don't flash at level start
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_InitFTAnims
|
||||
//
|
||||
// Initialize flat and texture animation lists.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_InitFTAnims(void)
|
||||
{
|
||||
int base;
|
||||
int mod;
|
||||
int fd;
|
||||
animDef_t *ad;
|
||||
boolean ignore;
|
||||
boolean done;
|
||||
|
||||
fd = 0;
|
||||
ad = AnimDefs;
|
||||
AnimDefCount = 0;
|
||||
SC_Open(ANIM_SCRIPT_NAME);
|
||||
while(SC_GetString())
|
||||
{
|
||||
if(AnimDefCount == MAX_ANIM_DEFS)
|
||||
{
|
||||
I_Error("P_InitFTAnims: too many AnimDefs.");
|
||||
}
|
||||
if(SC_Compare(SCI_FLAT))
|
||||
{
|
||||
ad->type = ANIM_FLAT;
|
||||
}
|
||||
else if(SC_Compare(SCI_TEXTURE))
|
||||
{
|
||||
ad->type = ANIM_TEXTURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_ScriptError(NULL);
|
||||
}
|
||||
SC_MustGetString(); // Name
|
||||
ignore = false;
|
||||
if(ad->type == ANIM_FLAT)
|
||||
{
|
||||
if(W_CheckNumForName(sc_String) == -1)
|
||||
{
|
||||
ignore = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ad->index = R_FlatNumForName(sc_String);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Texture
|
||||
if(R_CheckTextureNumForName(sc_String) == -1)
|
||||
{
|
||||
ignore = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ad->index = R_TextureNumForName(sc_String);
|
||||
}
|
||||
}
|
||||
ad->startFrameDef = fd;
|
||||
done = false;
|
||||
while(done == false)
|
||||
{
|
||||
if(SC_GetString())
|
||||
{
|
||||
if(SC_Compare(SCI_PIC))
|
||||
{
|
||||
if(fd == MAX_FRAME_DEFS)
|
||||
{
|
||||
I_Error("P_InitFTAnims: too many FrameDefs.");
|
||||
}
|
||||
SC_MustGetNumber();
|
||||
if(ignore == false)
|
||||
{
|
||||
FrameDefs[fd].index = ad->index+sc_Number-1;
|
||||
}
|
||||
SC_MustGetString();
|
||||
if(SC_Compare(SCI_TICS))
|
||||
{
|
||||
SC_MustGetNumber();
|
||||
if(ignore == false)
|
||||
{
|
||||
FrameDefs[fd].tics = sc_Number;
|
||||
fd++;
|
||||
}
|
||||
}
|
||||
else if(SC_Compare(SCI_RAND))
|
||||
{
|
||||
SC_MustGetNumber();
|
||||
base = sc_Number;
|
||||
SC_MustGetNumber();
|
||||
if(ignore == false)
|
||||
{
|
||||
mod = sc_Number-base+1;
|
||||
FrameDefs[fd].tics = (base<<16)+(mod<<8);
|
||||
fd++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_ScriptError(NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_UnGet();
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
if((ignore == false) && (fd-ad->startFrameDef < 2))
|
||||
{
|
||||
I_Error("P_InitFTAnims: AnimDef has framecount < 2.");
|
||||
}
|
||||
if(ignore == false)
|
||||
{
|
||||
ad->endFrameDef = fd-1;
|
||||
ad->currentFrameDef = ad->endFrameDef;
|
||||
ad->tics = 1; // Force 1st game tic to animate
|
||||
AnimDefCount++;
|
||||
ad++;
|
||||
}
|
||||
}
|
||||
SC_Close();
|
||||
}
|
294
Hexen Source/P_CEILNG.C
Normal file
294
Hexen Source/P_CEILNG.C
Normal file
|
@ -0,0 +1,294 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** p_ceilng.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: p_ceilng.c,v $
|
||||
//** $Revision: 1.17 $
|
||||
//** $Date: 95/09/11 22:06:25 $
|
||||
//** $Author: cjr $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
#include "soundst.h"
|
||||
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
//
|
||||
// CEILINGS
|
||||
//
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
|
||||
ceiling_t *activeceilings[MAXCEILINGS];
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// T_MoveCeiling
|
||||
//
|
||||
//==================================================================
|
||||
void T_MoveCeiling (ceiling_t *ceiling)
|
||||
{
|
||||
result_e res;
|
||||
|
||||
switch(ceiling->direction)
|
||||
{
|
||||
// case 0: // IN STASIS
|
||||
// break;
|
||||
case 1: // UP
|
||||
res = T_MovePlane(ceiling->sector,ceiling->speed,
|
||||
ceiling->topheight, false, 1, ceiling->direction);
|
||||
if (res == RES_PASTDEST)
|
||||
{
|
||||
SN_StopSequence((mobj_t *)&ceiling->sector->soundorg);
|
||||
switch(ceiling->type)
|
||||
{
|
||||
case CLEV_CRUSHANDRAISE:
|
||||
ceiling->direction = -1;
|
||||
ceiling->speed = ceiling->speed*2;
|
||||
break;
|
||||
default:
|
||||
P_RemoveActiveCeiling(ceiling);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case -1: // DOWN
|
||||
res = T_MovePlane(ceiling->sector,ceiling->speed,
|
||||
ceiling->bottomheight, ceiling->crush, 1, ceiling->direction);
|
||||
if(res == RES_PASTDEST)
|
||||
{
|
||||
SN_StopSequence((mobj_t *)&ceiling->sector->soundorg);
|
||||
switch(ceiling->type)
|
||||
{
|
||||
case CLEV_CRUSHANDRAISE:
|
||||
case CLEV_CRUSHRAISEANDSTAY:
|
||||
ceiling->direction = 1;
|
||||
ceiling->speed = ceiling->speed/2;
|
||||
break;
|
||||
default:
|
||||
P_RemoveActiveCeiling(ceiling);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(res == RES_CRUSHED)
|
||||
{
|
||||
switch(ceiling->type)
|
||||
{
|
||||
case CLEV_CRUSHANDRAISE:
|
||||
case CLEV_LOWERANDCRUSH:
|
||||
case CLEV_CRUSHRAISEANDSTAY:
|
||||
//ceiling->speed = ceiling->speed/4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// EV_DoCeiling
|
||||
// Move a ceiling up/down and all around!
|
||||
//
|
||||
//==================================================================
|
||||
int EV_DoCeiling (line_t *line, byte *arg, ceiling_e type)
|
||||
{
|
||||
int secnum,rtn;
|
||||
sector_t *sec;
|
||||
ceiling_t *ceiling;
|
||||
|
||||
secnum = -1;
|
||||
rtn = 0;
|
||||
|
||||
/* Old Ceiling stasis code
|
||||
//
|
||||
// Reactivate in-stasis ceilings...for certain types.
|
||||
//
|
||||
switch(type)
|
||||
{
|
||||
case CLEV_CRUSHANDRAISE:
|
||||
P_ActivateInStasisCeiling(line);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*/
|
||||
while ((secnum = P_FindSectorFromTag(arg[0], secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
if (sec->specialdata)
|
||||
continue;
|
||||
|
||||
//
|
||||
// new door thinker
|
||||
//
|
||||
rtn = 1;
|
||||
ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0);
|
||||
P_AddThinker (&ceiling->thinker);
|
||||
sec->specialdata = ceiling;
|
||||
ceiling->thinker.function = T_MoveCeiling;
|
||||
ceiling->sector = sec;
|
||||
ceiling->crush = 0;
|
||||
ceiling->speed = arg[1]*(FRACUNIT/8);
|
||||
switch(type)
|
||||
{
|
||||
case CLEV_CRUSHRAISEANDSTAY:
|
||||
ceiling->crush = arg[2]; // arg[2] = crushing value
|
||||
ceiling->topheight = sec->ceilingheight;
|
||||
ceiling->bottomheight = sec->floorheight + (8*FRACUNIT);
|
||||
ceiling->direction = -1;
|
||||
break;
|
||||
case CLEV_CRUSHANDRAISE:
|
||||
ceiling->topheight = sec->ceilingheight;
|
||||
case CLEV_LOWERANDCRUSH:
|
||||
ceiling->crush = arg[2]; // arg[2] = crushing value
|
||||
case CLEV_LOWERTOFLOOR:
|
||||
ceiling->bottomheight = sec->floorheight;
|
||||
if(type != CLEV_LOWERTOFLOOR)
|
||||
{
|
||||
ceiling->bottomheight += 8*FRACUNIT;
|
||||
}
|
||||
ceiling->direction = -1;
|
||||
break;
|
||||
case CLEV_RAISETOHIGHEST:
|
||||
ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
|
||||
ceiling->direction = 1;
|
||||
break;
|
||||
case CLEV_LOWERBYVALUE:
|
||||
ceiling->bottomheight = sec->ceilingheight-arg[2]*FRACUNIT;
|
||||
ceiling->direction = -1;
|
||||
break;
|
||||
case CLEV_RAISEBYVALUE:
|
||||
ceiling->topheight = sec->ceilingheight+arg[2]*FRACUNIT;
|
||||
ceiling->direction = 1;
|
||||
break;
|
||||
case CLEV_MOVETOVALUETIMES8:
|
||||
{
|
||||
int destHeight = arg[2]*FRACUNIT*8;
|
||||
|
||||
if(arg[3])
|
||||
{
|
||||
destHeight = -destHeight;
|
||||
}
|
||||
if(sec->ceilingheight <= destHeight)
|
||||
{
|
||||
ceiling->direction = 1;
|
||||
ceiling->topheight = destHeight;
|
||||
if(sec->ceilingheight == destHeight)
|
||||
{
|
||||
rtn = 0;
|
||||
}
|
||||
}
|
||||
else if(sec->ceilingheight > destHeight)
|
||||
{
|
||||
ceiling->direction = -1;
|
||||
ceiling->bottomheight = destHeight;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rtn = 0;
|
||||
break;
|
||||
}
|
||||
ceiling->tag = sec->tag;
|
||||
ceiling->type = type;
|
||||
P_AddActiveCeiling(ceiling);
|
||||
if(rtn)
|
||||
{
|
||||
SN_StartSequence((mobj_t *)&ceiling->sector->soundorg,
|
||||
SEQ_PLATFORM+ceiling->sector->seqType);
|
||||
}
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// Add an active ceiling
|
||||
//
|
||||
//==================================================================
|
||||
void P_AddActiveCeiling(ceiling_t *c)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAXCEILINGS;i++)
|
||||
if (activeceilings[i] == NULL)
|
||||
{
|
||||
activeceilings[i] = c;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// Remove a ceiling's thinker
|
||||
//
|
||||
//==================================================================
|
||||
void P_RemoveActiveCeiling(ceiling_t *c)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0;i < MAXCEILINGS;i++)
|
||||
if (activeceilings[i] == c)
|
||||
{
|
||||
activeceilings[i]->sector->specialdata = NULL;
|
||||
P_RemoveThinker (&activeceilings[i]->thinker);
|
||||
P_TagFinished(activeceilings[i]->sector->tag);
|
||||
activeceilings[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
//==================================================================
|
||||
//
|
||||
// Restart a ceiling that's in-stasis
|
||||
//
|
||||
//==================================================================
|
||||
void P_ActivateInStasisCeiling(line_t *line)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0;i < MAXCEILINGS;i++)
|
||||
if (activeceilings[i] && (activeceilings[i]->tag == line->arg1) &&
|
||||
(activeceilings[i]->direction == 0))
|
||||
{
|
||||
activeceilings[i]->direction = activeceilings[i]->olddirection;
|
||||
activeceilings[i]->thinker.function = T_MoveCeiling;
|
||||
SN_StartSequence((mobj_t *)&activeceilings[i]->sector->soundorg,
|
||||
SEQ_PLATFORM+activeceilings[i]->sector->seqType);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// EV_CeilingCrushStop
|
||||
// Stop a ceiling from crushing!
|
||||
//
|
||||
//==================================================================
|
||||
|
||||
int EV_CeilingCrushStop(line_t *line, byte *args)
|
||||
{
|
||||
int i;
|
||||
int rtn;
|
||||
|
||||
rtn = 0;
|
||||
for (i = 0;i < MAXCEILINGS;i++)
|
||||
{
|
||||
if(activeceilings[i] && activeceilings[i]->tag == args[0])
|
||||
{
|
||||
rtn = 1;
|
||||
SN_StopSequence((mobj_t*)&activeceilings[i]->sector->soundorg);
|
||||
activeceilings[i]->sector->specialdata = NULL;
|
||||
P_RemoveThinker (&activeceilings[i]->thinker);
|
||||
P_TagFinished(activeceilings[i]->sector->tag);
|
||||
activeceilings[i] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rtn;
|
||||
}
|
314
Hexen Source/P_DOORS.C
Normal file
314
Hexen Source/P_DOORS.C
Normal file
|
@ -0,0 +1,314 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** p_doors.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: p_doors.c,v $
|
||||
//** $Revision: 1.13 $
|
||||
//** $Date: 96/01/06 03:23:47 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
#include "soundst.h"
|
||||
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
//
|
||||
// VERTICAL DOORS
|
||||
//
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// T_VerticalDoor
|
||||
//
|
||||
//==================================================================
|
||||
void T_VerticalDoor(vldoor_t *door)
|
||||
{
|
||||
result_e res;
|
||||
|
||||
switch(door->direction)
|
||||
{
|
||||
case 0: // WAITING
|
||||
if(!--door->topcountdown)
|
||||
switch(door->type)
|
||||
{
|
||||
case DREV_NORMAL:
|
||||
door->direction = -1; // time to go back down
|
||||
SN_StartSequence((mobj_t *)&door->sector->soundorg,
|
||||
SEQ_DOOR_STONE+door->sector->seqType);
|
||||
break;
|
||||
case DREV_CLOSE30THENOPEN:
|
||||
door->direction = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2: // INITIAL WAIT
|
||||
if(!--door->topcountdown)
|
||||
{
|
||||
switch(door->type)
|
||||
{
|
||||
case DREV_RAISEIN5MINS:
|
||||
door->direction = 1;
|
||||
door->type = DREV_NORMAL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case -1: // DOWN
|
||||
res = T_MovePlane(door->sector, door->speed,
|
||||
door->sector->floorheight, false, 1, door->direction);
|
||||
if(res == RES_PASTDEST)
|
||||
{
|
||||
SN_StopSequence((mobj_t *)&door->sector->soundorg);
|
||||
switch(door->type)
|
||||
{
|
||||
case DREV_NORMAL:
|
||||
case DREV_CLOSE:
|
||||
door->sector->specialdata = NULL;
|
||||
P_TagFinished(door->sector->tag);
|
||||
P_RemoveThinker(&door->thinker); // unlink and free
|
||||
break;
|
||||
case DREV_CLOSE30THENOPEN:
|
||||
door->direction = 0;
|
||||
door->topcountdown = 35*30;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(res == RES_CRUSHED)
|
||||
{
|
||||
switch(door->type)
|
||||
{
|
||||
case DREV_CLOSE: // DON'T GO BACK UP!
|
||||
break;
|
||||
default:
|
||||
door->direction = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: // UP
|
||||
res = T_MovePlane(door->sector, door->speed,
|
||||
door->topheight, false, 1, door->direction);
|
||||
if(res == RES_PASTDEST)
|
||||
{
|
||||
SN_StopSequence((mobj_t *)&door->sector->soundorg);
|
||||
switch(door->type)
|
||||
{
|
||||
case DREV_NORMAL:
|
||||
door->direction = 0; // wait at top
|
||||
door->topcountdown = door->topwait;
|
||||
break;
|
||||
case DREV_CLOSE30THENOPEN:
|
||||
case DREV_OPEN:
|
||||
door->sector->specialdata = NULL;
|
||||
P_TagFinished(door->sector->tag);
|
||||
P_RemoveThinker (&door->thinker); // unlink and free
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// EV_DoDoor
|
||||
//
|
||||
// Move a door up/down
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
int EV_DoDoor(line_t *line, byte *args, vldoor_e type)
|
||||
{
|
||||
int secnum;
|
||||
int retcode;
|
||||
sector_t *sec;
|
||||
vldoor_t *door;
|
||||
fixed_t speed;
|
||||
|
||||
speed = args[1]*FRACUNIT/8;
|
||||
secnum = -1;
|
||||
retcode = 0;
|
||||
while((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
if(sec->specialdata)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Add new door thinker
|
||||
retcode = 1;
|
||||
door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
|
||||
P_AddThinker(&door->thinker);
|
||||
sec->specialdata = door;
|
||||
door->thinker.function = T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
switch(type)
|
||||
{
|
||||
case DREV_CLOSE:
|
||||
door->topheight = P_FindLowestCeilingSurrounding(sec);
|
||||
door->topheight -= 4*FRACUNIT;
|
||||
door->direction = -1;
|
||||
break;
|
||||
case DREV_CLOSE30THENOPEN:
|
||||
door->topheight = sec->ceilingheight;
|
||||
door->direction = -1;
|
||||
break;
|
||||
case DREV_NORMAL:
|
||||
case DREV_OPEN:
|
||||
door->direction = 1;
|
||||
door->topheight = P_FindLowestCeilingSurrounding(sec);
|
||||
door->topheight -= 4*FRACUNIT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
door->type = type;
|
||||
door->speed = speed;
|
||||
door->topwait = args[2]; // line->arg3
|
||||
SN_StartSequence((mobj_t *)&door->sector->soundorg,
|
||||
SEQ_DOOR_STONE+door->sector->seqType);
|
||||
}
|
||||
return(retcode);
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// EV_VerticalDoor : open a door manually, no tag value
|
||||
//
|
||||
//==================================================================
|
||||
boolean EV_VerticalDoor(line_t *line, mobj_t *thing)
|
||||
{
|
||||
int secnum;
|
||||
sector_t *sec;
|
||||
vldoor_t *door;
|
||||
int side;
|
||||
|
||||
side = 0; // only front sides can be used
|
||||
|
||||
// if the sector has an active thinker, use it
|
||||
sec = sides[line->sidenum[side^1]].sector;
|
||||
secnum = sec-sectors;
|
||||
if(sec->specialdata)
|
||||
{
|
||||
return false;
|
||||
/*
|
||||
door = sec->specialdata;
|
||||
switch(line->special)
|
||||
{ // only for raise doors
|
||||
case 12:
|
||||
if(door->direction == -1)
|
||||
{
|
||||
door->direction = 1; // go back up
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!thing->player)
|
||||
{ // Monsters don't close doors
|
||||
return;
|
||||
}
|
||||
door->direction = -1; // start going down immediately
|
||||
}
|
||||
return;
|
||||
}
|
||||
*/
|
||||
}
|
||||
//
|
||||
// new door thinker
|
||||
//
|
||||
door = Z_Malloc (sizeof(*door), PU_LEVSPEC, 0);
|
||||
P_AddThinker(&door->thinker);
|
||||
sec->specialdata = door;
|
||||
door->thinker.function = T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
door->direction = 1;
|
||||
switch(line->special)
|
||||
{
|
||||
case 11:
|
||||
door->type = DREV_OPEN;
|
||||
line->special = 0;
|
||||
break;
|
||||
case 12:
|
||||
case 13:
|
||||
door->type = DREV_NORMAL;
|
||||
break;
|
||||
default:
|
||||
door->type = DREV_NORMAL;
|
||||
break;
|
||||
}
|
||||
door->speed = line->arg2*(FRACUNIT/8);
|
||||
door->topwait = line->arg3;
|
||||
|
||||
//
|
||||
// find the top and bottom of the movement range
|
||||
//
|
||||
door->topheight = P_FindLowestCeilingSurrounding(sec);
|
||||
door->topheight -= 4*FRACUNIT;
|
||||
SN_StartSequence((mobj_t *)&door->sector->soundorg,
|
||||
SEQ_DOOR_STONE+door->sector->seqType);
|
||||
return true;
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// Spawn a door that closes after 30 seconds
|
||||
//
|
||||
//==================================================================
|
||||
|
||||
/*
|
||||
void P_SpawnDoorCloseIn30(sector_t *sec)
|
||||
{
|
||||
vldoor_t *door;
|
||||
|
||||
door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
|
||||
P_AddThinker(&door->thinker);
|
||||
sec->specialdata = door;
|
||||
sec->special = 0;
|
||||
door->thinker.function = T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
door->direction = 0;
|
||||
door->type = DREV_NORMAL;
|
||||
door->speed = VDOORSPEED;
|
||||
door->topcountdown = 30*35;
|
||||
}
|
||||
*/
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// Spawn a door that opens after 5 minutes
|
||||
//
|
||||
//==================================================================
|
||||
|
||||
/*
|
||||
void P_SpawnDoorRaiseIn5Mins(sector_t *sec, int secnum)
|
||||
{
|
||||
vldoor_t *door;
|
||||
|
||||
door = Z_Malloc(sizeof(*door), PU_LEVSPEC, 0);
|
||||
P_AddThinker(&door->thinker);
|
||||
sec->specialdata = door;
|
||||
sec->special = 0;
|
||||
door->thinker.function = T_VerticalDoor;
|
||||
door->sector = sec;
|
||||
door->direction = 2;
|
||||
door->type = DREV_RAISEIN5MINS;
|
||||
door->speed = VDOORSPEED;
|
||||
door->topheight = P_FindLowestCeilingSurrounding(sec);
|
||||
door->topheight -= 4*FRACUNIT;
|
||||
door->topwait = VDOORWAIT;
|
||||
door->topcountdown = 5*60*35;
|
||||
}
|
||||
*/
|
5308
Hexen Source/P_ENEMY.C
Normal file
5308
Hexen Source/P_ENEMY.C
Normal file
File diff suppressed because it is too large
Load diff
931
Hexen Source/P_FLOOR.C
Normal file
931
Hexen Source/P_FLOOR.C
Normal file
|
@ -0,0 +1,931 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** p_floor.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: p_floor.c,v $
|
||||
//** $Revision: 1.23 $
|
||||
//** $Date: 95/10/06 16:53:19 $
|
||||
//** $Author: paul $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
#include "soundst.h"
|
||||
|
||||
extern fixed_t FloatBobOffsets[64];
|
||||
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
//
|
||||
// FLOORS
|
||||
//
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// Move a plane (floor or ceiling) and check for crushing
|
||||
//
|
||||
//==================================================================
|
||||
result_e T_MovePlane(sector_t *sector,fixed_t speed,
|
||||
fixed_t dest, int crush,int floorOrCeiling,int direction)
|
||||
{
|
||||
boolean flag;
|
||||
fixed_t lastpos;
|
||||
|
||||
switch(floorOrCeiling)
|
||||
{
|
||||
case 0: // FLOOR
|
||||
switch(direction)
|
||||
{
|
||||
case -1: // DOWN
|
||||
if (sector->floorheight - speed < dest)
|
||||
{
|
||||
lastpos = sector->floorheight;
|
||||
sector->floorheight = dest;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
if (flag == true)
|
||||
{
|
||||
sector->floorheight =lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
//return RES_CRUSHED;
|
||||
}
|
||||
return RES_PASTDEST;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastpos = sector->floorheight;
|
||||
sector->floorheight -= speed;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
if (flag == true)
|
||||
{
|
||||
sector->floorheight = lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
return RES_CRUSHED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // UP
|
||||
if (sector->floorheight + speed > dest)
|
||||
{
|
||||
lastpos = sector->floorheight;
|
||||
sector->floorheight = dest;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
if (flag == true)
|
||||
{
|
||||
sector->floorheight = lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
//return RES_CRUSHED;
|
||||
}
|
||||
return RES_PASTDEST;
|
||||
}
|
||||
else // COULD GET CRUSHED
|
||||
{
|
||||
lastpos = sector->floorheight;
|
||||
sector->floorheight += speed;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
if (flag == true)
|
||||
{
|
||||
//if (crush == true)
|
||||
//{
|
||||
// return RES_CRUSHED;
|
||||
//}
|
||||
sector->floorheight = lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
return RES_CRUSHED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // CEILING
|
||||
switch(direction)
|
||||
{
|
||||
case -1: // DOWN
|
||||
if (sector->ceilingheight - speed < dest)
|
||||
{
|
||||
lastpos = sector->ceilingheight;
|
||||
sector->ceilingheight = dest;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
if (flag == true)
|
||||
{
|
||||
sector->ceilingheight = lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
//return RES_CRUSHED;
|
||||
}
|
||||
return RES_PASTDEST;
|
||||
}
|
||||
else // COULD GET CRUSHED
|
||||
{
|
||||
lastpos = sector->ceilingheight;
|
||||
sector->ceilingheight -= speed;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
if (flag == true)
|
||||
{
|
||||
//if (crush == true)
|
||||
//{
|
||||
// return RES_CRUSHED;
|
||||
//}
|
||||
sector->ceilingheight = lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
return RES_CRUSHED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // UP
|
||||
if (sector->ceilingheight + speed > dest)
|
||||
{
|
||||
lastpos = sector->ceilingheight;
|
||||
sector->ceilingheight = dest;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
if (flag == true)
|
||||
{
|
||||
sector->ceilingheight = lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
//return RES_CRUSHED;
|
||||
}
|
||||
return RES_PASTDEST;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastpos = sector->ceilingheight;
|
||||
sector->ceilingheight += speed;
|
||||
flag = P_ChangeSector(sector,crush);
|
||||
#if 0
|
||||
if (flag == true)
|
||||
{
|
||||
sector->ceilingheight = lastpos;
|
||||
P_ChangeSector(sector,crush);
|
||||
return RES_CRUSHED;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
return RES_OK;
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// MOVE A FLOOR TO IT'S DESTINATION (UP OR DOWN)
|
||||
//
|
||||
//==================================================================
|
||||
void T_MoveFloor(floormove_t *floor)
|
||||
{
|
||||
result_e res;
|
||||
|
||||
if(floor->resetDelayCount)
|
||||
{
|
||||
floor->resetDelayCount--;
|
||||
if(!floor->resetDelayCount)
|
||||
{
|
||||
floor->floordestheight = floor->resetHeight;
|
||||
floor->direction = -floor->direction;
|
||||
floor->resetDelay = 0;
|
||||
floor->delayCount = 0;
|
||||
floor->delayTotal = 0;
|
||||
}
|
||||
}
|
||||
if(floor->delayCount)
|
||||
{
|
||||
floor->delayCount--;
|
||||
if(!floor->delayCount && floor->textureChange)
|
||||
{
|
||||
floor->sector->floorpic += floor->textureChange;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
res = T_MovePlane(floor->sector,floor->speed,
|
||||
floor->floordestheight,floor->crush,0,floor->direction);
|
||||
|
||||
if(floor->type == FLEV_RAISEBUILDSTEP)
|
||||
{
|
||||
if((floor->direction == 1 && floor->sector->floorheight >=
|
||||
floor->stairsDelayHeight) || (floor->direction == -1 &&
|
||||
floor->sector->floorheight <= floor->stairsDelayHeight))
|
||||
{
|
||||
floor->delayCount = floor->delayTotal;
|
||||
floor->stairsDelayHeight += floor->stairsDelayHeightDelta;
|
||||
}
|
||||
}
|
||||
if (res == RES_PASTDEST)
|
||||
{
|
||||
SN_StopSequence((mobj_t *)&floor->sector->soundorg);
|
||||
if(floor->delayTotal)
|
||||
{
|
||||
floor->delayTotal = 0;
|
||||
}
|
||||
if(floor->resetDelay)
|
||||
{
|
||||
// floor->resetDelayCount = floor->resetDelay;
|
||||
// floor->resetDelay = 0;
|
||||
return;
|
||||
}
|
||||
floor->sector->specialdata = NULL;
|
||||
/*
|
||||
if (floor->direction == 1)
|
||||
switch(floor->type)
|
||||
{
|
||||
case donutRaise:
|
||||
floor->sector->special = floor->newspecial;
|
||||
floor->sector->floorpic = floor->texture;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else if (floor->direction == -1)
|
||||
switch(floor->type)
|
||||
{
|
||||
case lowerAndChange:
|
||||
floor->sector->special = floor->newspecial;
|
||||
floor->sector->floorpic = floor->texture;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*/
|
||||
if(floor->textureChange)
|
||||
{
|
||||
floor->sector->floorpic -= floor->textureChange;
|
||||
}
|
||||
P_TagFinished(floor->sector->tag);
|
||||
P_RemoveThinker(&floor->thinker);
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// HANDLE FLOOR TYPES
|
||||
//
|
||||
//==================================================================
|
||||
int EV_DoFloor(line_t *line, byte *args, floor_e floortype)
|
||||
{
|
||||
int secnum;
|
||||
int rtn;
|
||||
sector_t *sec;
|
||||
floormove_t *floor=NULL;
|
||||
|
||||
secnum = -1;
|
||||
rtn = 0;
|
||||
while ((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
|
||||
// ALREADY MOVING? IF SO, KEEP GOING...
|
||||
if (sec->specialdata)
|
||||
continue;
|
||||
|
||||
//
|
||||
// new floor thinker
|
||||
//
|
||||
rtn = 1;
|
||||
floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
|
||||
memset(floor, 0, sizeof(*floor));
|
||||
P_AddThinker (&floor->thinker);
|
||||
sec->specialdata = floor;
|
||||
floor->thinker.function = T_MoveFloor;
|
||||
floor->type = floortype;
|
||||
floor->crush = 0;
|
||||
floor->speed = args[1]*(FRACUNIT/8);
|
||||
if(floortype == FLEV_LOWERTIMES8INSTANT ||
|
||||
floortype == FLEV_RAISETIMES8INSTANT)
|
||||
{
|
||||
floor->speed = 2000<<FRACBITS;
|
||||
}
|
||||
switch(floortype)
|
||||
{
|
||||
case FLEV_LOWERFLOOR:
|
||||
floor->direction = -1;
|
||||
floor->sector = sec;
|
||||
floor->floordestheight =
|
||||
P_FindHighestFloorSurrounding(sec);
|
||||
break;
|
||||
case FLEV_LOWERFLOORTOLOWEST:
|
||||
floor->direction = -1;
|
||||
floor->sector = sec;
|
||||
floor->floordestheight =
|
||||
P_FindLowestFloorSurrounding(sec);
|
||||
break;
|
||||
case FLEV_LOWERFLOORBYVALUE:
|
||||
floor->direction = -1;
|
||||
floor->sector = sec;
|
||||
floor->floordestheight = floor->sector->floorheight-
|
||||
args[2]*FRACUNIT;
|
||||
break;
|
||||
case FLEV_LOWERTIMES8INSTANT:
|
||||
case FLEV_LOWERBYVALUETIMES8:
|
||||
floor->direction = -1;
|
||||
floor->sector = sec;
|
||||
floor->floordestheight = floor->sector->floorheight-
|
||||
args[2]*FRACUNIT*8;
|
||||
break;
|
||||
case FLEV_RAISEFLOORCRUSH:
|
||||
floor->crush = args[2]; // arg[2] = crushing value
|
||||
floor->direction = 1;
|
||||
floor->sector = sec;
|
||||
floor->floordestheight = sec->ceilingheight-8*FRACUNIT;
|
||||
break;
|
||||
case FLEV_RAISEFLOOR:
|
||||
floor->direction = 1;
|
||||
floor->sector = sec;
|
||||
floor->floordestheight =
|
||||
P_FindLowestCeilingSurrounding(sec);
|
||||
if (floor->floordestheight > sec->ceilingheight)
|
||||
floor->floordestheight = sec->ceilingheight;
|
||||
break;
|
||||
case FLEV_RAISEFLOORTONEAREST:
|
||||
floor->direction = 1;
|
||||
floor->sector = sec;
|
||||
floor->floordestheight =
|
||||
P_FindNextHighestFloor(sec,sec->floorheight);
|
||||
break;
|
||||
case FLEV_RAISEFLOORBYVALUE:
|
||||
floor->direction = 1;
|
||||
floor->sector = sec;
|
||||
floor->floordestheight = floor->sector->floorheight+
|
||||
args[2]*FRACUNIT;
|
||||
break;
|
||||
case FLEV_RAISETIMES8INSTANT:
|
||||
case FLEV_RAISEBYVALUETIMES8:
|
||||
floor->direction = 1;
|
||||
floor->sector = sec;
|
||||
floor->floordestheight = floor->sector->floorheight+
|
||||
args[2]*FRACUNIT*8;
|
||||
break;
|
||||
case FLEV_MOVETOVALUETIMES8:
|
||||
floor->sector = sec;
|
||||
floor->floordestheight = args[2]*FRACUNIT*8;
|
||||
if(args[3])
|
||||
{
|
||||
floor->floordestheight = -floor->floordestheight;
|
||||
}
|
||||
if(floor->floordestheight > floor->sector->floorheight)
|
||||
{
|
||||
floor->direction = 1;
|
||||
}
|
||||
else if(floor->floordestheight < floor->sector->floorheight)
|
||||
{
|
||||
floor->direction = -1;
|
||||
}
|
||||
else
|
||||
{ // already at lowest position
|
||||
rtn = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rtn = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(rtn)
|
||||
{
|
||||
SN_StartSequence((mobj_t *)&floor->sector->soundorg,
|
||||
SEQ_PLATFORM+floor->sector->seqType);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// EV_DoFloorAndCeiling
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
int EV_DoFloorAndCeiling(line_t *line, byte *args, boolean raise)
|
||||
{
|
||||
boolean floor, ceiling;
|
||||
int secnum;
|
||||
sector_t *sec;
|
||||
|
||||
if(raise)
|
||||
{
|
||||
floor = EV_DoFloor(line, args, FLEV_RAISEFLOORBYVALUE);
|
||||
secnum = -1;
|
||||
while((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
sec->specialdata = NULL;
|
||||
}
|
||||
ceiling = EV_DoCeiling(line, args, CLEV_RAISEBYVALUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
floor = EV_DoFloor(line, args, FLEV_LOWERFLOORBYVALUE);
|
||||
secnum = -1;
|
||||
while ((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
sec->specialdata = NULL;
|
||||
}
|
||||
ceiling = EV_DoCeiling(line, args, CLEV_LOWERBYVALUE);
|
||||
}
|
||||
return (floor|ceiling);
|
||||
}
|
||||
|
||||
// ===== Build Stairs Private Data =====
|
||||
|
||||
#define STAIR_SECTOR_TYPE 26
|
||||
#define STAIR_QUEUE_SIZE 32
|
||||
|
||||
struct
|
||||
{
|
||||
sector_t *sector;
|
||||
int type;
|
||||
int height;
|
||||
} StairQueue[STAIR_QUEUE_SIZE];
|
||||
|
||||
static int QueueHead;
|
||||
static int QueueTail;
|
||||
|
||||
static int StepDelta;
|
||||
static int Direction;
|
||||
static int Speed;
|
||||
static int Texture;
|
||||
static int StartDelay;
|
||||
static int StartDelayDelta;
|
||||
static int TextureChange;
|
||||
static int StartHeight;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// QueueStairSector
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void QueueStairSector(sector_t *sec, int type, int height)
|
||||
{
|
||||
if((QueueTail+1)%STAIR_QUEUE_SIZE == QueueHead)
|
||||
{
|
||||
I_Error("BuildStairs: Too many branches located.\n");
|
||||
}
|
||||
StairQueue[QueueTail].sector = sec;
|
||||
StairQueue[QueueTail].type = type;
|
||||
StairQueue[QueueTail].height = height;
|
||||
|
||||
QueueTail = (QueueTail+1)%STAIR_QUEUE_SIZE;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DequeueStairSector
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static sector_t *DequeueStairSector(int *type, int *height)
|
||||
{
|
||||
sector_t *sec;
|
||||
|
||||
if(QueueHead == QueueTail)
|
||||
{ // queue is empty
|
||||
return NULL;
|
||||
}
|
||||
*type = StairQueue[QueueHead].type;
|
||||
*height = StairQueue[QueueHead].height;
|
||||
sec = StairQueue[QueueHead].sector;
|
||||
QueueHead = (QueueHead+1)%STAIR_QUEUE_SIZE;
|
||||
|
||||
return sec;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ProcessStairSector
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ProcessStairSector(sector_t *sec, int type, int height,
|
||||
stairs_e stairsType, int delay, int resetDelay)
|
||||
{
|
||||
int i;
|
||||
sector_t *tsec;
|
||||
floormove_t *floor;
|
||||
|
||||
//
|
||||
// new floor thinker
|
||||
//
|
||||
height += StepDelta;
|
||||
floor = Z_Malloc(sizeof(*floor), PU_LEVSPEC, 0);
|
||||
memset(floor, 0, sizeof(*floor));
|
||||
P_AddThinker(&floor->thinker);
|
||||
sec->specialdata = floor;
|
||||
floor->thinker.function = T_MoveFloor;
|
||||
floor->type = FLEV_RAISEBUILDSTEP;
|
||||
floor->direction = Direction;
|
||||
floor->sector = sec;
|
||||
floor->floordestheight = height;
|
||||
switch(stairsType)
|
||||
{
|
||||
case STAIRS_NORMAL:
|
||||
floor->speed = Speed;
|
||||
if(delay)
|
||||
{
|
||||
floor->delayTotal = delay;
|
||||
floor->stairsDelayHeight = sec->floorheight+StepDelta;
|
||||
floor->stairsDelayHeightDelta = StepDelta;
|
||||
}
|
||||
floor->resetDelay = resetDelay;
|
||||
floor->resetDelayCount = resetDelay;
|
||||
floor->resetHeight = sec->floorheight;
|
||||
break;
|
||||
case STAIRS_SYNC:
|
||||
floor->speed = FixedMul(Speed, FixedDiv(height-StartHeight,
|
||||
StepDelta));
|
||||
floor->resetDelay = delay; //arg4
|
||||
floor->resetDelayCount = delay;
|
||||
floor->resetHeight = sec->floorheight;
|
||||
break;
|
||||
/*
|
||||
case STAIRS_PHASED:
|
||||
floor->floordestheight = sec->floorheight+StepDelta;
|
||||
floor->speed = Speed;
|
||||
floor->delayCount = StartDelay;
|
||||
StartDelay += StartDelayDelta;
|
||||
floor->textureChange = TextureChange;
|
||||
floor->resetDelayCount = StartDelay;
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SN_StartSequence((mobj_t *)&sec->soundorg, SEQ_PLATFORM+sec->seqType);
|
||||
//
|
||||
// Find next sector to raise
|
||||
// Find nearby sector with sector special equal to type
|
||||
//
|
||||
for (i = 0; i < sec->linecount; i++)
|
||||
{
|
||||
if(!((sec->lines[i])->flags&ML_TWOSIDED))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
tsec = (sec->lines[i])->frontsector;
|
||||
if(tsec->special == type+STAIR_SECTOR_TYPE && !tsec->specialdata
|
||||
&& tsec->floorpic == Texture && tsec->validcount != validcount)
|
||||
{
|
||||
QueueStairSector(tsec, type^1, height);
|
||||
tsec->validcount = validcount;
|
||||
//tsec->special = 0;
|
||||
}
|
||||
tsec = (sec->lines[i])->backsector;
|
||||
if(tsec->special == type+STAIR_SECTOR_TYPE && !tsec->specialdata
|
||||
&& tsec->floorpic == Texture && tsec->validcount != validcount)
|
||||
{
|
||||
QueueStairSector(tsec, type^1, height);
|
||||
tsec->validcount = validcount;
|
||||
//tsec->special = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// BUILD A STAIRCASE!
|
||||
//
|
||||
// Direction is either positive or negative, denoting build stairs
|
||||
// up or down.
|
||||
//==================================================================
|
||||
|
||||
int EV_BuildStairs(line_t *line, byte *args, int direction,
|
||||
stairs_e stairsType)
|
||||
{
|
||||
int secnum;
|
||||
int height;
|
||||
int delay;
|
||||
int resetDelay;
|
||||
sector_t *sec;
|
||||
sector_t *qSec;
|
||||
int type;
|
||||
|
||||
// Set global stairs variables
|
||||
TextureChange = 0;
|
||||
Direction = direction;
|
||||
StepDelta = Direction*(args[2]*FRACUNIT);
|
||||
Speed = args[1]*(FRACUNIT/8);
|
||||
resetDelay = args[4];
|
||||
delay = args[3];
|
||||
if(stairsType == STAIRS_PHASED)
|
||||
{
|
||||
StartDelayDelta = args[3];
|
||||
StartDelay = StartDelayDelta;
|
||||
resetDelay = StartDelayDelta;
|
||||
delay = 0;
|
||||
TextureChange = args[4];
|
||||
}
|
||||
|
||||
secnum = -1;
|
||||
|
||||
validcount++;
|
||||
while ((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
|
||||
Texture = sec->floorpic;
|
||||
StartHeight = sec->floorheight;
|
||||
|
||||
// ALREADY MOVING? IF SO, KEEP GOING...
|
||||
if (sec->specialdata)
|
||||
continue;
|
||||
|
||||
QueueStairSector(sec, 0, sec->floorheight);
|
||||
sec->special = 0;
|
||||
}
|
||||
while((qSec = DequeueStairSector(&type, &height)) != NULL)
|
||||
{
|
||||
ProcessStairSector(qSec, type, height, stairsType, delay, resetDelay);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
//
|
||||
// T_BuildPillar
|
||||
//
|
||||
//=========================================================================
|
||||
|
||||
void T_BuildPillar(pillar_t *pillar)
|
||||
{
|
||||
result_e res1;
|
||||
result_e res2;
|
||||
|
||||
// First, raise the floor
|
||||
res1 = T_MovePlane(pillar->sector, pillar->floorSpeed, pillar->floordest,
|
||||
pillar->crush, 0, pillar->direction); // floorOrCeiling, direction
|
||||
// Then, lower the ceiling
|
||||
res2 = T_MovePlane(pillar->sector, pillar->ceilingSpeed,
|
||||
pillar->ceilingdest, pillar->crush, 1, -pillar->direction);
|
||||
if (res1 == RES_PASTDEST && res2 == RES_PASTDEST)
|
||||
{
|
||||
pillar->sector->specialdata = NULL;
|
||||
SN_StopSequence((mobj_t *)&pillar->sector->soundorg);
|
||||
P_TagFinished(pillar->sector->tag);
|
||||
P_RemoveThinker(&pillar->thinker);
|
||||
}
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
//
|
||||
// EV_BuildPillar
|
||||
//
|
||||
//=========================================================================
|
||||
|
||||
int EV_BuildPillar(line_t *line, byte *args, boolean crush)
|
||||
{
|
||||
int secnum;
|
||||
sector_t *sec;
|
||||
pillar_t *pillar;
|
||||
int newHeight;
|
||||
int rtn;
|
||||
|
||||
rtn = 0;
|
||||
secnum = -1;
|
||||
while((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
if(sec->specialdata)
|
||||
continue; // already moving
|
||||
if(sec->floorheight == sec->ceilingheight)
|
||||
{ // pillar is already closed
|
||||
continue;
|
||||
}
|
||||
rtn = 1;
|
||||
if(!args[2])
|
||||
{
|
||||
newHeight = sec->floorheight+
|
||||
((sec->ceilingheight-sec->floorheight)/2);
|
||||
}
|
||||
else
|
||||
{
|
||||
newHeight = sec->floorheight+(args[2]<<FRACBITS);
|
||||
}
|
||||
|
||||
pillar = Z_Malloc(sizeof(*pillar), PU_LEVSPEC, 0);
|
||||
sec->specialdata = pillar;
|
||||
P_AddThinker(&pillar->thinker);
|
||||
pillar->thinker.function = T_BuildPillar;
|
||||
pillar->sector = sec;
|
||||
if(!args[2])
|
||||
{
|
||||
pillar->ceilingSpeed = pillar->floorSpeed = args[1]*(FRACUNIT/8);
|
||||
}
|
||||
else if(newHeight-sec->floorheight > sec->ceilingheight-newHeight)
|
||||
{
|
||||
pillar->floorSpeed = args[1]*(FRACUNIT/8);
|
||||
pillar->ceilingSpeed = FixedMul(sec->ceilingheight-newHeight,
|
||||
FixedDiv(pillar->floorSpeed, newHeight-sec->floorheight));
|
||||
}
|
||||
else
|
||||
{
|
||||
pillar->ceilingSpeed = args[1]*(FRACUNIT/8);
|
||||
pillar->floorSpeed = FixedMul(newHeight-sec->floorheight,
|
||||
FixedDiv(pillar->ceilingSpeed, sec->ceilingheight-newHeight));
|
||||
}
|
||||
pillar->floordest = newHeight;
|
||||
pillar->ceilingdest = newHeight;
|
||||
pillar->direction = 1;
|
||||
pillar->crush = crush*args[3];
|
||||
SN_StartSequence((mobj_t *)&pillar->sector->soundorg,
|
||||
SEQ_PLATFORM+pillar->sector->seqType);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
//
|
||||
// EV_OpenPillar
|
||||
//
|
||||
//=========================================================================
|
||||
|
||||
int EV_OpenPillar(line_t *line, byte *args)
|
||||
{
|
||||
int secnum;
|
||||
sector_t *sec;
|
||||
pillar_t *pillar;
|
||||
int rtn;
|
||||
|
||||
rtn = 0;
|
||||
secnum = -1;
|
||||
while((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
if(sec->specialdata)
|
||||
continue; // already moving
|
||||
if(sec->floorheight != sec->ceilingheight)
|
||||
{ // pillar isn't closed
|
||||
continue;
|
||||
}
|
||||
rtn = 1;
|
||||
pillar = Z_Malloc(sizeof(*pillar), PU_LEVSPEC, 0);
|
||||
sec->specialdata = pillar;
|
||||
P_AddThinker(&pillar->thinker);
|
||||
pillar->thinker.function = T_BuildPillar;
|
||||
pillar->sector = sec;
|
||||
if(!args[2])
|
||||
{
|
||||
pillar->floordest = P_FindLowestFloorSurrounding(sec);
|
||||
}
|
||||
else
|
||||
{
|
||||
pillar->floordest = sec->floorheight-(args[2]<<FRACBITS);
|
||||
}
|
||||
if(!args[3])
|
||||
{
|
||||
pillar->ceilingdest = P_FindHighestCeilingSurrounding(sec);
|
||||
}
|
||||
else
|
||||
{
|
||||
pillar->ceilingdest = sec->ceilingheight+(args[3]<<FRACBITS);
|
||||
}
|
||||
if(sec->floorheight-pillar->floordest >= pillar->ceilingdest-
|
||||
sec->ceilingheight)
|
||||
{
|
||||
pillar->floorSpeed = args[1]*(FRACUNIT/8);
|
||||
pillar->ceilingSpeed = FixedMul(sec->ceilingheight-
|
||||
pillar->ceilingdest, FixedDiv(pillar->floorSpeed,
|
||||
pillar->floordest-sec->floorheight));
|
||||
}
|
||||
else
|
||||
{
|
||||
pillar->ceilingSpeed = args[1]*(FRACUNIT/8);
|
||||
pillar->floorSpeed = FixedMul(pillar->floordest-sec->floorheight,
|
||||
FixedDiv(pillar->ceilingSpeed, sec->ceilingheight-
|
||||
pillar->ceilingdest));
|
||||
}
|
||||
pillar->direction = -1; // open the pillar
|
||||
SN_StartSequence((mobj_t *)&pillar->sector->soundorg,
|
||||
SEQ_PLATFORM+pillar->sector->seqType);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
//
|
||||
// EV_FloorCrushStop
|
||||
//
|
||||
//=========================================================================
|
||||
|
||||
int EV_FloorCrushStop(line_t *line, byte *args)
|
||||
{
|
||||
thinker_t *think;
|
||||
floormove_t *floor;
|
||||
boolean rtn;
|
||||
|
||||
rtn = 0;
|
||||
for(think = thinkercap.next; think != &thinkercap; think = think->next)
|
||||
{
|
||||
if(think->function != T_MoveFloor)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
floor = (floormove_t *)think;
|
||||
if(floor->type != FLEV_RAISEFLOORCRUSH)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Completely remove the crushing floor
|
||||
SN_StopSequence((mobj_t *)&floor->sector->soundorg);
|
||||
floor->sector->specialdata = NULL;
|
||||
P_TagFinished(floor->sector->tag);
|
||||
P_RemoveThinker(&floor->thinker);
|
||||
rtn = 1;
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// T_FloorWaggle
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
#define WGLSTATE_EXPAND 1
|
||||
#define WGLSTATE_STABLE 2
|
||||
#define WGLSTATE_REDUCE 3
|
||||
|
||||
void T_FloorWaggle(floorWaggle_t *waggle)
|
||||
{
|
||||
switch(waggle->state)
|
||||
{
|
||||
case WGLSTATE_EXPAND:
|
||||
if((waggle->scale += waggle->scaleDelta)
|
||||
>= waggle->targetScale)
|
||||
{
|
||||
waggle->scale = waggle->targetScale;
|
||||
waggle->state = WGLSTATE_STABLE;
|
||||
}
|
||||
break;
|
||||
case WGLSTATE_REDUCE:
|
||||
if((waggle->scale -= waggle->scaleDelta) <= 0)
|
||||
{ // Remove
|
||||
waggle->sector->floorheight = waggle->originalHeight;
|
||||
P_ChangeSector(waggle->sector, true);
|
||||
waggle->sector->specialdata = NULL;
|
||||
P_TagFinished(waggle->sector->tag);
|
||||
P_RemoveThinker(&waggle->thinker);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case WGLSTATE_STABLE:
|
||||
if(waggle->ticker != -1)
|
||||
{
|
||||
if(!--waggle->ticker)
|
||||
{
|
||||
waggle->state = WGLSTATE_REDUCE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
waggle->accumulator += waggle->accDelta;
|
||||
waggle->sector->floorheight = waggle->originalHeight
|
||||
+FixedMul(FloatBobOffsets[(waggle->accumulator>>FRACBITS)&63],
|
||||
waggle->scale);
|
||||
P_ChangeSector(waggle->sector, true);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// EV_StartFloorWaggle
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
boolean EV_StartFloorWaggle(int tag, int height, int speed, int offset,
|
||||
int timer)
|
||||
{
|
||||
int sectorIndex;
|
||||
sector_t *sector;
|
||||
floorWaggle_t *waggle;
|
||||
boolean retCode;
|
||||
|
||||
retCode = false;
|
||||
sectorIndex = -1;
|
||||
while((sectorIndex = P_FindSectorFromTag(tag, sectorIndex)) >= 0)
|
||||
{
|
||||
sector = §ors[sectorIndex];
|
||||
if(sector->specialdata)
|
||||
{ // Already busy with another thinker
|
||||
continue;
|
||||
}
|
||||
retCode = true;
|
||||
waggle = Z_Malloc(sizeof(*waggle), PU_LEVSPEC, 0);
|
||||
sector->specialdata = waggle;
|
||||
waggle->thinker.function = T_FloorWaggle;
|
||||
waggle->sector = sector;
|
||||
waggle->originalHeight = sector->floorheight;
|
||||
waggle->accumulator = offset*FRACUNIT;
|
||||
waggle->accDelta = speed<<10;
|
||||
waggle->scale = 0;
|
||||
waggle->targetScale = height<<10;
|
||||
waggle->scaleDelta = waggle->targetScale
|
||||
/(35+((3*35)*height)/255);
|
||||
waggle->ticker = timer ? timer*35 : -1;
|
||||
waggle->state = WGLSTATE_EXPAND;
|
||||
P_AddThinker(&waggle->thinker);
|
||||
}
|
||||
return retCode;
|
||||
}
|
2252
Hexen Source/P_INTER.C
Normal file
2252
Hexen Source/P_INTER.C
Normal file
File diff suppressed because it is too large
Load diff
351
Hexen Source/P_LIGHTS.C
Normal file
351
Hexen Source/P_LIGHTS.C
Normal file
|
@ -0,0 +1,351 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** p_lights.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: p_lights.c,v $
|
||||
//** $Revision: 1.2 $
|
||||
//** $Date: 95/07/11 10:23:36 $
|
||||
//** $Author: cjr $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// T_Light
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void T_Light(light_t *light)
|
||||
{
|
||||
if(light->count)
|
||||
{
|
||||
light->count--;
|
||||
return;
|
||||
}
|
||||
switch(light->type)
|
||||
{
|
||||
case LITE_FADE:
|
||||
light->sector->lightlevel = ((light->sector->lightlevel<<FRACBITS)
|
||||
+light->value2)>>FRACBITS;
|
||||
if(light->tics2 == 1)
|
||||
{
|
||||
if(light->sector->lightlevel >= light->value1)
|
||||
{
|
||||
light->sector->lightlevel = light->value1;
|
||||
P_RemoveThinker(&light->thinker);
|
||||
}
|
||||
}
|
||||
else if(light->sector->lightlevel <= light->value1)
|
||||
{
|
||||
light->sector->lightlevel = light->value1;
|
||||
P_RemoveThinker(&light->thinker);
|
||||
}
|
||||
break;
|
||||
case LITE_GLOW:
|
||||
light->sector->lightlevel = ((light->sector->lightlevel<<FRACBITS)
|
||||
+light->tics1)>>FRACBITS;
|
||||
if(light->tics2 == 1)
|
||||
{
|
||||
if(light->sector->lightlevel >= light->value1)
|
||||
{
|
||||
light->sector->lightlevel = light->value1;
|
||||
light->tics1 = -light->tics1;
|
||||
light->tics2 = -1; // reverse direction
|
||||
}
|
||||
}
|
||||
else if(light->sector->lightlevel <= light->value2)
|
||||
{
|
||||
light->sector->lightlevel = light->value2;
|
||||
light->tics1 = -light->tics1;
|
||||
light->tics2 = 1; // reverse direction
|
||||
}
|
||||
break;
|
||||
case LITE_FLICKER:
|
||||
if(light->sector->lightlevel == light->value1)
|
||||
{
|
||||
light->sector->lightlevel = light->value2;
|
||||
light->count = (P_Random()&7)+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
light->sector->lightlevel = light->value1;
|
||||
light->count = (P_Random()&31)+1;
|
||||
}
|
||||
break;
|
||||
case LITE_STROBE:
|
||||
if(light->sector->lightlevel == light->value1)
|
||||
{
|
||||
light->sector->lightlevel = light->value2;
|
||||
light->count = light->tics2;
|
||||
}
|
||||
else
|
||||
{
|
||||
light->sector->lightlevel = light->value1;
|
||||
light->count = light->tics1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// EV_SpawnLight
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
boolean EV_SpawnLight(line_t *line, byte *arg, lighttype_t type)
|
||||
{
|
||||
light_t *light;
|
||||
sector_t *sec;
|
||||
int secNum;
|
||||
int arg1, arg2, arg3, arg4;
|
||||
boolean think;
|
||||
boolean rtn;
|
||||
|
||||
arg1 = arg[1] > 255 ? 255 : arg[1];
|
||||
arg1 = arg1 < 0 ? 0 : arg1;
|
||||
arg2 = arg[2] > 255 ? 255 : arg[2];
|
||||
arg2 = arg2 < 0 ? 0 : arg2;
|
||||
arg3 = arg[3] > 255 ? 255 : arg[3];
|
||||
arg3 = arg3 < 0 ? 0 : arg3;
|
||||
arg4 = arg[4] > 255 ? 255 : arg[4];
|
||||
arg4 = arg4 < 0 ? 0 : arg4;
|
||||
|
||||
secNum = -1;
|
||||
rtn = false;
|
||||
think = false;
|
||||
while((secNum = P_FindSectorFromTag(arg[0], secNum)) >= 0)
|
||||
{
|
||||
think = false;
|
||||
sec = §ors[secNum];
|
||||
|
||||
light = (light_t *)Z_Malloc(sizeof(light_t), PU_LEVSPEC, 0);
|
||||
light->type = type;
|
||||
light->sector = sec;
|
||||
light->count = 0;
|
||||
rtn = true;
|
||||
switch(type)
|
||||
{
|
||||
case LITE_RAISEBYVALUE:
|
||||
sec->lightlevel += arg1;
|
||||
if(sec->lightlevel > 255)
|
||||
{
|
||||
sec->lightlevel = 255;
|
||||
}
|
||||
break;
|
||||
case LITE_LOWERBYVALUE:
|
||||
sec->lightlevel -= arg1;
|
||||
if(sec->lightlevel < 0)
|
||||
{
|
||||
sec->lightlevel = 0;
|
||||
}
|
||||
break;
|
||||
case LITE_CHANGETOVALUE:
|
||||
sec->lightlevel = arg1;
|
||||
if(sec->lightlevel < 0)
|
||||
{
|
||||
sec->lightlevel = 0;
|
||||
}
|
||||
else if(sec->lightlevel > 255)
|
||||
{
|
||||
sec->lightlevel = 255;
|
||||
}
|
||||
break;
|
||||
case LITE_FADE:
|
||||
think = true;
|
||||
light->value1 = arg1; // destination lightlevel
|
||||
light->value2 = FixedDiv((arg1-sec->lightlevel)<<FRACBITS,
|
||||
arg2<<FRACBITS); // delta lightlevel
|
||||
if(sec->lightlevel <= arg1)
|
||||
{
|
||||
light->tics2 = 1; // get brighter
|
||||
}
|
||||
else
|
||||
{
|
||||
light->tics2 = -1;
|
||||
}
|
||||
break;
|
||||
case LITE_GLOW:
|
||||
think = true;
|
||||
light->value1 = arg1; // upper lightlevel
|
||||
light->value2 = arg2; // lower lightlevel
|
||||
light->tics1 = FixedDiv((arg1-sec->lightlevel)<<FRACBITS,
|
||||
arg3<<FRACBITS); // lightlevel delta
|
||||
if(sec->lightlevel <= arg1)
|
||||
{
|
||||
light->tics2 = 1; // get brighter
|
||||
}
|
||||
else
|
||||
{
|
||||
light->tics2 = -1;
|
||||
}
|
||||
break;
|
||||
case LITE_FLICKER:
|
||||
think = true;
|
||||
light->value1 = arg1; // upper lightlevel
|
||||
light->value2 = arg2; // lower lightlevel
|
||||
sec->lightlevel = light->value1;
|
||||
light->count = (P_Random()&64)+1;
|
||||
break;
|
||||
case LITE_STROBE:
|
||||
think = true;
|
||||
light->value1 = arg1; // upper lightlevel
|
||||
light->value2 = arg2; // lower lightlevel
|
||||
light->tics1 = arg3; // upper tics
|
||||
light->tics2 = arg4; // lower tics
|
||||
light->count = arg3;
|
||||
sec->lightlevel = light->value1;
|
||||
break;
|
||||
default:
|
||||
rtn = false;
|
||||
break;
|
||||
}
|
||||
if(think)
|
||||
{
|
||||
P_AddThinker(&light->thinker);
|
||||
light->thinker.function = T_Light;
|
||||
}
|
||||
else
|
||||
{
|
||||
Z_Free(light);
|
||||
}
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// T_Phase
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
int PhaseTable[64] =
|
||||
{
|
||||
128, 112, 96, 80, 64, 48, 32, 32,
|
||||
16, 16, 16, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 16, 16, 16,
|
||||
32, 32, 48, 64, 80, 96, 112, 128
|
||||
};
|
||||
|
||||
void T_Phase(phase_t *phase)
|
||||
{
|
||||
phase->index = (phase->index+1)&63;
|
||||
phase->sector->lightlevel = phase->base+PhaseTable[phase->index];
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_SpawnPhasedLight
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_SpawnPhasedLight(sector_t *sector, int base, int index)
|
||||
{
|
||||
phase_t *phase;
|
||||
|
||||
phase = Z_Malloc(sizeof(*phase), PU_LEVSPEC, 0);
|
||||
P_AddThinker(&phase->thinker);
|
||||
phase->sector = sector;
|
||||
if(index == -1)
|
||||
{ // sector->lightlevel as the index
|
||||
phase->index = sector->lightlevel&63;
|
||||
}
|
||||
else
|
||||
{
|
||||
phase->index = index&63;
|
||||
}
|
||||
phase->base = base&255;
|
||||
sector->lightlevel = phase->base+PhaseTable[phase->index];
|
||||
phase->thinker.function = T_Phase;
|
||||
|
||||
sector->special = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_SpawnLightSequence
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_SpawnLightSequence(sector_t *sector, int indexStep)
|
||||
{
|
||||
sector_t *sec;
|
||||
sector_t *nextSec;
|
||||
sector_t *tempSec;
|
||||
int seqSpecial;
|
||||
int i;
|
||||
int count;
|
||||
fixed_t index;
|
||||
fixed_t indexDelta;
|
||||
int base;
|
||||
|
||||
seqSpecial = LIGHT_SEQUENCE; // look for Light_Sequence, first
|
||||
sec = sector;
|
||||
count = 1;
|
||||
do
|
||||
{
|
||||
nextSec = NULL;
|
||||
sec->special = LIGHT_SEQUENCE_START; // make sure that the search doesn't back up.
|
||||
for(i = 0; i < sec->linecount; i++)
|
||||
{
|
||||
tempSec = getNextSector(sec->lines[i], sec);
|
||||
if(!tempSec)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(tempSec->special == seqSpecial)
|
||||
{
|
||||
if(seqSpecial == LIGHT_SEQUENCE)
|
||||
{
|
||||
seqSpecial = LIGHT_SEQUENCE_ALT;
|
||||
}
|
||||
else
|
||||
{
|
||||
seqSpecial = LIGHT_SEQUENCE;
|
||||
}
|
||||
nextSec = tempSec;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
sec = nextSec;
|
||||
} while(sec);
|
||||
|
||||
sec = sector;
|
||||
count *= indexStep;
|
||||
index = 0;
|
||||
indexDelta = FixedDiv(64*FRACUNIT, count*FRACUNIT);
|
||||
base = sector->lightlevel;
|
||||
do
|
||||
{
|
||||
nextSec = NULL;
|
||||
if(sec->lightlevel)
|
||||
{
|
||||
base = sec->lightlevel;
|
||||
}
|
||||
P_SpawnPhasedLight(sec, base, index>>FRACBITS);
|
||||
index += indexDelta;
|
||||
for(i = 0; i < sec->linecount; i++)
|
||||
{
|
||||
tempSec = getNextSector(sec->lines[i], sec);
|
||||
if(!tempSec)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(tempSec->special == LIGHT_SEQUENCE_START)
|
||||
{
|
||||
nextSec = tempSec;
|
||||
}
|
||||
}
|
||||
sec = nextSec;
|
||||
} while(sec);
|
||||
}
|
372
Hexen Source/P_LOCAL.H
Normal file
372
Hexen Source/P_LOCAL.H
Normal file
|
@ -0,0 +1,372 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** p_local.h : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: p_local.h,v $
|
||||
//** $Revision: 1.64 $
|
||||
//** $Date: 95/10/13 03:00:16 $
|
||||
//** $Author: cjr $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#ifndef __P_LOCAL__
|
||||
#define __P_LOCAL__
|
||||
|
||||
#ifndef __R_LOCAL__
|
||||
#include "r_local.h"
|
||||
#endif
|
||||
|
||||
#define STARTREDPALS 1
|
||||
#define STARTBONUSPALS 9
|
||||
#define STARTPOISONPALS 13
|
||||
#define STARTICEPAL 21
|
||||
#define STARTHOLYPAL 22
|
||||
#define STARTSCOURGEPAL 25
|
||||
#define NUMREDPALS 8
|
||||
#define NUMBONUSPALS 4
|
||||
#define NUMPOISONPALS 8
|
||||
|
||||
#define TOCENTER -8
|
||||
#define FLOATSPEED (FRACUNIT*4)
|
||||
|
||||
#define MAXHEALTH 100
|
||||
#define MAXMORPHHEALTH 30
|
||||
#define VIEWHEIGHT (48*FRACUNIT)
|
||||
|
||||
// mapblocks are used to check movement against lines and things
|
||||
#define MAPBLOCKUNITS 128
|
||||
#define MAPBLOCKSIZE (MAPBLOCKUNITS*FRACUNIT)
|
||||
#define MAPBLOCKSHIFT (FRACBITS+7)
|
||||
#define MAPBMASK (MAPBLOCKSIZE-1)
|
||||
#define MAPBTOFRAC (MAPBLOCKSHIFT-FRACBITS)
|
||||
|
||||
// player radius for movement checking
|
||||
#define PLAYERRADIUS 16*FRACUNIT
|
||||
|
||||
// MAXRADIUS is for precalculated sector block boxes
|
||||
// the spider demon is larger, but we don't have any moving sectors
|
||||
// nearby
|
||||
#define MAXRADIUS 32*FRACUNIT
|
||||
|
||||
#define GRAVITY FRACUNIT
|
||||
#define MAXMOVE (30*FRACUNIT)
|
||||
|
||||
#define USERANGE (64*FRACUNIT)
|
||||
#define MELEERANGE (64*FRACUNIT)
|
||||
#define MISSILERANGE (32*64*FRACUNIT)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DI_EAST,
|
||||
DI_NORTHEAST,
|
||||
DI_NORTH,
|
||||
DI_NORTHWEST,
|
||||
DI_WEST,
|
||||
DI_SOUTHWEST,
|
||||
DI_SOUTH,
|
||||
DI_SOUTHEAST,
|
||||
DI_NODIR,
|
||||
NUMDIRS
|
||||
} dirtype_t;
|
||||
|
||||
#define BASETHRESHOLD 100 // follow a player exlusively for 3 seconds
|
||||
|
||||
// ***** P_TICK *****
|
||||
|
||||
extern thinker_t thinkercap; // both the head and tail of the thinker list
|
||||
extern int TimerGame; // tic countdown for deathmatch
|
||||
|
||||
void P_InitThinkers(void);
|
||||
void P_AddThinker(thinker_t *thinker);
|
||||
void P_RemoveThinker(thinker_t *thinker);
|
||||
|
||||
// ***** P_PSPR *****
|
||||
|
||||
#define USE_MANA1 1
|
||||
#define USE_MANA2 1
|
||||
|
||||
void P_SetPsprite(player_t *player, int position, statenum_t stnum);
|
||||
void P_SetPspriteNF(player_t *player, int position, statenum_t stnum);
|
||||
void P_SetupPsprites(player_t *curplayer);
|
||||
void P_MovePsprites(player_t *curplayer);
|
||||
void P_DropWeapon(player_t *player);
|
||||
void P_ActivateMorphWeapon(player_t *player);
|
||||
void P_PostMorphWeapon(player_t *player, weapontype_t weapon);
|
||||
|
||||
// ***** P_USER *****
|
||||
|
||||
extern int PStateNormal[NUMCLASSES];
|
||||
extern int PStateRun[NUMCLASSES];
|
||||
extern int PStateAttack[NUMCLASSES];
|
||||
extern int PStateAttackEnd[NUMCLASSES];
|
||||
|
||||
void P_PlayerThink(player_t *player);
|
||||
void P_Thrust(player_t *player, angle_t angle, fixed_t move);
|
||||
void P_PlayerRemoveArtifact(player_t *player, int slot);
|
||||
void P_PlayerUseArtifact(player_t *player, artitype_t arti);
|
||||
boolean P_UseArtifact(player_t *player, artitype_t arti);
|
||||
int P_GetPlayerNum(player_t *player);
|
||||
void P_TeleportOther(mobj_t *victim);
|
||||
void ResetBlasted(mobj_t *mo);
|
||||
|
||||
// ***** P_MOBJ *****
|
||||
|
||||
// Any floor type >= FLOOR_LIQUID will floorclip sprites
|
||||
enum
|
||||
{
|
||||
FLOOR_SOLID,
|
||||
FLOOR_ICE,
|
||||
FLOOR_LIQUID,
|
||||
FLOOR_WATER,
|
||||
FLOOR_LAVA,
|
||||
FLOOR_SLUDGE
|
||||
};
|
||||
|
||||
#define ONFLOORZ MININT
|
||||
#define ONCEILINGZ MAXINT
|
||||
#define FLOATRANDZ (MAXINT-1)
|
||||
#define FROMCEILINGZ128 (MAXINT-2)
|
||||
|
||||
extern mobjtype_t PuffType;
|
||||
extern mobj_t *MissileMobj;
|
||||
|
||||
mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type);
|
||||
void P_RemoveMobj(mobj_t *th);
|
||||
boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
|
||||
boolean P_SetMobjStateNF(mobj_t *mobj, statenum_t state);
|
||||
void P_ThrustMobj(mobj_t *mo, angle_t angle, fixed_t move);
|
||||
int P_FaceMobj(mobj_t *source, mobj_t *target, angle_t *delta);
|
||||
boolean P_SeekerMissile(mobj_t *actor, angle_t thresh, angle_t turnMax);
|
||||
void P_MobjThinker(mobj_t *mobj);
|
||||
void P_BlasterMobjThinker(mobj_t *mobj);
|
||||
void P_SpawnPuff(fixed_t x, fixed_t y, fixed_t z);
|
||||
void P_SpawnBlood(fixed_t x, fixed_t y, fixed_t z, int damage);
|
||||
void P_BloodSplatter(fixed_t x, fixed_t y, fixed_t z, mobj_t *originator);
|
||||
void P_BloodSplatter2(fixed_t x, fixed_t y, fixed_t z, mobj_t *originator);
|
||||
void P_RipperBlood(mobj_t *mo);
|
||||
int P_GetThingFloorType(mobj_t *thing);
|
||||
int P_HitFloor(mobj_t *thing);
|
||||
boolean P_CheckMissileSpawn(mobj_t *missile);
|
||||
mobj_t *P_SpawnMissile(mobj_t *source, mobj_t *dest, mobjtype_t type);
|
||||
mobj_t *P_SpawnMissileXYZ(fixed_t x, fixed_t y, fixed_t z,
|
||||
mobj_t *source, mobj_t *dest, mobjtype_t type);
|
||||
mobj_t *P_SpawnMissileAngle(mobj_t *source, mobjtype_t type,
|
||||
angle_t angle, fixed_t momz);
|
||||
mobj_t *P_SpawnMissileAngleSpeed(mobj_t *source, mobjtype_t type,
|
||||
angle_t angle, fixed_t momz, fixed_t speed);
|
||||
mobj_t *P_SpawnPlayerMissile(mobj_t *source, mobjtype_t type);
|
||||
mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle);
|
||||
mobj_t *P_SPMAngleXYZ(mobj_t *source, fixed_t x, fixed_t y,
|
||||
fixed_t z, mobjtype_t type, angle_t angle);
|
||||
void P_CreateTIDList(void);
|
||||
void P_RemoveMobjFromTIDList(mobj_t *mobj);
|
||||
void P_InsertMobjIntoTIDList(mobj_t *mobj, int tid);
|
||||
mobj_t *P_FindMobjFromTID(int tid, int *searchPosition);
|
||||
mobj_t *P_SpawnKoraxMissile(fixed_t x, fixed_t y, fixed_t z,
|
||||
mobj_t *source, mobj_t *dest, mobjtype_t type);
|
||||
|
||||
// ***** P_ENEMY *****
|
||||
|
||||
void P_NoiseAlert (mobj_t *target, mobj_t *emmiter);
|
||||
int P_Massacre(void);
|
||||
boolean A_RaiseMobj(mobj_t *actor);
|
||||
boolean A_SinkMobj(mobj_t *actor);
|
||||
void A_NoBlocking(mobj_t *actor);
|
||||
boolean P_LookForMonsters(mobj_t *actor);
|
||||
void P_InitCreatureCorpseQueue(boolean corpseScan);
|
||||
void A_DeQueueCorpse(mobj_t *actor);
|
||||
|
||||
|
||||
// ***** P_MAPUTL *****
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fixed_t x, y, dx, dy;
|
||||
} divline_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fixed_t frac; // along trace line
|
||||
boolean isaline;
|
||||
union {
|
||||
mobj_t *thing;
|
||||
line_t *line;
|
||||
} d;
|
||||
} intercept_t;
|
||||
|
||||
#define MAXINTERCEPTS 128
|
||||
extern intercept_t intercepts[MAXINTERCEPTS], *intercept_p;
|
||||
typedef boolean (*traverser_t) (intercept_t *in);
|
||||
|
||||
|
||||
fixed_t P_AproxDistance (fixed_t dx, fixed_t dy);
|
||||
int P_PointOnLineSide (fixed_t x, fixed_t y, line_t *line);
|
||||
int P_PointOnDivlineSide (fixed_t x, fixed_t y, divline_t *line);
|
||||
void P_MakeDivline (line_t *li, divline_t *dl);
|
||||
fixed_t P_InterceptVector (divline_t *v2, divline_t *v1);
|
||||
int P_BoxOnLineSide (fixed_t *tmbox, line_t *ld);
|
||||
|
||||
extern fixed_t opentop, openbottom, openrange;
|
||||
extern fixed_t lowfloor;
|
||||
void P_LineOpening (line_t *linedef);
|
||||
|
||||
boolean P_BlockLinesIterator (int x, int y, boolean(*func)(line_t*) );
|
||||
boolean P_BlockThingsIterator (int x, int y, boolean(*func)(mobj_t*) );
|
||||
|
||||
#define PT_ADDLINES 1
|
||||
#define PT_ADDTHINGS 2
|
||||
#define PT_EARLYOUT 4
|
||||
|
||||
extern divline_t trace;
|
||||
boolean P_PathTraverse (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2,
|
||||
int flags, boolean (*trav) (intercept_t *));
|
||||
|
||||
void P_UnsetThingPosition (mobj_t *thing);
|
||||
void P_SetThingPosition (mobj_t *thing);
|
||||
mobj_t *P_RoughMonsterSearch(mobj_t *mo, int distance);
|
||||
|
||||
// ***** P_MAP *****
|
||||
|
||||
extern boolean floatok; // if true, move would be ok if
|
||||
extern fixed_t tmfloorz, tmceilingz; // within tmfloorz - tmceilingz
|
||||
extern int tmfloorpic;
|
||||
extern mobj_t *BlockingMobj;
|
||||
|
||||
extern line_t *ceilingline;
|
||||
boolean P_TestMobjLocation(mobj_t *mobj);
|
||||
boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y);
|
||||
mobj_t *P_CheckOnmobj(mobj_t *thing);
|
||||
void P_FakeZMovement(mobj_t *mo);
|
||||
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y);
|
||||
boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y);
|
||||
void P_SlideMove(mobj_t *mo);
|
||||
void P_BounceWall(mobj_t *mo);
|
||||
boolean P_CheckSight(mobj_t *t1, mobj_t *t2);
|
||||
void P_UseLines(player_t *player);
|
||||
boolean P_UsePuzzleItem(player_t *player, int itemType);
|
||||
void PIT_ThrustSpike(mobj_t *actor);
|
||||
|
||||
boolean P_ChangeSector (sector_t *sector, int crunch);
|
||||
|
||||
extern mobj_t *PuffSpawned; // true if a puff was spawned
|
||||
extern mobj_t *linetarget; // who got hit (or NULL)
|
||||
fixed_t P_AimLineAttack (mobj_t *t1, angle_t angle, fixed_t distance);
|
||||
|
||||
void P_LineAttack (mobj_t *t1, angle_t angle, fixed_t distance, fixed_t slope, int damage);
|
||||
|
||||
void P_RadiusAttack (mobj_t *spot, mobj_t *source, int damage, int distance,
|
||||
boolean damageSource);
|
||||
|
||||
// ***** P_SETUP *****
|
||||
|
||||
extern byte *rejectmatrix; // for fast sight rejection
|
||||
extern short *blockmaplump; // offsets in blockmap are from here
|
||||
extern short *blockmap;
|
||||
extern int bmapwidth, bmapheight; // in mapblocks
|
||||
extern fixed_t bmaporgx, bmaporgy; // origin of block map
|
||||
extern mobj_t **blocklinks; // for thing chains
|
||||
|
||||
// ***** P_INTER *****
|
||||
|
||||
extern int clipmana[NUMMANA];
|
||||
|
||||
void P_SetMessage(player_t *player, char *message, boolean ultmsg);
|
||||
void P_SetYellowMessage(player_t *player, char *message, boolean ultmsg);
|
||||
void P_ClearMessage(player_t *player);
|
||||
void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher);
|
||||
void P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source,
|
||||
int damage);
|
||||
void P_FallingDamage(player_t *player);
|
||||
void P_PoisonPlayer(player_t *player, mobj_t *poisoner, int poison);
|
||||
void P_PoisonDamage(player_t *player, mobj_t *source, int damage,
|
||||
boolean playPainSound);
|
||||
boolean P_GiveMana(player_t *player, manatype_t mana, int count);
|
||||
boolean P_GiveArtifact(player_t *player, artitype_t arti, mobj_t *mo);
|
||||
boolean P_GiveArmor(player_t *player, armortype_t armortype, int amount);
|
||||
boolean P_GiveBody(player_t *player, int num);
|
||||
boolean P_GivePower(player_t *player, powertype_t power);
|
||||
boolean P_MorphPlayer(player_t *player);
|
||||
|
||||
// ***** AM_MAP *****
|
||||
|
||||
boolean AM_Responder(event_t *ev);
|
||||
void AM_Ticker(void);
|
||||
void AM_Drawer(void);
|
||||
|
||||
// ***** A_ACTION *****
|
||||
boolean A_LocalQuake(byte *args, mobj_t *victim);
|
||||
void P_SpawnDirt(mobj_t *actor, fixed_t radius);
|
||||
void A_BridgeRemove(mobj_t *actor);
|
||||
|
||||
// ***** SB_BAR *****
|
||||
|
||||
extern int SB_state;
|
||||
extern int ArtifactFlash;
|
||||
void SB_PaletteFlash(boolean forceChange);
|
||||
|
||||
// ===== PO_MAN =====
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PODOOR_NONE,
|
||||
PODOOR_SLIDE,
|
||||
PODOOR_SWING,
|
||||
} podoortype_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
int polyobj;
|
||||
int speed;
|
||||
unsigned int dist;
|
||||
int angle;
|
||||
fixed_t xSpeed; // for sliding walls
|
||||
fixed_t ySpeed;
|
||||
} polyevent_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
int polyobj;
|
||||
int speed;
|
||||
int dist;
|
||||
int totalDist;
|
||||
int direction;
|
||||
fixed_t xSpeed, ySpeed;
|
||||
int tics;
|
||||
int waitTics;
|
||||
podoortype_t type;
|
||||
boolean close;
|
||||
} polydoor_t;
|
||||
|
||||
enum
|
||||
{
|
||||
PO_ANCHOR_TYPE = 3000,
|
||||
PO_SPAWN_TYPE,
|
||||
PO_SPAWNCRUSH_TYPE
|
||||
};
|
||||
|
||||
#define PO_LINE_START 1 // polyobj line start special
|
||||
#define PO_LINE_EXPLICIT 5
|
||||
|
||||
extern polyobj_t *polyobjs; // list of all poly-objects on the level
|
||||
extern int po_NumPolyobjs;
|
||||
|
||||
void T_PolyDoor(polydoor_t *pd);
|
||||
void T_RotatePoly(polyevent_t *pe);
|
||||
boolean EV_RotatePoly(line_t *line, byte *args, int direction, boolean
|
||||
overRide);
|
||||
void T_MovePoly(polyevent_t *pe);
|
||||
boolean EV_MovePoly(line_t *line, byte *args, boolean timesEight, boolean
|
||||
overRide);
|
||||
boolean EV_OpenPolyDoor(line_t *line, byte *args, podoortype_t type);
|
||||
|
||||
boolean PO_MovePolyobj(int num, int x, int y);
|
||||
boolean PO_RotatePolyobj(int num, angle_t angle);
|
||||
void PO_Init(int lump);
|
||||
boolean PO_Busy(int polyobj);
|
||||
|
||||
#include "p_spec.h"
|
||||
|
||||
#endif // __P_LOCAL__
|
2296
Hexen Source/P_MAP.C
Normal file
2296
Hexen Source/P_MAP.C
Normal file
File diff suppressed because it is too large
Load diff
1056
Hexen Source/P_MAPUTL.C
Normal file
1056
Hexen Source/P_MAPUTL.C
Normal file
File diff suppressed because it is too large
Load diff
2441
Hexen Source/P_MOBJ.C
Normal file
2441
Hexen Source/P_MOBJ.C
Normal file
File diff suppressed because it is too large
Load diff
266
Hexen Source/P_PLATS.C
Normal file
266
Hexen Source/P_PLATS.C
Normal file
|
@ -0,0 +1,266 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** p_plats.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: p_plats.c,v $
|
||||
//** $Revision: 1.11 $
|
||||
//** $Date: 95/09/11 22:06:30 $
|
||||
//** $Author: cjr $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
#include "soundst.h"
|
||||
|
||||
plat_t *activeplats[MAXPLATS];
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// Move a plat up and down
|
||||
//
|
||||
//==================================================================
|
||||
void T_PlatRaise(plat_t *plat)
|
||||
{
|
||||
result_e res;
|
||||
|
||||
switch(plat->status)
|
||||
{
|
||||
case PLAT_UP:
|
||||
res = T_MovePlane(plat->sector, plat->speed,
|
||||
plat->high, plat->crush, 0, 1);
|
||||
if (res == RES_CRUSHED && (!plat->crush))
|
||||
{
|
||||
plat->count = plat->wait;
|
||||
plat->status = PLAT_DOWN;
|
||||
SN_StartSequence((mobj_t *)&plat->sector->soundorg,
|
||||
SEQ_PLATFORM+plat->sector->seqType);
|
||||
}
|
||||
else
|
||||
if (res == RES_PASTDEST)
|
||||
{
|
||||
plat->count = plat->wait;
|
||||
plat->status = PLAT_WAITING;
|
||||
SN_StopSequence((mobj_t *)&plat->sector->soundorg);
|
||||
switch(plat->type)
|
||||
{
|
||||
case PLAT_DOWNWAITUPSTAY:
|
||||
case PLAT_DOWNBYVALUEWAITUPSTAY:
|
||||
P_RemoveActivePlat(plat);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PLAT_DOWN:
|
||||
res = T_MovePlane(plat->sector,plat->speed,plat->low,false,0,-1);
|
||||
if (res == RES_PASTDEST)
|
||||
{
|
||||
plat->count = plat->wait;
|
||||
plat->status = PLAT_WAITING;
|
||||
switch(plat->type)
|
||||
{
|
||||
case PLAT_UPWAITDOWNSTAY:
|
||||
case PLAT_UPBYVALUEWAITDOWNSTAY:
|
||||
P_RemoveActivePlat(plat);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
SN_StopSequence((mobj_t *)&plat->sector->soundorg);
|
||||
}
|
||||
break;
|
||||
case PLAT_WAITING:
|
||||
if (!--plat->count)
|
||||
{
|
||||
if (plat->sector->floorheight == plat->low)
|
||||
plat->status = PLAT_UP;
|
||||
else
|
||||
plat->status = PLAT_DOWN;
|
||||
SN_StartSequence((mobj_t *)&plat->sector->soundorg,
|
||||
SEQ_PLATFORM+plat->sector->seqType);
|
||||
}
|
||||
// case PLAT_IN_STASIS:
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// Do Platforms
|
||||
// "amount" is only used for SOME platforms.
|
||||
//
|
||||
//==================================================================
|
||||
int EV_DoPlat(line_t *line, byte *args, plattype_e type, int amount)
|
||||
{
|
||||
plat_t *plat;
|
||||
int secnum;
|
||||
int rtn;
|
||||
sector_t *sec;
|
||||
|
||||
secnum = -1;
|
||||
rtn = 0;
|
||||
|
||||
/*
|
||||
//
|
||||
// Activate all <type> plats that are in_stasis
|
||||
//
|
||||
switch(type)
|
||||
{
|
||||
case PLAT_PERPETUALRAISE:
|
||||
P_ActivateInStasis(args[0]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
while ((secnum = P_FindSectorFromTag(args[0], secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
if (sec->specialdata)
|
||||
continue;
|
||||
|
||||
//
|
||||
// Find lowest & highest floors around sector
|
||||
//
|
||||
rtn = 1;
|
||||
plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0);
|
||||
P_AddThinker(&plat->thinker);
|
||||
|
||||
plat->type = type;
|
||||
plat->sector = sec;
|
||||
plat->sector->specialdata = plat;
|
||||
plat->thinker.function = T_PlatRaise;
|
||||
plat->crush = false;
|
||||
plat->tag = args[0];
|
||||
plat->speed = args[1]*(FRACUNIT/8);
|
||||
switch(type)
|
||||
{
|
||||
case PLAT_DOWNWAITUPSTAY:
|
||||
plat->low = P_FindLowestFloorSurrounding(sec)+8*FRACUNIT;
|
||||
if (plat->low > sec->floorheight)
|
||||
plat->low = sec->floorheight;
|
||||
plat->high = sec->floorheight;
|
||||
plat->wait = args[2];
|
||||
plat->status = PLAT_DOWN;
|
||||
break;
|
||||
case PLAT_DOWNBYVALUEWAITUPSTAY:
|
||||
plat->low = sec->floorheight-args[3]*8*FRACUNIT;
|
||||
if (plat->low > sec->floorheight)
|
||||
plat->low = sec->floorheight;
|
||||
plat->high = sec->floorheight;
|
||||
plat->wait = args[2];
|
||||
plat->status = PLAT_DOWN;
|
||||
break;
|
||||
case PLAT_UPWAITDOWNSTAY:
|
||||
plat->high = P_FindHighestFloorSurrounding(sec);
|
||||
if (plat->high < sec->floorheight)
|
||||
plat->high = sec->floorheight;
|
||||
plat->low = sec->floorheight;
|
||||
plat->wait = args[2];
|
||||
plat->status = PLAT_UP;
|
||||
break;
|
||||
case PLAT_UPBYVALUEWAITDOWNSTAY:
|
||||
plat->high = sec->floorheight+args[3]*8*FRACUNIT;
|
||||
if (plat->high < sec->floorheight)
|
||||
plat->high = sec->floorheight;
|
||||
plat->low = sec->floorheight;
|
||||
plat->wait = args[2];
|
||||
plat->status = PLAT_UP;
|
||||
break;
|
||||
case PLAT_PERPETUALRAISE:
|
||||
plat->low = P_FindLowestFloorSurrounding(sec)+8*FRACUNIT;
|
||||
if (plat->low > sec->floorheight)
|
||||
plat->low = sec->floorheight;
|
||||
plat->high = P_FindHighestFloorSurrounding(sec);
|
||||
if (plat->high < sec->floorheight)
|
||||
plat->high = sec->floorheight;
|
||||
plat->wait = args[2];
|
||||
plat->status = P_Random()&1;
|
||||
break;
|
||||
}
|
||||
P_AddActivePlat(plat);
|
||||
SN_StartSequence((mobj_t *)&sec->soundorg, SEQ_PLATFORM+sec->seqType);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void P_ActivateInStasis(int tag)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0;i < MAXPLATS;i++)
|
||||
if (activeplats[i] &&
|
||||
(activeplats[i])->tag == tag &&
|
||||
(activeplats[i])->status == PLAT_IN_STASIS)
|
||||
{
|
||||
(activeplats[i])->status = (activeplats[i])->oldstatus;
|
||||
(activeplats[i])->thinker.function = T_PlatRaise;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void EV_StopPlat(line_t *line, byte *args)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < MAXPLATS; i++)
|
||||
{
|
||||
if((activeplats[i])->tag = args[0])
|
||||
{
|
||||
(activeplats[i])->sector->specialdata = NULL;
|
||||
P_TagFinished((activeplats[i])->sector->tag);
|
||||
P_RemoveThinker(&(activeplats[i])->thinker);
|
||||
activeplats[i] = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
int j;
|
||||
|
||||
for (j = 0;j < MAXPLATS;j++)
|
||||
{
|
||||
if (activeplats[j] && ((activeplats[j])->status != PLAT_IN_STASIS) &&
|
||||
((activeplats[j])->tag == args[0]))
|
||||
{
|
||||
(activeplats[j])->oldstatus = (activeplats[j])->status;
|
||||
(activeplats[j])->status = PLAT_IN_STASIS;
|
||||
(activeplats[j])->thinker.function = NULL;
|
||||
SN_StopSequence((mobj_t *)&(activeplats[j])->sector->soundorg);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void P_AddActivePlat(plat_t *plat)
|
||||
{
|
||||
int i;
|
||||
for (i = 0;i < MAXPLATS;i++)
|
||||
if (activeplats[i] == NULL)
|
||||
{
|
||||
activeplats[i] = plat;
|
||||
return;
|
||||
}
|
||||
I_Error ("P_AddActivePlat: no more plats!");
|
||||
}
|
||||
|
||||
void P_RemoveActivePlat(plat_t *plat)
|
||||
{
|
||||
int i;
|
||||
for (i = 0;i < MAXPLATS;i++)
|
||||
if (plat == activeplats[i])
|
||||
{
|
||||
(activeplats[i])->sector->specialdata = NULL;
|
||||
P_TagFinished(plat->sector->tag);
|
||||
P_RemoveThinker(&(activeplats[i])->thinker);
|
||||
activeplats[i] = NULL;
|
||||
return;
|
||||
}
|
||||
I_Error ("P_RemoveActivePlat: can't find plat!");
|
||||
}
|
2456
Hexen Source/P_PSPR.C
Normal file
2456
Hexen Source/P_PSPR.C
Normal file
File diff suppressed because it is too large
Load diff
1218
Hexen Source/P_SETUP.C
Normal file
1218
Hexen Source/P_SETUP.C
Normal file
File diff suppressed because it is too large
Load diff
395
Hexen Source/P_SIGHT.C
Normal file
395
Hexen Source/P_SIGHT.C
Normal file
|
@ -0,0 +1,395 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** p_sight.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: p_sight.c,v $
|
||||
//** $Revision: 1.1 $
|
||||
//** $Date: 95/05/11 00:22:50 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
P_CheckSight
|
||||
|
||||
This uses specialized forms of the maputils routines for optimized performance
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
fixed_t sightzstart; // eye z of looker
|
||||
fixed_t topslope, bottomslope; // slopes to top and bottom of target
|
||||
|
||||
int sightcounts[3];
|
||||
|
||||
/*
|
||||
==============
|
||||
=
|
||||
= PTR_SightTraverse
|
||||
=
|
||||
==============
|
||||
*/
|
||||
|
||||
boolean PTR_SightTraverse (intercept_t *in)
|
||||
{
|
||||
line_t *li;
|
||||
fixed_t slope;
|
||||
|
||||
li = in->d.line;
|
||||
|
||||
//
|
||||
// crosses a two sided line
|
||||
//
|
||||
P_LineOpening (li);
|
||||
|
||||
if (openbottom >= opentop) // quick test for totally closed doors
|
||||
return false; // stop
|
||||
|
||||
if (li->frontsector->floorheight != li->backsector->floorheight)
|
||||
{
|
||||
slope = FixedDiv (openbottom - sightzstart , in->frac);
|
||||
if (slope > bottomslope)
|
||||
bottomslope = slope;
|
||||
}
|
||||
|
||||
if (li->frontsector->ceilingheight != li->backsector->ceilingheight)
|
||||
{
|
||||
slope = FixedDiv (opentop - sightzstart , in->frac);
|
||||
if (slope < topslope)
|
||||
topslope = slope;
|
||||
}
|
||||
|
||||
if (topslope <= bottomslope)
|
||||
return false; // stop
|
||||
|
||||
return true; // keep going
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
=
|
||||
= P_SightBlockLinesIterator
|
||||
=
|
||||
===================
|
||||
*/
|
||||
|
||||
boolean P_SightBlockLinesIterator (int x, int y )
|
||||
{
|
||||
int offset;
|
||||
short *list;
|
||||
line_t *ld;
|
||||
int s1, s2;
|
||||
divline_t dl;
|
||||
|
||||
polyblock_t *polyLink;
|
||||
seg_t **segList;
|
||||
int i;
|
||||
extern polyblock_t **PolyBlockMap;
|
||||
|
||||
offset = y*bmapwidth+x;
|
||||
|
||||
polyLink = PolyBlockMap[offset];
|
||||
while(polyLink)
|
||||
{
|
||||
if(polyLink->polyobj)
|
||||
{ // only check non-empty links
|
||||
if(polyLink->polyobj->validcount != validcount)
|
||||
{
|
||||
segList = polyLink->polyobj->segs;
|
||||
for(i = 0; i < polyLink->polyobj->numsegs; i++, segList++)
|
||||
{
|
||||
ld = (*segList)->linedef;
|
||||
if(ld->validcount == validcount)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ld->validcount = validcount;
|
||||
s1 = P_PointOnDivlineSide (ld->v1->x, ld->v1->y, &trace);
|
||||
s2 = P_PointOnDivlineSide (ld->v2->x, ld->v2->y, &trace);
|
||||
if (s1 == s2)
|
||||
continue; // line isn't crossed
|
||||
P_MakeDivline (ld, &dl);
|
||||
s1 = P_PointOnDivlineSide (trace.x, trace.y, &dl);
|
||||
s2 = P_PointOnDivlineSide (trace.x+trace.dx, trace.y+trace.dy, &dl);
|
||||
if (s1 == s2)
|
||||
continue; // line isn't crossed
|
||||
|
||||
// try to early out the check
|
||||
if (!ld->backsector)
|
||||
return false; // stop checking
|
||||
|
||||
// store the line for later intersection testing
|
||||
intercept_p->d.line = ld;
|
||||
intercept_p++;
|
||||
}
|
||||
polyLink->polyobj->validcount = validcount;
|
||||
}
|
||||
}
|
||||
polyLink = polyLink->next;
|
||||
}
|
||||
|
||||
offset = *(blockmap+offset);
|
||||
|
||||
for ( list = blockmaplump+offset ; *list != -1 ; list++)
|
||||
{
|
||||
ld = &lines[*list];
|
||||
if (ld->validcount == validcount)
|
||||
continue; // line has already been checked
|
||||
ld->validcount = validcount;
|
||||
|
||||
s1 = P_PointOnDivlineSide (ld->v1->x, ld->v1->y, &trace);
|
||||
s2 = P_PointOnDivlineSide (ld->v2->x, ld->v2->y, &trace);
|
||||
if (s1 == s2)
|
||||
continue; // line isn't crossed
|
||||
P_MakeDivline (ld, &dl);
|
||||
s1 = P_PointOnDivlineSide (trace.x, trace.y, &dl);
|
||||
s2 = P_PointOnDivlineSide (trace.x+trace.dx, trace.y+trace.dy, &dl);
|
||||
if (s1 == s2)
|
||||
continue; // line isn't crossed
|
||||
|
||||
// try to early out the check
|
||||
if (!ld->backsector)
|
||||
return false; // stop checking
|
||||
|
||||
// store the line for later intersection testing
|
||||
intercept_p->d.line = ld;
|
||||
intercept_p++;
|
||||
|
||||
}
|
||||
|
||||
return true; // everything was checked
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
=
|
||||
= P_SightTraverseIntercepts
|
||||
=
|
||||
= Returns true if the traverser function returns true for all lines
|
||||
====================
|
||||
*/
|
||||
|
||||
boolean P_SightTraverseIntercepts ( void )
|
||||
{
|
||||
int count;
|
||||
fixed_t dist;
|
||||
intercept_t *scan, *in;
|
||||
divline_t dl;
|
||||
|
||||
count = intercept_p - intercepts;
|
||||
//
|
||||
// calculate intercept distance
|
||||
//
|
||||
for (scan = intercepts ; scan<intercept_p ; scan++)
|
||||
{
|
||||
P_MakeDivline (scan->d.line, &dl);
|
||||
scan->frac = P_InterceptVector (&trace, &dl);
|
||||
}
|
||||
|
||||
//
|
||||
// go through in order
|
||||
//
|
||||
in = 0; // shut up compiler warning
|
||||
|
||||
while (count--)
|
||||
{
|
||||
dist = MAXINT;
|
||||
for (scan = intercepts ; scan<intercept_p ; scan++)
|
||||
if (scan->frac < dist)
|
||||
{
|
||||
dist = scan->frac;
|
||||
in = scan;
|
||||
}
|
||||
|
||||
if ( !PTR_SightTraverse (in) )
|
||||
return false; // don't bother going farther
|
||||
in->frac = MAXINT;
|
||||
}
|
||||
|
||||
return true; // everything was traversed
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
=
|
||||
= P_SightPathTraverse
|
||||
=
|
||||
= Traces a line from x1,y1 to x2,y2, calling the traverser function for each
|
||||
= Returns true if the traverser function returns true for all lines
|
||||
==================
|
||||
*/
|
||||
|
||||
boolean P_SightPathTraverse (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2)
|
||||
{
|
||||
fixed_t xt1,yt1,xt2,yt2;
|
||||
fixed_t xstep,ystep;
|
||||
fixed_t partial;
|
||||
fixed_t xintercept, yintercept;
|
||||
int mapx, mapy, mapxstep, mapystep;
|
||||
int count;
|
||||
|
||||
validcount++;
|
||||
intercept_p = intercepts;
|
||||
|
||||
if ( ((x1-bmaporgx)&(MAPBLOCKSIZE-1)) == 0)
|
||||
x1 += FRACUNIT; // don't side exactly on a line
|
||||
if ( ((y1-bmaporgy)&(MAPBLOCKSIZE-1)) == 0)
|
||||
y1 += FRACUNIT; // don't side exactly on a line
|
||||
trace.x = x1;
|
||||
trace.y = y1;
|
||||
trace.dx = x2 - x1;
|
||||
trace.dy = y2 - y1;
|
||||
|
||||
x1 -= bmaporgx;
|
||||
y1 -= bmaporgy;
|
||||
xt1 = x1>>MAPBLOCKSHIFT;
|
||||
yt1 = y1>>MAPBLOCKSHIFT;
|
||||
|
||||
x2 -= bmaporgx;
|
||||
y2 -= bmaporgy;
|
||||
xt2 = x2>>MAPBLOCKSHIFT;
|
||||
yt2 = y2>>MAPBLOCKSHIFT;
|
||||
|
||||
// points should never be out of bounds, but check once instead of
|
||||
// each block
|
||||
if (xt1<0 || yt1<0 || xt1>=bmapwidth || yt1>=bmapheight
|
||||
|| xt2<0 || yt2<0 || xt2>=bmapwidth || yt2>=bmapheight)
|
||||
return false;
|
||||
|
||||
if (xt2 > xt1)
|
||||
{
|
||||
mapxstep = 1;
|
||||
partial = FRACUNIT - ((x1>>MAPBTOFRAC)&(FRACUNIT-1));
|
||||
ystep = FixedDiv (y2-y1,abs(x2-x1));
|
||||
}
|
||||
else if (xt2 < xt1)
|
||||
{
|
||||
mapxstep = -1;
|
||||
partial = (x1>>MAPBTOFRAC)&(FRACUNIT-1);
|
||||
ystep = FixedDiv (y2-y1,abs(x2-x1));
|
||||
}
|
||||
else
|
||||
{
|
||||
mapxstep = 0;
|
||||
partial = FRACUNIT;
|
||||
ystep = 256*FRACUNIT;
|
||||
}
|
||||
yintercept = (y1>>MAPBTOFRAC) + FixedMul (partial, ystep);
|
||||
|
||||
|
||||
if (yt2 > yt1)
|
||||
{
|
||||
mapystep = 1;
|
||||
partial = FRACUNIT - ((y1>>MAPBTOFRAC)&(FRACUNIT-1));
|
||||
xstep = FixedDiv (x2-x1,abs(y2-y1));
|
||||
}
|
||||
else if (yt2 < yt1)
|
||||
{
|
||||
mapystep = -1;
|
||||
partial = (y1>>MAPBTOFRAC)&(FRACUNIT-1);
|
||||
xstep = FixedDiv (x2-x1,abs(y2-y1));
|
||||
}
|
||||
else
|
||||
{
|
||||
mapystep = 0;
|
||||
partial = FRACUNIT;
|
||||
xstep = 256*FRACUNIT;
|
||||
}
|
||||
xintercept = (x1>>MAPBTOFRAC) + FixedMul (partial, xstep);
|
||||
|
||||
|
||||
//
|
||||
// step through map blocks
|
||||
// Count is present to prevent a round off error from skipping the break
|
||||
mapx = xt1;
|
||||
mapy = yt1;
|
||||
|
||||
|
||||
for (count = 0 ; count < 64 ; count++)
|
||||
{
|
||||
if (!P_SightBlockLinesIterator (mapx, mapy))
|
||||
{
|
||||
sightcounts[1]++;
|
||||
return false; // early out
|
||||
}
|
||||
|
||||
if (mapx == xt2 && mapy == yt2)
|
||||
break;
|
||||
|
||||
if ( (yintercept >> FRACBITS) == mapy)
|
||||
{
|
||||
yintercept += ystep;
|
||||
mapx += mapxstep;
|
||||
}
|
||||
else if ( (xintercept >> FRACBITS) == mapx)
|
||||
{
|
||||
xintercept += xstep;
|
||||
mapy += mapystep;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// couldn't early out, so go through the sorted list
|
||||
//
|
||||
sightcounts[2]++;
|
||||
|
||||
return P_SightTraverseIntercepts ( );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
=
|
||||
= P_CheckSight
|
||||
=
|
||||
= Returns true if a straight line between t1 and t2 is unobstructed
|
||||
= look from eyes of t1 to any part of t2
|
||||
=
|
||||
=====================
|
||||
*/
|
||||
|
||||
boolean P_CheckSight (mobj_t *t1, mobj_t *t2)
|
||||
{
|
||||
int s1, s2;
|
||||
int pnum, bytenum, bitnum;
|
||||
|
||||
//
|
||||
// check for trivial rejection
|
||||
//
|
||||
s1 = (t1->subsector->sector - sectors);
|
||||
s2 = (t2->subsector->sector - sectors);
|
||||
pnum = s1*numsectors + s2;
|
||||
bytenum = pnum>>3;
|
||||
bitnum = 1 << (pnum&7);
|
||||
|
||||
if (rejectmatrix[bytenum]&bitnum)
|
||||
{
|
||||
sightcounts[0]++;
|
||||
return false; // can't possibly be connected
|
||||
}
|
||||
|
||||
//
|
||||
// check precisely
|
||||
//
|
||||
sightzstart = t1->z + t1->height - (t1->height>>2);
|
||||
topslope = (t2->z+t2->height) - sightzstart;
|
||||
bottomslope = (t2->z) - sightzstart;
|
||||
|
||||
return P_SightPathTraverse ( t1->x, t1->y, t2->x, t2->y );
|
||||
}
|
||||
|
||||
|
||||
|
1152
Hexen Source/P_SPEC.C
Normal file
1152
Hexen Source/P_SPEC.C
Normal file
File diff suppressed because it is too large
Load diff
563
Hexen Source/P_SPEC.H
Normal file
563
Hexen Source/P_SPEC.H
Normal file
|
@ -0,0 +1,563 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** p_spec.h : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: p_spec.h,v $
|
||||
//** $Revision: 1.38 $
|
||||
//** $Date: 96/01/06 18:37:35 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
extern int *TerrainTypes;
|
||||
|
||||
//
|
||||
// scrolling line specials
|
||||
//
|
||||
|
||||
#define MAXLINEANIMS 64
|
||||
extern short numlinespecials;
|
||||
extern line_t *linespeciallist[MAXLINEANIMS];
|
||||
|
||||
// Define values for map objects
|
||||
#define MO_TELEPORTMAN 14
|
||||
|
||||
// at game start
|
||||
void P_InitTerrainTypes(void);
|
||||
void P_InitLava(void);
|
||||
|
||||
// at map load
|
||||
void P_SpawnSpecials(void);
|
||||
|
||||
// every tic
|
||||
void P_UpdateSpecials(void);
|
||||
|
||||
// when needed
|
||||
boolean P_ExecuteLineSpecial(int special, byte *args, line_t *line, int side,
|
||||
mobj_t *mo);
|
||||
boolean P_ActivateLine(line_t *ld, mobj_t *mo, int side, int activationType);
|
||||
//boolean P_UseSpecialLine ( mobj_t *thing, line_t *line);
|
||||
//void P_ShootSpecialLine ( mobj_t *thing, line_t *line);
|
||||
//void P_CrossSpecialLine (int linenum, int side, mobj_t *thing);
|
||||
|
||||
void P_PlayerInSpecialSector(player_t *player);
|
||||
void P_PlayerOnSpecialFlat(player_t *player, int floorType);
|
||||
|
||||
//int twoSided(int sector,int line);
|
||||
//sector_t *getSector(int currentSector,int line,int side);
|
||||
//side_t *getSide(int currentSector,int line, int side);
|
||||
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_FindLowestCeilingSurrounding(sector_t *sec);
|
||||
fixed_t P_FindHighestCeilingSurrounding(sector_t *sec);
|
||||
//int P_FindSectorFromLineTag(line_t *line,int start);
|
||||
int P_FindSectorFromTag(int tag, int start);
|
||||
//int P_FindMinSurroundingLight(sector_t *sector,int max);
|
||||
sector_t *getNextSector(line_t *line,sector_t *sec);
|
||||
line_t *P_FindLine(int lineTag, int *searchPosition);
|
||||
|
||||
//
|
||||
// SPECIAL
|
||||
//
|
||||
//int EV_DoDonut(line_t *line);
|
||||
|
||||
//-------------------------------
|
||||
// P_anim.c
|
||||
//-------------------------------
|
||||
|
||||
void P_AnimateSurfaces(void);
|
||||
void P_InitFTAnims(void);
|
||||
void P_InitLightning(void);
|
||||
void P_ForceLightning(void);
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
P_LIGHTS
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LITE_RAISEBYVALUE,
|
||||
LITE_LOWERBYVALUE,
|
||||
LITE_CHANGETOVALUE,
|
||||
LITE_FADE,
|
||||
LITE_GLOW,
|
||||
LITE_FLICKER,
|
||||
LITE_STROBE
|
||||
} lighttype_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
lighttype_t type;
|
||||
int value1;
|
||||
int value2;
|
||||
int tics1;
|
||||
int tics2;
|
||||
int count;
|
||||
} light_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
int index;
|
||||
int base;
|
||||
} phase_t;
|
||||
|
||||
#define LIGHT_SEQUENCE_START 2
|
||||
#define LIGHT_SEQUENCE 3
|
||||
#define LIGHT_SEQUENCE_ALT 4
|
||||
|
||||
void T_Phase(phase_t *phase);
|
||||
void T_Light(light_t *light);
|
||||
void P_SpawnPhasedLight(sector_t *sector, int base, int index);
|
||||
void P_SpawnLightSequence(sector_t *sector, int indexStep);
|
||||
boolean EV_SpawnLight(line_t *line, byte *arg, lighttype_t type);
|
||||
|
||||
#if 0
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
int count;
|
||||
int maxlight;
|
||||
int minlight;
|
||||
int maxtime;
|
||||
int mintime;
|
||||
} lightflash_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
int count;
|
||||
int minlight;
|
||||
int maxlight;
|
||||
int darktime;
|
||||
int brighttime;
|
||||
} strobe_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
int minlight;
|
||||
int maxlight;
|
||||
int direction;
|
||||
} glow_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
int index;
|
||||
int base;
|
||||
} phase_t;
|
||||
|
||||
#define GLOWSPEED 8
|
||||
#define STROBEBRIGHT 5
|
||||
#define FASTDARK 15
|
||||
#define SLOWDARK 35
|
||||
|
||||
#define LIGHT_SEQUENCE_START 2
|
||||
#define LIGHT_SEQUENCE 3
|
||||
#define LIGHT_SEQUENCE_ALT 4
|
||||
|
||||
void T_LightFlash (lightflash_t *flash);
|
||||
void P_SpawnLightFlash (sector_t *sector);
|
||||
void T_StrobeFlash (strobe_t *flash);
|
||||
void P_SpawnStrobeFlash (sector_t *sector, int fastOrSlow, int inSync);
|
||||
void EV_StartLightStrobing(line_t *line);
|
||||
void EV_TurnTagLightsOff(line_t *line);
|
||||
void EV_LightTurnOn(line_t *line, int bright);
|
||||
void T_Glow(glow_t *g);
|
||||
void P_SpawnGlowingLight(sector_t *sector);
|
||||
void T_Phase(phase_t *phase);
|
||||
void P_SpawnPhasedLight(sector_t *sector, int base, int index);
|
||||
void P_SpawnLightSequence(sector_t *sector, int indexStep);
|
||||
#endif
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
P_SWITCH
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char name1[9];
|
||||
char name2[9];
|
||||
int soundID;
|
||||
} switchlist_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SWTCH_TOP,
|
||||
SWTCH_MIDDLE,
|
||||
SWTCH_BOTTOM
|
||||
} bwhere_e;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
line_t *line;
|
||||
bwhere_e where;
|
||||
int btexture;
|
||||
int btimer;
|
||||
mobj_t *soundorg;
|
||||
} button_t;
|
||||
|
||||
#define MAXSWITCHES 50 // max # of wall switches in a level
|
||||
#define MAXBUTTONS 16 // 4 players, 4 buttons each at once, max.
|
||||
#define BUTTONTIME 35 // 1 second
|
||||
|
||||
extern button_t buttonlist[MAXBUTTONS];
|
||||
|
||||
void P_ChangeSwitchTexture(line_t *line, int useAgain);
|
||||
void P_InitSwitchList(void);
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
P_PLATS
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PLAT_UP,
|
||||
PLAT_DOWN,
|
||||
PLAT_WAITING,
|
||||
// PLAT_IN_STASIS
|
||||
} plat_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PLAT_PERPETUALRAISE,
|
||||
PLAT_DOWNWAITUPSTAY,
|
||||
PLAT_DOWNBYVALUEWAITUPSTAY,
|
||||
PLAT_UPWAITDOWNSTAY,
|
||||
PLAT_UPBYVALUEWAITDOWNSTAY,
|
||||
//PLAT_RAISEANDCHANGE,
|
||||
//PLAT_RAISETONEARESTANDCHANGE
|
||||
} plattype_e;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
fixed_t speed;
|
||||
fixed_t low;
|
||||
fixed_t high;
|
||||
int wait;
|
||||
int count;
|
||||
plat_e status;
|
||||
plat_e oldstatus;
|
||||
int crush;
|
||||
int tag;
|
||||
plattype_e type;
|
||||
} plat_t;
|
||||
|
||||
#define PLATWAIT 3
|
||||
#define PLATSPEED FRACUNIT
|
||||
#define MAXPLATS 30
|
||||
|
||||
extern plat_t *activeplats[MAXPLATS];
|
||||
|
||||
void T_PlatRaise(plat_t *plat);
|
||||
int EV_DoPlat(line_t *line, byte *args, plattype_e type, int amount);
|
||||
void P_AddActivePlat(plat_t *plat);
|
||||
void P_RemoveActivePlat(plat_t *plat);
|
||||
void EV_StopPlat(line_t *line, byte *args);
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
P_DOORS
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
DREV_NORMAL,
|
||||
DREV_CLOSE30THENOPEN,
|
||||
DREV_CLOSE,
|
||||
DREV_OPEN,
|
||||
DREV_RAISEIN5MINS,
|
||||
} vldoor_e;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
vldoor_e type;
|
||||
fixed_t topheight;
|
||||
fixed_t speed;
|
||||
int direction; // 1 = up, 0 = waiting at top, -1 = down
|
||||
int topwait; // tics to wait at the top (keep in case a door going down is reset)
|
||||
int topcountdown; // when it reaches 0, start going down
|
||||
} vldoor_t;
|
||||
|
||||
#define VDOORSPEED FRACUNIT*2
|
||||
#define VDOORWAIT 150
|
||||
|
||||
boolean EV_VerticalDoor(line_t *line, mobj_t *thing);
|
||||
int EV_DoDoor(line_t *line, byte *args, vldoor_e type);
|
||||
void T_VerticalDoor(vldoor_t *door);
|
||||
//void P_SpawnDoorCloseIn30(sector_t *sec);
|
||||
//void P_SpawnDoorRaiseIn5Mins(sector_t *sec, int secnum);
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
P_CEILNG
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CLEV_LOWERTOFLOOR,
|
||||
CLEV_RAISETOHIGHEST,
|
||||
CLEV_LOWERANDCRUSH,
|
||||
CLEV_CRUSHANDRAISE,
|
||||
CLEV_LOWERBYVALUE,
|
||||
CLEV_RAISEBYVALUE,
|
||||
CLEV_CRUSHRAISEANDSTAY,
|
||||
CLEV_MOVETOVALUETIMES8
|
||||
} ceiling_e;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
ceiling_e type;
|
||||
fixed_t bottomheight, topheight;
|
||||
fixed_t speed;
|
||||
int crush;
|
||||
int direction; // 1 = up, 0 = waiting, -1 = down
|
||||
int tag; // ID
|
||||
int olddirection;
|
||||
} ceiling_t;
|
||||
|
||||
#define CEILSPEED FRACUNIT
|
||||
#define CEILWAIT 150
|
||||
#define MAXCEILINGS 30
|
||||
|
||||
extern ceiling_t *activeceilings[MAXCEILINGS];
|
||||
|
||||
int EV_DoCeiling(line_t *line, byte *args, ceiling_e type);
|
||||
void T_MoveCeiling(ceiling_t *ceiling);
|
||||
void P_AddActiveCeiling(ceiling_t *c);
|
||||
void P_RemoveActiveCeiling(ceiling_t *c);
|
||||
int EV_CeilingCrushStop(line_t *line, byte *args);
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
P_FLOOR
|
||||
|
||||
===============================================================================
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
FLEV_LOWERFLOOR, // lower floor to highest surrounding floor
|
||||
FLEV_LOWERFLOORTOLOWEST, // lower floor to lowest surrounding floor
|
||||
FLEV_LOWERFLOORBYVALUE,
|
||||
FLEV_RAISEFLOOR, // raise floor to lowest surrounding CEILING
|
||||
FLEV_RAISEFLOORTONEAREST, // raise floor to next highest surrounding floor
|
||||
FLEV_RAISEFLOORBYVALUE,
|
||||
FLEV_RAISEFLOORCRUSH,
|
||||
FLEV_RAISEBUILDSTEP, // One step of a staircase
|
||||
FLEV_RAISEBYVALUETIMES8,
|
||||
FLEV_LOWERBYVALUETIMES8,
|
||||
FLEV_LOWERTIMES8INSTANT,
|
||||
FLEV_RAISETIMES8INSTANT,
|
||||
FLEV_MOVETOVALUETIMES8
|
||||
} floor_e;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
floor_e type;
|
||||
int crush;
|
||||
int direction;
|
||||
int newspecial;
|
||||
short texture;
|
||||
fixed_t floordestheight;
|
||||
fixed_t speed;
|
||||
int delayCount;
|
||||
int delayTotal;
|
||||
fixed_t stairsDelayHeight;
|
||||
fixed_t stairsDelayHeightDelta;
|
||||
fixed_t resetHeight;
|
||||
short resetDelay;
|
||||
short resetDelayCount;
|
||||
byte textureChange;
|
||||
} floormove_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
int ceilingSpeed;
|
||||
int floorSpeed;
|
||||
int floordest;
|
||||
int ceilingdest;
|
||||
int direction;
|
||||
int crush;
|
||||
} pillar_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
thinker_t thinker;
|
||||
sector_t *sector;
|
||||
fixed_t originalHeight;
|
||||
fixed_t accumulator;
|
||||
fixed_t accDelta;
|
||||
fixed_t targetScale;
|
||||
fixed_t scale;
|
||||
fixed_t scaleDelta;
|
||||
int ticker;
|
||||
int state;
|
||||
} floorWaggle_t;
|
||||
|
||||
#define FLOORSPEED FRACUNIT
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RES_OK,
|
||||
RES_CRUSHED,
|
||||
RES_PASTDEST
|
||||
} result_e;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STAIRS_NORMAL,
|
||||
STAIRS_SYNC,
|
||||
STAIRS_PHASED
|
||||
} stairs_e;
|
||||
|
||||
result_e T_MovePlane(sector_t *sector, fixed_t speed,
|
||||
fixed_t dest, int crush, int floorOrCeiling, int direction);
|
||||
|
||||
int EV_BuildStairs(line_t *line, byte *args, int direction, stairs_e type);
|
||||
int EV_DoFloor(line_t *line, byte *args, floor_e floortype);
|
||||
void T_MoveFloor(floormove_t *floor);
|
||||
void T_BuildPillar(pillar_t *pillar);
|
||||
void T_FloorWaggle(floorWaggle_t *waggle);
|
||||
int EV_BuildPillar(line_t *line, byte *args, boolean crush);
|
||||
int EV_OpenPillar(line_t *line, byte *args);
|
||||
int EV_DoFloorAndCeiling(line_t *line, byte *args, boolean raise);
|
||||
int EV_FloorCrushStop(line_t *line, byte *args);
|
||||
boolean EV_StartFloorWaggle(int tag, int height, int speed, int offset,
|
||||
int timer);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// p_telept
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, angle_t angle,
|
||||
boolean useFog);
|
||||
boolean EV_Teleport(int tid, mobj_t *thing, boolean fog);
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// p_acs
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#define MAX_ACS_SCRIPT_VARS 10
|
||||
#define MAX_ACS_MAP_VARS 32
|
||||
#define MAX_ACS_WORLD_VARS 64
|
||||
#define ACS_STACK_DEPTH 32
|
||||
#define MAX_ACS_STORE 20
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ASTE_INACTIVE,
|
||||
ASTE_RUNNING,
|
||||
ASTE_SUSPENDED,
|
||||
ASTE_WAITINGFORTAG,
|
||||
ASTE_WAITINGFORPOLY,
|
||||
ASTE_WAITINGFORSCRIPT,
|
||||
ASTE_TERMINATING
|
||||
} aste_t;
|
||||
|
||||
typedef struct acs_s acs_t;
|
||||
typedef struct acsInfo_s acsInfo_t;
|
||||
|
||||
struct acsInfo_s
|
||||
{
|
||||
int number;
|
||||
int *address;
|
||||
int argCount;
|
||||
aste_t state;
|
||||
int waitValue;
|
||||
};
|
||||
|
||||
struct acs_s
|
||||
{
|
||||
thinker_t thinker;
|
||||
mobj_t *activator;
|
||||
line_t *line;
|
||||
int side;
|
||||
int number;
|
||||
int infoIndex;
|
||||
int delayCount;
|
||||
int stack[ACS_STACK_DEPTH];
|
||||
int stackPtr;
|
||||
int vars[MAX_ACS_SCRIPT_VARS];
|
||||
int *ip;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int map; // Target map
|
||||
int script; // Script number on target map
|
||||
byte args[4]; // Padded to 4 for alignment
|
||||
} acsstore_t;
|
||||
|
||||
void P_LoadACScripts(int lump);
|
||||
boolean P_StartACS(int number, int map, byte *args, mobj_t *activator,
|
||||
line_t *line, int side);
|
||||
boolean P_StartLockedACS(line_t *line, byte *args, mobj_t *mo, int side);
|
||||
boolean P_TerminateACS(int number, int map);
|
||||
boolean P_SuspendACS(int number, int map);
|
||||
void T_InterpretACS(acs_t *script);
|
||||
void P_TagFinished(int tag);
|
||||
void P_PolyobjFinished(int po);
|
||||
void P_ACSInitNewGame(void);
|
||||
void P_CheckACSStore(void);
|
||||
|
||||
extern int ACScriptCount;
|
||||
extern byte *ActionCodeBase;
|
||||
extern acsInfo_t *ACSInfo;
|
||||
extern int MapVars[MAX_ACS_MAP_VARS];
|
||||
extern int WorldVars[MAX_ACS_WORLD_VARS];
|
||||
extern acsstore_t ACSStore[MAX_ACS_STORE+1]; // +1 for termination marker
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// p_things
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
extern mobjtype_t TranslateThingType[];
|
||||
|
||||
boolean EV_ThingProjectile(byte *args, boolean gravity);
|
||||
boolean EV_ThingSpawn(byte *args, boolean fog);
|
||||
boolean EV_ThingActivate(int tid);
|
||||
boolean EV_ThingDeactivate(int tid);
|
||||
boolean EV_ThingRemove(int tid);
|
||||
boolean EV_ThingDestroy(int tid);
|
146
Hexen Source/P_SWITCH.C
Normal file
146
Hexen Source/P_SWITCH.C
Normal file
|
@ -0,0 +1,146 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** p_switch.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: p_switch.c,v $
|
||||
//** $Revision: 1.8 $
|
||||
//** $Date: 95/09/05 13:58:59 $
|
||||
//** $Author: cjr $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
#include "soundst.h"
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// CHANGE THE TEXTURE OF A WALL SWITCH TO ITS OPPOSITE
|
||||
//
|
||||
//==================================================================
|
||||
switchlist_t alphSwitchList[] =
|
||||
{
|
||||
{ "SW_1_UP", "SW_1_DN", SFX_SWITCH1 },
|
||||
{ "SW_2_UP", "SW_2_DN", SFX_SWITCH1 },
|
||||
{ "VALVE1", "VALVE2", SFX_VALVE_TURN },
|
||||
{ "SW51_OFF", "SW51_ON", SFX_SWITCH2 },
|
||||
{ "SW52_OFF", "SW52_ON", SFX_SWITCH2 },
|
||||
{ "SW53_UP", "SW53_DN", SFX_ROPE_PULL },
|
||||
{ "PUZZLE5", "PUZZLE9", SFX_SWITCH1 },
|
||||
{ "PUZZLE6", "PUZZLE10", SFX_SWITCH1 },
|
||||
{ "PUZZLE7", "PUZZLE11", SFX_SWITCH1 },
|
||||
{ "PUZZLE8", "PUZZLE12", SFX_SWITCH1 },
|
||||
{"\0", "\0", 0}
|
||||
};
|
||||
|
||||
int switchlist[MAXSWITCHES * 2];
|
||||
int numswitches;
|
||||
button_t buttonlist[MAXBUTTONS];
|
||||
|
||||
/*
|
||||
===============
|
||||
=
|
||||
= P_InitSwitchList
|
||||
=
|
||||
= Only called at game initialization
|
||||
=
|
||||
===============
|
||||
*/
|
||||
|
||||
void P_InitSwitchList(void)
|
||||
{
|
||||
int i;
|
||||
int index;
|
||||
|
||||
for (index = 0, i = 0; i < MAXSWITCHES; i++)
|
||||
{
|
||||
if(!alphSwitchList[i].soundID)
|
||||
{
|
||||
numswitches = index/2;
|
||||
switchlist[index] = -1;
|
||||
break;
|
||||
}
|
||||
switchlist[index++] = R_TextureNumForName(alphSwitchList[i].name1);
|
||||
switchlist[index++] = R_TextureNumForName(alphSwitchList[i].name2);
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// Start a button counting down till it turns off.
|
||||
//
|
||||
//==================================================================
|
||||
void P_StartButton(line_t *line,bwhere_e w,int texture,int time)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0;i < MAXBUTTONS;i++)
|
||||
{
|
||||
if (!buttonlist[i].btimer)
|
||||
{
|
||||
buttonlist[i].line = line;
|
||||
buttonlist[i].where = w;
|
||||
buttonlist[i].btexture = texture;
|
||||
buttonlist[i].btimer = time;
|
||||
buttonlist[i].soundorg = (mobj_t *)&line->frontsector->soundorg;
|
||||
return;
|
||||
}
|
||||
}
|
||||
I_Error("P_StartButton: no button slots left!");
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
//
|
||||
// Function that changes wall texture.
|
||||
// Tell it if switch is ok to use again (1=yes, it's a button).
|
||||
//
|
||||
//==================================================================
|
||||
void P_ChangeSwitchTexture(line_t *line, int useAgain)
|
||||
{
|
||||
int texTop;
|
||||
int texMid;
|
||||
int texBot;
|
||||
int i;
|
||||
|
||||
texTop = sides[line->sidenum[0]].toptexture;
|
||||
texMid = sides[line->sidenum[0]].midtexture;
|
||||
texBot = sides[line->sidenum[0]].bottomtexture;
|
||||
|
||||
for (i = 0; i < numswitches*2; i++)
|
||||
{
|
||||
if (switchlist[i] == texTop)
|
||||
{
|
||||
S_StartSound((mobj_t *)&line->frontsector->soundorg,
|
||||
alphSwitchList[i/2].soundID);
|
||||
sides[line->sidenum[0]].toptexture = switchlist[i^1];
|
||||
if(useAgain)
|
||||
{
|
||||
P_StartButton(line, SWTCH_TOP, switchlist[i], BUTTONTIME);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (switchlist[i] == texMid)
|
||||
{
|
||||
S_StartSound((mobj_t *)&line->frontsector->soundorg,
|
||||
alphSwitchList[i/2].soundID);
|
||||
sides[line->sidenum[0]].midtexture = switchlist[i^1];
|
||||
if(useAgain)
|
||||
{
|
||||
P_StartButton(line, SWTCH_MIDDLE, switchlist[i], BUTTONTIME);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (switchlist[i] == texBot)
|
||||
{
|
||||
S_StartSound((mobj_t *)&line->frontsector->soundorg,
|
||||
alphSwitchList[i/2].soundID);
|
||||
sides[line->sidenum[0]].bottomtexture = switchlist[i^1];
|
||||
if(useAgain)
|
||||
{
|
||||
P_StartButton(line, SWTCH_BOTTOM, switchlist[i], BUTTONTIME);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
177
Hexen Source/P_TELEPT.C
Normal file
177
Hexen Source/P_TELEPT.C
Normal file
|
@ -0,0 +1,177 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** p_telept.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: p_telept.c,v $
|
||||
//** $Revision: 1.13 $
|
||||
//** $Date: 95/10/08 04:23:24 $
|
||||
//** $Author: paul $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
#include "soundst.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_Teleport
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, angle_t angle,
|
||||
boolean useFog)
|
||||
{
|
||||
fixed_t oldx;
|
||||
fixed_t oldy;
|
||||
fixed_t oldz;
|
||||
fixed_t aboveFloor;
|
||||
fixed_t fogDelta;
|
||||
player_t *player;
|
||||
unsigned an;
|
||||
mobj_t *fog;
|
||||
|
||||
oldx = thing->x;
|
||||
oldy = thing->y;
|
||||
oldz = thing->z;
|
||||
aboveFloor = thing->z-thing->floorz;
|
||||
if(!P_TeleportMove(thing, x, y))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(thing->player)
|
||||
{
|
||||
player = thing->player;
|
||||
if(player->powers[pw_flight] && aboveFloor)
|
||||
{
|
||||
thing->z = thing->floorz+aboveFloor;
|
||||
if(thing->z+thing->height > thing->ceilingz)
|
||||
{
|
||||
thing->z = thing->ceilingz-thing->height;
|
||||
}
|
||||
player->viewz = thing->z+player->viewheight;
|
||||
}
|
||||
else
|
||||
{
|
||||
thing->z = thing->floorz;
|
||||
player->viewz = thing->z+player->viewheight;
|
||||
if(useFog)
|
||||
{
|
||||
player->lookdir = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(thing->flags&MF_MISSILE)
|
||||
{
|
||||
thing->z = thing->floorz+aboveFloor;
|
||||
if(thing->z+thing->height > thing->ceilingz)
|
||||
{
|
||||
thing->z = thing->ceilingz-thing->height;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
thing->z = thing->floorz;
|
||||
}
|
||||
// Spawn teleport fog at source and destination
|
||||
if(useFog)
|
||||
{
|
||||
fogDelta = thing->flags&MF_MISSILE ? 0 : TELEFOGHEIGHT;
|
||||
fog = P_SpawnMobj(oldx, oldy, oldz+fogDelta, MT_TFOG);
|
||||
S_StartSound(fog, SFX_TELEPORT);
|
||||
an = angle>>ANGLETOFINESHIFT;
|
||||
fog = P_SpawnMobj(x+20*finecosine[an],
|
||||
y+20*finesine[an], thing->z+fogDelta, MT_TFOG);
|
||||
S_StartSound(fog, SFX_TELEPORT);
|
||||
if(thing->player && !thing->player->powers[pw_speed])
|
||||
{ // Freeze player for about .5 sec
|
||||
thing->reactiontime = 18;
|
||||
}
|
||||
thing->angle = angle;
|
||||
}
|
||||
if(thing->flags2&MF2_FLOORCLIP)
|
||||
{
|
||||
if(thing->z == thing->subsector->sector->floorheight
|
||||
&& P_GetThingFloorType(thing) > FLOOR_SOLID)
|
||||
{
|
||||
thing->floorclip = 10*FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
thing->floorclip = 0;
|
||||
}
|
||||
}
|
||||
if(thing->flags&MF_MISSILE)
|
||||
{
|
||||
angle >>= ANGLETOFINESHIFT;
|
||||
thing->momx = FixedMul(thing->info->speed, finecosine[angle]);
|
||||
thing->momy = FixedMul(thing->info->speed, finesine[angle]);
|
||||
}
|
||||
else if(useFog) // no fog doesn't alter the player's momentums
|
||||
{
|
||||
thing->momx = thing->momy = thing->momz = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// EV_Teleport
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
boolean EV_Teleport(int tid, mobj_t *thing, boolean fog)
|
||||
{
|
||||
int i;
|
||||
int count;
|
||||
mobj_t *mo;
|
||||
int searcher;
|
||||
|
||||
if(!thing)
|
||||
{ // Teleport function called with an invalid mobj
|
||||
return false;
|
||||
}
|
||||
if(thing->flags2&MF2_NOTELEPORT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
count = 0;
|
||||
searcher = -1;
|
||||
while(P_FindMobjFromTID(tid, &searcher) != NULL)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
if(count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
count = 1+(P_Random()%count);
|
||||
searcher = -1;
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
mo = P_FindMobjFromTID(tid, &searcher);
|
||||
}
|
||||
if (!mo) I_Error("Can't find teleport mapspot\n");
|
||||
return P_Teleport(thing, mo->x, mo->y, mo->angle, fog);
|
||||
}
|
533
Hexen Source/P_THINGS.C
Normal file
533
Hexen Source/P_THINGS.C
Normal file
|
@ -0,0 +1,533 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** p_things.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: p_things.c,v $
|
||||
//** $Revision: 1.36 $
|
||||
//** $Date: 96/02/08 15:16:13 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
#include "soundst.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static boolean ActivateThing(mobj_t *mobj);
|
||||
static boolean DeactivateThing(mobj_t *mobj);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
mobjtype_t TranslateThingType[] =
|
||||
{
|
||||
MT_MAPSPOT, // T_NONE
|
||||
MT_CENTAUR, // T_CENTAUR
|
||||
MT_CENTAURLEADER, // T_CENTAURLEADER
|
||||
MT_DEMON, // T_DEMON
|
||||
MT_ETTIN, // T_ETTIN
|
||||
MT_FIREDEMON, // T_FIREGARGOYLE
|
||||
MT_SERPENT, // T_WATERLURKER
|
||||
MT_SERPENTLEADER, // T_WATERLURKERLEADER
|
||||
MT_WRAITH, // T_WRAITH
|
||||
MT_WRAITHB, // T_WRAITHBURIED
|
||||
MT_FIREBALL1, // T_FIREBALL1
|
||||
MT_MANA1, // T_MANA1
|
||||
MT_MANA2, // T_MANA2
|
||||
MT_SPEEDBOOTS, // T_ITEMBOOTS
|
||||
MT_ARTIEGG, // T_ITEMEGG
|
||||
MT_ARTIFLY, // T_ITEMFLIGHT
|
||||
MT_SUMMONMAULATOR, // T_ITEMSUMMON
|
||||
MT_TELEPORTOTHER, // T_ITEMTPORTOTHER
|
||||
MT_ARTITELEPORT, // T_ITEMTELEPORT
|
||||
MT_BISHOP, // T_BISHOP
|
||||
MT_ICEGUY, // T_ICEGOLEM
|
||||
MT_BRIDGE, // T_BRIDGE
|
||||
MT_BOOSTARMOR, // T_DRAGONSKINBRACERS
|
||||
MT_HEALINGBOTTLE, // T_ITEMHEALTHPOTION
|
||||
MT_HEALTHFLASK, // T_ITEMHEALTHFLASK
|
||||
MT_ARTISUPERHEAL, // T_ITEMHEALTHFULL
|
||||
MT_BOOSTMANA, // T_ITEMBOOSTMANA
|
||||
MT_FW_AXE, // T_FIGHTERAXE
|
||||
MT_FW_HAMMER, // T_FIGHTERHAMMER
|
||||
MT_FW_SWORD1, // T_FIGHTERSWORD1
|
||||
MT_FW_SWORD2, // T_FIGHTERSWORD2
|
||||
MT_FW_SWORD3, // T_FIGHTERSWORD3
|
||||
MT_CW_SERPSTAFF, // T_CLERICSTAFF
|
||||
MT_CW_HOLY1, // T_CLERICHOLY1
|
||||
MT_CW_HOLY2, // T_CLERICHOLY2
|
||||
MT_CW_HOLY3, // T_CLERICHOLY3
|
||||
MT_MW_CONE, // T_MAGESHARDS
|
||||
MT_MW_STAFF1, // T_MAGESTAFF1
|
||||
MT_MW_STAFF2, // T_MAGESTAFF2
|
||||
MT_MW_STAFF3, // T_MAGESTAFF3
|
||||
MT_EGGFX, // T_MORPHBLAST
|
||||
MT_ROCK1, // T_ROCK1
|
||||
MT_ROCK2, // T_ROCK2
|
||||
MT_ROCK3, // T_ROCK3
|
||||
MT_DIRT1, // T_DIRT1
|
||||
MT_DIRT2, // T_DIRT2
|
||||
MT_DIRT3, // T_DIRT3
|
||||
MT_DIRT4, // T_DIRT4
|
||||
MT_DIRT5, // T_DIRT5
|
||||
MT_DIRT6, // T_DIRT6
|
||||
MT_ARROW, // T_ARROW
|
||||
MT_DART, // T_DART
|
||||
MT_POISONDART, // T_POISONDART
|
||||
MT_RIPPERBALL, // T_RIPPERBALL
|
||||
MT_SGSHARD1, // T_STAINEDGLASS1
|
||||
MT_SGSHARD2, // T_STAINEDGLASS2
|
||||
MT_SGSHARD3, // T_STAINEDGLASS3
|
||||
MT_SGSHARD4, // T_STAINEDGLASS4
|
||||
MT_SGSHARD5, // T_STAINEDGLASS5
|
||||
MT_SGSHARD6, // T_STAINEDGLASS6
|
||||
MT_SGSHARD7, // T_STAINEDGLASS7
|
||||
MT_SGSHARD8, // T_STAINEDGLASS8
|
||||
MT_SGSHARD9, // T_STAINEDGLASS9
|
||||
MT_SGSHARD0, // T_STAINEDGLASS0
|
||||
MT_PROJECTILE_BLADE, // T_BLADE
|
||||
MT_ICESHARD, // T_ICESHARD
|
||||
MT_FLAME_SMALL, // T_FLAME_SMALL
|
||||
MT_FLAME_LARGE, // T_FLAME_LARGE
|
||||
MT_ARMOR_1, // T_MESHARMOR
|
||||
MT_ARMOR_2, // T_FALCONSHIELD
|
||||
MT_ARMOR_3, // T_PLATINUMHELM
|
||||
MT_ARMOR_4, // T_AMULETOFWARDING
|
||||
MT_ARTIPOISONBAG, // T_ITEMFLECHETTE
|
||||
MT_ARTITORCH, // T_ITEMTORCH
|
||||
MT_BLASTRADIUS, // T_ITEMREPULSION
|
||||
MT_MANA3, // T_MANA3
|
||||
MT_ARTIPUZZSKULL, // T_PUZZSKULL
|
||||
MT_ARTIPUZZGEMBIG, // T_PUZZGEMBIG
|
||||
MT_ARTIPUZZGEMRED, // T_PUZZGEMRED
|
||||
MT_ARTIPUZZGEMGREEN1, // T_PUZZGEMGREEN1
|
||||
MT_ARTIPUZZGEMGREEN2, // T_PUZZGEMGREEN2
|
||||
MT_ARTIPUZZGEMBLUE1, // T_PUZZGEMBLUE1
|
||||
MT_ARTIPUZZGEMBLUE2, // T_PUZZGEMBLUE2
|
||||
MT_ARTIPUZZBOOK1, // T_PUZZBOOK1
|
||||
MT_ARTIPUZZBOOK2, // T_PUZZBOOK2
|
||||
MT_KEY1, // T_METALKEY
|
||||
MT_KEY2, // T_SMALLMETALKEY
|
||||
MT_KEY3, // T_AXEKEY
|
||||
MT_KEY4, // T_FIREKEY
|
||||
MT_KEY5, // T_GREENKEY
|
||||
MT_KEY6, // T_MACEKEY
|
||||
MT_KEY7, // T_SILVERKEY
|
||||
MT_KEY8, // T_RUSTYKEY
|
||||
MT_KEY9, // T_HORNKEY
|
||||
MT_KEYA, // T_SERPENTKEY
|
||||
MT_WATER_DRIP, // T_WATERDRIP
|
||||
MT_FLAME_SMALL_TEMP, // T_TEMPSMALLFLAME
|
||||
MT_FLAME_SMALL, // T_PERMSMALLFLAME
|
||||
MT_FLAME_LARGE_TEMP, // T_TEMPLARGEFLAME
|
||||
MT_FLAME_LARGE, // T_PERMLARGEFLAME
|
||||
MT_DEMON_MASH, // T_DEMON_MASH
|
||||
MT_DEMON2_MASH, // T_DEMON2_MASH
|
||||
MT_ETTIN_MASH, // T_ETTIN_MASH
|
||||
MT_CENTAUR_MASH, // T_CENTAUR_MASH
|
||||
MT_THRUSTFLOOR_UP, // T_THRUSTSPIKEUP
|
||||
MT_THRUSTFLOOR_DOWN, // T_THRUSTSPIKEDOWN
|
||||
MT_WRAITHFX4, // T_FLESH_DRIP1
|
||||
MT_WRAITHFX5, // T_FLESH_DRIP2
|
||||
MT_WRAITHFX2 // T_SPARK_DRIP
|
||||
};
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// EV_ThingProjectile
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
boolean EV_ThingProjectile(byte *args, boolean gravity)
|
||||
{
|
||||
int tid;
|
||||
angle_t angle;
|
||||
int fineAngle;
|
||||
fixed_t speed;
|
||||
fixed_t vspeed;
|
||||
mobjtype_t moType;
|
||||
mobj_t *mobj;
|
||||
mobj_t *newMobj;
|
||||
int searcher;
|
||||
boolean success;
|
||||
|
||||
success = false;
|
||||
searcher = -1;
|
||||
tid = args[0];
|
||||
moType = TranslateThingType[args[1]];
|
||||
if(nomonsters && (mobjinfo[moType].flags&MF_COUNTKILL))
|
||||
{ // Don't spawn monsters if -nomonsters
|
||||
return false;
|
||||
}
|
||||
angle = (int)args[2]<<24;
|
||||
fineAngle = angle>>ANGLETOFINESHIFT;
|
||||
speed = (int)args[3]<<13;
|
||||
vspeed = (int)args[4]<<13;
|
||||
while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
|
||||
{
|
||||
newMobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, moType);
|
||||
if(newMobj->info->seesound)
|
||||
{
|
||||
S_StartSound(newMobj, newMobj->info->seesound);
|
||||
}
|
||||
newMobj->target = mobj; // Originator
|
||||
newMobj->angle = angle;
|
||||
newMobj->momx = FixedMul(speed, finecosine[fineAngle]);
|
||||
newMobj->momy = FixedMul(speed, finesine[fineAngle]);
|
||||
newMobj->momz = vspeed;
|
||||
newMobj->flags2 |= MF2_DROPPED; // Don't respawn
|
||||
if(gravity == true)
|
||||
{
|
||||
newMobj->flags &= ~MF_NOGRAVITY;
|
||||
newMobj->flags2 |= MF2_LOGRAV;
|
||||
}
|
||||
if(P_CheckMissileSpawn(newMobj) == true)
|
||||
{
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// EV_ThingSpawn
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
boolean EV_ThingSpawn(byte *args, boolean fog)
|
||||
{
|
||||
int tid;
|
||||
angle_t angle;
|
||||
mobj_t *mobj;
|
||||
mobj_t *newMobj;
|
||||
mobj_t *fogMobj;
|
||||
mobjtype_t moType;
|
||||
int searcher;
|
||||
boolean success;
|
||||
fixed_t z;
|
||||
|
||||
success = false;
|
||||
searcher = -1;
|
||||
tid = args[0];
|
||||
moType = TranslateThingType[args[1]];
|
||||
if(nomonsters && (mobjinfo[moType].flags&MF_COUNTKILL))
|
||||
{ // Don't spawn monsters if -nomonsters
|
||||
return false;
|
||||
}
|
||||
angle = (int)args[2]<<24;
|
||||
while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
|
||||
{
|
||||
if (mobjinfo[moType].flags2&MF2_FLOATBOB)
|
||||
{
|
||||
z = mobj->z - mobj->floorz;
|
||||
}
|
||||
else
|
||||
{
|
||||
z = mobj->z;
|
||||
}
|
||||
newMobj = P_SpawnMobj(mobj->x, mobj->y, z, moType);
|
||||
if(P_TestMobjLocation(newMobj) == false)
|
||||
{ // Didn't fit
|
||||
P_RemoveMobj(newMobj);
|
||||
}
|
||||
else
|
||||
{
|
||||
newMobj->angle = angle;
|
||||
if(fog == true)
|
||||
{
|
||||
fogMobj = P_SpawnMobj(mobj->x, mobj->y,
|
||||
mobj->z+TELEFOGHEIGHT, MT_TFOG);
|
||||
S_StartSound(fogMobj, SFX_TELEPORT);
|
||||
}
|
||||
newMobj->flags2 |= MF2_DROPPED; // Don't respawn
|
||||
if (newMobj->flags2&MF2_FLOATBOB)
|
||||
{
|
||||
newMobj->special1 = newMobj->z - newMobj->floorz;
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// EV_ThingActivate
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
boolean EV_ThingActivate(int tid)
|
||||
{
|
||||
mobj_t *mobj;
|
||||
int searcher;
|
||||
boolean success;
|
||||
|
||||
success = false;
|
||||
searcher = -1;
|
||||
while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
|
||||
{
|
||||
if(ActivateThing(mobj) == true)
|
||||
{
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// EV_ThingDeactivate
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
boolean EV_ThingDeactivate(int tid)
|
||||
{
|
||||
mobj_t *mobj;
|
||||
int searcher;
|
||||
boolean success;
|
||||
|
||||
success = false;
|
||||
searcher = -1;
|
||||
while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
|
||||
{
|
||||
if(DeactivateThing(mobj) == true)
|
||||
{
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// EV_ThingRemove
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
boolean EV_ThingRemove(int tid)
|
||||
{
|
||||
mobj_t *mobj;
|
||||
int searcher;
|
||||
boolean success;
|
||||
|
||||
success = false;
|
||||
searcher = -1;
|
||||
while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
|
||||
{
|
||||
if (mobj->type == MT_BRIDGE)
|
||||
{
|
||||
A_BridgeRemove(mobj);
|
||||
return true;
|
||||
}
|
||||
P_RemoveMobj(mobj);
|
||||
success = true;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// EV_ThingDestroy
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
boolean EV_ThingDestroy(int tid)
|
||||
{
|
||||
mobj_t *mobj;
|
||||
int searcher;
|
||||
boolean success;
|
||||
|
||||
success = false;
|
||||
searcher = -1;
|
||||
while((mobj = P_FindMobjFromTID(tid, &searcher)) != NULL)
|
||||
{
|
||||
if(mobj->flags&MF_SHOOTABLE)
|
||||
{
|
||||
P_DamageMobj(mobj, NULL, NULL, 10000);
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// EV_ThingMove
|
||||
//
|
||||
// arg[0] = tid
|
||||
// arg[1] = speed
|
||||
// arg[2] = angle (255 = use mobj angle)
|
||||
// arg[3] = distance (pixels>>2)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
boolean EV_ThingMove(byte *args)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ActivateThing
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static boolean ActivateThing(mobj_t *mobj)
|
||||
{
|
||||
if(mobj->flags&MF_COUNTKILL)
|
||||
{ // Monster
|
||||
if(mobj->flags2&MF2_DORMANT)
|
||||
{
|
||||
mobj->flags2 &= ~MF2_DORMANT;
|
||||
mobj->tics = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
switch(mobj->type)
|
||||
{
|
||||
case MT_ZTWINEDTORCH:
|
||||
case MT_ZTWINEDTORCH_UNLIT:
|
||||
P_SetMobjState(mobj, S_ZTWINEDTORCH_1);
|
||||
S_StartSound(mobj, SFX_IGNITE);
|
||||
break;
|
||||
case MT_ZWALLTORCH:
|
||||
case MT_ZWALLTORCH_UNLIT:
|
||||
P_SetMobjState(mobj, S_ZWALLTORCH1);
|
||||
S_StartSound(mobj, SFX_IGNITE);
|
||||
break;
|
||||
case MT_ZGEMPEDESTAL:
|
||||
P_SetMobjState(mobj, S_ZGEMPEDESTAL2);
|
||||
break;
|
||||
case MT_ZWINGEDSTATUENOSKULL:
|
||||
P_SetMobjState(mobj, S_ZWINGEDSTATUENOSKULL2);
|
||||
break;
|
||||
case MT_THRUSTFLOOR_UP:
|
||||
case MT_THRUSTFLOOR_DOWN:
|
||||
if (mobj->args[0]==0)
|
||||
{
|
||||
S_StartSound(mobj, SFX_THRUSTSPIKE_LOWER);
|
||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
||||
if (mobj->args[1])
|
||||
P_SetMobjState(mobj, S_BTHRUSTRAISE1);
|
||||
else
|
||||
P_SetMobjState(mobj, S_THRUSTRAISE1);
|
||||
}
|
||||
break;
|
||||
case MT_ZFIREBULL:
|
||||
case MT_ZFIREBULL_UNLIT:
|
||||
P_SetMobjState(mobj, S_ZFIREBULL_BIRTH);
|
||||
S_StartSound(mobj, SFX_IGNITE);
|
||||
break;
|
||||
case MT_ZBELL:
|
||||
if(mobj->health > 0)
|
||||
{
|
||||
P_DamageMobj(mobj, NULL, NULL, 10); // 'ring' the bell
|
||||
}
|
||||
break;
|
||||
case MT_ZCAULDRON:
|
||||
case MT_ZCAULDRON_UNLIT:
|
||||
P_SetMobjState(mobj, S_ZCAULDRON1);
|
||||
S_StartSound(mobj, SFX_IGNITE);
|
||||
break;
|
||||
case MT_FLAME_SMALL:
|
||||
S_StartSound(mobj, SFX_IGNITE);
|
||||
P_SetMobjState(mobj, S_FLAME_SMALL1);
|
||||
break;
|
||||
case MT_FLAME_LARGE:
|
||||
S_StartSound(mobj, SFX_IGNITE);
|
||||
P_SetMobjState(mobj, S_FLAME_LARGE1);
|
||||
break;
|
||||
case MT_BAT_SPAWNER:
|
||||
P_SetMobjState(mobj, S_SPAWNBATS1);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DeactivateThing
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static boolean DeactivateThing(mobj_t *mobj)
|
||||
{
|
||||
if(mobj->flags&MF_COUNTKILL)
|
||||
{ // Monster
|
||||
if(!(mobj->flags2&MF2_DORMANT))
|
||||
{
|
||||
mobj->flags2 |= MF2_DORMANT;
|
||||
mobj->tics = -1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
switch(mobj->type)
|
||||
{
|
||||
case MT_ZTWINEDTORCH:
|
||||
case MT_ZTWINEDTORCH_UNLIT:
|
||||
P_SetMobjState(mobj, S_ZTWINEDTORCH_UNLIT);
|
||||
break;
|
||||
case MT_ZWALLTORCH:
|
||||
case MT_ZWALLTORCH_UNLIT:
|
||||
P_SetMobjState(mobj, S_ZWALLTORCH_U);
|
||||
break;
|
||||
case MT_THRUSTFLOOR_UP:
|
||||
case MT_THRUSTFLOOR_DOWN:
|
||||
if (mobj->args[0]==1)
|
||||
{
|
||||
S_StartSound(mobj, SFX_THRUSTSPIKE_RAISE);
|
||||
if (mobj->args[1])
|
||||
P_SetMobjState(mobj, S_BTHRUSTLOWER);
|
||||
else
|
||||
P_SetMobjState(mobj, S_THRUSTLOWER);
|
||||
}
|
||||
break;
|
||||
case MT_ZFIREBULL:
|
||||
case MT_ZFIREBULL_UNLIT:
|
||||
P_SetMobjState(mobj, S_ZFIREBULL_DEATH);
|
||||
break;
|
||||
case MT_ZCAULDRON:
|
||||
case MT_ZCAULDRON_UNLIT:
|
||||
P_SetMobjState(mobj, S_ZCAULDRON_U);
|
||||
break;
|
||||
case MT_FLAME_SMALL:
|
||||
P_SetMobjState(mobj, S_FLAME_SDORM1);
|
||||
break;
|
||||
case MT_FLAME_LARGE:
|
||||
P_SetMobjState(mobj, S_FLAME_LDORM1);
|
||||
break;
|
||||
case MT_BAT_SPAWNER:
|
||||
P_SetMobjState(mobj, S_SPAWNBATS_OFF);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
142
Hexen Source/P_TICK.C
Normal file
142
Hexen Source/P_TICK.C
Normal file
|
@ -0,0 +1,142 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** p_tick.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: p_tick.c,v $
|
||||
//** $Revision: 1.5 $
|
||||
//** $Date: 95/10/08 21:53:00 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include "h2def.h"
|
||||
#include "p_local.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static void RunThinkers(void);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
int leveltime;
|
||||
int TimerGame;
|
||||
thinker_t thinkercap; // The head and tail of the thinker list
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_Ticker
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_Ticker(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(paused)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for(i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if(playeringame[i])
|
||||
{
|
||||
P_PlayerThink(&players[i]);
|
||||
}
|
||||
}
|
||||
if(TimerGame)
|
||||
{
|
||||
if(!--TimerGame)
|
||||
{
|
||||
G_Completed(P_TranslateMap(P_GetMapNextMap(gamemap)), 0);
|
||||
}
|
||||
}
|
||||
RunThinkers();
|
||||
P_UpdateSpecials();
|
||||
P_AnimateSurfaces();
|
||||
leveltime++;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// RunThinkers
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void RunThinkers(void)
|
||||
{
|
||||
thinker_t *currentthinker;
|
||||
|
||||
currentthinker = thinkercap.next;
|
||||
while(currentthinker != &thinkercap)
|
||||
{
|
||||
if(currentthinker->function == (think_t)-1)
|
||||
{ // Time to remove it
|
||||
currentthinker->next->prev = currentthinker->prev;
|
||||
currentthinker->prev->next = currentthinker->next;
|
||||
Z_Free(currentthinker);
|
||||
}
|
||||
else if(currentthinker->function)
|
||||
{
|
||||
currentthinker->function(currentthinker);
|
||||
}
|
||||
currentthinker = currentthinker->next;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_InitThinkers
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_InitThinkers(void)
|
||||
{
|
||||
thinkercap.prev = thinkercap.next = &thinkercap;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_AddThinker
|
||||
//
|
||||
// Adds a new thinker at the end of the list.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_AddThinker(thinker_t *thinker)
|
||||
{
|
||||
thinkercap.prev->next = thinker;
|
||||
thinker->next = &thinkercap;
|
||||
thinker->prev = thinkercap.prev;
|
||||
thinkercap.prev = thinker;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// P_RemoveThinker
|
||||
//
|
||||
// Deallocation is lazy -- it will not actually be freed until its
|
||||
// thinking turn comes up.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void P_RemoveThinker(thinker_t *thinker)
|
||||
{
|
||||
thinker->function = (think_t)-1;
|
||||
}
|
1652
Hexen Source/P_USER.C
Normal file
1652
Hexen Source/P_USER.C
Normal file
File diff suppressed because it is too large
Load diff
504
Hexen Source/R_BSP.C
Normal file
504
Hexen Source/R_BSP.C
Normal file
|
@ -0,0 +1,504 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** r_bsp.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: r_bsp.c,v $
|
||||
//** $Revision: 1.2 $
|
||||
//** $Date: 95/07/13 15:17:10 $
|
||||
//** $Author: cjr $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
#include "r_local.h"
|
||||
|
||||
seg_t *curline;
|
||||
side_t *sidedef;
|
||||
line_t *linedef;
|
||||
sector_t *frontsector, *backsector;
|
||||
|
||||
drawseg_t drawsegs[MAXDRAWSEGS], *ds_p;
|
||||
|
||||
void R_StoreWallRange (int start, int stop);
|
||||
|
||||
/*
|
||||
====================
|
||||
=
|
||||
= R_ClearDrawSegs
|
||||
=
|
||||
====================
|
||||
*/
|
||||
|
||||
void R_ClearDrawSegs (void)
|
||||
{
|
||||
ds_p = drawsegs;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
=
|
||||
= ClipWallSegment
|
||||
=
|
||||
= Clips the given range of columns and includes it in the new clip list
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int first, last;
|
||||
} cliprange_t;
|
||||
|
||||
#define MAXSEGS 32
|
||||
|
||||
cliprange_t solidsegs[MAXSEGS], *newend; // newend is one past the last valid seg
|
||||
|
||||
|
||||
void R_ClipSolidWallSegment (int first, int last)
|
||||
{
|
||||
cliprange_t *next, *start;
|
||||
|
||||
// find the first range that touches the range (adjacent pixels are touching)
|
||||
start = solidsegs;
|
||||
while (start->last < first-1)
|
||||
start++;
|
||||
|
||||
if (first < start->first)
|
||||
{
|
||||
if (last < start->first-1)
|
||||
{ // post is entirely visible (above start), so insert a new clippost
|
||||
R_StoreWallRange (first, last);
|
||||
next = newend;
|
||||
newend++;
|
||||
while (next != start)
|
||||
{
|
||||
*next = *(next-1);
|
||||
next--;
|
||||
}
|
||||
next->first = first;
|
||||
next->last = last;
|
||||
return;
|
||||
}
|
||||
|
||||
// there is a fragment above *start
|
||||
R_StoreWallRange (first, start->first - 1);
|
||||
start->first = first; // adjust the clip size
|
||||
}
|
||||
|
||||
if (last <= start->last)
|
||||
return; // bottom contained in start
|
||||
|
||||
next = start;
|
||||
while (last >= (next+1)->first-1)
|
||||
{
|
||||
// there is a fragment between two posts
|
||||
R_StoreWallRange (next->last + 1, (next+1)->first - 1);
|
||||
next++;
|
||||
if (last <= next->last)
|
||||
{ // bottom is contained in next
|
||||
start->last = next->last; // adjust the clip size
|
||||
goto crunch;
|
||||
}
|
||||
}
|
||||
|
||||
// there is a fragment after *next
|
||||
R_StoreWallRange (next->last + 1, last);
|
||||
start->last = last; // adjust the clip size
|
||||
|
||||
|
||||
// remove start+1 to next from the clip list,
|
||||
// because start now covers their area
|
||||
crunch:
|
||||
if (next == start)
|
||||
return; // post just extended past the bottom of one post
|
||||
|
||||
while (next++ != newend) // remove a post
|
||||
*++start = *next;
|
||||
newend = start+1;
|
||||
}
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
=
|
||||
= R_ClipPassWallSegment
|
||||
=
|
||||
= Clips the given range of columns, but does not includes it in the clip list
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
void R_ClipPassWallSegment (int first, int last)
|
||||
{
|
||||
cliprange_t *start;
|
||||
|
||||
// find the first range that touches the range (adjacent pixels are touching)
|
||||
start = solidsegs;
|
||||
while (start->last < first-1)
|
||||
start++;
|
||||
|
||||
if (first < start->first)
|
||||
{
|
||||
if (last < start->first-1)
|
||||
{ // post is entirely visible (above start)
|
||||
R_StoreWallRange (first, last);
|
||||
return;
|
||||
}
|
||||
|
||||
// there is a fragment above *start
|
||||
R_StoreWallRange (first, start->first - 1);
|
||||
}
|
||||
|
||||
if (last <= start->last)
|
||||
return; // bottom contained in start
|
||||
|
||||
while (last >= (start+1)->first-1)
|
||||
{
|
||||
// there is a fragment between two posts
|
||||
R_StoreWallRange (start->last + 1, (start+1)->first - 1);
|
||||
start++;
|
||||
if (last <= start->last)
|
||||
return;
|
||||
}
|
||||
|
||||
// there is a fragment after *next
|
||||
R_StoreWallRange (start->last + 1, last);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
====================
|
||||
=
|
||||
= R_ClearClipSegs
|
||||
=
|
||||
====================
|
||||
*/
|
||||
|
||||
void R_ClearClipSegs (void)
|
||||
{
|
||||
solidsegs[0].first = -0x7fffffff;
|
||||
solidsegs[0].last = -1;
|
||||
solidsegs[1].first = viewwidth;
|
||||
solidsegs[1].last = 0x7fffffff;
|
||||
newend = solidsegs+2;
|
||||
}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
======================
|
||||
=
|
||||
= R_AddLine
|
||||
=
|
||||
= Clips the given segment and adds any visible pieces to the line list
|
||||
=
|
||||
======================
|
||||
*/
|
||||
|
||||
void R_AddLine (seg_t *line)
|
||||
{
|
||||
int x1, x2;
|
||||
angle_t angle1, angle2, span, tspan;
|
||||
|
||||
#ifdef __NeXT__
|
||||
RD_DrawLineCheck (line);
|
||||
#endif
|
||||
curline = line;
|
||||
|
||||
// OPTIMIZE: quickly reject orthogonal back sides
|
||||
|
||||
angle1 = R_PointToAngle (line->v1->x, line->v1->y);
|
||||
angle2 = R_PointToAngle (line->v2->x, line->v2->y);
|
||||
|
||||
//
|
||||
// clip to view edges
|
||||
// OPTIMIZE: make constant out of 2*clipangle (FIELDOFVIEW)
|
||||
span = angle1 - angle2;
|
||||
if (span >= ANG180)
|
||||
return; // back side
|
||||
|
||||
rw_angle1 = angle1; // global angle needed by segcalc
|
||||
angle1 -= viewangle;
|
||||
angle2 -= viewangle;
|
||||
|
||||
tspan = angle1 + clipangle;
|
||||
if (tspan > 2*clipangle)
|
||||
{
|
||||
tspan -= 2*clipangle;
|
||||
if (tspan >= span)
|
||||
return; // totally off the left edge
|
||||
angle1 = clipangle;
|
||||
}
|
||||
tspan = clipangle - angle2;
|
||||
if (tspan > 2*clipangle)
|
||||
{
|
||||
tspan -= 2*clipangle;
|
||||
if (tspan >= span)
|
||||
return; // totally off the left edge
|
||||
angle2 = -clipangle;
|
||||
}
|
||||
|
||||
//
|
||||
// the seg is in the view range, but not necessarily visible
|
||||
//
|
||||
angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT;
|
||||
angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT;
|
||||
x1 = viewangletox[angle1];
|
||||
x2 = viewangletox[angle2];
|
||||
if (x1 == x2)
|
||||
return; // does not cross a pixel
|
||||
|
||||
backsector = line->backsector;
|
||||
|
||||
if (!backsector)
|
||||
goto clipsolid; // single sided line
|
||||
|
||||
if (backsector->ceilingheight <= frontsector->floorheight
|
||||
|| backsector->floorheight >= frontsector->ceilingheight)
|
||||
goto clipsolid; // closed door
|
||||
|
||||
if (backsector->ceilingheight != frontsector->ceilingheight
|
||||
|| backsector->floorheight != frontsector->floorheight)
|
||||
goto clippass; // window
|
||||
|
||||
// reject empty lines used for triggers and special events
|
||||
if (backsector->ceilingpic == frontsector->ceilingpic
|
||||
&& backsector->floorpic == frontsector->floorpic
|
||||
&& backsector->lightlevel == frontsector->lightlevel
|
||||
&& backsector->special == frontsector->special
|
||||
&& curline->sidedef->midtexture == 0)
|
||||
return;
|
||||
|
||||
clippass:
|
||||
R_ClipPassWallSegment (x1, x2-1);
|
||||
return;
|
||||
|
||||
clipsolid:
|
||||
R_ClipSolidWallSegment (x1, x2-1);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
=
|
||||
= R_CheckBBox
|
||||
=
|
||||
= Returns true if some part of the bbox might be visible
|
||||
=
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
int checkcoord[12][4] = {
|
||||
{3,0, 2,1},
|
||||
{3,0, 2,0},
|
||||
{3,1, 2,0},
|
||||
{0},
|
||||
{2,0, 2,1},
|
||||
{0,0,0,0},
|
||||
{3,1, 3,0},
|
||||
{0},
|
||||
{2,0, 3,1},
|
||||
{2,1, 3,1},
|
||||
{2,1, 3,0} };
|
||||
|
||||
|
||||
boolean R_CheckBBox (fixed_t *bspcoord)
|
||||
{
|
||||
int boxx, boxy, boxpos;
|
||||
fixed_t x1, y1, x2, y2;
|
||||
angle_t angle1, angle2, span, tspan;
|
||||
cliprange_t *start;
|
||||
int sx1, sx2;
|
||||
|
||||
#ifdef __NeXT__
|
||||
RD_DrawBBox (bspcoord);
|
||||
#endif
|
||||
|
||||
// find the corners of the box that define the edges from current viewpoint
|
||||
if (viewx <= bspcoord[BOXLEFT])
|
||||
boxx = 0;
|
||||
else if (viewx < bspcoord[BOXRIGHT])
|
||||
boxx = 1;
|
||||
else
|
||||
boxx = 2;
|
||||
|
||||
if (viewy >= bspcoord[BOXTOP])
|
||||
boxy = 0;
|
||||
else if (viewy > bspcoord[BOXBOTTOM])
|
||||
boxy = 1;
|
||||
else
|
||||
boxy = 2;
|
||||
|
||||
boxpos = (boxy<<2)+boxx;
|
||||
if (boxpos == 5)
|
||||
return true;
|
||||
|
||||
x1 = bspcoord[checkcoord[boxpos][0]];
|
||||
y1 = bspcoord[checkcoord[boxpos][1]];
|
||||
x2 = bspcoord[checkcoord[boxpos][2]];
|
||||
y2 = bspcoord[checkcoord[boxpos][3]];
|
||||
|
||||
|
||||
#ifdef __NeXT__
|
||||
// RD_DisplayLine (x1, y1, x2, y2, 0.1);
|
||||
#endif
|
||||
|
||||
//
|
||||
// check clip list for an open space
|
||||
//
|
||||
angle1 = R_PointToAngle (x1, y1) - viewangle;
|
||||
angle2 = R_PointToAngle (x2, y2) - viewangle;
|
||||
|
||||
span = angle1 - angle2;
|
||||
if (span >= ANG180)
|
||||
return true; // sitting on a line
|
||||
tspan = angle1 + clipangle;
|
||||
if (tspan > 2*clipangle)
|
||||
{
|
||||
tspan -= 2*clipangle;
|
||||
if (tspan >= span)
|
||||
return false; // totally off the left edge
|
||||
angle1 = clipangle;
|
||||
}
|
||||
tspan = clipangle - angle2;
|
||||
if (tspan > 2*clipangle)
|
||||
{
|
||||
tspan -= 2*clipangle;
|
||||
if (tspan >= span)
|
||||
return false; // totally off the left edge
|
||||
angle2 = -clipangle;
|
||||
}
|
||||
|
||||
|
||||
// find the first clippost that touches the source post (adjacent pixels are touching)
|
||||
angle1 = (angle1+ANG90)>>ANGLETOFINESHIFT;
|
||||
angle2 = (angle2+ANG90)>>ANGLETOFINESHIFT;
|
||||
sx1 = viewangletox[angle1];
|
||||
sx2 = viewangletox[angle2];
|
||||
if (sx1 == sx2)
|
||||
return false; // does not cross a pixel
|
||||
sx2--;
|
||||
|
||||
start = solidsegs;
|
||||
while (start->last < sx2)
|
||||
start++;
|
||||
if (sx1 >= start->first && sx2 <= start->last)
|
||||
return false; // the clippost contains the new span
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
=
|
||||
= R_Subsector
|
||||
=
|
||||
= Draw one or more segments
|
||||
================
|
||||
*/
|
||||
|
||||
void R_Subsector (int num)
|
||||
{
|
||||
int count;
|
||||
seg_t *line;
|
||||
subsector_t *sub;
|
||||
int polyCount;
|
||||
seg_t **polySeg;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (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,
|
||||
frontsector->special);
|
||||
}
|
||||
else
|
||||
{
|
||||
floorplane = NULL;
|
||||
}
|
||||
|
||||
if(frontsector->ceilingheight > viewz
|
||||
|| frontsector->ceilingpic == skyflatnum)
|
||||
{
|
||||
ceilingplane = R_FindPlane(frontsector->ceilingheight,
|
||||
frontsector->ceilingpic, frontsector->lightlevel, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ceilingplane = NULL;
|
||||
}
|
||||
|
||||
R_AddSprites(frontsector);
|
||||
if(sub->poly)
|
||||
{ // Render the polyobj in the subsector first
|
||||
polyCount = sub->poly->numsegs;
|
||||
polySeg = sub->poly->segs;
|
||||
while(polyCount--)
|
||||
{
|
||||
R_AddLine(*polySeg++);
|
||||
}
|
||||
}
|
||||
while (count--)
|
||||
{
|
||||
R_AddLine (line);
|
||||
line++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
=
|
||||
= RenderBSPNode
|
||||
=
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
void R_RenderBSPNode (int bspnum)
|
||||
{
|
||||
node_t *bsp;
|
||||
int side;
|
||||
|
||||
if (bspnum & NF_SUBSECTOR)
|
||||
{
|
||||
if (bspnum == -1)
|
||||
R_Subsector (0);
|
||||
else
|
||||
R_Subsector (bspnum&(~NF_SUBSECTOR));
|
||||
return;
|
||||
}
|
||||
|
||||
bsp = &nodes[bspnum];
|
||||
|
||||
#ifdef __NeXT__
|
||||
RD_DrawNodeLine (bsp);
|
||||
#endif
|
||||
|
||||
//
|
||||
// decide which side the view point is on
|
||||
//
|
||||
side = R_PointOnSide (viewx, viewy, bsp);
|
||||
|
||||
R_RenderBSPNode (bsp->children[side]); // recursively divide front space
|
||||
|
||||
if (R_CheckBBox (bsp->bbox[side^1])) // possibly divide back space
|
||||
R_RenderBSPNode (bsp->children[side^1]);
|
||||
}
|
||||
|
||||
|
676
Hexen Source/R_DATA.C
Normal file
676
Hexen Source/R_DATA.C
Normal file
|
@ -0,0 +1,676 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** r_data.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: r_data.c,v $
|
||||
//** $Revision: 1.8 $
|
||||
//** $Date: 96/03/12 12:04:04 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
#include "r_local.h"
|
||||
#include "p_local.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int originx; // block origin (allways UL), which has allready
|
||||
int originy; // accounted for the patch's internal origin
|
||||
int patch;
|
||||
} texpatch_t;
|
||||
|
||||
// a maptexturedef_t describes a rectangular texture, which is composed of one
|
||||
// or more mappatch_t structures that arrange graphic patches
|
||||
typedef struct
|
||||
{
|
||||
char name[8]; // for switch changing, etc
|
||||
short width;
|
||||
short height;
|
||||
short patchcount;
|
||||
texpatch_t patches[1]; // [patchcount] drawn back to front
|
||||
// into the cached texture
|
||||
} texture_t;
|
||||
|
||||
|
||||
|
||||
int firstflat, lastflat, numflats;
|
||||
int firstpatch, lastpatch, numpatches;
|
||||
int firstspritelump, lastspritelump, numspritelumps;
|
||||
|
||||
int numtextures;
|
||||
texture_t **textures;
|
||||
int *texturewidthmask;
|
||||
fixed_t *textureheight; // needed for texture pegging
|
||||
int *texturecompositesize;
|
||||
short **texturecolumnlump;
|
||||
unsigned short **texturecolumnofs;
|
||||
byte **texturecomposite;
|
||||
|
||||
int *flattranslation; // for global animation
|
||||
int *texturetranslation; // for global animation
|
||||
|
||||
fixed_t *spritewidth; // needed for pre rendering
|
||||
fixed_t *spriteoffset;
|
||||
fixed_t *spritetopoffset;
|
||||
|
||||
lighttable_t *colormaps;
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
MAPTEXTURE_T CACHING
|
||||
|
||||
when a texture is first needed, it counts the number of composite columns
|
||||
required in the texture and allocates space for a column directory and any
|
||||
new columns. The directory will simply point inside other patches if there
|
||||
is only one patch in a given column, but any columns with multiple patches
|
||||
will have new column_ts generated.
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
===================
|
||||
=
|
||||
= 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)
|
||||
{
|
||||
int count, position;
|
||||
byte *source, *dest;
|
||||
|
||||
dest = (byte *)cache + 3;
|
||||
|
||||
while (patch->topdelta != 0xff)
|
||||
{
|
||||
source = (byte *)patch + 3;
|
||||
count = patch->length;
|
||||
position = originy + patch->topdelta;
|
||||
if (position < 0)
|
||||
{
|
||||
count += position;
|
||||
position = 0;
|
||||
}
|
||||
if (position + count > cacheheight)
|
||||
count = cacheheight - position;
|
||||
if (count > 0)
|
||||
memcpy (cache + position, source, count);
|
||||
|
||||
patch = (column_t *)( (byte *)patch + patch->length
+ 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
=
|
||||
= R_GenerateComposite
|
||||
=
|
||||
===================
|
||||
*/
|
||||
|
||||
void R_GenerateComposite (int texnum)
|
||||
{
|
||||
byte *block;
|
||||
texture_t *texture;
|
||||
texpatch_t *patch;
|
||||
patch_t *realpatch;
|
||||
int x, x1, x2;
|
||||
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];
|
||||
|
||||
//
|
||||
// composite the columns together
|
||||
//
|
||||
patch = texture->patches;
|
||||
|
||||
for (i=0 , patch = texture->patches; i<texture->patchcount ; i++, patch++)
|
||||
{
|
||||
realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
|
||||
x1 = patch->originx;
|
||||
x2 = x1 + SHORT(realpatch->width);
|
||||
|
||||
if (x1<0)
|
||||
x = 0;
|
||||
else
|
||||
x = x1;
|
||||
if (x2 > texture->width)
|
||||
x2 = texture->width;
|
||||
|
||||
for ( ; x<x2 ; x++)
|
||||
{
|
||||
if (collump[x] >= 0)
|
||||
continue; // column does not have multiple patches
|
||||
patchcol = (column_t *)((byte *)realpatch +
|
||||
LONG(realpatch->columnofs[x-x1]));
|
||||
R_DrawColumnInCache (patchcol, block + colofs[x], patch->originy,
|
||||
texture->height);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// now that the texture has been built, it is purgable
|
||||
Z_ChangeTag (block, PU_CACHE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
=
|
||||
= R_GenerateLookup
|
||||
=
|
||||
===================
|
||||
*/
|
||||
|
||||
void R_GenerateLookup (int texnum)
|
||||
{
|
||||
texture_t *texture;
|
||||
byte *patchcount; // [texture->width]
|
||||
texpatch_t *patch;
|
||||
patch_t *realpatch;
|
||||
int x, x1, x2;
|
||||
int i;
|
||||
short *collump;
|
||||
unsigned short *colofs;
|
||||
|
||||
texture = textures[texnum];
|
||||
|
||||
texturecomposite[texnum] = 0; // composited not created yet
|
||||
texturecompositesize[texnum] = 0;
|
||||
collump = texturecolumnlump[texnum];
|
||||
colofs = texturecolumnofs[texnum];
|
||||
|
||||
//
|
||||
// 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 *)alloca (texture->width);
|
||||
memset (patchcount, 0, texture->width);
|
||||
patch = texture->patches;
|
||||
|
||||
for (i=0 , patch = texture->patches; i<texture->patchcount ; i++, patch++)
|
||||
{
|
||||
realpatch = W_CacheLumpNum (patch->patch, PU_CACHE);
|
||||
x1 = patch->originx;
|
||||
x2 = x1 + SHORT(realpatch->width);
|
||||
if (x1 < 0)
|
||||
x = 0;
|
||||
else
|
||||
x = x1;
|
||||
if (x2 > texture->width)
|
||||
x2 = texture->width;
|
||||
for ( ; x<x2 ; x++)
|
||||
{
|
||||
patchcount[x]++;
|
||||
collump[x] = patch->patch;
|
||||
colofs[x] = LONG(realpatch->columnofs[x-x1])+3;
|
||||
}
|
||||
}
|
||||
|
||||
for (x=0 ; x<texture->width ; x++)
|
||||
{
|
||||
if (!patchcount[x])
|
||||
{
|
||||
ST_Message ("R_GenerateLookup: column without a patch (%s)\n", texture->name);
|
||||
return;
|
||||
}
|
||||
// I_Error ("R_GenerateLookup: column without a patch");
|
||||
if (patchcount[x] > 1)
|
||||
{
|
||||
collump[x] = -1; // use the cached block
|
||||
colofs[x] = texturecompositesize[texnum];
|
||||
if (texturecompositesize[texnum] > 0x10000-texture->height)
|
||||
I_Error ("R_GenerateLookup: texture %i is >64k",texnum);
|
||||
texturecompositesize[texnum] += texture->height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
=
|
||||
= R_GetColumn
|
||||
=
|
||||
================
|
||||
*/
|
||||
|
||||
byte *R_GetColumn (int tex, int col)
|
||||
{
|
||||
int lump, ofs;
|
||||
|
||||
col &= texturewidthmask[tex];
|
||||
lump = texturecolumnlump[tex][col];
|
||||
ofs = texturecolumnofs[tex][col];
|
||||
if (lump > 0)
|
||||
return (byte *)W_CacheLumpNum(lump,PU_CACHE)+ofs;
|
||||
if (!texturecomposite[tex])
|
||||
R_GenerateComposite (tex);
|
||||
return texturecomposite[tex] + ofs;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
=
|
||||
= R_InitTextures
|
||||
=
|
||||
= Initializes the texture list with the textures from the world map
|
||||
=
|
||||
==================
|
||||
*/
|
||||
|
||||
void R_InitTextures (void)
|
||||
{
|
||||
maptexture_t *mtexture;
|
||||
texture_t *texture;
|
||||
mappatch_t *mpatch;
|
||||
texpatch_t *patch;
|
||||
int i,j;
|
||||
int *maptex, *maptex2, *maptex1;
|
||||
char name[9], *names, *name_p;
|
||||
int *patchlookup;
|
||||
int totalwidth;
|
||||
int nummappatches;
|
||||
int offset, maxoff, maxoff2;
|
||||
int numtextures1, numtextures2;
|
||||
int *directory;
|
||||
|
||||
//
|
||||
// load the patch names from pnames.lmp
|
||||
//
|
||||
name[8] = 0;
|
||||
names = W_CacheLumpName ("PNAMES", PU_STATIC);
|
||||
nummappatches = LONG ( *((int *)names) );
|
||||
name_p = names+4;
|
||||
patchlookup = alloca (nummappatches*sizeof(*patchlookup));
|
||||
for (i=0 ; i<nummappatches ; i++)
|
||||
{
|
||||
strncpy (name,name_p+i*8, 8);
|
||||
patchlookup[i] = W_CheckNumForName (name);
|
||||
}
|
||||
Z_Free (names);
|
||||
|
||||
//
|
||||
// load the map texture definitions from textures.lmp
|
||||
//
|
||||
maptex = maptex1 = W_CacheLumpName ("TEXTURE1", PU_STATIC);
|
||||
numtextures1 = LONG(*maptex);
|
||||
maxoff = W_LumpLength (W_GetNumForName ("TEXTURE1"));
|
||||
directory = maptex+1;
|
||||
|
||||
if (W_CheckNumForName ("TEXTURE2") != -1)
|
||||
{
|
||||
maptex2 = W_CacheLumpName ("TEXTURE2", PU_STATIC);
|
||||
numtextures2 = LONG(*maptex2);
|
||||
maxoff2 = W_LumpLength (W_GetNumForName ("TEXTURE2"));
|
||||
}
|
||||
else
|
||||
{
|
||||
maptex2 = NULL;
|
||||
numtextures2 = 0;
|
||||
maxoff2 = 0;
|
||||
}
|
||||
numtextures = numtextures1 + numtextures2;
|
||||
|
||||
textures = Z_Malloc (numtextures*4, PU_STATIC, 0);
|
||||
texturecolumnlump = Z_Malloc (numtextures*4, PU_STATIC, 0);
|
||||
texturecolumnofs = Z_Malloc (numtextures*4, PU_STATIC, 0);
|
||||
texturecomposite = Z_Malloc (numtextures*4, PU_STATIC, 0);
|
||||
texturecompositesize = Z_Malloc (numtextures*4, PU_STATIC, 0);
|
||||
texturewidthmask = Z_Malloc (numtextures*4, PU_STATIC, 0);
|
||||
textureheight = Z_Malloc (numtextures*4, PU_STATIC, 0);
|
||||
|
||||
totalwidth = 0;
|
||||
|
||||
for (i=0 ; i<numtextures ; i++, directory++)
|
||||
{
|
||||
if (i == numtextures1)
|
||||
{ // start looking in second texture file
|
||||
maptex = maptex2;
|
||||
maxoff = maxoff2;
|
||||
directory = maptex+1;
|
||||
}
|
||||
|
||||
offset = LONG(*directory);
|
||||
if (offset > maxoff)
|
||||
I_Error ("R_InitTextures: bad texture directory");
|
||||
mtexture = (maptexture_t *) ( (byte *)maptex + offset);
|
||||
texture = textures[i] = Z_Malloc (sizeof(texture_t)
|
||||
+ sizeof(texpatch_t)*(SHORT(mtexture->patchcount)-1), PU_STATIC,
|
||||
0);
|
||||
texture->width = SHORT(mtexture->width);
|
||||
texture->height = SHORT(mtexture->height);
|
||||
texture->patchcount = SHORT(mtexture->patchcount);
|
||||
memcpy (texture->name, mtexture->name, sizeof(texture->name));
|
||||
mpatch = &mtexture->patches[0];
|
||||
patch = &texture->patches[0];
|
||||
for (j=0 ; j<texture->patchcount ; j++, mpatch++, patch++)
|
||||
{
|
||||
patch->originx = SHORT(mpatch->originx);
|
||||
patch->originy = SHORT(mpatch->originy);
|
||||
patch->patch = patchlookup[SHORT(mpatch->patch)];
|
||||
if (patch->patch == -1)
|
||||
I_Error (
|
||||
"R_InitTextures: Missing patch in texture %s",texture->name);
|
||||
}
|
||||
texturecolumnlump[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
|
||||
texturecolumnofs[i] = Z_Malloc (texture->width*2, PU_STATIC,0);
|
||||
j = 1;
|
||||
while (j*2 <= texture->width)
|
||||
j<<=1;
|
||||
texturewidthmask[i] = j-1;
|
||||
textureheight[i] = texture->height<<FRACBITS;
|
||||
|
||||
totalwidth += texture->width;
|
||||
}
|
||||
|
||||
Z_Free (maptex1);
|
||||
if (maptex2)
|
||||
Z_Free (maptex2);
|
||||
|
||||
//
|
||||
// precalculate whatever possible
|
||||
//
|
||||
for (i=0 ; i<numtextures ; i++)
|
||||
{
|
||||
R_GenerateLookup (i);
|
||||
if(!(i&31)) ST_Progress();
|
||||
}
|
||||
|
||||
//
|
||||
// translation table for global animation
|
||||
//
|
||||
texturetranslation = Z_Malloc ((numtextures+1)*4, PU_STATIC, 0);
|
||||
for (i=0 ; i<numtextures ; i++)
|
||||
texturetranslation[i] = i;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
=
|
||||
= R_InitFlats
|
||||
=
|
||||
=================
|
||||
*/
|
||||
|
||||
void R_InitFlats (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
firstflat = W_GetNumForName ("F_START") + 1;
|
||||
lastflat = W_GetNumForName ("F_END") - 1;
|
||||
numflats = lastflat - firstflat + 1;
|
||||
|
||||
// translation table for global animation
|
||||
flattranslation = Z_Malloc ((numflats+1)*4, PU_STATIC, 0);
|
||||
for (i=0 ; i<numflats ; i++)
|
||||
flattranslation[i] = i;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
=
|
||||
= R_InitSpriteLumps
|
||||
=
|
||||
= Finds the width and hoffset of all sprites in the wad, so the sprite doesn't
|
||||
= need to be cached just for the header during rendering
|
||||
=================
|
||||
*/
|
||||
|
||||
void R_InitSpriteLumps (void)
|
||||
{
|
||||
int i;
|
||||
patch_t *patch;
|
||||
|
||||
firstspritelump = W_GetNumForName ("S_START") + 1;
|
||||
lastspritelump = W_GetNumForName ("S_END") - 1;
|
||||
numspritelumps = lastspritelump - firstspritelump + 1;
|
||||
spritewidth = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
|
||||
spriteoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
|
||||
spritetopoffset = Z_Malloc (numspritelumps*4, PU_STATIC, 0);
|
||||
|
||||
for (i=0 ; i< numspritelumps ; i++)
|
||||
{
|
||||
if (!(i&127)) ST_Progress();
|
||||
patch = W_CacheLumpNum (firstspritelump+i, PU_CACHE);
|
||||
spritewidth[i] = SHORT(patch->width)<<FRACBITS;
|
||||
spriteoffset[i] = SHORT(patch->leftoffset)<<FRACBITS;
|
||||
spritetopoffset[i] = SHORT(patch->topoffset)<<FRACBITS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
=
|
||||
= R_InitColormaps
|
||||
=
|
||||
=================
|
||||
*/
|
||||
|
||||
void R_InitColormaps (void)
|
||||
{
|
||||
int lump, length;
|
||||
//
|
||||
// load in the light tables
|
||||
// 256 byte align tables
|
||||
//
|
||||
lump = W_GetNumForName("COLORMAP");
|
||||
length = W_LumpLength (lump) + 255;
|
||||
colormaps = Z_Malloc (length, PU_STATIC, 0);
|
||||
colormaps = (byte *)( ((int)colormaps + 255)&~0xff);
|
||||
W_ReadLump (lump,colormaps);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
=
|
||||
= R_InitData
|
||||
=
|
||||
= Locates all the lumps that will be used by all views
|
||||
= Must be called after W_Init
|
||||
=================
|
||||
*/
|
||||
|
||||
void R_InitData (void)
|
||||
{
|
||||
R_InitTextures();
|
||||
R_InitFlats();
|
||||
R_InitSpriteLumps();
|
||||
R_InitColormaps();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
================
|
||||
=
|
||||
= R_FlatNumForName
|
||||
=
|
||||
================
|
||||
*/
|
||||
|
||||
int R_FlatNumForName (char *name)
|
||||
{
|
||||
int i;
|
||||
char namet[9];
|
||||
|
||||
i = W_CheckNumForName (name);
|
||||
if (i == -1)
|
||||
{
|
||||
namet[8] = 0;
|
||||
memcpy (namet, name,8);
|
||||
I_Error ("R_FlatNumForName: %s not found",namet);
|
||||
}
|
||||
return i - firstflat;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
=
|
||||
= R_CheckTextureNumForName
|
||||
=
|
||||
================
|
||||
*/
|
||||
|
||||
int R_CheckTextureNumForName (char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (name[0] == '-') // no texture marker
|
||||
return 0;
|
||||
|
||||
for (i=0 ; i<numtextures ; i++)
|
||||
if (!strncasecmp (textures[i]->name, name, 8) )
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
=
|
||||
= R_TextureNumForName
|
||||
=
|
||||
================
|
||||
*/
|
||||
|
||||
int R_TextureNumForName (char *name)
|
||||
{
|
||||
int i;
|
||||
//char namet[9];
|
||||
|
||||
i = R_CheckTextureNumForName (name);
|
||||
if (i==-1)
|
||||
I_Error ("R_TextureNumForName: %s not found",name);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
=
|
||||
= R_PrecacheLevel
|
||||
=
|
||||
= Preloads all relevent graphics for the level
|
||||
=================
|
||||
*/
|
||||
|
||||
int flatmemory, texturememory, spritememory;
|
||||
|
||||
void R_PrecacheLevel (void)
|
||||
{
|
||||
char *flatpresent;
|
||||
char *texturepresent;
|
||||
char *spritepresent;
|
||||
int i,j,k, lump;
|
||||
texture_t *texture;
|
||||
thinker_t *th;
|
||||
spriteframe_t *sf;
|
||||
|
||||
if (demoplayback)
|
||||
return;
|
||||
|
||||
//
|
||||
// precache flats
|
||||
//
|
||||
flatpresent = alloca(numflats);
|
||||
memset (flatpresent,0,numflats);
|
||||
for (i=0 ; i<numsectors ; i++)
|
||||
{
|
||||
flatpresent[sectors[i].floorpic] = 1;
|
||||
flatpresent[sectors[i].ceilingpic] = 1;
|
||||
}
|
||||
|
||||
flatmemory = 0;
|
||||
for (i=0 ; i<numflats ; i++)
|
||||
if (flatpresent[i])
|
||||
{
|
||||
lump = firstflat + i;
|
||||
flatmemory += lumpinfo[lump].size;
|
||||
W_CacheLumpNum(lump, PU_CACHE);
|
||||
}
|
||||
|
||||
//
|
||||
// precache textures
|
||||
//
|
||||
texturepresent = alloca(numtextures);
|
||||
memset (texturepresent,0, numtextures);
|
||||
|
||||
for (i=0 ; i<numsides ; i++)
|
||||
{
|
||||
texturepresent[sides[i].toptexture] = 1;
|
||||
texturepresent[sides[i].midtexture] = 1;
|
||||
texturepresent[sides[i].bottomtexture] = 1;
|
||||
}
|
||||
|
||||
texturepresent[Sky1Texture] = 1;
|
||||
texturepresent[Sky2Texture] = 1;
|
||||
|
||||
texturememory = 0;
|
||||
for (i=0 ; i<numtextures ; i++)
|
||||
{
|
||||
if (!texturepresent[i])
|
||||
continue;
|
||||
texture = textures[i];
|
||||
for (j=0 ; j<texture->patchcount ; j++)
|
||||
{
|
||||
lump = texture->patches[j].patch;
|
||||
texturememory += lumpinfo[lump].size;
|
||||
W_CacheLumpNum(lump , PU_CACHE);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// precache sprites
|
||||
//
|
||||
spritepresent = alloca(numsprites);
|
||||
memset (spritepresent,0, numsprites);
|
||||
|
||||
for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
|
||||
{
|
||||
if (th->function == P_MobjThinker)
|
||||
spritepresent[((mobj_t *)th)->sprite] = 1;
|
||||
}
|
||||
|
||||
spritememory = 0;
|
||||
for (i=0 ; i<numsprites ; i++)
|
||||
{
|
||||
if (!spritepresent[i])
|
||||
continue;
|
||||
for (j=0 ; j<sprites[i].numframes ; j++)
|
||||
{
|
||||
sf = &sprites[i].spriteframes[j];
|
||||
for (k=0 ; k<8 ; k++)
|
||||
{
|
||||
lump = firstspritelump + sf->lump[k];
|
||||
spritememory += lumpinfo[lump].size;
|
||||
W_CacheLumpNum(lump , PU_CACHE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
576
Hexen Source/R_DRAW.C
Normal file
576
Hexen Source/R_DRAW.C
Normal file
|
@ -0,0 +1,576 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** r_draw.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: r_draw.c,v $
|
||||
//** $Revision: 1.11 $
|
||||
//** $Date: 96/01/06 18:37:37 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
#include "r_local.h"
|
||||
|
||||
/*
|
||||
|
||||
All drawing to the view buffer is accomplished in this file. The other refresh
|
||||
files only know about ccordinates, not the architecture of the frame buffer.
|
||||
|
||||
*/
|
||||
|
||||
byte *viewimage;
|
||||
int viewwidth, scaledviewwidth, viewheight, viewwindowx, viewwindowy;
|
||||
byte *ylookup[MAXHEIGHT];
|
||||
int columnofs[MAXWIDTH];
|
||||
//byte translations[3][256]; // color tables for different players
|
||||
byte *tinttable; // used for translucent sprites
|
||||
|
||||
/*
|
||||
==================
|
||||
=
|
||||
= R_DrawColumn
|
||||
=
|
||||
= Source is the top of the column to scale
|
||||
=
|
||||
==================
|
||||
*/
|
||||
|
||||
lighttable_t *dc_colormap;
|
||||
int dc_x;
|
||||
int dc_yl;
|
||||
int dc_yh;
|
||||
fixed_t dc_iscale;
|
||||
fixed_t dc_texturemid;
|
||||
byte *dc_source; // first pixel in a column (possibly virtual)
|
||||
|
||||
int dccount; // just for profiling
|
||||
|
||||
#ifndef __WATCOMC__
|
||||
#ifndef __i386
|
||||
#ifndef __m68k
|
||||
void R_DrawColumn (void)
|
||||
{
|
||||
int count;
|
||||
byte *dest;
|
||||
fixed_t frac, fracstep;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
if (count < 0)
|
||||
return;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
|
||||
I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
|
||||
#endif
|
||||
|
||||
dest = ylookup[dc_yl] + columnofs[dc_x];
|
||||
|
||||
fracstep = dc_iscale;
|
||||
frac = dc_texturemid + (dc_yl-centery)*fracstep;
|
||||
|
||||
do
|
||||
{
|
||||
*dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
|
||||
dest += SCREENWIDTH;
|
||||
frac += fracstep;
|
||||
} while (count--);
|
||||
}
|
||||
#endif // __m68k
|
||||
#endif // __i386
|
||||
#endif
|
||||
|
||||
void R_DrawColumnLow (void)
|
||||
{
|
||||
int count;
|
||||
byte *dest;
|
||||
fixed_t frac, fracstep;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
if (count < 0)
|
||||
return;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
|
||||
I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
|
||||
// dccount++;
|
||||
#endif
|
||||
|
||||
dest = ylookup[dc_yl] + columnofs[dc_x];
|
||||
|
||||
fracstep = dc_iscale;
|
||||
frac = dc_texturemid + (dc_yl-centery)*fracstep;
|
||||
|
||||
do
|
||||
{
|
||||
*dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
|
||||
dest += SCREENWIDTH;
|
||||
frac += fracstep;
|
||||
} while (count--);
|
||||
}
|
||||
|
||||
/*
|
||||
#define FUZZTABLE 50
|
||||
#define FUZZOFF (SCREENWIDTH)
|
||||
int fuzzoffset[FUZZTABLE] = {
|
||||
FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF
|
||||
};
|
||||
int fuzzpos = 0;
|
||||
*/
|
||||
|
||||
#ifndef __WATCOMC__
|
||||
void R_DrawFuzzColumn (void)
|
||||
{
|
||||
int count;
|
||||
byte *dest;
|
||||
fixed_t frac, fracstep;
|
||||
|
||||
if (!dc_yl)
|
||||
dc_yl = 1;
|
||||
if (dc_yh == viewheight-1)
|
||||
dc_yh = viewheight - 2;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
if (count < 0)
|
||||
return;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
|
||||
I_Error ("R_DrawFuzzColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
|
||||
#endif
|
||||
|
||||
dest = ylookup[dc_yl] + columnofs[dc_x];
|
||||
|
||||
fracstep = dc_iscale;
|
||||
frac = dc_texturemid + (dc_yl-centery)*fracstep;
|
||||
|
||||
// OLD FUZZY INVISO SPRITE STUFF
|
||||
/* do
|
||||
{
|
||||
*dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]];
|
||||
if (++fuzzpos == FUZZTABLE)
|
||||
fuzzpos = 0;
|
||||
dest += SCREENWIDTH;
|
||||
frac += fracstep;
|
||||
} while (count--);
|
||||
*/
|
||||
|
||||
do
|
||||
{
|
||||
*dest = tinttable[*dest+
|
||||
(dc_colormap[dc_source[(frac>>FRACBITS)&127]]<<8)];
|
||||
dest += SCREENWIDTH;
|
||||
frac += fracstep;
|
||||
} while(count--);
|
||||
}
|
||||
#endif
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// R_DrawAltFuzzColumn
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void R_DrawAltFuzzColumn (void)
|
||||
{
|
||||
int count;
|
||||
byte *dest;
|
||||
fixed_t frac, fracstep;
|
||||
|
||||
if (!dc_yl)
|
||||
dc_yl = 1;
|
||||
if (dc_yh == viewheight-1)
|
||||
dc_yh = viewheight - 2;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
if (count < 0)
|
||||
return;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
|
||||
I_Error ("R_DrawFuzzColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
|
||||
#endif
|
||||
|
||||
dest = ylookup[dc_yl] + columnofs[dc_x];
|
||||
|
||||
fracstep = dc_iscale;
|
||||
frac = dc_texturemid + (dc_yl-centery)*fracstep;
|
||||
|
||||
do
|
||||
{
|
||||
*dest = tinttable[((*dest)<<8)
|
||||
+dc_colormap[dc_source[(frac>>FRACBITS)&127]]];
|
||||
dest += SCREENWIDTH;
|
||||
frac += fracstep;
|
||||
} while(count--);
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
=
|
||||
= R_DrawTranslatedColumn
|
||||
=
|
||||
========================
|
||||
*/
|
||||
|
||||
byte *dc_translation;
|
||||
byte *translationtables;
|
||||
|
||||
void R_DrawTranslatedColumn (void)
|
||||
{
|
||||
int count;
|
||||
byte *dest;
|
||||
fixed_t frac, fracstep;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
if (count < 0)
|
||||
return;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
|
||||
I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
|
||||
#endif
|
||||
|
||||
dest = ylookup[dc_yl] + columnofs[dc_x];
|
||||
|
||||
fracstep = dc_iscale;
|
||||
frac = dc_texturemid + (dc_yl-centery)*fracstep;
|
||||
|
||||
do
|
||||
{
|
||||
*dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
|
||||
dest += SCREENWIDTH;
|
||||
frac += fracstep;
|
||||
} while (count--);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// R_DrawTranslatedFuzzColumn
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void R_DrawTranslatedFuzzColumn (void)
|
||||
{
|
||||
int count;
|
||||
byte *dest;
|
||||
fixed_t frac, fracstep;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
if (count < 0)
|
||||
return;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
|
||||
I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
|
||||
#endif
|
||||
|
||||
dest = ylookup[dc_yl] + columnofs[dc_x];
|
||||
|
||||
fracstep = dc_iscale;
|
||||
frac = dc_texturemid + (dc_yl-centery)*fracstep;
|
||||
|
||||
do
|
||||
{
|
||||
*dest = tinttable[((*dest)<<8)
|
||||
+dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]];
|
||||
dest += SCREENWIDTH;
|
||||
frac += fracstep;
|
||||
} while (count--);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// R_DrawTranslatedAltFuzzColumn
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
void R_DrawTranslatedAltFuzzColumn (void)
|
||||
{
|
||||
int count;
|
||||
byte *dest;
|
||||
fixed_t frac, fracstep;
|
||||
|
||||
count = dc_yh - dc_yl;
|
||||
if (count < 0)
|
||||
return;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
|
||||
I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
|
||||
#endif
|
||||
|
||||
dest = ylookup[dc_yl] + columnofs[dc_x];
|
||||
|
||||
fracstep = dc_iscale;
|
||||
frac = dc_texturemid + (dc_yl-centery)*fracstep;
|
||||
|
||||
do
|
||||
{
|
||||
*dest = tinttable[*dest
|
||||
+(dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]<<8)];
|
||||
dest += SCREENWIDTH;
|
||||
frac += fracstep;
|
||||
} while (count--);
|
||||
}
|
||||
*/
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// PROC R_InitTranslationTables
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void R_InitTranslationTables (void)
|
||||
{
|
||||
int i;
|
||||
byte *transLump;
|
||||
|
||||
// Load tint table
|
||||
tinttable = W_CacheLumpName("TINTTAB", PU_STATIC);
|
||||
|
||||
// Allocate translation tables
|
||||
translationtables = Z_Malloc(256*3*(MAXPLAYERS-1)+255,
|
||||
PU_STATIC, 0);
|
||||
translationtables = (byte *)(((int)translationtables+255)&~255);
|
||||
|
||||
for(i = 0; i < 3*(MAXPLAYERS-1); i++)
|
||||
{
|
||||
transLump = W_CacheLumpNum(W_GetNumForName("trantbl0")+i, PU_STATIC);
|
||||
memcpy(translationtables+i*256, transLump, 256);
|
||||
Z_Free(transLump);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
=
|
||||
= R_DrawSpan
|
||||
=
|
||||
================
|
||||
*/
|
||||
|
||||
int ds_y;
|
||||
int ds_x1;
|
||||
int ds_x2;
|
||||
lighttable_t *ds_colormap;
|
||||
fixed_t ds_xfrac;
|
||||
fixed_t ds_yfrac;
|
||||
fixed_t ds_xstep;
|
||||
fixed_t ds_ystep;
|
||||
byte *ds_source; // start of a 64*64 tile image
|
||||
|
||||
int dscount; // just for profiling
|
||||
|
||||
#ifndef __WATCOMC__
|
||||
#ifndef __i386
|
||||
#ifndef __m68k
|
||||
void R_DrawSpan (void)
|
||||
{
|
||||
fixed_t xfrac, yfrac;
|
||||
byte *dest;
|
||||
int count, spot;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (ds_x2 < ds_x1 || ds_x1<0 || ds_x2>=SCREENWIDTH
|
||||
|| (unsigned)ds_y>SCREENHEIGHT)
|
||||
I_Error ("R_DrawSpan: %i to %i at %i",ds_x1,ds_x2,ds_y);
|
||||
// dscount++;
|
||||
#endif
|
||||
|
||||
xfrac = ds_xfrac;
|
||||
yfrac = ds_yfrac;
|
||||
|
||||
dest = ylookup[ds_y] + columnofs[ds_x1];
|
||||
count = ds_x2 - ds_x1;
|
||||
do
|
||||
{
|
||||
spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
|
||||
*dest++ = ds_colormap[ds_source[spot]];
|
||||
xfrac += ds_xstep;
|
||||
yfrac += ds_ystep;
|
||||
} while (count--);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void R_DrawSpanLow (void)
|
||||
{
|
||||
fixed_t xfrac, yfrac;
|
||||
byte *dest;
|
||||
int count, spot;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (ds_x2 < ds_x1 || ds_x1<0 || ds_x2>=SCREENWIDTH
|
||||
|| (unsigned)ds_y>SCREENHEIGHT)
|
||||
I_Error ("R_DrawSpan: %i to %i at %i",ds_x1,ds_x2,ds_y);
|
||||
// dscount++;
|
||||
#endif
|
||||
|
||||
xfrac = ds_xfrac;
|
||||
yfrac = ds_yfrac;
|
||||
|
||||
dest = ylookup[ds_y] + columnofs[ds_x1];
|
||||
count = ds_x2 - ds_x1;
|
||||
do
|
||||
{
|
||||
spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
|
||||
*dest++ = ds_colormap[ds_source[spot]];
|
||||
xfrac += ds_xstep;
|
||||
yfrac += ds_ystep;
|
||||
} while (count--);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
=
|
||||
= R_InitBuffer
|
||||
=
|
||||
=================
|
||||
*/
|
||||
|
||||
void R_InitBuffer (int width, int height)
|
||||
{
|
||||
int i;
|
||||
|
||||
viewwindowx = (SCREENWIDTH-width) >> 1;
|
||||
for (i=0 ; i<width ; i++)
|
||||
columnofs[i] = viewwindowx + i;
|
||||
if (width == SCREENWIDTH)
|
||||
viewwindowy = 0;
|
||||
else
|
||||
viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1;
|
||||
for (i=0 ; i<height ; i++)
|
||||
ylookup[i] = screen + (i+viewwindowy)*SCREENWIDTH;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
=
|
||||
= R_DrawViewBorder
|
||||
=
|
||||
= Draws the border around the view for different size windows
|
||||
==================
|
||||
*/
|
||||
|
||||
boolean BorderNeedRefresh;
|
||||
|
||||
void R_DrawViewBorder (void)
|
||||
{
|
||||
byte *src, *dest;
|
||||
int x,y;
|
||||
|
||||
if (scaledviewwidth == SCREENWIDTH)
|
||||
return;
|
||||
|
||||
src = W_CacheLumpName("F_022", PU_CACHE);
|
||||
dest = screen;
|
||||
|
||||
for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++)
|
||||
{
|
||||
for (x=0 ; x<SCREENWIDTH/64 ; x++)
|
||||
{
|
||||
memcpy (dest, src+((y&63)<<6), 64);
|
||||
dest += 64;
|
||||
}
|
||||
if (SCREENWIDTH&63)
|
||||
{
|
||||
memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
|
||||
dest += (SCREENWIDTH&63);
|
||||
}
|
||||
}
|
||||
for(x=viewwindowx; x < viewwindowx+viewwidth; x += 16)
|
||||
{
|
||||
V_DrawPatch(x, viewwindowy-4, W_CacheLumpName("bordt", PU_CACHE));
|
||||
V_DrawPatch(x, viewwindowy+viewheight, W_CacheLumpName("bordb",
|
||||
PU_CACHE));
|
||||
}
|
||||
for(y=viewwindowy; y < viewwindowy+viewheight; y += 16)
|
||||
{
|
||||
V_DrawPatch(viewwindowx-4, y, W_CacheLumpName("bordl", PU_CACHE));
|
||||
V_DrawPatch(viewwindowx+viewwidth, y, W_CacheLumpName("bordr",
|
||||
PU_CACHE));
|
||||
}
|
||||
V_DrawPatch(viewwindowx-4, viewwindowy-4, W_CacheLumpName("bordtl",
|
||||
PU_CACHE));
|
||||
V_DrawPatch(viewwindowx+viewwidth, viewwindowy-4,
|
||||
W_CacheLumpName("bordtr", PU_CACHE));
|
||||
V_DrawPatch(viewwindowx+viewwidth, viewwindowy+viewheight,
|
||||
W_CacheLumpName("bordbr", PU_CACHE));
|
||||
V_DrawPatch(viewwindowx-4, viewwindowy+viewheight,
|
||||
W_CacheLumpName("bordbl", PU_CACHE));
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
=
|
||||
= R_DrawTopBorder
|
||||
=
|
||||
= Draws the top border around the view for different size windows
|
||||
==================
|
||||
*/
|
||||
|
||||
boolean BorderTopRefresh;
|
||||
|
||||
void R_DrawTopBorder (void)
|
||||
{
|
||||
byte *src, *dest;
|
||||
int x,y;
|
||||
|
||||
if (scaledviewwidth == SCREENWIDTH)
|
||||
return;
|
||||
|
||||
/* if(shareware)
|
||||
{
|
||||
src = W_CacheLumpName ("FLOOR04", PU_CACHE);
|
||||
}
|
||||
else
|
||||
{
|
||||
src = W_CacheLumpName ("FLAT513", PU_CACHE);
|
||||
}
|
||||
*/
|
||||
src = W_CacheLumpName("F_022", PU_CACHE);
|
||||
dest = screen;
|
||||
|
||||
for (y=0 ; y<34 ; y++)
|
||||
{
|
||||
for (x=0 ; x<SCREENWIDTH/64 ; x++)
|
||||
{
|
||||
memcpy (dest, src+((y&63)<<6), 64);
|
||||
dest += 64;
|
||||
}
|
||||
if (SCREENWIDTH&63)
|
||||
{
|
||||
memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
|
||||
dest += (SCREENWIDTH&63);
|
||||
}
|
||||
}
|
||||
if(viewwindowy < 35)
|
||||
{
|
||||
for(x=viewwindowx; x < viewwindowx+viewwidth; x += 16)
|
||||
{
|
||||
V_DrawPatch(x, viewwindowy-4, W_CacheLumpName("bordt", PU_CACHE));
|
||||
}
|
||||
V_DrawPatch(viewwindowx-4, viewwindowy, W_CacheLumpName("bordl",
|
||||
PU_CACHE));
|
||||
V_DrawPatch(viewwindowx+viewwidth, viewwindowy,
|
||||
W_CacheLumpName("bordr", PU_CACHE));
|
||||
V_DrawPatch(viewwindowx-4, viewwindowy+16, W_CacheLumpName("bordl",
|
||||
PU_CACHE));
|
||||
V_DrawPatch(viewwindowx+viewwidth, viewwindowy+16,
|
||||
W_CacheLumpName("bordr", PU_CACHE));
|
||||
|
||||
V_DrawPatch(viewwindowx-4, viewwindowy-4, W_CacheLumpName("bordtl",
|
||||
PU_CACHE));
|
||||
V_DrawPatch(viewwindowx+viewwidth, viewwindowy-4,
|
||||
W_CacheLumpName("bordtr", PU_CACHE));
|
||||
}
|
||||
}
|
||||
|
||||
|
538
Hexen Source/R_LOCAL.H
Normal file
538
Hexen Source/R_LOCAL.H
Normal file
|
@ -0,0 +1,538 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** r_local.h : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: r_local.h,v $
|
||||
//** $Revision: 1.12 $
|
||||
//** $Date: 96/01/06 18:37:38 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#ifndef __R_LOCAL__
|
||||
#define __R_LOCAL__
|
||||
|
||||
#define ANGLETOSKYSHIFT 22 // sky map is 256*128*4 maps
|
||||
|
||||
#define BASEYCENTER 100
|
||||
|
||||
#define MAXWIDTH 1120
|
||||
#define MAXHEIGHT 832
|
||||
|
||||
#define PI 3.141592657
|
||||
|
||||
#define CENTERY (SCREENHEIGHT/2)
|
||||
|
||||
#define MINZ (FRACUNIT*4)
|
||||
|
||||
#define FIELDOFVIEW 2048 // fineangles in the SCREENWIDTH wide window
|
||||
|
||||
//
|
||||
// lighting constants
|
||||
//
|
||||
#define LIGHTLEVELS 16
|
||||
#define LIGHTSEGSHIFT 4
|
||||
#define MAXLIGHTSCALE 48
|
||||
#define LIGHTSCALESHIFT 12
|
||||
#define MAXLIGHTZ 128
|
||||
#define LIGHTZSHIFT 20
|
||||
#define NUMCOLORMAPS 32 // number of diminishing
|
||||
#define INVERSECOLORMAP 32
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
INTERNAL MAP TYPES
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
//================ used by play and refresh
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fixed_t x,y;
|
||||
} vertex_t;
|
||||
|
||||
struct line_s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fixed_t floorheight, ceilingheight;
|
||||
short floorpic, ceilingpic;
|
||||
short lightlevel;
|
||||
short special, tag;
|
||||
|
||||
int soundtraversed; // 0 = untraversed, 1,2 = sndlines -1
|
||||
mobj_t *soundtarget; // thing that made a sound (or null)
|
||||
seqtype_t seqType; // stone, metal, heavy, etc...
|
||||
|
||||
int blockbox[4]; // mapblock bounding box for height changes
|
||||
degenmobj_t soundorg; // for any sounds played by the sector
|
||||
int validcount; // if == validcount, already checked
|
||||
mobj_t *thinglist; // list of mobjs in sector
|
||||
void *specialdata; // thinker_t for reversable actions
|
||||
int linecount;
|
||||
struct line_s **lines; // [linecount] size
|
||||
} sector_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fixed_t textureoffset; // add this to the calculated texture col
|
||||
fixed_t rowoffset; // add this to the calculated texture top
|
||||
short toptexture, bottomtexture, midtexture;
|
||||
sector_t *sector;
|
||||
} side_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ST_HORIZONTAL,
|
||||
ST_VERTICAL,
|
||||
ST_POSITIVE,
|
||||
ST_NEGATIVE
|
||||
} slopetype_t;
|
||||
|
||||
/*
|
||||
typedef struct line_s
|
||||
{
|
||||
vertex_t *v1, *v2;
|
||||
fixed_t dx,dy; // v2 - v1 for side checking
|
||||
short flags;
|
||||
short special, tag;
|
||||
short sidenum[2]; // sidenum[1] will be -1 if one sided
|
||||
fixed_t bbox[4];
|
||||
slopetype_t slopetype; // to aid move clipping
|
||||
sector_t *frontsector, *backsector;
|
||||
int validcount; // if == validcount, already checked
|
||||
void *specialdata; // thinker_t for reversable actions
|
||||
} line_t;
|
||||
*/
|
||||
|
||||
typedef struct line_s
|
||||
{
|
||||
vertex_t *v1;
|
||||
vertex_t *v2;
|
||||
fixed_t dx;
|
||||
fixed_t dy;
|
||||
short flags;
|
||||
byte special;
|
||||
byte arg1;
|
||||
byte arg2;
|
||||
byte arg3;
|
||||
byte arg4;
|
||||
byte arg5;
|
||||
short sidenum[2];
|
||||
fixed_t bbox[4];
|
||||
slopetype_t slopetype;
|
||||
sector_t *frontsector;
|
||||
sector_t *backsector;
|
||||
int validcount;
|
||||
void *specialdata;
|
||||
} line_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vertex_t *v1, *v2;
|
||||
fixed_t offset;
|
||||
angle_t angle;
|
||||
side_t *sidedef;
|
||||
line_t *linedef;
|
||||
sector_t *frontsector;
|
||||
sector_t *backsector; // NULL for one sided lines
|
||||
} seg_t;
|
||||
|
||||
// ===== Polyobj data =====
|
||||
typedef struct
|
||||
{
|
||||
int numsegs;
|
||||
seg_t **segs;
|
||||
degenmobj_t startSpot;
|
||||
vertex_t *originalPts; // used as the base for the rotations
|
||||
vertex_t *prevPts; // use to restore the old point values
|
||||
angle_t angle;
|
||||
int tag; // reference tag assigned in HereticEd
|
||||
int bbox[4];
|
||||
int validcount;
|
||||
boolean crush; // should the polyobj attempt to crush mobjs?
|
||||
int seqType;
|
||||
fixed_t size; // polyobj size (area of POLY_AREAUNIT == size of FRACUNIT)
|
||||
void *specialdata; // pointer a thinker, if the poly is moving
|
||||
} polyobj_t;
|
||||
|
||||
typedef struct polyblock_s
|
||||
{
|
||||
polyobj_t *polyobj;
|
||||
struct polyblock_s *prev;
|
||||
struct polyblock_s *next;
|
||||
} polyblock_t;
|
||||
|
||||
typedef struct subsector_s
|
||||
{
|
||||
sector_t *sector;
|
||||
short numlines;
|
||||
short firstline;
|
||||
polyobj_t *poly;
|
||||
} subsector_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fixed_t x,y,dx,dy; // partition line
|
||||
fixed_t bbox[2][4]; // bounding box for each child
|
||||
unsigned short children[2]; // if NF_SUBSECTOR its a subsector
|
||||
} node_t;
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
OTHER TYPES
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
typedef byte lighttable_t; // this could be wider for >8 bit display
|
||||
|
||||
#define MAXVISPLANES 160
|
||||
#define MAXOPENINGS SCREENWIDTH*64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fixed_t height;
|
||||
int picnum;
|
||||
int lightlevel;
|
||||
int special;
|
||||
int minx, maxx;
|
||||
byte pad1; // leave pads for [minx-1]/[maxx+1]
|
||||
byte top[SCREENWIDTH];
|
||||
byte pad2;
|
||||
byte pad3;
|
||||
byte bottom[SCREENWIDTH];
|
||||
byte pad4;
|
||||
} visplane_t;
|
||||
|
||||
typedef struct drawseg_s
|
||||
{
|
||||
seg_t *curline;
|
||||
int x1, x2;
|
||||
fixed_t scale1, scale2, scalestep;
|
||||
int silhouette; // 0=none, 1=bottom, 2=top, 3=both
|
||||
fixed_t bsilheight; // don't clip sprites above this
|
||||
fixed_t tsilheight; // don't clip sprites below this
|
||||
// pointers to lists for sprite clipping
|
||||
short *sprtopclip; // adjusted so [x1] is first value
|
||||
short *sprbottomclip; // adjusted so [x1] is first value
|
||||
short *maskedtexturecol; // adjusted so [x1] is first value
|
||||
} drawseg_t;
|
||||
|
||||
#define SIL_NONE 0
|
||||
#define SIL_BOTTOM 1
|
||||
#define SIL_TOP 2
|
||||
#define SIL_BOTH 3
|
||||
|
||||
#define MAXDRAWSEGS 256
|
||||
|
||||
// A vissprite_t is a thing that will be drawn during a refresh
|
||||
typedef struct vissprite_s
|
||||
{
|
||||
struct vissprite_s *prev, *next;
|
||||
int x1, x2;
|
||||
fixed_t gx, gy; // for line side calculation
|
||||
fixed_t gz, gzt; // global bottom / top for silhouette clipping
|
||||
fixed_t startfrac; // horizontal position of x1
|
||||
fixed_t scale;
|
||||
fixed_t xiscale; // negative if flipped
|
||||
fixed_t texturemid;
|
||||
int patch;
|
||||
lighttable_t *colormap;
|
||||
int mobjflags; // for color translation and shadow draw
|
||||
boolean psprite; // true if psprite
|
||||
int class; // player class (used in translation)
|
||||
fixed_t floorclip;
|
||||
} vissprite_t;
|
||||
|
||||
|
||||
extern visplane_t *floorplane, *ceilingplane;
|
||||
|
||||
// Sprites are patches with a special naming convention so they can be
|
||||
// recognized by R_InitSprites. The sprite and frame specified by a
|
||||
// thing_t is range checked at run time.
|
||||
// a sprite is a patch_t that is assumed to represent a three dimensional
|
||||
// object and may have multiple rotations pre drawn. Horizontal flipping
|
||||
// is used to save space. Some sprites will only have one picture used
|
||||
// for all views.
|
||||
|
||||
typedef struct
|
||||
{
|
||||
boolean rotate; // if false use 0 for any position
|
||||
short lump[8]; // lump to use for view angles 0-7
|
||||
byte flip[8]; // flip (1 = flip) to use for view angles 0-7
|
||||
} spriteframe_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int numframes;
|
||||
spriteframe_t *spriteframes;
|
||||
} spritedef_t;
|
||||
|
||||
extern spritedef_t *sprites;
|
||||
extern int numsprites;
|
||||
|
||||
//=============================================================================
|
||||
|
||||
extern int numvertexes;
|
||||
extern vertex_t *vertexes;
|
||||
|
||||
extern int numsegs;
|
||||
extern seg_t *segs;
|
||||
|
||||
extern int numsectors;
|
||||
extern sector_t *sectors;
|
||||
|
||||
extern int numsubsectors;
|
||||
extern subsector_t *subsectors;
|
||||
|
||||
extern int numnodes;
|
||||
extern node_t *nodes;
|
||||
|
||||
extern int numlines;
|
||||
extern line_t *lines;
|
||||
|
||||
extern int numsides;
|
||||
extern side_t *sides;
|
||||
|
||||
|
||||
|
||||
extern fixed_t viewx, viewy, viewz;
|
||||
extern angle_t viewangle;
|
||||
extern player_t *viewplayer;
|
||||
|
||||
|
||||
extern angle_t clipangle;
|
||||
|
||||
extern int viewangletox[FINEANGLES/2];
|
||||
extern angle_t xtoviewangle[SCREENWIDTH+1];
|
||||
extern fixed_t finetangent[FINEANGLES/2];
|
||||
|
||||
extern fixed_t rw_distance;
|
||||
extern angle_t rw_normalangle;
|
||||
|
||||
//
|
||||
// R_main.c
|
||||
//
|
||||
extern int viewwidth, viewheight, viewwindowx, viewwindowy;
|
||||
extern int centerx, centery;
|
||||
extern int flyheight;
|
||||
extern fixed_t centerxfrac;
|
||||
extern fixed_t centeryfrac;
|
||||
extern fixed_t projection;
|
||||
|
||||
extern int validcount;
|
||||
|
||||
extern int sscount, linecount, loopcount;
|
||||
extern lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
|
||||
extern lighttable_t *scalelightfixed[MAXLIGHTSCALE];
|
||||
extern lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
|
||||
|
||||
extern int extralight;
|
||||
extern lighttable_t *fixedcolormap;
|
||||
|
||||
extern fixed_t viewcos, viewsin;
|
||||
|
||||
extern int detailshift; // 0 = high, 1 = low
|
||||
|
||||
extern void (*colfunc) (void);
|
||||
extern void (*basecolfunc) (void);
|
||||
extern void (*fuzzcolfunc) (void);
|
||||
extern void (*spanfunc) (void);
|
||||
|
||||
int R_PointOnSide (fixed_t x, fixed_t y, node_t *node);
|
||||
int R_PointOnSegSide (fixed_t x, fixed_t y, seg_t *line);
|
||||
angle_t R_PointToAngle (fixed_t x, fixed_t y);
|
||||
angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2);
|
||||
fixed_t R_PointToDist (fixed_t x, fixed_t y);
|
||||
fixed_t R_ScaleFromGlobalAngle (angle_t visangle);
|
||||
subsector_t *R_PointInSubsector (fixed_t x, fixed_t y);
|
||||
//void R_AddPointToBox (int x, int y, fixed_t *box);
|
||||
|
||||
|
||||
//
|
||||
// R_bsp.c
|
||||
//
|
||||
extern seg_t *curline;
|
||||
extern side_t *sidedef;
|
||||
extern line_t *linedef;
|
||||
extern sector_t *frontsector, *backsector;
|
||||
|
||||
extern int rw_x;
|
||||
extern int rw_stopx;
|
||||
|
||||
extern boolean segtextured;
|
||||
extern boolean markfloor; // false if the back side is the same plane
|
||||
extern boolean markceiling;
|
||||
extern boolean skymap;
|
||||
|
||||
extern drawseg_t drawsegs[MAXDRAWSEGS], *ds_p;
|
||||
|
||||
extern lighttable_t **hscalelight, **vscalelight, **dscalelight;
|
||||
|
||||
typedef void (*drawfunc_t) (int start, int stop);
|
||||
void R_ClearClipSegs (void);
|
||||
|
||||
void R_ClearDrawSegs (void);
|
||||
void R_InitSkyMap (void);
|
||||
void R_RenderBSPNode (int bspnum);
|
||||
|
||||
//
|
||||
// R_segs.c
|
||||
//
|
||||
extern int rw_angle1; // angle to line origin
|
||||
extern int TransTextureStart;
|
||||
extern int TransTextureEnd;
|
||||
|
||||
void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2);
|
||||
|
||||
//
|
||||
// R_plane.c
|
||||
//
|
||||
typedef void (*planefunction_t) (int top, int bottom);
|
||||
extern planefunction_t floorfunc, ceilingfunc;
|
||||
|
||||
extern int skyflatnum;
|
||||
|
||||
extern short openings[MAXOPENINGS], *lastopening;
|
||||
|
||||
extern short floorclip[SCREENWIDTH];
|
||||
extern short ceilingclip[SCREENWIDTH];
|
||||
|
||||
extern fixed_t yslope[SCREENHEIGHT];
|
||||
extern fixed_t distscale[SCREENWIDTH];
|
||||
|
||||
void R_InitPlanes (void);
|
||||
void R_ClearPlanes (void);
|
||||
void R_MapPlane (int y, int x1, int x2);
|
||||
void R_MakeSpans (int x, int t1, int b1, int t2, int b2);
|
||||
void R_DrawPlanes (void);
|
||||
|
||||
visplane_t *R_FindPlane (fixed_t height, int picnum, int lightlevel,
|
||||
int special);
|
||||
visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop);
|
||||
|
||||
|
||||
//
|
||||
// R_debug.m
|
||||
//
|
||||
extern int drawbsp;
|
||||
|
||||
void RD_OpenMapWindow (void);
|
||||
void RD_ClearMapWindow (void);
|
||||
void RD_DisplayLine (int x1, int y1, int x2, int y2, float gray);
|
||||
void RD_DrawNodeLine (node_t *node);
|
||||
void RD_DrawLineCheck (seg_t *line);
|
||||
void RD_DrawLine (seg_t *line);
|
||||
void RD_DrawBBox (fixed_t *bbox);
|
||||
|
||||
|
||||
//
|
||||
// R_data.c
|
||||
//
|
||||
extern fixed_t *textureheight; // needed for texture pegging
|
||||
extern fixed_t *spritewidth; // needed for pre rendering (fracs)
|
||||
extern fixed_t *spriteoffset;
|
||||
extern fixed_t *spritetopoffset;
|
||||
extern lighttable_t *colormaps;
|
||||
extern int viewwidth, scaledviewwidth, viewheight;
|
||||
extern int firstflat;
|
||||
extern int numflats;
|
||||
|
||||
extern int *flattranslation; // for global animation
|
||||
extern int *texturetranslation; // for global animation
|
||||
|
||||
extern int firstspritelump, lastspritelump, numspritelumps;
|
||||
extern boolean LevelUseFullBright;
|
||||
|
||||
byte *R_GetColumn (int tex, int col);
|
||||
void R_InitData (void);
|
||||
void R_PrecacheLevel (void);
|
||||
|
||||
|
||||
//
|
||||
// R_things.c
|
||||
//
|
||||
#define MAXVISSPRITES 192
|
||||
|
||||
extern vissprite_t vissprites[MAXVISSPRITES], *vissprite_p;
|
||||
extern vissprite_t vsprsortedhead;
|
||||
|
||||
// constant arrays used for psprite clipping and initializing clipping
|
||||
extern short negonearray[SCREENWIDTH];
|
||||
extern short screenheightarray[SCREENWIDTH];
|
||||
|
||||
// vars for R_DrawMaskedColumn
|
||||
extern short *mfloorclip;
|
||||
extern short *mceilingclip;
|
||||
extern fixed_t spryscale;
|
||||
extern fixed_t sprtopscreen;
|
||||
extern fixed_t sprbotscreen;
|
||||
|
||||
extern fixed_t pspritescale, pspriteiscale;
|
||||
|
||||
|
||||
void R_DrawMaskedColumn (column_t *column, signed int baseclip);
|
||||
|
||||
|
||||
void R_SortVisSprites (void);
|
||||
|
||||
void R_AddSprites (sector_t *sec);
|
||||
void R_AddPSprites (void);
|
||||
void R_DrawSprites (void);
|
||||
void R_InitSprites (char **namelist);
|
||||
void R_ClearSprites (void);
|
||||
void R_DrawMasked (void);
|
||||
void R_ClipVisSprite (vissprite_t *vis, int xl, int xh);
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// R_draw.c
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
extern lighttable_t *dc_colormap;
|
||||
extern int dc_x;
|
||||
extern int dc_yl;
|
||||
extern int dc_yh;
|
||||
extern fixed_t dc_iscale;
|
||||
extern fixed_t dc_texturemid;
|
||||
extern byte *dc_source; // first pixel in a column
|
||||
|
||||
void R_DrawColumn (void);
|
||||
void R_DrawColumnLow (void);
|
||||
void R_DrawFuzzColumn (void);
|
||||
void R_DrawFuzzColumnLow (void);
|
||||
void R_DrawTranslatedColumn (void);
|
||||
void R_DrawTranslatedFuzzColumn (void);
|
||||
void R_DrawTranslatedColumnLow (void);
|
||||
void R_DrawAltFuzzColumn(void);
|
||||
//void R_DrawTranslatedAltFuzzColumn(void);
|
||||
|
||||
extern int ds_y;
|
||||
extern int ds_x1;
|
||||
extern int ds_x2;
|
||||
extern lighttable_t *ds_colormap;
|
||||
extern fixed_t ds_xfrac;
|
||||
extern fixed_t ds_yfrac;
|
||||
extern fixed_t ds_xstep;
|
||||
extern fixed_t ds_ystep;
|
||||
extern byte *ds_source; // start of a 64*64 tile image
|
||||
|
||||
extern byte *translationtables;
|
||||
extern byte *dc_translation;
|
||||
|
||||
void R_DrawSpan (void);
|
||||
void R_DrawSpanLow (void);
|
||||
|
||||
void R_InitBuffer (int width, int height);
|
||||
void R_InitTranslationTables (void);
|
||||
|
||||
#endif // __R_LOCAL__
|
||||
|
860
Hexen Source/R_MAIN.C
Normal file
860
Hexen Source/R_MAIN.C
Normal file
|
@ -0,0 +1,860 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** r_main.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: r_main.c,v $
|
||||
//** $Revision: 1.16 $
|
||||
//** $Date: 96/01/06 18:37:41 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include "h2def.h"
|
||||
#include "r_local.h"
|
||||
|
||||
int viewangleoffset;
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
int newViewAngleOff;
|
||||
#endif
|
||||
|
||||
int validcount = 1; // increment every time a check is made
|
||||
|
||||
lighttable_t *fixedcolormap;
|
||||
extern lighttable_t **walllights;
|
||||
|
||||
int centerx, centery;
|
||||
fixed_t centerxfrac, centeryfrac;
|
||||
fixed_t projection;
|
||||
|
||||
int framecount; // just for profiling purposes
|
||||
|
||||
int sscount, linecount, loopcount;
|
||||
|
||||
fixed_t viewx, viewy, viewz;
|
||||
angle_t viewangle;
|
||||
fixed_t viewcos, viewsin;
|
||||
player_t *viewplayer;
|
||||
|
||||
int detailshift; // 0 = high, 1 = low
|
||||
|
||||
//
|
||||
// precalculated math tables
|
||||
//
|
||||
angle_t clipangle;
|
||||
|
||||
// The viewangletox[viewangle + FINEANGLES/4] lookup maps the visible view
|
||||
// angles to screen X coordinates, flattening the arc to a flat projection
|
||||
// plane. There will be many angles mapped to the same X.
|
||||
int viewangletox[FINEANGLES/2];
|
||||
|
||||
// The xtoviewangleangle[] table maps a screen pixel to the lowest viewangle
|
||||
// that maps back to x ranges from clipangle to -clipangle
|
||||
angle_t xtoviewangle[SCREENWIDTH+1];
|
||||
|
||||
// the finetangentgent[angle+FINEANGLES/4] table holds the fixed_t tangent
|
||||
// values for view angles, ranging from MININT to 0 to MAXINT.
|
||||
// fixed_t finetangent[FINEANGLES/2];
|
||||
|
||||
// fixed_t finesine[5*FINEANGLES/4];
|
||||
fixed_t *finecosine = &finesine[FINEANGLES/4];
|
||||
|
||||
|
||||
lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
|
||||
lighttable_t *scalelightfixed[MAXLIGHTSCALE];
|
||||
lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
|
||||
|
||||
int extralight; // bumped light from gun blasts
|
||||
|
||||
void (*colfunc) (void);
|
||||
void (*basecolfunc) (void);
|
||||
void (*fuzzcolfunc) (void);
|
||||
void (*transcolfunc) (void);
|
||||
void (*spanfunc) (void);
|
||||
|
||||
/*
|
||||
===================
|
||||
=
|
||||
= R_AddPointToBox
|
||||
=
|
||||
===================
|
||||
*/
|
||||
|
||||
/*
|
||||
void R_AddPointToBox (int x, int y, fixed_t *box)
|
||||
{
|
||||
if (x< box[BOXLEFT])
|
||||
box[BOXLEFT] = x;
|
||||
if (x> box[BOXRIGHT])
|
||||
box[BOXRIGHT] = x;
|
||||
if (y< box[BOXBOTTOM])
|
||||
box[BOXBOTTOM] = y;
|
||||
if (y> box[BOXTOP])
|
||||
box[BOXTOP] = y;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
=
|
||||
= R_PointOnSide
|
||||
=
|
||||
= Returns side 0 (front) or 1 (back)
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
int R_PointOnSide (fixed_t x, fixed_t y, node_t *node)
|
||||
{
|
||||
fixed_t dx,dy;
|
||||
fixed_t left, right;
|
||||
|
||||
if (!node->dx)
|
||||
{
|
||||
if (x <= node->x)
|
||||
return node->dy > 0;
|
||||
return node->dy < 0;
|
||||
}
|
||||
if (!node->dy)
|
||||
{
|
||||
if (y <= node->y)
|
||||
return node->dx < 0;
|
||||
return node->dx > 0;
|
||||
}
|
||||
|
||||
dx = (x - node->x);
|
||||
dy = (y - node->y);
|
||||
|
||||
// try to quickly decide by looking at sign bits
|
||||
if ( (node->dy ^ node->dx ^ dx ^ dy)&0x80000000 )
|
||||
{
|
||||
if ( (node->dy ^ dx) & 0x80000000 )
|
||||
return 1; // (left is negative)
|
||||
return 0;
|
||||
}
|
||||
|
||||
left = FixedMul ( node->dy>>FRACBITS , dx );
|
||||
right = FixedMul ( dy , node->dx>>FRACBITS );
|
||||
|
||||
if (right < left)
|
||||
return 0; // front side
|
||||
return 1; // back side
|
||||
}
|
||||
|
||||
|
||||
int R_PointOnSegSide (fixed_t x, fixed_t y, seg_t *line)
|
||||
{
|
||||
fixed_t lx, ly;
|
||||
fixed_t ldx, ldy;
|
||||
fixed_t dx,dy;
|
||||
fixed_t left, right;
|
||||
|
||||
lx = line->v1->x;
|
||||
ly = line->v1->y;
|
||||
|
||||
ldx = line->v2->x - lx;
|
||||
ldy = line->v2->y - ly;
|
||||
|
||||
if (!ldx)
|
||||
{
|
||||
if (x <= lx)
|
||||
return ldy > 0;
|
||||
return ldy < 0;
|
||||
}
|
||||
if (!ldy)
|
||||
{
|
||||
if (y <= ly)
|
||||
return ldx < 0;
|
||||
return ldx > 0;
|
||||
}
|
||||
|
||||
dx = (x - lx);
|
||||
dy = (y - ly);
|
||||
|
||||
// try to quickly decide by looking at sign bits
|
||||
if ( (ldy ^ ldx ^ dx ^ dy)&0x80000000 )
|
||||
{
|
||||
if ( (ldy ^ dx) & 0x80000000 )
|
||||
return 1; // (left is negative)
|
||||
return 0;
|
||||
}
|
||||
|
||||
left = FixedMul ( ldy>>FRACBITS , dx );
|
||||
right = FixedMul ( dy , ldx>>FRACBITS );
|
||||
|
||||
if (right < left)
|
||||
return 0; // front side
|
||||
return 1; // back side
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
=
|
||||
= R_PointToAngle
|
||||
=
|
||||
===============================================================================
|
||||
*/
|
||||
|
||||
// to get a global angle from cartesian coordinates, the coordinates are
|
||||
// flipped until they are in the first octant of the coordinate system, then
|
||||
// the y (<=x) is scaled and divided by x to get a tangent (slope) value
|
||||
// which is looked up in the tantoangle[] table. The +1 size is to handle
|
||||
// the case when x==y without additional checking.
|
||||
#define SLOPERANGE 2048
|
||||
#define SLOPEBITS 11
|
||||
#define DBITS (FRACBITS-SLOPEBITS)
|
||||
|
||||
|
||||
extern int tantoangle[SLOPERANGE+1]; // get from tables.c
|
||||
|
||||
// int tantoangle[SLOPERANGE+1];
|
||||
|
||||
int SlopeDiv (unsigned num, unsigned den)
|
||||
{
|
||||
unsigned ans;
|
||||
if (den < 512)
|
||||
return SLOPERANGE;
|
||||
ans = (num<<3)/(den>>8);
|
||||
return ans <= SLOPERANGE ? ans : SLOPERANGE;
|
||||
}
|
||||
|
||||
angle_t R_PointToAngle (fixed_t x, fixed_t y)
|
||||
{
|
||||
x -= viewx;
|
||||
y -= viewy;
|
||||
if ( (!x) && (!y) )
|
||||
return 0;
|
||||
if (x>= 0)
|
||||
{ // x >=0
|
||||
if (y>= 0)
|
||||
{ // y>= 0
|
||||
if (x>y)
|
||||
return tantoangle[ SlopeDiv(y,x)]; // octant 0
|
||||
else
|
||||
return ANG90-1-tantoangle[ SlopeDiv(x,y)]; // octant 1
|
||||
}
|
||||
else
|
||||
{ // y<0
|
||||
y = -y;
|
||||
if (x>y)
|
||||
return -tantoangle[SlopeDiv(y,x)]; // octant 8
|
||||
else
|
||||
return ANG270+tantoangle[ SlopeDiv(x,y)]; // octant 7
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // x<0
|
||||
x = -x;
|
||||
if (y>= 0)
|
||||
{ // y>= 0
|
||||
if (x>y)
|
||||
return ANG180-1-tantoangle[ SlopeDiv(y,x)]; // octant 3
|
||||
else
|
||||
return ANG90+ tantoangle[ SlopeDiv(x,y)]; // octant 2
|
||||
}
|
||||
else
|
||||
{ // y<0
|
||||
y = -y;
|
||||
if (x>y)
|
||||
return ANG180+tantoangle[ SlopeDiv(y,x)]; // octant 4
|
||||
else
|
||||
return ANG270-1-tantoangle[ SlopeDiv(x,y)]; // octant 5
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
angle_t R_PointToAngle2 (fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2)
|
||||
{
|
||||
viewx = x1;
|
||||
viewy = y1;
|
||||
return R_PointToAngle (x2, y2);
|
||||
}
|
||||
|
||||
|
||||
fixed_t R_PointToDist (fixed_t x, fixed_t y)
|
||||
{
|
||||
int angle;
|
||||
fixed_t dx, dy, 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;
|
||||
|
||||
dist = FixedDiv (dx, finesine[angle] ); // use as cosine
|
||||
|
||||
return dist;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
=
|
||||
= R_InitPointToAngle
|
||||
=
|
||||
=================
|
||||
*/
|
||||
|
||||
void R_InitPointToAngle (void)
|
||||
{
|
||||
// now getting from tables.c
|
||||
#if 0
|
||||
int i;
|
||||
long t;
|
||||
float f;
|
||||
//
|
||||
// slope (tangent) to angle lookup
|
||||
//
|
||||
for (i=0 ; i<=SLOPERANGE ; i++)
|
||||
{
|
||||
f = atan( (float)i/SLOPERANGE )/(3.141592657*2);
|
||||
t = 0xffffffff*f;
|
||||
tantoangle[i] = t;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
================
|
||||
=
|
||||
= R_ScaleFromGlobalAngle
|
||||
=
|
||||
= Returns the texture mapping scale for the current line at the given angle
|
||||
= rw_distance must be calculated first
|
||||
================
|
||||
*/
|
||||
|
||||
fixed_t R_ScaleFromGlobalAngle (angle_t visangle)
|
||||
{
|
||||
fixed_t scale;
|
||||
int anglea, angleb;
|
||||
int sinea, sineb;
|
||||
fixed_t num,den;
|
||||
|
||||
#if 0
|
||||
{
|
||||
fixed_t dist,z;
|
||||
fixed_t sinv, cosv;
|
||||
|
||||
sinv = finesine[(visangle-rw_normalangle)>>ANGLETOFINESHIFT];
|
||||
dist = FixedDiv (rw_distance, sinv);
|
||||
cosv = finecosine[(viewangle-visangle)>>ANGLETOFINESHIFT];
|
||||
z = abs(FixedMul (dist, cosv));
|
||||
scale = FixedDiv(projection, z);
|
||||
return scale;
|
||||
}
|
||||
#endif
|
||||
|
||||
anglea = ANG90 + (visangle-viewangle);
|
||||
angleb = ANG90 + (visangle-rw_normalangle);
|
||||
// bothe sines are allways positive
|
||||
sinea = finesine[anglea>>ANGLETOFINESHIFT];
|
||||
sineb = finesine[angleb>>ANGLETOFINESHIFT];
|
||||
num = FixedMul(projection,sineb)<<detailshift;
|
||||
den = FixedMul(rw_distance,sinea);
|
||||
if (den > num>>16)
|
||||
{
|
||||
scale = FixedDiv (num, den);
|
||||
if (scale > 64*FRACUNIT)
|
||||
scale = 64*FRACUNIT;
|
||||
else if (scale < 256)
|
||||
scale = 256;
|
||||
}
|
||||
else
|
||||
scale = 64*FRACUNIT;
|
||||
|
||||
return scale;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
=
|
||||
= R_InitTables
|
||||
=
|
||||
=================
|
||||
*/
|
||||
|
||||
void R_InitTables (void)
|
||||
{
|
||||
// now getting from tables.c
|
||||
#if 0
|
||||
int i;
|
||||
float a, fv;
|
||||
int t;
|
||||
|
||||
//
|
||||
// viewangle tangent table
|
||||
//
|
||||
for (i=0 ; i<FINEANGLES/2 ; i++)
|
||||
{
|
||||
a = (i-FINEANGLES/4+0.5)*PI*2/FINEANGLES;
|
||||
fv = FRACUNIT*tan (a);
|
||||
t = fv;
|
||||
finetangent[i] = t;
|
||||
}
|
||||
|
||||
//
|
||||
// finesine table
|
||||
//
|
||||
for (i=0 ; i<5*FINEANGLES/4 ; i++)
|
||||
{
|
||||
// OPTIMIZE: mirror...
|
||||
a = (i+0.5)*PI*2/FINEANGLES;
|
||||
t = FRACUNIT*sin (a);
|
||||
finesine[i] = t;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
=
|
||||
= R_InitTextureMapping
|
||||
=
|
||||
=================
|
||||
*/
|
||||
|
||||
void R_InitTextureMapping (void)
|
||||
{
|
||||
int i;
|
||||
int x;
|
||||
int t;
|
||||
fixed_t focallength;
|
||||
|
||||
|
||||
//
|
||||
// use tangent table to generate viewangletox
|
||||
// viewangletox will give the next greatest x after the view angle
|
||||
//
|
||||
// calc focallength so FIELDOFVIEW angles covers SCREENWIDTH
|
||||
focallength = FixedDiv (centerxfrac
|
||||
, finetangent[FINEANGLES/4+FIELDOFVIEW/2] );
|
||||
|
||||
for (i=0 ; i<FINEANGLES/2 ; i++)
|
||||
{
|
||||
if (finetangent[i] > FRACUNIT*2)
|
||||
t = -1;
|
||||
else if (finetangent[i] < -FRACUNIT*2)
|
||||
t = viewwidth+1;
|
||||
else
|
||||
{
|
||||
t = FixedMul (finetangent[i], focallength);
|
||||
t = (centerxfrac - t+FRACUNIT-1)>>FRACBITS;
|
||||
if (t < -1)
|
||||
t = -1;
|
||||
else if (t>viewwidth+1)
|
||||
t = viewwidth+1;
|
||||
}
|
||||
viewangletox[i] = t;
|
||||
}
|
||||
|
||||
//
|
||||
// scan viewangletox[] to generate xtoviewangleangle[]
|
||||
//
|
||||
// xtoviewangle will give the smallest view angle that maps to x
|
||||
for (x=0;x<=viewwidth;x++)
|
||||
{
|
||||
i = 0;
|
||||
while (viewangletox[i]>x)
|
||||
i++;
|
||||
xtoviewangle[x] = (i<<ANGLETOFINESHIFT)-ANG90;
|
||||
}
|
||||
|
||||
//
|
||||
// take out the fencepost cases from viewangletox
|
||||
//
|
||||
for (i=0 ; i<FINEANGLES/2 ; i++)
|
||||
{
|
||||
t = FixedMul (finetangent[i], focallength);
|
||||
t = centerx - t;
|
||||
if (viewangletox[i] == -1)
|
||||
viewangletox[i] = 0;
|
||||
else if (viewangletox[i] == viewwidth+1)
|
||||
viewangletox[i] = viewwidth;
|
||||
}
|
||||
|
||||
clipangle = xtoviewangle[0];
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
====================
|
||||
=
|
||||
= R_InitLightTables
|
||||
=
|
||||
= Only inits the zlight table, because the scalelight table changes
|
||||
= with view size
|
||||
=
|
||||
====================
|
||||
*/
|
||||
|
||||
#define DISTMAP 2
|
||||
|
||||
void R_InitLightTables (void)
|
||||
{
|
||||
int i,j, level, startmap;
|
||||
int scale;
|
||||
|
||||
//
|
||||
// Calculate the light levels to use for each level / distance combination
|
||||
//
|
||||
for (i=0 ; i< LIGHTLEVELS ; i++)
|
||||
{
|
||||
startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
|
||||
for (j=0 ; j<MAXLIGHTZ ; j++)
|
||||
{
|
||||
scale = FixedDiv ((SCREENWIDTH/2*FRACUNIT), (j+1)<<LIGHTZSHIFT);
|
||||
scale >>= LIGHTSCALESHIFT;
|
||||
level = startmap - scale/DISTMAP;
|
||||
if (level < 0)
|
||||
level = 0;
|
||||
if (level >= NUMCOLORMAPS)
|
||||
level = NUMCOLORMAPS-1;
|
||||
zlight[i][j] = colormaps + level*256;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
=
|
||||
= R_SetViewSize
|
||||
=
|
||||
= Don't really change anything here, because i might be in the middle of
|
||||
= a refresh. The change will take effect next refresh.
|
||||
=
|
||||
==============
|
||||
*/
|
||||
|
||||
boolean setsizeneeded;
|
||||
int setblocks, setdetail;
|
||||
|
||||
void R_SetViewSize (int blocks, int detail)
|
||||
{
|
||||
setsizeneeded = true;
|
||||
setblocks = blocks;
|
||||
setdetail = detail;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
=
|
||||
= R_ExecuteSetViewSize
|
||||
=
|
||||
==============
|
||||
*/
|
||||
|
||||
void R_ExecuteSetViewSize (void)
|
||||
{
|
||||
fixed_t cosadj, dy;
|
||||
int i,j, level, startmap;
|
||||
|
||||
setsizeneeded = false;
|
||||
|
||||
if (setblocks == 11)
|
||||
{
|
||||
scaledviewwidth = SCREENWIDTH;
|
||||
viewheight = SCREENHEIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
scaledviewwidth = setblocks*32;
|
||||
viewheight = (setblocks*161/10);
|
||||
}
|
||||
|
||||
detailshift = setdetail;
|
||||
viewwidth = scaledviewwidth>>detailshift;
|
||||
|
||||
centery = viewheight/2;
|
||||
centerx = viewwidth/2;
|
||||
centerxfrac = centerx<<FRACBITS;
|
||||
centeryfrac = centery<<FRACBITS;
|
||||
projection = centerxfrac;
|
||||
|
||||
if (!detailshift)
|
||||
{
|
||||
colfunc = basecolfunc = R_DrawColumn;
|
||||
fuzzcolfunc = R_DrawFuzzColumn;
|
||||
transcolfunc = R_DrawTranslatedColumn;
|
||||
spanfunc = R_DrawSpan;
|
||||
}
|
||||
else
|
||||
{
|
||||
colfunc = basecolfunc = R_DrawColumnLow;
|
||||
fuzzcolfunc = R_DrawFuzzColumn;
|
||||
transcolfunc = R_DrawTranslatedColumn;
|
||||
spanfunc = R_DrawSpanLow;
|
||||
}
|
||||
|
||||
R_InitBuffer (scaledviewwidth, viewheight);
|
||||
|
||||
R_InitTextureMapping ();
|
||||
|
||||
//
|
||||
// psprite scales
|
||||
//
|
||||
pspritescale = FRACUNIT*viewwidth/SCREENWIDTH;
|
||||
pspriteiscale = FRACUNIT*SCREENWIDTH/viewwidth;
|
||||
|
||||
//
|
||||
// thing clipping
|
||||
//
|
||||
for (i=0 ; i<viewwidth ; i++)
|
||||
screenheightarray[i] = viewheight;
|
||||
|
||||
//
|
||||
// planes
|
||||
//
|
||||
for (i=0 ; i<viewheight ; i++)
|
||||
{
|
||||
dy = ((i-viewheight/2)<<FRACBITS)+FRACUNIT/2;
|
||||
dy = abs(dy);
|
||||
yslope[i] = FixedDiv ( (viewwidth<<detailshift)/2*FRACUNIT, dy);
|
||||
}
|
||||
|
||||
for (i=0 ; i<viewwidth ; i++)
|
||||
{
|
||||
cosadj = abs(finecosine[xtoviewangle[i]>>ANGLETOFINESHIFT]);
|
||||
distscale[i] = FixedDiv (FRACUNIT,cosadj);
|
||||
}
|
||||
|
||||
//
|
||||
// Calculate the light levels to use for each level / scale combination
|
||||
//
|
||||
for (i=0 ; i< LIGHTLEVELS ; i++)
|
||||
{
|
||||
startmap = ((LIGHTLEVELS-1-i)*2)*NUMCOLORMAPS/LIGHTLEVELS;
|
||||
for (j=0 ; j<MAXLIGHTSCALE ; j++)
|
||||
{
|
||||
level = startmap - j*SCREENWIDTH/(viewwidth<<detailshift)/DISTMAP;
|
||||
if (level < 0)
|
||||
level = 0;
|
||||
if (level >= NUMCOLORMAPS)
|
||||
level = NUMCOLORMAPS-1;
|
||||
scalelight[i][j] = colormaps + level*256;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// draw the border
|
||||
//
|
||||
R_DrawViewBorder (); // erase old menu stuff
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
=
|
||||
= R_Init
|
||||
=
|
||||
==============
|
||||
*/
|
||||
|
||||
int detailLevel;
|
||||
int screenblocks;
|
||||
|
||||
void R_Init(void)
|
||||
{
|
||||
R_InitData();
|
||||
R_InitPointToAngle();
|
||||
R_InitTables();
|
||||
// viewwidth / viewheight / detailLevel are set by the defaults
|
||||
R_SetViewSize(screenblocks, detailLevel);
|
||||
R_InitPlanes();
|
||||
R_InitLightTables();
|
||||
R_InitSkyMap();
|
||||
R_InitTranslationTables();
|
||||
framecount = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
=
|
||||
= R_PointInSubsector
|
||||
=
|
||||
==============
|
||||
*/
|
||||
|
||||
subsector_t *R_PointInSubsector (fixed_t x, fixed_t y)
|
||||
{
|
||||
node_t *node;
|
||||
int side, nodenum;
|
||||
|
||||
if (!numnodes) // single subsector is a special case
|
||||
return subsectors;
|
||||
|
||||
nodenum = numnodes-1;
|
||||
|
||||
while (! (nodenum & NF_SUBSECTOR) )
|
||||
{
|
||||
node = &nodes[nodenum];
|
||||
side = R_PointOnSide (x, y, node);
|
||||
nodenum = node->children[side];
|
||||
}
|
||||
|
||||
return &subsectors[nodenum & ~NF_SUBSECTOR];
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// PROC R_SetupFrame
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void R_SetupFrame(player_t *player)
|
||||
{
|
||||
int i;
|
||||
int tableAngle;
|
||||
int tempCentery;
|
||||
int intensity;
|
||||
|
||||
//drawbsp = 1;
|
||||
viewplayer = player;
|
||||
#ifdef __WATCOMC__
|
||||
if(newViewAngleOff)
|
||||
{
|
||||
viewangleoffset = newViewAngleOff<<ANGLETOFINESHIFT;
|
||||
}
|
||||
#endif
|
||||
viewangle = player->mo->angle+viewangleoffset;
|
||||
tableAngle = viewangle>>ANGLETOFINESHIFT;
|
||||
viewx = player->mo->x;
|
||||
viewy = player->mo->y;
|
||||
|
||||
if(localQuakeHappening[displayplayer] && !paused)
|
||||
{
|
||||
intensity = localQuakeHappening[displayplayer];
|
||||
viewx += ((M_Random() % (intensity<<2))
|
||||
-(intensity<<1))<<FRACBITS;
|
||||
viewy += ((M_Random()%(intensity<<2))
|
||||
-(intensity<<1))<<FRACBITS;
|
||||
}
|
||||
|
||||
extralight = player->extralight;
|
||||
viewz = player->viewz;
|
||||
|
||||
tempCentery = viewheight/2+(player->lookdir)*screenblocks/10;
|
||||
if(centery != tempCentery)
|
||||
{
|
||||
centery = tempCentery;
|
||||
centeryfrac = centery<<FRACBITS;
|
||||
for(i = 0; i < viewheight; i++)
|
||||
{
|
||||
yslope[i] = FixedDiv ((viewwidth<<detailshift)/2*FRACUNIT,
|
||||
abs(((i-centery)<<FRACBITS)+FRACUNIT/2));
|
||||
}
|
||||
}
|
||||
viewsin = finesine[tableAngle];
|
||||
viewcos = finecosine[tableAngle];
|
||||
sscount = 0;
|
||||
if(player->fixedcolormap)
|
||||
{
|
||||
fixedcolormap = colormaps+player->fixedcolormap
|
||||
*256*sizeof(lighttable_t);
|
||||
walllights = scalelightfixed;
|
||||
for(i = 0; i < MAXLIGHTSCALE; i++)
|
||||
{
|
||||
scalelightfixed[i] = fixedcolormap;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fixedcolormap = 0;
|
||||
}
|
||||
framecount++;
|
||||
validcount++;
|
||||
if(BorderNeedRefresh)
|
||||
{
|
||||
if(setblocks < 10)
|
||||
{
|
||||
R_DrawViewBorder();
|
||||
}
|
||||
BorderNeedRefresh = false;
|
||||
BorderTopRefresh = false;
|
||||
UpdateState |= I_FULLSCRN;
|
||||
}
|
||||
if(BorderTopRefresh)
|
||||
{
|
||||
if(setblocks < 10)
|
||||
{
|
||||
R_DrawTopBorder();
|
||||
}
|
||||
BorderTopRefresh = false;
|
||||
UpdateState |= I_MESSAGES;
|
||||
}
|
||||
|
||||
#ifdef __NeXT__
|
||||
RD_ClearMapWindow ();
|
||||
#endif
|
||||
#ifdef __WATCOMC__
|
||||
destview = destscreen+(viewwindowx>>2)+viewwindowy*80;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
{
|
||||
static int frame;
|
||||
memset (screen, frame, SCREENWIDTH*SCREENHEIGHT);
|
||||
frame++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
=
|
||||
= R_RenderView
|
||||
=
|
||||
==============
|
||||
*/
|
||||
|
||||
void R_RenderPlayerView (player_t *player)
|
||||
{
|
||||
R_SetupFrame (player);
|
||||
R_ClearClipSegs ();
|
||||
R_ClearDrawSegs ();
|
||||
R_ClearPlanes ();
|
||||
R_ClearSprites ();
|
||||
NetUpdate (); // check for new console commands
|
||||
|
||||
// Make displayed player invisible locally
|
||||
if (localQuakeHappening[displayplayer] && gamestate == GS_LEVEL)
|
||||
{
|
||||
players[displayplayer].mo->flags2 |= MF2_DONTDRAW;
|
||||
R_RenderBSPNode (numnodes-1); // head node is the last node output
|
||||
players[displayplayer].mo->flags2 &= ~MF2_DONTDRAW;
|
||||
}
|
||||
else
|
||||
{
|
||||
R_RenderBSPNode (numnodes-1); // head node is the last node output
|
||||
}
|
||||
|
||||
NetUpdate (); // check for new console commands
|
||||
R_DrawPlanes ();
|
||||
NetUpdate (); // check for new console commands
|
||||
R_DrawMasked ();
|
||||
NetUpdate (); // check for new console commands
|
||||
}
|
559
Hexen Source/R_PLANE.C
Normal file
559
Hexen Source/R_PLANE.C
Normal file
|
@ -0,0 +1,559 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** r_plane.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: r_plane.c,v $
|
||||
//** $Revision: 1.5 $
|
||||
//** $Date: 95/07/13 15:17:12 $
|
||||
//** $Author: cjr $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include "h2def.h"
|
||||
#include "r_local.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
extern fixed_t Sky1ScrollDelta;
|
||||
extern fixed_t Sky2ScrollDelta;
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
int Sky1Texture;
|
||||
int Sky2Texture;
|
||||
fixed_t Sky1ColumnOffset;
|
||||
fixed_t Sky2ColumnOffset;
|
||||
int skyflatnum;
|
||||
int skytexturemid;
|
||||
fixed_t skyiscale;
|
||||
boolean DoubleSky;
|
||||
planefunction_t floorfunc, ceilingfunc;
|
||||
|
||||
// Opening
|
||||
visplane_t visplanes[MAXVISPLANES], *lastvisplane;
|
||||
visplane_t *floorplane, *ceilingplane;
|
||||
short openings[MAXOPENINGS], *lastopening;
|
||||
|
||||
// Clip values are the solid pixel bounding the range.
|
||||
// floorclip start out SCREENHEIGHT
|
||||
// ceilingclip starts out -1
|
||||
short floorclip[SCREENWIDTH];
|
||||
short ceilingclip[SCREENWIDTH];
|
||||
|
||||
// spanstart holds the start of a plane span, initialized to 0
|
||||
int spanstart[SCREENHEIGHT];
|
||||
int spanstop[SCREENHEIGHT];
|
||||
|
||||
// Texture mapping
|
||||
lighttable_t **planezlight;
|
||||
fixed_t planeheight;
|
||||
fixed_t yslope[SCREENHEIGHT];
|
||||
fixed_t distscale[SCREENWIDTH];
|
||||
fixed_t basexscale, baseyscale;
|
||||
fixed_t cachedheight[SCREENHEIGHT];
|
||||
fixed_t cacheddistance[SCREENHEIGHT];
|
||||
fixed_t cachedxstep[SCREENHEIGHT];
|
||||
fixed_t cachedystep[SCREENHEIGHT];
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_InitSky
|
||||
//
|
||||
// Called at level load.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void R_InitSky(int map)
|
||||
{
|
||||
Sky1Texture = P_GetMapSky1Texture(map);
|
||||
Sky2Texture = P_GetMapSky2Texture(map);
|
||||
Sky1ScrollDelta = P_GetMapSky1ScrollDelta(map);
|
||||
Sky2ScrollDelta = P_GetMapSky2ScrollDelta(map);
|
||||
Sky1ColumnOffset = 0;
|
||||
Sky2ColumnOffset = 0;
|
||||
DoubleSky = P_GetMapDoubleSky(map);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_InitSkyMap
|
||||
//
|
||||
// Called whenever the view size changes.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void R_InitSkyMap(void)
|
||||
{
|
||||
skyflatnum = R_FlatNumForName("F_SKY");
|
||||
skytexturemid = 200*FRACUNIT;
|
||||
skyiscale = FRACUNIT;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_InitPlanes
|
||||
//
|
||||
// Called at game startup.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void R_InitPlanes(void)
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_MapPlane
|
||||
//
|
||||
// Globals used: planeheight, ds_source, basexscale, baseyscale,
|
||||
// viewx, viewy.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void R_MapPlane(int y, int x1, int x2)
|
||||
{
|
||||
angle_t angle;
|
||||
fixed_t distance, length;
|
||||
unsigned index;
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if(x2 < x1 || x1 < 0 || x2 >= viewwidth || (unsigned)y > viewheight)
|
||||
{
|
||||
I_Error("R_MapPlane: %i, %i at %i", x1, x2, y);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(planeheight != cachedheight[y])
|
||||
{
|
||||
cachedheight[y] = planeheight;
|
||||
distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]);
|
||||
ds_xstep = cachedxstep[y] = FixedMul(distance, basexscale);
|
||||
ds_ystep = cachedystep[y] = FixedMul(distance, baseyscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
distance = cacheddistance[y];
|
||||
ds_xstep = cachedxstep[y];
|
||||
ds_ystep = cachedystep[y];
|
||||
}
|
||||
|
||||
length = FixedMul(distance, distscale[x1]);
|
||||
angle = (viewangle+xtoviewangle[x1])>>ANGLETOFINESHIFT;
|
||||
ds_xfrac = viewx+FixedMul(finecosine[angle], length);
|
||||
ds_yfrac = -viewy-FixedMul(finesine[angle], length);
|
||||
|
||||
if(fixedcolormap)
|
||||
{
|
||||
ds_colormap = fixedcolormap;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = distance >> LIGHTZSHIFT;
|
||||
if(index >= MAXLIGHTZ )
|
||||
{
|
||||
index = MAXLIGHTZ-1;
|
||||
}
|
||||
ds_colormap = planezlight[index];
|
||||
}
|
||||
|
||||
ds_y = y;
|
||||
ds_x1 = x1;
|
||||
ds_x2 = x2;
|
||||
|
||||
spanfunc(); // High or low detail
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_ClearPlanes
|
||||
//
|
||||
// Called at the beginning of each frame.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void R_ClearPlanes(void)
|
||||
{
|
||||
int i;
|
||||
angle_t angle;
|
||||
|
||||
// Opening / clipping determination
|
||||
for(i = 0; i < viewwidth; i++)
|
||||
{
|
||||
floorclip[i] = viewheight;
|
||||
ceilingclip[i] = -1;
|
||||
}
|
||||
|
||||
lastvisplane = visplanes;
|
||||
lastopening = openings;
|
||||
|
||||
// Texture calculation
|
||||
memset(cachedheight, 0, sizeof(cachedheight));
|
||||
angle = (viewangle-ANG90)>>ANGLETOFINESHIFT; // left to right mapping
|
||||
// Scale will be unit scale at SCREENWIDTH/2 distance
|
||||
basexscale = FixedDiv(finecosine[angle], centerxfrac);
|
||||
baseyscale = -FixedDiv(finesine[angle], centerxfrac);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_FindPlane
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
visplane_t *R_FindPlane(fixed_t height, int picnum,
|
||||
int lightlevel, int special)
|
||||
{
|
||||
visplane_t *check;
|
||||
|
||||
if(special < 150)
|
||||
{ // Don't let low specials affect search
|
||||
special = 0;
|
||||
}
|
||||
|
||||
if(picnum == skyflatnum)
|
||||
{ // All skies map together
|
||||
height = 0;
|
||||
lightlevel = 0;
|
||||
}
|
||||
|
||||
for(check = visplanes; check < lastvisplane; check++)
|
||||
{
|
||||
if(height == check->height
|
||||
&& picnum == check->picnum
|
||||
&& lightlevel == check->lightlevel
|
||||
&& special == check->special)
|
||||
break;
|
||||
}
|
||||
|
||||
if(check < lastvisplane)
|
||||
{
|
||||
return(check);
|
||||
}
|
||||
|
||||
if(lastvisplane-visplanes == MAXVISPLANES)
|
||||
{
|
||||
I_Error("R_FindPlane: no more visplanes");
|
||||
}
|
||||
|
||||
lastvisplane++;
|
||||
check->height = height;
|
||||
check->picnum = picnum;
|
||||
check->lightlevel = lightlevel;
|
||||
check->special = special;
|
||||
check->minx = SCREENWIDTH;
|
||||
check->maxx = -1;
|
||||
memset(check->top, 0xff, sizeof(check->top));
|
||||
return(check);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_CheckPlane
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
visplane_t *R_CheckPlane(visplane_t *pl, int start, int stop)
|
||||
{
|
||||
int intrl, intrh;
|
||||
int unionl, unionh;
|
||||
int x;
|
||||
|
||||
if(start < pl->minx)
|
||||
{
|
||||
intrl = pl->minx;
|
||||
unionl = start;
|
||||
}
|
||||
else
|
||||
{
|
||||
unionl = pl->minx;
|
||||
intrl = start;
|
||||
}
|
||||
if(stop > pl->maxx)
|
||||
{
|
||||
intrh = pl->maxx;
|
||||
unionh = stop;
|
||||
}
|
||||
else
|
||||
{
|
||||
unionh = pl->maxx;
|
||||
intrh = stop;
|
||||
}
|
||||
|
||||
for(x = intrl; x <= intrh; x++)
|
||||
{
|
||||
if(pl->top[x] != 0xff)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(x > intrh)
|
||||
{
|
||||
pl->minx = unionl;
|
||||
pl->maxx = unionh;
|
||||
return pl; // use the same visplane
|
||||
}
|
||||
|
||||
// Make a new visplane
|
||||
lastvisplane->height = pl->height;
|
||||
lastvisplane->picnum = pl->picnum;
|
||||
lastvisplane->lightlevel = pl->lightlevel;
|
||||
lastvisplane->special = pl->special;
|
||||
pl = lastvisplane++;
|
||||
pl->minx = start;
|
||||
pl->maxx = stop;
|
||||
memset(pl->top, 0xff, sizeof(pl->top));
|
||||
|
||||
return pl;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_MakeSpans
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void R_MakeSpans(int x, int t1, int b1, int t2, int b2)
|
||||
{
|
||||
while(t1 < t2 && t1 <= b1)
|
||||
{
|
||||
R_MapPlane(t1, spanstart[t1], x-1);
|
||||
t1++;
|
||||
}
|
||||
while(b1 > b2 && b1 >= t1)
|
||||
{
|
||||
R_MapPlane(b1, spanstart[b1], x-1);
|
||||
b1--;
|
||||
}
|
||||
while(t2 < t1 && t2 <= b2)
|
||||
{
|
||||
spanstart[t2] = x;
|
||||
t2++;
|
||||
}
|
||||
while(b2 > b1 && b2 >= t2)
|
||||
{
|
||||
spanstart[b2] = x;
|
||||
b2--;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// R_DrawPlanes
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
#define SKYTEXTUREMIDSHIFTED 200
|
||||
|
||||
void R_DrawPlanes(void)
|
||||
{
|
||||
visplane_t *pl;
|
||||
int light;
|
||||
int x, stop;
|
||||
int angle;
|
||||
byte *tempSource;
|
||||
byte *source;
|
||||
byte *source2;
|
||||
byte *dest;
|
||||
int count;
|
||||
int offset;
|
||||
int skyTexture;
|
||||
int offset2;
|
||||
int skyTexture2;
|
||||
int scrollOffset;
|
||||
|
||||
extern byte *ylookup[MAXHEIGHT];
|
||||
extern int columnofs[MAXWIDTH];
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if(ds_p-drawsegs > MAXDRAWSEGS)
|
||||
{
|
||||
I_Error("R_DrawPlanes: drawsegs overflow (%i)", ds_p-drawsegs);
|
||||
}
|
||||
if(lastvisplane-visplanes > MAXVISPLANES)
|
||||
{
|
||||
I_Error("R_DrawPlanes: visplane overflow (%i)",
|
||||
lastvisplane-visplanes);
|
||||
}
|
||||
if(lastopening-openings > MAXOPENINGS)
|
||||
{
|
||||
I_Error("R_DrawPlanes: opening overflow (%i)",
|
||||
lastopening-openings);
|
||||
}
|
||||
#endif
|
||||
|
||||
for(pl = visplanes; pl < lastvisplane; pl++)
|
||||
{
|
||||
if(pl->minx > pl->maxx)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(pl->picnum == skyflatnum)
|
||||
{ // Sky flat
|
||||
if(DoubleSky)
|
||||
{ // Render 2 layers, sky 1 in front
|
||||
offset = Sky1ColumnOffset>>16;
|
||||
skyTexture = texturetranslation[Sky1Texture];
|
||||
offset2 = Sky2ColumnOffset>>16;
|
||||
skyTexture2 = texturetranslation[Sky2Texture];
|
||||
for(x = pl->minx; x <= pl->maxx; x++)
|
||||
{
|
||||
dc_yl = pl->top[x];
|
||||
dc_yh = pl->bottom[x];
|
||||
if(dc_yl <= dc_yh)
|
||||
{
|
||||
count = dc_yh-dc_yl;
|
||||
if(count < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
angle = (viewangle+xtoviewangle[x])
|
||||
>>ANGLETOSKYSHIFT;
|
||||
source = R_GetColumn(skyTexture, angle+offset)
|
||||
+SKYTEXTUREMIDSHIFTED+(dc_yl-centery);
|
||||
source2 = R_GetColumn(skyTexture2, angle+offset2)
|
||||
+SKYTEXTUREMIDSHIFTED+(dc_yl-centery);
|
||||
dest = ylookup[dc_yl]+columnofs[x];
|
||||
do
|
||||
{
|
||||
if(*source)
|
||||
{
|
||||
*dest = *source++;
|
||||
source2++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*dest = *source2++;
|
||||
source++;
|
||||
}
|
||||
dest += SCREENWIDTH;
|
||||
} while(count--);
|
||||
}
|
||||
}
|
||||
continue; // Next visplane
|
||||
}
|
||||
else
|
||||
{ // Render single layer
|
||||
if(pl->special == 200)
|
||||
{ // Use sky 2
|
||||
offset = Sky2ColumnOffset>>16;
|
||||
skyTexture = texturetranslation[Sky2Texture];
|
||||
}
|
||||
else
|
||||
{ // Use sky 1
|
||||
offset = Sky1ColumnOffset>>16;
|
||||
skyTexture = texturetranslation[Sky1Texture];
|
||||
}
|
||||
for(x = pl->minx; x <= pl->maxx; x++)
|
||||
{
|
||||
dc_yl = pl->top[x];
|
||||
dc_yh = pl->bottom[x];
|
||||
if(dc_yl <= dc_yh)
|
||||
{
|
||||
count = dc_yh-dc_yl;
|
||||
if(count < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
angle = (viewangle+xtoviewangle[x])
|
||||
>>ANGLETOSKYSHIFT;
|
||||
source = R_GetColumn(skyTexture, angle+offset)
|
||||
+SKYTEXTUREMIDSHIFTED+(dc_yl-centery);
|
||||
dest = ylookup[dc_yl]+columnofs[x];
|
||||
do
|
||||
{
|
||||
*dest = *source++;
|
||||
dest += SCREENWIDTH;
|
||||
} while(count--);
|
||||
}
|
||||
}
|
||||
continue; // Next visplane
|
||||
}
|
||||
}
|
||||
// Regular flat
|
||||
tempSource = W_CacheLumpNum(firstflat+
|
||||
flattranslation[pl->picnum], PU_STATIC);
|
||||
scrollOffset = leveltime>>1&63;
|
||||
switch(pl->special)
|
||||
{ // Handle scrolling flats
|
||||
case 201: case 202: case 203: // Scroll_North_xxx
|
||||
ds_source = tempSource+((scrollOffset
|
||||
<<(pl->special-201)&63)<<6);
|
||||
break;
|
||||
case 204: case 205: case 206: // Scroll_East_xxx
|
||||
ds_source = tempSource+((63-scrollOffset)
|
||||
<<(pl->special-204)&63);
|
||||
break;
|
||||
case 207: case 208: case 209: // Scroll_South_xxx
|
||||
ds_source = tempSource+(((63-scrollOffset)
|
||||
<<(pl->special-207)&63)<<6);
|
||||
break;
|
||||
case 210: case 211: case 212: // Scroll_West_xxx
|
||||
ds_source = tempSource+(scrollOffset
|
||||
<<(pl->special-210)&63);
|
||||
break;
|
||||
case 213: case 214: case 215: // Scroll_NorthWest_xxx
|
||||
ds_source = tempSource+(scrollOffset
|
||||
<<(pl->special-213)&63)+((scrollOffset
|
||||
<<(pl->special-213)&63)<<6);
|
||||
break;
|
||||
case 216: case 217: case 218: // Scroll_NorthEast_xxx
|
||||
ds_source = tempSource+((63-scrollOffset)
|
||||
<<(pl->special-216)&63)+((scrollOffset
|
||||
<<(pl->special-216)&63)<<6);
|
||||
break;
|
||||
case 219: case 220: case 221: // Scroll_SouthEast_xxx
|
||||
ds_source = tempSource+((63-scrollOffset)
|
||||
<<(pl->special-219)&63)+(((63-scrollOffset)
|
||||
<<(pl->special-219)&63)<<6);
|
||||
break;
|
||||
case 222: case 223: case 224: // Scroll_SouthWest_xxx
|
||||
ds_source = tempSource+(scrollOffset
|
||||
<<(pl->special-222)&63)+(((63-scrollOffset)
|
||||
<<(pl->special-222)&63)<<6);
|
||||
break;
|
||||
default:
|
||||
ds_source = tempSource;
|
||||
break;
|
||||
}
|
||||
planeheight = abs(pl->height-viewz);
|
||||
light = (pl->lightlevel >> LIGHTSEGSHIFT)+extralight;
|
||||
if(light >= LIGHTLEVELS)
|
||||
{
|
||||
light = LIGHTLEVELS-1;
|
||||
}
|
||||
if(light < 0)
|
||||
{
|
||||
light = 0;
|
||||
}
|
||||
planezlight = zlight[light];
|
||||
|
||||
pl->top[pl->maxx+1] = 0xff;
|
||||
pl->top[pl->minx-1] = 0xff;
|
||||
|
||||
stop = pl->maxx+1;
|
||||
for(x = pl->minx; x <= stop; x++)
|
||||
{
|
||||
R_MakeSpans(x, pl->top[x-1], pl->bottom[x-1],
|
||||
pl->top[x], pl->bottom[x]);
|
||||
}
|
||||
Z_ChangeTag(tempSource, PU_CACHE);
|
||||
}
|
||||
}
|
651
Hexen Source/R_SEGS.C
Normal file
651
Hexen Source/R_SEGS.C
Normal file
|
@ -0,0 +1,651 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** r_segs.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: r_segs.c,v $
|
||||
//** $Revision: 1.4 $
|
||||
//** $Date: 95/08/28 17:02:44 $
|
||||
//** $Author: cjr $
|
||||
//**
|
||||
//** This version has the tall-sector-crossing-precision-bug fixed.
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
#include "r_local.h"
|
||||
|
||||
// OPTIMIZE: closed two sided lines as single sided
|
||||
|
||||
boolean segtextured; // true if any of the segs textures might be vis
|
||||
boolean markfloor; // false if the back side is the same plane
|
||||
boolean markceiling;
|
||||
boolean maskedtexture;
|
||||
int toptexture, bottomtexture, midtexture;
|
||||
|
||||
|
||||
angle_t rw_normalangle;
|
||||
int rw_angle1; // angle to line origin
|
||||
|
||||
//
|
||||
// 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;
|
||||
|
||||
int worldtop, worldbottom, worldhigh, worldlow;
|
||||
|
||||
fixed_t pixhigh, pixlow;
|
||||
fixed_t pixhighstep, pixlowstep;
|
||||
fixed_t topfrac, topstep;
|
||||
fixed_t bottomfrac, bottomstep;
|
||||
|
||||
|
||||
lighttable_t **walllights;
|
||||
|
||||
short *maskedtexturecol;
|
||||
|
||||
/*
|
||||
================
|
||||
=
|
||||
= R_RenderMaskedSegRange
|
||||
=
|
||||
================
|
||||
*/
|
||||
|
||||
void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
|
||||
{
|
||||
unsigned index;
|
||||
column_t *col;
|
||||
int lightnum;
|
||||
int texnum;
|
||||
|
||||
//
|
||||
// calculate light table
|
||||
// use different light tables for horizontal / vertical / 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;
|
||||
//if (curline->v1->y == curline->v2->y)
|
||||
// lightnum--;
|
||||
//else if (curline->v1->x == curline->v2->x)
|
||||
// lightnum++;
|
||||
//if (lightnum < 0)
|
||||
// walllights = scalelight[0];
|
||||
if (lightnum >= LIGHTLEVELS)
|
||||
walllights = scalelight[LIGHTLEVELS-1];
|
||||
else
|
||||
walllights = scalelight[lightnum];
|
||||
|
||||
maskedtexturecol = ds->maskedtexturecol;
|
||||
|
||||
rw_scalestep = ds->scalestep;
|
||||
spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
|
||||
mfloorclip = ds->sprbottomclip;
|
||||
mceilingclip = ds->sprtopclip;
|
||||
|
||||
//
|
||||
// find positioning
|
||||
//
|
||||
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
|
||||
{
|
||||
dc_texturemid = frontsector->floorheight > backsector->floorheight
|
||||
? frontsector->floorheight : backsector->floorheight;
|
||||
dc_texturemid = dc_texturemid + textureheight[texnum] - viewz;
|
||||
}
|
||||
else
|
||||
{
|
||||
dc_texturemid =frontsector->ceilingheight<backsector->ceilingheight
|
||||
? frontsector->ceilingheight : backsector->ceilingheight;
|
||||
dc_texturemid = dc_texturemid - viewz;
|
||||
}
|
||||
dc_texturemid += curline->sidedef->rowoffset;
|
||||
|
||||
if (fixedcolormap)
|
||||
dc_colormap = fixedcolormap;
|
||||
//
|
||||
// draw the columns
|
||||
//
|
||||
for (dc_x = x1 ; dc_x <= x2 ; dc_x++)
|
||||
{
|
||||
// calculate lighting
|
||||
if (maskedtexturecol[dc_x] != MAXSHORT)
|
||||
{
|
||||
if (!fixedcolormap)
|
||||
{
|
||||
index = spryscale>>LIGHTSCALESHIFT;
|
||||
if (index >= MAXLIGHTSCALE )
|
||||
index = MAXLIGHTSCALE-1;
|
||||
dc_colormap = walllights[index];
|
||||
}
|
||||
|
||||
sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
|
||||
dc_iscale = 0xffffffffu / (unsigned)spryscale;
|
||||
|
||||
//
|
||||
// draw the texture
|
||||
//
|
||||
col = (column_t *)(
|
||||
(byte *)R_GetColumn(texnum,maskedtexturecol[dc_x]) -3);
|
||||
|
||||
R_DrawMaskedColumn (col, -1);
|
||||
maskedtexturecol[dc_x] = MAXSHORT;
|
||||
}
|
||||
spryscale += rw_scalestep;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
=
|
||||
= R_RenderSegLoop
|
||||
=
|
||||
= Draws zero, one, or two textures (and possibly a masked texture) for walls
|
||||
= Can draw or mark the starting pixel of floor and ceiling textures
|
||||
=
|
||||
= CALLED: CORE LOOPING ROUTINE
|
||||
================
|
||||
*/
|
||||
|
||||
#define HEIGHTBITS 12
|
||||
#define HEIGHTUNIT (1<<HEIGHTBITS)
|
||||
|
||||
void R_RenderSegLoop (void)
|
||||
{
|
||||
angle_t angle;
|
||||
unsigned index;
|
||||
int yl, yh, mid;
|
||||
fixed_t texturecolumn;
|
||||
int top, bottom;
|
||||
|
||||
// texturecolumn = 0; // shut up compiler warning
|
||||
|
||||
for ( ; rw_x < rw_stopx ; rw_x++)
|
||||
{
|
||||
//
|
||||
// mark floor / ceiling areas
|
||||
//
|
||||
yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;
|
||||
if (yl < ceilingclip[rw_x]+1)
|
||||
yl = ceilingclip[rw_x]+1; // no space above wall
|
||||
if (markceiling)
|
||||
{
|
||||
top = ceilingclip[rw_x]+1;
|
||||
bottom = yl-1;
|
||||
if (bottom >= floorclip[rw_x])
|
||||
bottom = floorclip[rw_x]-1;
|
||||
if (top <= bottom)
|
||||
{
|
||||
ceilingplane->top[rw_x] = top;
|
||||
ceilingplane->bottom[rw_x] = bottom;
|
||||
}
|
||||
}
|
||||
|
||||
yh = bottomfrac>>HEIGHTBITS;
|
||||
if (yh >= floorclip[rw_x])
|
||||
yh = floorclip[rw_x]-1;
|
||||
if (markfloor)
|
||||
{
|
||||
top = yh+1;
|
||||
bottom = floorclip[rw_x]-1;
|
||||
if (top <= ceilingclip[rw_x])
|
||||
top = ceilingclip[rw_x]+1;
|
||||
if (top <= bottom)
|
||||
{
|
||||
floorplane->top[rw_x] = top;
|
||||
floorplane->bottom[rw_x] = bottom;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// texturecolumn and lighting are independent of wall tiers
|
||||
//
|
||||
if (segtextured)
|
||||
{
|
||||
// calculate texture offset
|
||||
angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
|
||||
texturecolumn = rw_offset-FixedMul(finetangent[angle],rw_distance);
|
||||
texturecolumn >>= FRACBITS;
|
||||
// calculate lighting
|
||||
index = rw_scale>>LIGHTSCALESHIFT;
|
||||
if (index >= MAXLIGHTSCALE )
|
||||
index = MAXLIGHTSCALE-1;
|
||||
dc_colormap = walllights[index];
|
||||
dc_x = rw_x;
|
||||
dc_iscale = 0xffffffffu / (unsigned)rw_scale;
|
||||
}
|
||||
|
||||
//
|
||||
// draw the wall tiers
|
||||
//
|
||||
if (midtexture)
|
||||
{ // single sided line
|
||||
dc_yl = yl;
|
||||
dc_yh = yh;
|
||||
dc_texturemid = rw_midtexturemid;
|
||||
dc_source = R_GetColumn(midtexture,texturecolumn);
|
||||
colfunc ();
|
||||
ceilingclip[rw_x] = viewheight;
|
||||
floorclip[rw_x] = -1;
|
||||
}
|
||||
else
|
||||
{ // two sided line
|
||||
if (toptexture)
|
||||
{ // top wall
|
||||
mid = pixhigh>>HEIGHTBITS;
|
||||
pixhigh += pixhighstep;
|
||||
if (mid >= floorclip[rw_x])
|
||||
mid = floorclip[rw_x]-1;
|
||||
if (mid >= yl)
|
||||
{
|
||||
dc_yl = yl;
|
||||
dc_yh = mid;
|
||||
dc_texturemid = rw_toptexturemid;
|
||||
dc_source = R_GetColumn(toptexture,texturecolumn);
|
||||
colfunc ();
|
||||
ceilingclip[rw_x] = mid;
|
||||
}
|
||||
else
|
||||
ceilingclip[rw_x] = yl-1;
|
||||
}
|
||||
else
|
||||
{ // no top wall
|
||||
if (markceiling)
|
||||
ceilingclip[rw_x] = yl-1;
|
||||
}
|
||||
|
||||
if (bottomtexture)
|
||||
{ // bottom wall
|
||||
mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS;
|
||||
pixlow += pixlowstep;
|
||||
if (mid <= ceilingclip[rw_x])
|
||||
mid = ceilingclip[rw_x]+1; // no space above wall
|
||||
if (mid <= yh)
|
||||
{
|
||||
dc_yl = mid;
|
||||
dc_yh = yh;
|
||||
dc_texturemid = rw_bottomtexturemid;
|
||||
dc_source = R_GetColumn(bottomtexture,
|
||||
texturecolumn);
|
||||
colfunc ();
|
||||
floorclip[rw_x] = mid;
|
||||
}
|
||||
else
|
||||
floorclip[rw_x] = yh+1;
|
||||
}
|
||||
else
|
||||
{ // no bottom wall
|
||||
if (markfloor)
|
||||
floorclip[rw_x] = yh+1;
|
||||
}
|
||||
|
||||
if (maskedtexture)
|
||||
{ // save texturecol for backdrawing of masked mid texture
|
||||
maskedtexturecol[rw_x] = texturecolumn;
|
||||
}
|
||||
}
|
||||
|
||||
rw_scale += rw_scalestep;
|
||||
topfrac += topstep;
|
||||
bottomfrac += bottomstep;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=====================
|
||||
=
|
||||
= R_StoreWallRange
|
||||
=
|
||||
= A wall segment will be drawn between start and stop pixels (inclusive)
|
||||
=
|
||||
======================
|
||||
*/
|
||||
|
||||
void R_StoreWallRange (int start, int stop)
|
||||
{
|
||||
fixed_t hyp;
|
||||
fixed_t sineval;
|
||||
angle_t distangle, offsetangle;
|
||||
fixed_t vtop;
|
||||
int lightnum;
|
||||
|
||||
if (ds_p == &drawsegs[MAXDRAWSEGS])
|
||||
return; // don't overflow and crash
|
||||
|
||||
#ifdef RANGECHECK
|
||||
if (start >=viewwidth || start > stop)
|
||||
I_Error ("Bad R_RenderWallRange: %i to %i", start , stop);
|
||||
#endif
|
||||
#ifdef __NeXT__
|
||||
RD_DrawLine (curline);
|
||||
#endif
|
||||
|
||||
sidedef = curline->sidedef;
|
||||
linedef = curline->linedef;
|
||||
|
||||
// mark the segment as visible for auto map
|
||||
linedef->flags |= ML_MAPPED;
|
||||
|
||||
//
|
||||
// calculate rw_distance for scale calculation
|
||||
//
|
||||
rw_normalangle = curline->angle + ANG90;
|
||||
offsetangle = abs(rw_normalangle-rw_angle1);
|
||||
if (offsetangle > ANG90)
|
||||
offsetangle = ANG90;
|
||||
distangle = ANG90 - offsetangle;
|
||||
hyp = R_PointToDist (curline->v1->x, curline->v1->y);
|
||||
sineval = finesine[distangle>>ANGLETOFINESHIFT];
|
||||
rw_distance = FixedMul (hyp, sineval);
|
||||
|
||||
|
||||
ds_p->x1 = rw_x = start;
|
||||
ds_p->x2 = stop;
|
||||
ds_p->curline = curline;
|
||||
rw_stopx = stop+1;
|
||||
|
||||
//
|
||||
// calculate scale at both ends and step
|
||||
//
|
||||
ds_p->scale1 = rw_scale =
|
||||
R_ScaleFromGlobalAngle (viewangle + xtoviewangle[start]);
|
||||
if (stop > start )
|
||||
{
|
||||
ds_p->scale2 = R_ScaleFromGlobalAngle (viewangle + xtoviewangle[stop]);
|
||||
ds_p->scalestep = rw_scalestep =
|
||||
(ds_p->scale2 - rw_scale) / (stop-start);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// calculate texture boundaries and decide if floor / ceiling marks
|
||||
// are needed
|
||||
//
|
||||
worldtop = frontsector->ceilingheight - viewz;
|
||||
worldbottom = frontsector->floorheight - viewz;
|
||||
|
||||
midtexture = toptexture = bottomtexture = maskedtexture = 0;
|
||||
ds_p->maskedtexturecol = NULL;
|
||||
|
||||
if (!backsector)
|
||||
{
|
||||
//
|
||||
// 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 +
|
||||
textureheight[sidedef->midtexture];
|
||||
rw_midtexturemid = vtop - viewz; // bottom of texture at bottom
|
||||
}
|
||||
else
|
||||
rw_midtexturemid = worldtop; // top of texture at top
|
||||
rw_midtexturemid += sidedef->rowoffset;
|
||||
ds_p->silhouette = SIL_BOTH;
|
||||
ds_p->sprtopclip = screenheightarray;
|
||||
ds_p->sprbottomclip = negonearray;
|
||||
ds_p->bsilheight = MAXINT;
|
||||
ds_p->tsilheight = MININT;
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// two sided line
|
||||
//
|
||||
ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
|
||||
ds_p->silhouette = 0;
|
||||
if (frontsector->floorheight > backsector->floorheight)
|
||||
{
|
||||
ds_p->silhouette = SIL_BOTTOM;
|
||||
ds_p->bsilheight = frontsector->floorheight;
|
||||
}
|
||||
else if (backsector->floorheight > viewz)
|
||||
{
|
||||
ds_p->silhouette = SIL_BOTTOM;
|
||||
ds_p->bsilheight = MAXINT;
|
||||
// ds_p->sprbottomclip = negonearray;
|
||||
}
|
||||
if (frontsector->ceilingheight < backsector->ceilingheight)
|
||||
{
|
||||
ds_p->silhouette |= SIL_TOP;
|
||||
ds_p->tsilheight = frontsector->ceilingheight;
|
||||
}
|
||||
else if (backsector->ceilingheight < viewz)
|
||||
{
|
||||
ds_p->silhouette |= SIL_TOP;
|
||||
ds_p->tsilheight = MININT;
|
||||
// ds_p->sprtopclip = screenheightarray;
|
||||
}
|
||||
|
||||
if (backsector->ceilingheight <= frontsector->floorheight)
|
||||
{
|
||||
ds_p->sprbottomclip = negonearray;
|
||||
ds_p->bsilheight = MAXINT;
|
||||
ds_p->silhouette |= SIL_BOTTOM;
|
||||
}
|
||||
if (backsector->floorheight >= frontsector->ceilingheight)
|
||||
{
|
||||
ds_p->sprtopclip = screenheightarray;
|
||||
ds_p->tsilheight = MININT;
|
||||
ds_p->silhouette |= SIL_TOP;
|
||||
}
|
||||
worldhigh = backsector->ceilingheight - viewz;
|
||||
worldlow = backsector->floorheight - viewz;
|
||||
|
||||
// hack to allow height changes in outdoor areas
|
||||
if (frontsector->ceilingpic == skyflatnum
|
||||
&& backsector->ceilingpic == skyflatnum)
|
||||
worldtop = worldhigh;
|
||||
|
||||
if (worldlow != worldbottom
|
||||
|| backsector->floorpic != frontsector->floorpic
|
||||
|| backsector->lightlevel != frontsector->lightlevel
|
||||
|| backsector->special != frontsector->special)
|
||||
markfloor = true;
|
||||
else
|
||||
markfloor = false; // same plane on both sides
|
||||
|
||||
if (worldhigh != worldtop
|
||||
|| backsector->ceilingpic != frontsector->ceilingpic
|
||||
|| backsector->lightlevel != frontsector->lightlevel)
|
||||
markceiling = true;
|
||||
else
|
||||
markceiling = false; // same plane on both sides
|
||||
|
||||
if (backsector->ceilingheight <= frontsector->floorheight
|
||||
|| backsector->floorheight >= frontsector->ceilingheight)
|
||||
markceiling = markfloor = true; // closed door
|
||||
|
||||
if (worldhigh < worldtop)
|
||||
{ // top texture
|
||||
toptexture = texturetranslation[sidedef->toptexture];
|
||||
if (linedef->flags & ML_DONTPEGTOP)
|
||||
rw_toptexturemid = worldtop; // top of texture at top
|
||||
else
|
||||
{
|
||||
vtop = backsector->ceilingheight +
|
||||
textureheight[sidedef->toptexture];
|
||||
rw_toptexturemid = vtop - viewz; // bottom of texture
|
||||
}
|
||||
}
|
||||
if (worldlow > worldbottom)
|
||||
{ // bottom texture
|
||||
bottomtexture = texturetranslation[sidedef->bottomtexture];
|
||||
if (linedef->flags & ML_DONTPEGBOTTOM )
|
||||
{ // bottom of texture at bottom
|
||||
rw_bottomtexturemid = worldtop;// top of texture at top
|
||||
}
|
||||
else // top of texture at top
|
||||
rw_bottomtexturemid = worldlow;
|
||||
}
|
||||
rw_toptexturemid += sidedef->rowoffset;
|
||||
rw_bottomtexturemid += sidedef->rowoffset;
|
||||
|
||||
//
|
||||
// allocate space for masked texture tables
|
||||
//
|
||||
if (sidedef->midtexture)
|
||||
{ // masked midtexture
|
||||
maskedtexture = true;
|
||||
ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x;
|
||||
lastopening += rw_stopx - rw_x;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// calculate rw_offset (only needed for textured lines)
|
||||
//
|
||||
segtextured = midtexture | toptexture | bottomtexture | maskedtexture;
|
||||
|
||||
if (segtextured)
|
||||
{
|
||||
offsetangle = rw_normalangle-rw_angle1;
|
||||
if (offsetangle > ANG180)
|
||||
offsetangle = -offsetangle;
|
||||
if (offsetangle > ANG90)
|
||||
offsetangle = ANG90;
|
||||
sineval = finesine[offsetangle >>ANGLETOFINESHIFT];
|
||||
rw_offset = FixedMul (hyp, sineval);
|
||||
if (rw_normalangle-rw_angle1 < ANG180)
|
||||
rw_offset = -rw_offset;
|
||||
rw_offset += sidedef->textureoffset + curline->offset;
|
||||
rw_centerangle = ANG90 + viewangle - rw_normalangle;
|
||||
|
||||
//
|
||||
// calculate light table
|
||||
// use different light tables for horizontal / vertical / diagonal
|
||||
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
|
||||
if (!fixedcolormap)
|
||||
{
|
||||
lightnum = (frontsector->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];
|
||||
if (lightnum >= LIGHTLEVELS)
|
||||
walllights = scalelight[LIGHTLEVELS-1];
|
||||
else
|
||||
walllights = scalelight[lightnum];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// if a floor / ceiling plane is on the wrong side of the view plane
|
||||
// it is definately invisible and doesn't need to be marked
|
||||
//
|
||||
if (frontsector->floorheight >= viewz)
|
||||
markfloor = false; // above view plane
|
||||
if (frontsector->ceilingheight <= viewz
|
||||
&& frontsector->ceilingpic != skyflatnum)
|
||||
markceiling = false; // below view plane
|
||||
|
||||
//
|
||||
// calculate incremental stepping values for texture edges
|
||||
//
|
||||
worldtop >>= 4;
|
||||
worldbottom >>= 4;
|
||||
|
||||
topstep = -FixedMul (rw_scalestep, worldtop);
|
||||
topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale);
|
||||
|
||||
bottomstep = -FixedMul (rw_scalestep,worldbottom);
|
||||
bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
|
||||
|
||||
if (backsector)
|
||||
{
|
||||
worldhigh >>= 4;
|
||||
worldlow >>= 4;
|
||||
|
||||
if (worldhigh < worldtop)
|
||||
{
|
||||
pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale);
|
||||
pixhighstep = -FixedMul (rw_scalestep,worldhigh);
|
||||
}
|
||||
if (worldlow > worldbottom)
|
||||
{
|
||||
pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
|
||||
pixlowstep = -FixedMul (rw_scalestep,worldlow);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// render it
|
||||
//
|
||||
if (markceiling)
|
||||
ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1);
|
||||
if (markfloor)
|
||||
floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1);
|
||||
|
||||
R_RenderSegLoop ();
|
||||
|
||||
//
|
||||
// save sprite clipping info
|
||||
//
|
||||
if ( ((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip)
|
||||
{
|
||||
memcpy (lastopening, ceilingclip+start, 2*(rw_stopx-start));
|
||||
ds_p->sprtopclip = lastopening - start;
|
||||
lastopening += rw_stopx - start;
|
||||
}
|
||||
if ( ((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip)
|
||||
{
|
||||
memcpy (lastopening, floorclip+start, 2*(rw_stopx-start));
|
||||
ds_p->sprbottomclip = lastopening - start;
|
||||
lastopening += rw_stopx - start;
|
||||
}
|
||||
if (maskedtexture && !(ds_p->silhouette&SIL_TOP))
|
||||
{
|
||||
ds_p->silhouette |= SIL_TOP;
|
||||
ds_p->tsilheight = MININT;
|
||||
}
|
||||
if (maskedtexture && !(ds_p->silhouette&SIL_BOTTOM))
|
||||
{
|
||||
ds_p->silhouette |= SIL_BOTTOM;
|
||||
ds_p->bsilheight = MAXINT;
|
||||
}
|
||||
ds_p++;
|
||||
}
|
||||
|
1033
Hexen Source/R_THINGS.C
Normal file
1033
Hexen Source/R_THINGS.C
Normal file
File diff suppressed because it is too large
Load diff
2240
Hexen Source/SB_BAR.C
Normal file
2240
Hexen Source/SB_BAR.C
Normal file
File diff suppressed because it is too large
Load diff
485
Hexen Source/SC_MAN.C
Normal file
485
Hexen Source/SC_MAN.C
Normal file
|
@ -0,0 +1,485 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** sc_man.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: sc_man.c,v $
|
||||
//** $Revision: 1.3 $
|
||||
//** $Date: 96/01/06 03:23:43 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "h2def.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
#define MAX_STRING_SIZE 64
|
||||
#define ASCII_COMMENT (';')
|
||||
#define ASCII_QUOTE (34)
|
||||
#define LUMP_SCRIPT 1
|
||||
#define FILE_ZONE_SCRIPT 2
|
||||
#define FILE_CLIB_SCRIPT 3
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static void CheckOpen(void);
|
||||
static void OpenScript(char *name, int type);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
char *sc_String;
|
||||
int sc_Number;
|
||||
int sc_Line;
|
||||
boolean sc_End;
|
||||
boolean sc_Crossed;
|
||||
boolean sc_FileScripts = false;
|
||||
char *sc_ScriptsDir = "";
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static char ScriptName[16];
|
||||
static char *ScriptBuffer;
|
||||
static char *ScriptPtr;
|
||||
static char *ScriptEndPtr;
|
||||
static char StringBuffer[MAX_STRING_SIZE];
|
||||
static boolean ScriptOpen = false;
|
||||
static boolean ScriptFreeCLib; // true = de-allocate using free()
|
||||
static int ScriptSize;
|
||||
static boolean AlreadyGot = false;
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_Open
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SC_Open(char *name)
|
||||
{
|
||||
char fileName[128];
|
||||
|
||||
if(sc_FileScripts == true)
|
||||
{
|
||||
sprintf(fileName, "%s%s.txt", sc_ScriptsDir, name);
|
||||
SC_OpenFile(fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_OpenLump(name);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_OpenLump
|
||||
//
|
||||
// Loads a script (from the WAD files) and prepares it for parsing.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SC_OpenLump(char *name)
|
||||
{
|
||||
OpenScript(name, LUMP_SCRIPT);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_OpenFile
|
||||
//
|
||||
// Loads a script (from a file) and prepares it for parsing. Uses the
|
||||
// zone memory allocator for memory allocation and de-allocation.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SC_OpenFile(char *name)
|
||||
{
|
||||
OpenScript(name, FILE_ZONE_SCRIPT);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_OpenFileCLib
|
||||
//
|
||||
// Loads a script (from a file) and prepares it for parsing. Uses C
|
||||
// library function calls for memory allocation and de-allocation.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SC_OpenFileCLib(char *name)
|
||||
{
|
||||
OpenScript(name, FILE_CLIB_SCRIPT);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenScript
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void OpenScript(char *name, int type)
|
||||
{
|
||||
SC_Close();
|
||||
if(type == LUMP_SCRIPT)
|
||||
{ // Lump script
|
||||
ScriptBuffer = (char *)W_CacheLumpName(name, PU_STATIC);
|
||||
ScriptSize = W_LumpLength(W_GetNumForName(name));
|
||||
strcpy(ScriptName, name);
|
||||
ScriptFreeCLib = false; // De-allocate using Z_Free()
|
||||
}
|
||||
else if(type == FILE_ZONE_SCRIPT)
|
||||
{ // File script - zone
|
||||
ScriptSize = M_ReadFile(name, (byte **)&ScriptBuffer);
|
||||
M_ExtractFileBase(name, ScriptName);
|
||||
ScriptFreeCLib = false; // De-allocate using Z_Free()
|
||||
}
|
||||
else
|
||||
{ // File script - clib
|
||||
ScriptSize = M_ReadFileCLib(name, (byte **)&ScriptBuffer);
|
||||
M_ExtractFileBase(name, ScriptName);
|
||||
ScriptFreeCLib = true; // De-allocate using free()
|
||||
}
|
||||
ScriptPtr = ScriptBuffer;
|
||||
ScriptEndPtr = ScriptPtr+ScriptSize;
|
||||
sc_Line = 1;
|
||||
sc_End = false;
|
||||
ScriptOpen = true;
|
||||
sc_String = StringBuffer;
|
||||
AlreadyGot = false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_Close
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SC_Close(void)
|
||||
{
|
||||
if(ScriptOpen)
|
||||
{
|
||||
if(ScriptFreeCLib == true)
|
||||
{
|
||||
free(ScriptBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
Z_Free(ScriptBuffer);
|
||||
}
|
||||
ScriptOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_GetString
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
boolean SC_GetString(void)
|
||||
{
|
||||
char *text;
|
||||
boolean foundToken;
|
||||
|
||||
CheckOpen();
|
||||
if(AlreadyGot)
|
||||
{
|
||||
AlreadyGot = false;
|
||||
return true;
|
||||
}
|
||||
foundToken = false;
|
||||
sc_Crossed = false;
|
||||
if(ScriptPtr >= ScriptEndPtr)
|
||||
{
|
||||
sc_End = true;
|
||||
return false;
|
||||
}
|
||||
while(foundToken == false)
|
||||
{
|
||||
while(*ScriptPtr <= 32)
|
||||
{
|
||||
if(ScriptPtr >= ScriptEndPtr)
|
||||
{
|
||||
sc_End = true;
|
||||
return false;
|
||||
}
|
||||
if(*ScriptPtr++ == '\n')
|
||||
{
|
||||
sc_Line++;
|
||||
sc_Crossed = true;
|
||||
}
|
||||
}
|
||||
if(ScriptPtr >= ScriptEndPtr)
|
||||
{
|
||||
sc_End = true;
|
||||
return false;
|
||||
}
|
||||
if(*ScriptPtr != ASCII_COMMENT)
|
||||
{ // Found a token
|
||||
foundToken = true;
|
||||
}
|
||||
else
|
||||
{ // Skip comment
|
||||
while(*ScriptPtr++ != '\n')
|
||||
{
|
||||
if(ScriptPtr >= ScriptEndPtr)
|
||||
{
|
||||
sc_End = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
sc_Line++;
|
||||
sc_Crossed = true;
|
||||
}
|
||||
}
|
||||
text = sc_String;
|
||||
if(*ScriptPtr == ASCII_QUOTE)
|
||||
{ // Quoted string
|
||||
ScriptPtr++;
|
||||
while(*ScriptPtr != ASCII_QUOTE)
|
||||
{
|
||||
*text++ = *ScriptPtr++;
|
||||
if(ScriptPtr == ScriptEndPtr
|
||||
|| text == &sc_String[MAX_STRING_SIZE-1])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
ScriptPtr++;
|
||||
}
|
||||
else
|
||||
{ // Normal string
|
||||
while((*ScriptPtr > 32) && (*ScriptPtr != ASCII_COMMENT))
|
||||
{
|
||||
*text++ = *ScriptPtr++;
|
||||
if(ScriptPtr == ScriptEndPtr
|
||||
|| text == &sc_String[MAX_STRING_SIZE-1])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*text = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_MustGetString
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SC_MustGetString(void)
|
||||
{
|
||||
if(SC_GetString() == false)
|
||||
{
|
||||
SC_ScriptError("Missing string.");
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_MustGetStringName
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SC_MustGetStringName(char *name)
|
||||
{
|
||||
SC_MustGetString();
|
||||
if(SC_Compare(name) == false)
|
||||
{
|
||||
SC_ScriptError(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_GetNumber
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
boolean SC_GetNumber(void)
|
||||
{
|
||||
char *stopper;
|
||||
|
||||
CheckOpen();
|
||||
if(SC_GetString())
|
||||
{
|
||||
sc_Number = strtol(sc_String, &stopper, 0);
|
||||
if(*stopper != 0)
|
||||
{
|
||||
I_Error("SC_GetNumber: Bad numeric constant \"%s\".\n"
|
||||
"Script %s, Line %d", sc_String, ScriptName, sc_Line);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_MustGetNumber
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SC_MustGetNumber(void)
|
||||
{
|
||||
if(SC_GetNumber() == false)
|
||||
{
|
||||
SC_ScriptError("Missing integer.");
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_UnGet
|
||||
//
|
||||
// Assumes there is a valid string in sc_String.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SC_UnGet(void)
|
||||
{
|
||||
AlreadyGot = true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_Check
|
||||
//
|
||||
// Returns true if another token is on the current line.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
/*
|
||||
boolean SC_Check(void)
|
||||
{
|
||||
char *text;
|
||||
|
||||
CheckOpen();
|
||||
text = ScriptPtr;
|
||||
if(text >= ScriptEndPtr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
while(*text <= 32)
|
||||
{
|
||||
if(*text == '\n')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
text++;
|
||||
if(text == ScriptEndPtr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(*text == ASCII_COMMENT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_MatchString
|
||||
//
|
||||
// Returns the index of the first match to sc_String from the passed
|
||||
// array of strings, or -1 if not found.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int SC_MatchString(char **strings)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; *strings != NULL; i++)
|
||||
{
|
||||
if(SC_Compare(*strings++))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_MustMatchString
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int SC_MustMatchString(char **strings)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = SC_MatchString(strings);
|
||||
if(i == -1)
|
||||
{
|
||||
SC_ScriptError(NULL);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_Compare
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
boolean SC_Compare(char *text)
|
||||
{
|
||||
if(strcasecmp(text, sc_String) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SC_ScriptError
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SC_ScriptError(char *message)
|
||||
{
|
||||
if(message == NULL)
|
||||
{
|
||||
message = "Bad syntax.";
|
||||
}
|
||||
I_Error("Script error, \"%s\" line %d: %s", ScriptName,
|
||||
sc_Line, message);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CheckOpen
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void CheckOpen(void)
|
||||
{
|
||||
if(ScriptOpen == false)
|
||||
{
|
||||
I_Error("SC_ call before SC_Open().");
|
||||
}
|
||||
}
|
506
Hexen Source/SN_SONIX.C
Normal file
506
Hexen Source/SN_SONIX.C
Normal file
|
@ -0,0 +1,506 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** sn_sonix.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: sn_sonix.c,v $
|
||||
//** $Revision: 1.17 $
|
||||
//** $Date: 95/10/05 18:25:44 $
|
||||
//** $Author: paul $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include <string.h>
|
||||
#include "h2def.h"
|
||||
#include "soundst.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
#define SS_MAX_SCRIPTS 64
|
||||
#define SS_TEMPBUFFER_SIZE 1024
|
||||
#define SS_SEQUENCE_NAME_LENGTH 32
|
||||
|
||||
#define SS_SCRIPT_NAME "SNDSEQ"
|
||||
#define SS_STRING_PLAY "play"
|
||||
#define SS_STRING_PLAYUNTILDONE "playuntildone"
|
||||
#define SS_STRING_PLAYTIME "playtime"
|
||||
#define SS_STRING_PLAYREPEAT "playrepeat"
|
||||
#define SS_STRING_DELAY "delay"
|
||||
#define SS_STRING_DELAYRAND "delayrand"
|
||||
#define SS_STRING_VOLUME "volume"
|
||||
#define SS_STRING_END "end"
|
||||
#define SS_STRING_STOPSOUND "stopsound"
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SS_CMD_NONE,
|
||||
SS_CMD_PLAY,
|
||||
SS_CMD_WAITUNTILDONE, // used by PLAYUNTILDONE
|
||||
SS_CMD_PLAYTIME,
|
||||
SS_CMD_PLAYREPEAT,
|
||||
SS_CMD_DELAY,
|
||||
SS_CMD_DELAYRAND,
|
||||
SS_CMD_VOLUME,
|
||||
SS_CMD_STOPSOUND,
|
||||
SS_CMD_END
|
||||
} sscmds_t;
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static void VerifySequencePtr(int *base, int *ptr);
|
||||
static int GetSoundOffset(char *name);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
extern sfxinfo_t S_sfx[];
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static struct
|
||||
{
|
||||
char name[SS_SEQUENCE_NAME_LENGTH];
|
||||
int scriptNum;
|
||||
int stopSound;
|
||||
} SequenceTranslate[SEQ_NUMSEQ] =
|
||||
{
|
||||
{ "Platform", 0, 0 },
|
||||
{ "Platform", 0, 0 }, // a 'heavy' platform is just a platform
|
||||
{ "PlatformMetal", 0, 0 },
|
||||
{ "Platform", 0, 0 }, // same with a 'creak' platform
|
||||
{ "Silence", 0, 0 },
|
||||
{ "Lava", 0, 0 },
|
||||
{ "Water", 0, 0 },
|
||||
{ "Ice", 0, 0 },
|
||||
{ "Earth", 0, 0 },
|
||||
{ "PlatformMetal2", 0, 0 },
|
||||
{ "DoorNormal", 0, 0 },
|
||||
{ "DoorHeavy", 0, 0 },
|
||||
{ "DoorMetal", 0, 0 },
|
||||
{ "DoorCreak", 0, 0 },
|
||||
{ "Silence", 0, 0 },
|
||||
{ "Lava", 0, 0 },
|
||||
{ "Water", 0, 0},
|
||||
{ "Ice", 0, 0 },
|
||||
{ "Earth", 0, 0},
|
||||
{ "DoorMetal2", 0, 0 },
|
||||
{ "Wind", 0, 0 }
|
||||
};
|
||||
|
||||
static int *SequenceData[SS_MAX_SCRIPTS];
|
||||
|
||||
int ActiveSequences;
|
||||
seqnode_t *SequenceListHead;
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// VerifySequencePtr
|
||||
//
|
||||
// Verifies the integrity of the temporary ptr, and ensures that the ptr
|
||||
// isn't exceeding the size of the temporary buffer
|
||||
//==========================================================================
|
||||
|
||||
static void VerifySequencePtr(int *base, int *ptr)
|
||||
{
|
||||
if(ptr-base > SS_TEMPBUFFER_SIZE)
|
||||
{
|
||||
I_Error("VerifySequencePtr: tempPtr >= %d\n", SS_TEMPBUFFER_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// GetSoundOffset
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static int GetSoundOffset(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < NUMSFX; i++)
|
||||
{
|
||||
if(!strcasecmp(name, S_sfx[i].tagName))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
SC_ScriptError("GetSoundOffset: Unknown sound name\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SN_InitSequenceScript
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SN_InitSequenceScript(void)
|
||||
{
|
||||
int i, j;
|
||||
int inSequence;
|
||||
int *tempDataStart;
|
||||
int *tempDataPtr;
|
||||
|
||||
inSequence = -1;
|
||||
ActiveSequences = 0;
|
||||
for(i = 0; i < SS_MAX_SCRIPTS; i++)
|
||||
{
|
||||
SequenceData[i] = NULL;
|
||||
}
|
||||
SC_Open(SS_SCRIPT_NAME);
|
||||
while(SC_GetString())
|
||||
{
|
||||
if(*sc_String == ':')
|
||||
{
|
||||
if(inSequence != -1)
|
||||
{
|
||||
SC_ScriptError("SN_InitSequenceScript: Nested Script Error");
|
||||
}
|
||||
tempDataStart = (int *)Z_Malloc(SS_TEMPBUFFER_SIZE,
|
||||
PU_STATIC, NULL);
|
||||
memset(tempDataStart, 0, SS_TEMPBUFFER_SIZE);
|
||||
tempDataPtr = tempDataStart;
|
||||
for(i = 0; i < SS_MAX_SCRIPTS; i++)
|
||||
{
|
||||
if(SequenceData[i] == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == SS_MAX_SCRIPTS)
|
||||
{
|
||||
I_Error("Number of SS Scripts >= SS_MAX_SCRIPTS");
|
||||
}
|
||||
for(j = 0; j < SEQ_NUMSEQ; j++)
|
||||
{
|
||||
if(!strcasecmp(SequenceTranslate[j].name, sc_String+1))
|
||||
{
|
||||
SequenceTranslate[j].scriptNum = i;
|
||||
inSequence = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue; // parse the next command
|
||||
}
|
||||
if(inSequence == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(SC_Compare(SS_STRING_PLAYUNTILDONE))
|
||||
{
|
||||
VerifySequencePtr(tempDataStart, tempDataPtr);
|
||||
SC_MustGetString();
|
||||
*tempDataPtr++ = SS_CMD_PLAY;
|
||||
*tempDataPtr++ = GetSoundOffset(sc_String);
|
||||
*tempDataPtr++ = SS_CMD_WAITUNTILDONE;
|
||||
}
|
||||
else if(SC_Compare(SS_STRING_PLAY))
|
||||
{
|
||||
VerifySequencePtr(tempDataStart, tempDataPtr);
|
||||
SC_MustGetString();
|
||||
*tempDataPtr++ = SS_CMD_PLAY;
|
||||
*tempDataPtr++ = GetSoundOffset(sc_String);
|
||||
}
|
||||
else if(SC_Compare(SS_STRING_PLAYTIME))
|
||||
{
|
||||
VerifySequencePtr(tempDataStart, tempDataPtr);
|
||||
SC_MustGetString();
|
||||
*tempDataPtr++ = SS_CMD_PLAY;
|
||||
*tempDataPtr++ = GetSoundOffset(sc_String);
|
||||
SC_MustGetNumber();
|
||||
*tempDataPtr++ = SS_CMD_DELAY;
|
||||
*tempDataPtr++ = sc_Number;
|
||||
}
|
||||
else if(SC_Compare(SS_STRING_PLAYREPEAT))
|
||||
{
|
||||
VerifySequencePtr(tempDataStart, tempDataPtr);
|
||||
SC_MustGetString();
|
||||
*tempDataPtr++ = SS_CMD_PLAYREPEAT;
|
||||
*tempDataPtr++ = GetSoundOffset(sc_String);
|
||||
}
|
||||
else if(SC_Compare(SS_STRING_DELAY))
|
||||
{
|
||||
VerifySequencePtr(tempDataStart, tempDataPtr);
|
||||
*tempDataPtr++ = SS_CMD_DELAY;
|
||||
SC_MustGetNumber();
|
||||
*tempDataPtr++ = sc_Number;
|
||||
}
|
||||
else if(SC_Compare(SS_STRING_DELAYRAND))
|
||||
{
|
||||
VerifySequencePtr(tempDataStart, tempDataPtr);
|
||||
*tempDataPtr++ = SS_CMD_DELAYRAND;
|
||||
SC_MustGetNumber();
|
||||
*tempDataPtr++ = sc_Number;
|
||||
SC_MustGetNumber();
|
||||
*tempDataPtr++ = sc_Number;
|
||||
}
|
||||
else if(SC_Compare(SS_STRING_VOLUME))
|
||||
{
|
||||
VerifySequencePtr(tempDataStart, tempDataPtr);
|
||||
*tempDataPtr++ = SS_CMD_VOLUME;
|
||||
SC_MustGetNumber();
|
||||
*tempDataPtr++ = sc_Number;
|
||||
}
|
||||
else if(SC_Compare(SS_STRING_END))
|
||||
{
|
||||
int dataSize;
|
||||
|
||||
*tempDataPtr++ = SS_CMD_END;
|
||||
dataSize = (tempDataPtr-tempDataStart)*sizeof(int);
|
||||
SequenceData[i] = (int *)Z_Malloc(dataSize, PU_STATIC,
|
||||
NULL);
|
||||
memcpy(SequenceData[i], tempDataStart, dataSize);
|
||||
Z_Free(tempDataStart);
|
||||
inSequence = -1;
|
||||
}
|
||||
else if(SC_Compare(SS_STRING_STOPSOUND))
|
||||
{
|
||||
SC_MustGetString();
|
||||
SequenceTranslate[inSequence].stopSound =
|
||||
GetSoundOffset(sc_String);
|
||||
*tempDataPtr++ = SS_CMD_STOPSOUND;
|
||||
}
|
||||
else
|
||||
{
|
||||
SC_ScriptError("SN_InitSequenceScript: Unknown commmand.\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SN_StartSequence
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SN_StartSequence(mobj_t *mobj, int sequence)
|
||||
{
|
||||
seqnode_t *node;
|
||||
|
||||
SN_StopSequence(mobj); // Stop any previous sequence
|
||||
node = (seqnode_t *)Z_Malloc(sizeof(seqnode_t), PU_STATIC, NULL);
|
||||
node->sequencePtr = SequenceData[SequenceTranslate[sequence].scriptNum];
|
||||
node->sequence = sequence;
|
||||
node->mobj = mobj;
|
||||
node->delayTics = 0;
|
||||
node->stopSound = SequenceTranslate[sequence].stopSound;
|
||||
node->volume = 127; // Start at max volume
|
||||
|
||||
if(!SequenceListHead)
|
||||
{
|
||||
SequenceListHead = node;
|
||||
node->next = node->prev = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
SequenceListHead->prev = node;
|
||||
node->next = SequenceListHead;
|
||||
node->prev = NULL;
|
||||
SequenceListHead = node;
|
||||
}
|
||||
ActiveSequences++;
|
||||
return;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SN_StartSequenceName
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SN_StartSequenceName(mobj_t *mobj, char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < SEQ_NUMSEQ; i++)
|
||||
{
|
||||
if(!strcmp(name, SequenceTranslate[i].name))
|
||||
{
|
||||
SN_StartSequence(mobj, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SN_StopSequence
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SN_StopSequence(mobj_t *mobj)
|
||||
{
|
||||
seqnode_t *node;
|
||||
|
||||
for(node = SequenceListHead; node; node = node->next)
|
||||
{
|
||||
if(node->mobj == mobj)
|
||||
{
|
||||
S_StopSound(mobj);
|
||||
if(node->stopSound)
|
||||
{
|
||||
S_StartSoundAtVolume(mobj, node->stopSound, node->volume);
|
||||
}
|
||||
if(SequenceListHead == node)
|
||||
{
|
||||
SequenceListHead = node->next;
|
||||
}
|
||||
if(node->prev)
|
||||
{
|
||||
node->prev->next = node->next;
|
||||
}
|
||||
if(node->next)
|
||||
{
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
Z_Free(node);
|
||||
ActiveSequences--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SN_UpdateActiveSequences
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SN_UpdateActiveSequences(void)
|
||||
{
|
||||
seqnode_t *node;
|
||||
boolean sndPlaying;
|
||||
|
||||
if(!ActiveSequences || paused)
|
||||
{ // No sequences currently playing/game is paused
|
||||
return;
|
||||
}
|
||||
for(node = SequenceListHead; node; node = node->next)
|
||||
{
|
||||
if(node->delayTics)
|
||||
{
|
||||
node->delayTics--;
|
||||
continue;
|
||||
}
|
||||
sndPlaying = S_GetSoundPlayingInfo(node->mobj, node->currentSoundID);
|
||||
switch(*node->sequencePtr)
|
||||
{
|
||||
case SS_CMD_PLAY:
|
||||
if(!sndPlaying)
|
||||
{
|
||||
node->currentSoundID = *(node->sequencePtr+1);
|
||||
S_StartSoundAtVolume(node->mobj, node->currentSoundID,
|
||||
node->volume);
|
||||
}
|
||||
node->sequencePtr += 2;
|
||||
break;
|
||||
case SS_CMD_WAITUNTILDONE:
|
||||
if(!sndPlaying)
|
||||
{
|
||||
node->sequencePtr++;
|
||||
node->currentSoundID = 0;
|
||||
}
|
||||
break;
|
||||
case SS_CMD_PLAYREPEAT:
|
||||
if(!sndPlaying)
|
||||
{
|
||||
node->currentSoundID = *(node->sequencePtr+1);
|
||||
S_StartSoundAtVolume(node->mobj, node->currentSoundID,
|
||||
node->volume);
|
||||
}
|
||||
break;
|
||||
case SS_CMD_DELAY:
|
||||
node->delayTics = *(node->sequencePtr+1);
|
||||
node->sequencePtr += 2;
|
||||
node->currentSoundID = 0;
|
||||
break;
|
||||
case SS_CMD_DELAYRAND:
|
||||
node->delayTics = *(node->sequencePtr+1)+
|
||||
M_Random()%(*(node->sequencePtr+2)-*(node->sequencePtr+1));
|
||||
node->sequencePtr += 2;
|
||||
node->currentSoundID = 0;
|
||||
break;
|
||||
case SS_CMD_VOLUME:
|
||||
node->volume = (127*(*(node->sequencePtr+1)))/100;
|
||||
node->sequencePtr += 2;
|
||||
break;
|
||||
case SS_CMD_STOPSOUND:
|
||||
// Wait until something else stops the sequence
|
||||
break;
|
||||
case SS_CMD_END:
|
||||
SN_StopSequence(node->mobj);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SN_StopAllSequences
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SN_StopAllSequences(void)
|
||||
{
|
||||
seqnode_t *node;
|
||||
|
||||
for(node = SequenceListHead; node; node = node->next)
|
||||
{
|
||||
node->stopSound = 0; // don't play any stop sounds
|
||||
SN_StopSequence(node->mobj);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SN_GetSequenceOffset
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int SN_GetSequenceOffset(int sequence, int *sequencePtr)
|
||||
{
|
||||
return (sequencePtr-SequenceData[SequenceTranslate[sequence].scriptNum]);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SN_ChangeNodeData
|
||||
//
|
||||
// nodeNum zero is the first node
|
||||
//==========================================================================
|
||||
|
||||
void SN_ChangeNodeData(int nodeNum, int seqOffset, int delayTics, int volume,
|
||||
int currentSoundID)
|
||||
{
|
||||
int i;
|
||||
seqnode_t *node;
|
||||
|
||||
i = 0;
|
||||
node = SequenceListHead;
|
||||
while(node && i < nodeNum)
|
||||
{
|
||||
node = node->next;
|
||||
i++;
|
||||
}
|
||||
if(!node)
|
||||
{ // reach the end of the list before finding the nodeNum-th node
|
||||
return;
|
||||
}
|
||||
node->delayTics = delayTics;
|
||||
node->volume = volume;
|
||||
node->sequencePtr += seqOffset;
|
||||
node->currentSoundID = currentSoundID;
|
||||
}
|
306
Hexen Source/SOUNDS.C
Normal file
306
Hexen Source/SOUNDS.C
Normal file
|
@ -0,0 +1,306 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** sounds.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: sounds.c,v $
|
||||
//** $Revision: 1.83 $
|
||||
//** $Date: 96/01/06 18:37:44 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
#include "sounds.h"
|
||||
|
||||
// Music info
|
||||
|
||||
/*
|
||||
musicinfo_t S_music[] =
|
||||
{
|
||||
{ "MUS_E1M1", 0 }, // 1-1
|
||||
{ "MUS_E1M2", 0 },
|
||||
{ "MUS_E1M3", 0 },
|
||||
{ "MUS_E1M4", 0 },
|
||||
{ "MUS_E1M5", 0 },
|
||||
{ "MUS_E1M6", 0 },
|
||||
{ "MUS_E1M7", 0 },
|
||||
{ "MUS_E1M8", 0 },
|
||||
{ "MUS_E1M9", 0 },
|
||||
{ "MUS_E2M1", 0 }, // 2-1
|
||||
{ "MUS_E2M2", 0 },
|
||||
{ "MUS_E2M3", 0 },
|
||||
{ "MUS_E2M4", 0 },
|
||||
{ "MUS_E1M4", 0 },
|
||||
{ "MUS_E2M6", 0 },
|
||||
{ "MUS_E2M7", 0 },
|
||||
{ "MUS_E2M8", 0 },
|
||||
{ "MUS_E2M9", 0 },
|
||||
{ "MUS_E1M1", 0 }, // 3-1
|
||||
{ "MUS_E3M2", 0 },
|
||||
{ "MUS_E3M3", 0 },
|
||||
{ "MUS_E1M6", 0 },
|
||||
{ "MUS_E1M3", 0 },
|
||||
{ "MUS_E1M2", 0 },
|
||||
{ "MUS_E1M5", 0 },
|
||||
{ "MUS_E1M9", 0 },
|
||||
{ "MUS_E2M6", 0 },
|
||||
{ "MUS_E1M6", 0 }, // 4-1
|
||||
{ "MUS_TITL", 0 },
|
||||
{ "MUS_INTR", 0 },
|
||||
{ "MUS_CPTD", 0 }
|
||||
};
|
||||
*/
|
||||
|
||||
// Sound info
|
||||
|
||||
sfxinfo_t S_sfx[] =
|
||||
{
|
||||
// tagname, lumpname, priority, usefulness, snd_ptr, lumpnum, numchannels,
|
||||
// pitchshift
|
||||
{ "", "", 0, -1, NULL, 0, 0, 0 },
|
||||
{ "PlayerFighterNormalDeath", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerFighterCrazyDeath", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerFighterExtreme1Death", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerFighterExtreme2Death", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerFighterExtreme3Death", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerFighterBurnDeath", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerClericNormalDeath", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerClericCrazyDeath", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerClericExtreme1Death", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerClericExtreme2Death", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerClericExtreme3Death", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerClericBurnDeath", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerMageNormalDeath", "", 256, -1, NULL, 0, 2, 0 },
|
||||
{ "PlayerMageCrazyDeath", "", 256, -1, NULL, 0, 2, 0 },
|
||||
{ "PlayerMageExtreme1Death", "", 256, -1, NULL, 0, 2, 0 },
|
||||
{ "PlayerMageExtreme2Death", "", 256, -1, NULL, 0, 2, 0 },
|
||||
{ "PlayerMageExtreme3Death", "", 256, -1, NULL, 0, 2, 0 },
|
||||
{ "PlayerMageBurnDeath", "", 256, -1, NULL, 0, 2, 0 },
|
||||
{ "PlayerFighterPain", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerClericPain", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerMagePain", "", 256, -1, NULL, 0, 2, 0 },
|
||||
{ "PlayerFighterGrunt", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerClericGrunt", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerMageGrunt", "", 256, -1, NULL, 0, 2, 0 },
|
||||
{ "PlayerLand", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerPoisonCough", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerFighterFallingScream", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerClericFallingScream", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerMageFallingScream", "", 256, -1, NULL, 0, 2, 0 },
|
||||
{ "PlayerFallingSplat", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PlayerFighterFailedUse", "", 256, -1, NULL, 0, 1, 1 },
|
||||
{ "PlayerClericFailedUse", "", 256, -1, NULL, 0, 1, 1 },
|
||||
{ "PlayerMageFailedUse", "", 256, -1, NULL, 0, 1, 0 },
|
||||
{ "PlatformStart", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "PlatformStartMetal", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "PlatformStop", "", 40, -1, NULL, 0, 2, 1 },
|
||||
{ "StoneMove", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "MetalMove", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "DoorOpen", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "DoorLocked", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "DoorOpenMetal", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "DoorCloseMetal", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "DoorCloseLight", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "DoorCloseHeavy", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "DoorCreak", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "PickupWeapon", "", 36, -1, NULL, 0, 2, 0 },
|
||||
{ "PickupArtifact", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "PickupKey", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "PickupItem", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "PickupPiece", "", 36, -1, NULL, 0, 2, 0 },
|
||||
{ "WeaponBuild", "", 36, -1, NULL, 0, 2, 0 },
|
||||
{ "UseArtifact", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "BlastRadius", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "Teleport", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "ThunderCrash", "", 30, -1, NULL, 0, 2, 1 },
|
||||
{ "FighterPunchMiss", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "FighterPunchHitThing", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "FighterPunchHitWall", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "FighterGrunt", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "FighterAxeHitThing", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "FighterHammerMiss", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "FighterHammerHitThing", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "FighterHammerHitWall", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "FighterHammerContinuous", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "FighterHammerExplode", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "FighterSwordFire", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "FighterSwordExplode", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "ClericCStaffFire", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "ClericCStaffExplode", "", 40, -1, NULL, 0, 2, 1 },
|
||||
{ "ClericCStaffHitThing", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "ClericFlameFire", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "ClericFlameExplode", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "ClericFlameCircle", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "MageWandFire", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "MageLightningFire", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "MageLightningZap", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "MageLightningContinuous", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "MageLightningReady", "", 30, -1, NULL, 0, 2, 1 },
|
||||
{ "MageShardsFire","", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "MageShardsExplode","", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "MageStaffFire","", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "MageStaffExplode","", 40, -1, NULL, 0, 2, 1 },
|
||||
{ "Switch1", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "Switch2", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "SerpentSight", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "SerpentActive", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "SerpentPain", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "SerpentAttack", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "SerpentMeleeHit", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "SerpentDeath", "", 40, -1, NULL, 0, 2, 1 },
|
||||
{ "SerpentBirth", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "SerpentFXContinuous", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "SerpentFXHit", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "PotteryExplode", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "Drip", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "CentaurSight", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "CentaurActive", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "CentaurPain", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "CentaurAttack", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "CentaurDeath", "", 40, -1, NULL, 0, 2, 1 },
|
||||
{ "CentaurLeaderAttack", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "CentaurMissileExplode", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "Wind", "", 1, -1, NULL, 0, 2, 1 },
|
||||
{ "BishopSight", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "BishopActive", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "BishopPain", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "BishopAttack", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "BishopDeath", "", 40, -1, NULL, 0, 2, 1 },
|
||||
{ "BishopMissileExplode", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "BishopBlur", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "DemonSight", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "DemonActive", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "DemonPain", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "DemonAttack", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "DemonMissileFire", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "DemonMissileExplode", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "DemonDeath", "", 40, -1, NULL, 0, 2, 1 },
|
||||
{ "WraithSight", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "WraithActive", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "WraithPain", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "WraithAttack", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "WraithMissileFire", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "WraithMissileExplode", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "WraithDeath", "", 40, -1, NULL, 0, 2, 1 },
|
||||
{ "PigActive1", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "PigActive2", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "PigPain", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "PigAttack", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "PigDeath", "", 40, -1, NULL, 0, 2, 1 },
|
||||
{ "MaulatorSight", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "MaulatorActive", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "MaulatorPain", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "MaulatorHamSwing", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "MaulatorHamHit", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "MaulatorMissileHit", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "MaulatorDeath", "", 40, -1, NULL, 0, 2, 1 },
|
||||
{ "FreezeDeath", "", 40, -1, NULL, 0, 2, 1 },
|
||||
{ "FreezeShatter", "", 40, -1, NULL, 0, 2, 1 },
|
||||
{ "EttinSight", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "EttinActive", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "EttinPain", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "EttinAttack", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "EttinDeath", "", 40, -1, NULL, 0, 2, 1 },
|
||||
{ "FireDemonSpawn", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "FireDemonActive", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "FireDemonPain", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "FireDemonAttack", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "FireDemonMissileHit", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "FireDemonDeath", "", 40, -1, NULL, 0, 2, 1 },
|
||||
{ "IceGuySight", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "IceGuyActive", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "IceGuyAttack", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "IceGuyMissileExplode", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "SorcererSight", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "SorcererActive", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "SorcererPain", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "SorcererSpellCast", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "SorcererBallWoosh", "", 256, -1, NULL, 0, 4, 1 },
|
||||
{ "SorcererDeathScream", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "SorcererBishopSpawn", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "SorcererBallPop", "", 80, -1, NULL, 0, 2, 1 },
|
||||
{ "SorcererBallBounce", "", 80, -1, NULL, 0, 3, 1 },
|
||||
{ "SorcererBallExplode", "", 80, -1, NULL, 0, 3, 1 },
|
||||
{ "SorcererBigBallExplode", "", 80, -1, NULL, 0, 3, 1 },
|
||||
{ "SorcererHeadScream", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "DragonSight", "", 64, -1, NULL, 0, 2, 1 },
|
||||
{ "DragonActive", "", 64, -1, NULL, 0, 2, 1 },
|
||||
{ "DragonWingflap", "", 64, -1, NULL, 0, 2, 1 },
|
||||
{ "DragonAttack", "", 64, -1, NULL, 0, 2, 1 },
|
||||
{ "DragonPain", "", 64, -1, NULL, 0, 2, 1 },
|
||||
{ "DragonDeath", "", 64, -1, NULL, 0, 2, 1 },
|
||||
{ "DragonFireballExplode", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxSight", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxActive", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxPain", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxAttack", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxCommand", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxDeath", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxStep", "", 128, -1, NULL, 0, 2, 1 },
|
||||
{ "ThrustSpikeRaise", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "ThrustSpikeLower", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "GlassShatter", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "FlechetteBounce", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "FlechetteExplode", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "LavaMove", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "WaterMove", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "IceStartMove", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "EarthStartMove", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "WaterSplash", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "LavaSizzle", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "SludgeGloop", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "HolySymbolFire", "", 64, -1, NULL, 0, 2, 1 },
|
||||
{ "SpiritActive", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "SpiritAttack", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "SpiritDie", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "ValveTurn", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "RopePull", "", 36, -1, NULL, 0, 2, 1 },
|
||||
{ "FlyBuzz", "", 20, -1, NULL, 0, 2, 1 },
|
||||
{ "Ignite", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "PuzzleSuccess", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PuzzleFailFighter", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PuzzleFailCleric", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "PuzzleFailMage", "", 256, -1, NULL, 0, 2, 1 },
|
||||
{ "Earthquake", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "BellRing", "", 32, -1, NULL, 0, 2, 0 },
|
||||
{ "TreeBreak", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "TreeExplode", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "SuitofArmorBreak", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "PoisonShroomPain", "", 20, -1, NULL, 0, 2, 1 },
|
||||
{ "PoisonShroomDeath", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "Ambient1", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "Ambient2", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "Ambient3", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "Ambient4", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "Ambient5", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "Ambient6", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "Ambient7", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "Ambient8", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "Ambient9", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "Ambient10", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "Ambient11", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "Ambient12", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "Ambient13", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "Ambient14", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "Ambient15", "", 1, -1, NULL, 0, 1, 1 },
|
||||
{ "StartupTick", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "SwitchOtherLevel", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "Respawn", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxVoiceGreetings", "", 512, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxVoiceReady", "", 512, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxVoiceBlood", "", 512, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxVoiceGame", "", 512, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxVoiceBoard", "", 512, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxVoiceWorship", "", 512, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxVoiceMaybe", "", 512, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxVoiceStrong", "", 512, -1, NULL, 0, 2, 1 },
|
||||
{ "KoraxVoiceFace", "", 512, -1, NULL, 0, 2, 1 },
|
||||
{ "BatScream", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "Chat", "", 512, -1, NULL, 0, 2, 1 },
|
||||
{ "MenuMove", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "ClockTick", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "Fireball", "", 32, -1, NULL, 0, 2, 1 },
|
||||
{ "PuppyBeat", "", 30, -1, NULL, 0, 2, 1 },
|
||||
{ "MysticIncant", "", 32, -1, NULL, 0, 4, 1 }
|
||||
};
|
311
Hexen Source/SOUNDS.H
Normal file
311
Hexen Source/SOUNDS.H
Normal file
|
@ -0,0 +1,311 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** sounds.h : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: sounds.h,v $
|
||||
//** $Revision: 1.74 $
|
||||
//** $Date: 95/10/10 21:51:20 $
|
||||
//** $Author: paul $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#ifndef __SOUNDSH__
|
||||
#define __SOUNDSH__
|
||||
|
||||
#include "soundst.h"
|
||||
|
||||
#define MAX_SND_DIST 2025
|
||||
#define MAX_CHANNELS 16
|
||||
|
||||
// Music identifiers
|
||||
|
||||
typedef enum
|
||||
{
|
||||
mus_e1m1,
|
||||
mus_e1m2,
|
||||
mus_e1m3,
|
||||
mus_e1m4,
|
||||
mus_e1m5,
|
||||
mus_e1m6,
|
||||
mus_e1m7,
|
||||
mus_e1m8,
|
||||
mus_e1m9,
|
||||
mus_e2m1,
|
||||
mus_e2m2,
|
||||
mus_e2m3,
|
||||
mus_e2m4,
|
||||
mus_e2m5,
|
||||
mus_e2m6,
|
||||
mus_e2m7,
|
||||
mus_e2m8,
|
||||
mus_e2m9,
|
||||
mus_e3m1,
|
||||
mus_e3m2,
|
||||
mus_e3m3,
|
||||
mus_e3m4,
|
||||
mus_e3m5,
|
||||
mus_e3m6,
|
||||
mus_e3m7,
|
||||
mus_e3m8,
|
||||
mus_e3m9,
|
||||
mus_e4m1,
|
||||
mus_titl,
|
||||
mus_intr,
|
||||
mus_cptd,
|
||||
NUMMUSIC
|
||||
} musicenum_t;
|
||||
|
||||
// Sound identifiers
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SFX_NONE,
|
||||
SFX_PLAYER_FIGHTER_NORMAL_DEATH, // class specific death screams
|
||||
SFX_PLAYER_FIGHTER_CRAZY_DEATH,
|
||||
SFX_PLAYER_FIGHTER_EXTREME1_DEATH,
|
||||
SFX_PLAYER_FIGHTER_EXTREME2_DEATH,
|
||||
SFX_PLAYER_FIGHTER_EXTREME3_DEATH,
|
||||
SFX_PLAYER_FIGHTER_BURN_DEATH,
|
||||
SFX_PLAYER_CLERIC_NORMAL_DEATH,
|
||||
SFX_PLAYER_CLERIC_CRAZY_DEATH,
|
||||
SFX_PLAYER_CLERIC_EXTREME1_DEATH,
|
||||
SFX_PLAYER_CLERIC_EXTREME2_DEATH,
|
||||
SFX_PLAYER_CLERIC_EXTREME3_DEATH,
|
||||
SFX_PLAYER_CLERIC_BURN_DEATH,
|
||||
SFX_PLAYER_MAGE_NORMAL_DEATH,
|
||||
SFX_PLAYER_MAGE_CRAZY_DEATH,
|
||||
SFX_PLAYER_MAGE_EXTREME1_DEATH,
|
||||
SFX_PLAYER_MAGE_EXTREME2_DEATH,
|
||||
SFX_PLAYER_MAGE_EXTREME3_DEATH,
|
||||
SFX_PLAYER_MAGE_BURN_DEATH,
|
||||
SFX_PLAYER_FIGHTER_PAIN,
|
||||
SFX_PLAYER_CLERIC_PAIN,
|
||||
SFX_PLAYER_MAGE_PAIN,
|
||||
SFX_PLAYER_FIGHTER_GRUNT,
|
||||
SFX_PLAYER_CLERIC_GRUNT,
|
||||
SFX_PLAYER_MAGE_GRUNT,
|
||||
SFX_PLAYER_LAND,
|
||||
SFX_PLAYER_POISONCOUGH,
|
||||
SFX_PLAYER_FIGHTER_FALLING_SCREAM, // class specific falling screams
|
||||
SFX_PLAYER_CLERIC_FALLING_SCREAM,
|
||||
SFX_PLAYER_MAGE_FALLING_SCREAM,
|
||||
SFX_PLAYER_FALLING_SPLAT,
|
||||
SFX_PLAYER_FIGHTER_FAILED_USE,
|
||||
SFX_PLAYER_CLERIC_FAILED_USE,
|
||||
SFX_PLAYER_MAGE_FAILED_USE,
|
||||
SFX_PLATFORM_START,
|
||||
SFX_PLATFORM_STARTMETAL,
|
||||
SFX_PLATFORM_STOP,
|
||||
SFX_STONE_MOVE,
|
||||
SFX_METAL_MOVE,
|
||||
SFX_DOOR_OPEN,
|
||||
SFX_DOOR_LOCKED,
|
||||
SFX_DOOR_METAL_OPEN,
|
||||
SFX_DOOR_METAL_CLOSE,
|
||||
SFX_DOOR_LIGHT_CLOSE,
|
||||
SFX_DOOR_HEAVY_CLOSE,
|
||||
SFX_DOOR_CREAK,
|
||||
SFX_PICKUP_WEAPON,
|
||||
SFX_PICKUP_ARTIFACT,
|
||||
SFX_PICKUP_KEY,
|
||||
SFX_PICKUP_ITEM,
|
||||
SFX_PICKUP_PIECE,
|
||||
SFX_WEAPON_BUILD,
|
||||
SFX_ARTIFACT_USE,
|
||||
SFX_ARTIFACT_BLAST,
|
||||
SFX_TELEPORT,
|
||||
SFX_THUNDER_CRASH,
|
||||
SFX_FIGHTER_PUNCH_MISS,
|
||||
SFX_FIGHTER_PUNCH_HITTHING,
|
||||
SFX_FIGHTER_PUNCH_HITWALL,
|
||||
SFX_FIGHTER_GRUNT,
|
||||
SFX_FIGHTER_AXE_HITTHING,
|
||||
SFX_FIGHTER_HAMMER_MISS,
|
||||
SFX_FIGHTER_HAMMER_HITTHING,
|
||||
SFX_FIGHTER_HAMMER_HITWALL,
|
||||
SFX_FIGHTER_HAMMER_CONTINUOUS,
|
||||
SFX_FIGHTER_HAMMER_EXPLODE,
|
||||
SFX_FIGHTER_SWORD_FIRE,
|
||||
SFX_FIGHTER_SWORD_EXPLODE,
|
||||
SFX_CLERIC_CSTAFF_FIRE,
|
||||
SFX_CLERIC_CSTAFF_EXPLODE,
|
||||
SFX_CLERIC_CSTAFF_HITTHING,
|
||||
SFX_CLERIC_FLAME_FIRE,
|
||||
SFX_CLERIC_FLAME_EXPLODE,
|
||||
SFX_CLERIC_FLAME_CIRCLE,
|
||||
SFX_MAGE_WAND_FIRE,
|
||||
SFX_MAGE_LIGHTNING_FIRE,
|
||||
SFX_MAGE_LIGHTNING_ZAP,
|
||||
SFX_MAGE_LIGHTNING_CONTINUOUS,
|
||||
SFX_MAGE_LIGHTNING_READY,
|
||||
SFX_MAGE_SHARDS_FIRE,
|
||||
SFX_MAGE_SHARDS_EXPLODE,
|
||||
SFX_MAGE_STAFF_FIRE,
|
||||
SFX_MAGE_STAFF_EXPLODE,
|
||||
SFX_SWITCH1,
|
||||
SFX_SWITCH2,
|
||||
SFX_SERPENT_SIGHT,
|
||||
SFX_SERPENT_ACTIVE,
|
||||
SFX_SERPENT_PAIN,
|
||||
SFX_SERPENT_ATTACK,
|
||||
SFX_SERPENT_MELEEHIT,
|
||||
SFX_SERPENT_DEATH,
|
||||
SFX_SERPENT_BIRTH,
|
||||
SFX_SERPENTFX_CONTINUOUS,
|
||||
SFX_SERPENTFX_HIT,
|
||||
SFX_POTTERY_EXPLODE,
|
||||
SFX_DRIP,
|
||||
SFX_CENTAUR_SIGHT,
|
||||
SFX_CENTAUR_ACTIVE,
|
||||
SFX_CENTAUR_PAIN,
|
||||
SFX_CENTAUR_ATTACK,
|
||||
SFX_CENTAUR_DEATH,
|
||||
SFX_CENTAURLEADER_ATTACK,
|
||||
SFX_CENTAUR_MISSILE_EXPLODE,
|
||||
SFX_WIND,
|
||||
SFX_BISHOP_SIGHT,
|
||||
SFX_BISHOP_ACTIVE,
|
||||
SFX_BISHOP_PAIN,
|
||||
SFX_BISHOP_ATTACK,
|
||||
SFX_BISHOP_DEATH,
|
||||
SFX_BISHOP_MISSILE_EXPLODE,
|
||||
SFX_BISHOP_BLUR,
|
||||
SFX_DEMON_SIGHT,
|
||||
SFX_DEMON_ACTIVE,
|
||||
SFX_DEMON_PAIN,
|
||||
SFX_DEMON_ATTACK,
|
||||
SFX_DEMON_MISSILE_FIRE,
|
||||
SFX_DEMON_MISSILE_EXPLODE,
|
||||
SFX_DEMON_DEATH,
|
||||
SFX_WRAITH_SIGHT,
|
||||
SFX_WRAITH_ACTIVE,
|
||||
SFX_WRAITH_PAIN,
|
||||
SFX_WRAITH_ATTACK,
|
||||
SFX_WRAITH_MISSILE_FIRE,
|
||||
SFX_WRAITH_MISSILE_EXPLODE,
|
||||
SFX_WRAITH_DEATH,
|
||||
SFX_PIG_ACTIVE1,
|
||||
SFX_PIG_ACTIVE2,
|
||||
SFX_PIG_PAIN,
|
||||
SFX_PIG_ATTACK,
|
||||
SFX_PIG_DEATH,
|
||||
SFX_MAULATOR_SIGHT,
|
||||
SFX_MAULATOR_ACTIVE,
|
||||
SFX_MAULATOR_PAIN,
|
||||
SFX_MAULATOR_HAMMER_SWING,
|
||||
SFX_MAULATOR_HAMMER_HIT,
|
||||
SFX_MAULATOR_MISSILE_HIT,
|
||||
SFX_MAULATOR_DEATH,
|
||||
SFX_FREEZE_DEATH,
|
||||
SFX_FREEZE_SHATTER,
|
||||
SFX_ETTIN_SIGHT,
|
||||
SFX_ETTIN_ACTIVE,
|
||||
SFX_ETTIN_PAIN,
|
||||
SFX_ETTIN_ATTACK,
|
||||
SFX_ETTIN_DEATH,
|
||||
SFX_FIRED_SPAWN,
|
||||
SFX_FIRED_ACTIVE,
|
||||
SFX_FIRED_PAIN,
|
||||
SFX_FIRED_ATTACK,
|
||||
SFX_FIRED_MISSILE_HIT,
|
||||
SFX_FIRED_DEATH,
|
||||
SFX_ICEGUY_SIGHT,
|
||||
SFX_ICEGUY_ACTIVE,
|
||||
SFX_ICEGUY_ATTACK,
|
||||
SFX_ICEGUY_FX_EXPLODE,
|
||||
SFX_SORCERER_SIGHT,
|
||||
SFX_SORCERER_ACTIVE,
|
||||
SFX_SORCERER_PAIN,
|
||||
SFX_SORCERER_SPELLCAST,
|
||||
SFX_SORCERER_BALLWOOSH,
|
||||
SFX_SORCERER_DEATHSCREAM,
|
||||
SFX_SORCERER_BISHOPSPAWN,
|
||||
SFX_SORCERER_BALLPOP,
|
||||
SFX_SORCERER_BALLBOUNCE,
|
||||
SFX_SORCERER_BALLEXPLODE,
|
||||
SFX_SORCERER_BIGBALLEXPLODE,
|
||||
SFX_SORCERER_HEADSCREAM,
|
||||
SFX_DRAGON_SIGHT,
|
||||
SFX_DRAGON_ACTIVE,
|
||||
SFX_DRAGON_WINGFLAP,
|
||||
SFX_DRAGON_ATTACK,
|
||||
SFX_DRAGON_PAIN,
|
||||
SFX_DRAGON_DEATH,
|
||||
SFX_DRAGON_FIREBALL_EXPLODE,
|
||||
SFX_KORAX_SIGHT,
|
||||
SFX_KORAX_ACTIVE,
|
||||
SFX_KORAX_PAIN,
|
||||
SFX_KORAX_ATTACK,
|
||||
SFX_KORAX_COMMAND,
|
||||
SFX_KORAX_DEATH,
|
||||
SFX_KORAX_STEP,
|
||||
SFX_THRUSTSPIKE_RAISE,
|
||||
SFX_THRUSTSPIKE_LOWER,
|
||||
SFX_STAINEDGLASS_SHATTER,
|
||||
SFX_FLECHETTE_BOUNCE,
|
||||
SFX_FLECHETTE_EXPLODE,
|
||||
SFX_LAVA_MOVE,
|
||||
SFX_WATER_MOVE,
|
||||
SFX_ICE_STARTMOVE,
|
||||
SFX_EARTH_STARTMOVE,
|
||||
SFX_WATER_SPLASH,
|
||||
SFX_LAVA_SIZZLE,
|
||||
SFX_SLUDGE_GLOOP,
|
||||
SFX_CHOLY_FIRE,
|
||||
SFX_SPIRIT_ACTIVE,
|
||||
SFX_SPIRIT_ATTACK,
|
||||
SFX_SPIRIT_DIE,
|
||||
SFX_VALVE_TURN,
|
||||
SFX_ROPE_PULL,
|
||||
SFX_FLY_BUZZ,
|
||||
SFX_IGNITE,
|
||||
SFX_PUZZLE_SUCCESS,
|
||||
SFX_PUZZLE_FAIL_FIGHTER,
|
||||
SFX_PUZZLE_FAIL_CLERIC,
|
||||
SFX_PUZZLE_FAIL_MAGE,
|
||||
SFX_EARTHQUAKE,
|
||||
SFX_BELLRING,
|
||||
SFX_TREE_BREAK,
|
||||
SFX_TREE_EXPLODE,
|
||||
SFX_SUITOFARMOR_BREAK,
|
||||
SFX_POISONSHROOM_PAIN,
|
||||
SFX_POISONSHROOM_DEATH,
|
||||
SFX_AMBIENT1,
|
||||
SFX_AMBIENT2,
|
||||
SFX_AMBIENT3,
|
||||
SFX_AMBIENT4,
|
||||
SFX_AMBIENT5,
|
||||
SFX_AMBIENT6,
|
||||
SFX_AMBIENT7,
|
||||
SFX_AMBIENT8,
|
||||
SFX_AMBIENT9,
|
||||
SFX_AMBIENT10,
|
||||
SFX_AMBIENT11,
|
||||
SFX_AMBIENT12,
|
||||
SFX_AMBIENT13,
|
||||
SFX_AMBIENT14,
|
||||
SFX_AMBIENT15,
|
||||
SFX_STARTUP_TICK,
|
||||
SFX_SWITCH_OTHERLEVEL,
|
||||
SFX_RESPAWN,
|
||||
SFX_KORAX_VOICE_1,
|
||||
SFX_KORAX_VOICE_2,
|
||||
SFX_KORAX_VOICE_3,
|
||||
SFX_KORAX_VOICE_4,
|
||||
SFX_KORAX_VOICE_5,
|
||||
SFX_KORAX_VOICE_6,
|
||||
SFX_KORAX_VOICE_7,
|
||||
SFX_KORAX_VOICE_8,
|
||||
SFX_KORAX_VOICE_9,
|
||||
SFX_BAT_SCREAM,
|
||||
SFX_CHAT,
|
||||
SFX_MENU_MOVE,
|
||||
SFX_CLOCK_TICK,
|
||||
SFX_FIREBALL,
|
||||
SFX_PUPPYBEAT,
|
||||
SFX_MYSTICINCANT,
|
||||
NUMSFX
|
||||
} sfxenum_t;
|
||||
|
||||
#endif
|
81
Hexen Source/SOUNDST.H
Normal file
81
Hexen Source/SOUNDST.H
Normal file
|
@ -0,0 +1,81 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** soundst.h : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: soundst.h,v $
|
||||
//** $Revision: 1.13 $
|
||||
//** $Date: 95/10/12 18:01:27 $
|
||||
//** $Author: cjr $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#ifndef __SOUNDSTH__
|
||||
#define __SOUNDSTH__
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[8];
|
||||
int p1;
|
||||
} musicinfo_t;
|
||||
|
||||
typedef struct sfxinfo_s
|
||||
{
|
||||
char tagName[32];
|
||||
char lumpname[12]; // Only need 9 bytes, but padded out to be dword aligned
|
||||
//struct sfxinfo_s *link; // Make alias for another sound
|
||||
int priority; // Higher priority takes precendence
|
||||
int usefulness; // Determines when a sound should be cached out
|
||||
void *snd_ptr;
|
||||
int lumpnum;
|
||||
int numchannels; // total number of channels a sound type may occupy
|
||||
boolean changePitch;
|
||||
} sfxinfo_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
mobj_t *mo;
|
||||
int sound_id;
|
||||
int handle;
|
||||
int volume;
|
||||
int pitch;
|
||||
int priority;
|
||||
} channel_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
long id;
|
||||
unsigned short priority;
|
||||
char *name;
|
||||
mobj_t *mo;
|
||||
int distance;
|
||||
} ChanInfo_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int channelCount;
|
||||
int musicVolume;
|
||||
int soundVolume;
|
||||
ChanInfo_t chan[8];
|
||||
} SoundInfo_t;
|
||||
|
||||
extern int snd_MaxVolume;
|
||||
extern int snd_MusicVolume;
|
||||
|
||||
void S_Start(void);
|
||||
void S_StartSound(mobj_t *origin, int sound_id);
|
||||
int S_GetSoundID(char *name);
|
||||
void S_StartSoundAtVolume(mobj_t *origin, int sound_id, int volume);
|
||||
void S_StopSound(mobj_t *origin);
|
||||
void S_StopAllSound(void);
|
||||
void S_PauseSound(void);
|
||||
void S_ResumeSound(void);
|
||||
void S_UpdateSounds(mobj_t *listener);
|
||||
void S_StartSong(int song, boolean loop);
|
||||
void S_StartSongName(char *songLump, boolean loop);
|
||||
void S_Init(void);
|
||||
void S_GetChannelInfo(SoundInfo_t *s);
|
||||
void S_SetMusicVolume(void);
|
||||
boolean S_GetSoundPlayingInfo(mobj_t *mobj, int sound_id);
|
||||
|
||||
#endif
|
347
Hexen Source/ST_START.C
Normal file
347
Hexen Source/ST_START.C
Normal file
|
@ -0,0 +1,347 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** st_start.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: st_start.c,v $
|
||||
//** $Revision: 1.21 $
|
||||
//** $Date: 95/12/21 15:03:51 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
#ifdef __WATCOMC__
|
||||
#include <sys\stat.h>
|
||||
#include <sys\types.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <libc.h>
|
||||
#include <ctype.h>
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
#include "h2def.h"
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h> // Needed for next as well as dos
|
||||
#include "st_start.h"
|
||||
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
#define ST_MAX_NOTCHES 32
|
||||
#define ST_NOTCH_WIDTH 16
|
||||
#define ST_NOTCH_HEIGHT 23
|
||||
#define ST_PROGRESS_X 64 // Start of notches x screen pos.
|
||||
#define ST_PROGRESS_Y 441 // Start of notches y screen pos.
|
||||
|
||||
#define ST_NETPROGRESS_X 288
|
||||
#define ST_NETPROGRESS_Y 32
|
||||
#define ST_NETNOTCH_WIDTH 8
|
||||
#define ST_NETNOTCH_HEIGHT 16
|
||||
#define ST_MAX_NETNOTCHES 8
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
extern void SetVideoModeHR(void);
|
||||
extern void ClearScreenHR(void);
|
||||
extern void SlamHR(char *buffer);
|
||||
extern void SlamBlockHR(int x, int y, int w, int h, char *src);
|
||||
extern void InitPaletteHR(void);
|
||||
extern void SetPaletteHR(byte *palette);
|
||||
extern void GetPaletteHR(byte *palette);
|
||||
extern void FadeToPaletteHR(byte *palette);
|
||||
extern void FadeToBlackHR(void);
|
||||
extern void BlackPaletteHR(void);
|
||||
extern void I_StartupReadKeys(void);
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
char *ST_LoadScreen(void);
|
||||
void ST_UpdateNotches(int notchPosition);
|
||||
void ST_UpdateNetNotches(int notchPosition);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
char *bitmap = NULL;
|
||||
|
||||
char notchTable[]=
|
||||
{
|
||||
// plane 0
|
||||
0x00, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40,
|
||||
0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x03, 0xC0,
|
||||
0x0F, 0x90, 0x1B, 0x68, 0x3D, 0xBC, 0x3F, 0xFC, 0x20, 0x08, 0x20, 0x08,
|
||||
0x2F, 0xD8, 0x37, 0xD8, 0x37, 0xF8, 0x1F, 0xF8, 0x1C, 0x50,
|
||||
|
||||
// plane 1
|
||||
0x00, 0x80, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x02, 0x40,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xA0,
|
||||
0x30, 0x6C, 0x24, 0x94, 0x42, 0x4A, 0x60, 0x0E, 0x60, 0x06, 0x7F, 0xF6,
|
||||
0x7F, 0xF6, 0x7F, 0xF6, 0x5E, 0xF6, 0x38, 0x16, 0x23, 0xAC,
|
||||
|
||||
// plane 2
|
||||
0x00, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00, 0x02, 0x40, 0x02, 0x40,
|
||||
0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0x40, 0x03, 0xE0,
|
||||
0x30, 0x6C, 0x24, 0x94, 0x52, 0x6A, 0x7F, 0xFE, 0x60, 0x0E, 0x60, 0x0E,
|
||||
0x6F, 0xD6, 0x77, 0xD6, 0x56, 0xF6, 0x38, 0x36, 0x23, 0xAC,
|
||||
|
||||
// plane 3
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80,
|
||||
0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0xC0, 0x03, 0x80, 0x02, 0x40,
|
||||
0x0F, 0x90, 0x1B, 0x68, 0x3D, 0xB4, 0x1F, 0xF0, 0x1F, 0xF8, 0x1F, 0xF8,
|
||||
0x10, 0x28, 0x08, 0x28, 0x29, 0x08, 0x07, 0xE8, 0x1C, 0x50
|
||||
};
|
||||
|
||||
|
||||
// Red Network Progress notches
|
||||
char netnotchTable[]=
|
||||
{
|
||||
// plane 0
|
||||
0x80, 0x50, 0xD0, 0xf0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xD0, 0xF0, 0xC0,
|
||||
0x70, 0x50, 0x80, 0x60,
|
||||
|
||||
// plane 1
|
||||
0x60, 0xE0, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, 0xA0,
|
||||
0xA0, 0xE0, 0x60, 0x00,
|
||||
|
||||
// plane 2
|
||||
0x80, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00,
|
||||
0x10, 0x10, 0x80, 0x60,
|
||||
|
||||
// plane 3
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Startup Screen Functions
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ST_Init - Do the startup screen
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ST_Init(void)
|
||||
{
|
||||
#ifdef __WATCOMC__
|
||||
char *pal;
|
||||
char *buffer;
|
||||
|
||||
if (!debugmode)
|
||||
{
|
||||
// Set 640x480x16 mode
|
||||
SetVideoModeHR();
|
||||
ClearScreenHR();
|
||||
InitPaletteHR();
|
||||
BlackPaletteHR();
|
||||
|
||||
// Load graphic
|
||||
buffer = ST_LoadScreen();
|
||||
pal = buffer;
|
||||
bitmap = buffer + 16*3;
|
||||
|
||||
SlamHR(bitmap);
|
||||
FadeToPaletteHR(pal);
|
||||
Z_Free(buffer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ST_Done(void)
|
||||
{
|
||||
#ifdef __WATCOMC__
|
||||
ClearScreenHR();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ST_UpdateNotches
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ST_UpdateNotches(int notchPosition)
|
||||
{
|
||||
#ifdef __WATCOMC__
|
||||
int x = ST_PROGRESS_X + notchPosition*ST_NOTCH_WIDTH;
|
||||
int y = ST_PROGRESS_Y;
|
||||
SlamBlockHR(x,y, ST_NOTCH_WIDTH,ST_NOTCH_HEIGHT, notchTable);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ST_UpdateNetNotches - indicates network progress
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ST_UpdateNetNotches(int notchPosition)
|
||||
{
|
||||
#ifdef __WATCOMC__
|
||||
int x = ST_NETPROGRESS_X + notchPosition*ST_NETNOTCH_WIDTH;
|
||||
int y = ST_NETPROGRESS_Y;
|
||||
SlamBlockHR(x,y, ST_NETNOTCH_WIDTH, ST_NETNOTCH_HEIGHT, netnotchTable);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ST_Progress - increments progress indicator
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ST_Progress(void)
|
||||
{
|
||||
#ifdef __WATCOMC__
|
||||
static int notchPosition=0;
|
||||
|
||||
// Check for ESC press -- during startup all events eaten here
|
||||
I_StartupReadKeys();
|
||||
|
||||
if (debugmode)
|
||||
{
|
||||
printf(".");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(notchPosition<ST_MAX_NOTCHES)
|
||||
{
|
||||
ST_UpdateNotches(notchPosition);
|
||||
S_StartSound(NULL, SFX_STARTUP_TICK);
|
||||
notchPosition++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
printf(".");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ST_NetProgress - indicates network progress
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ST_NetProgress(void)
|
||||
{
|
||||
#ifdef __WATCOMC__
|
||||
static int netnotchPosition=0;
|
||||
if (debugmode)
|
||||
{
|
||||
printf("*");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(netnotchPosition<ST_MAX_NETNOTCHES)
|
||||
{
|
||||
ST_UpdateNetNotches(netnotchPosition);
|
||||
S_StartSound(NULL, SFX_DRIP);
|
||||
netnotchPosition++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ST_NetDone - net progress complete
|
||||
//
|
||||
//==========================================================================
|
||||
void ST_NetDone(void)
|
||||
{
|
||||
S_StartSound(NULL, SFX_PICKUP_WEAPON);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ST_Message - gives debug message
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ST_Message(char *message, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char buffer[80];
|
||||
|
||||
va_start(argptr, message);
|
||||
vsprintf(buffer, message, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
if ( strlen(buffer) >= 80 )
|
||||
{
|
||||
I_Error("Long debug message has overwritten memory");
|
||||
}
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
if (debugmode)
|
||||
{
|
||||
printf(buffer);
|
||||
}
|
||||
#else
|
||||
printf(buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ST_RealMessage - gives user message
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ST_RealMessage(char *message, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
char buffer[80];
|
||||
|
||||
va_start(argptr, message);
|
||||
vsprintf(buffer, message, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
if ( strlen(buffer) >= 80 )
|
||||
{
|
||||
I_Error("Long debug message has overwritten memory\n");
|
||||
}
|
||||
|
||||
printf(buffer); // Always print these messages
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ST_LoadScreen - loads startup graphic
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
|
||||
char *ST_LoadScreen(void)
|
||||
{
|
||||
int length,lump;
|
||||
char *buffer;
|
||||
|
||||
lump = W_GetNumForName("STARTUP");
|
||||
length = W_LumpLength(lump);
|
||||
buffer = (char *)Z_Malloc(length, PU_STATIC, NULL);
|
||||
W_ReadLump(lump, buffer);
|
||||
return(buffer);
|
||||
}
|
28
Hexen Source/ST_START.H
Normal file
28
Hexen Source/ST_START.H
Normal file
|
@ -0,0 +1,28 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** template.h : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: st_start.h,v $
|
||||
//** $Revision: 1.5 $
|
||||
//** $Date: 95/10/11 23:35:33 $
|
||||
//** $Author: paul $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
extern void ST_Init(void);
|
||||
extern void ST_Done(void);
|
||||
extern void ST_Message(char *message, ...);
|
||||
extern void ST_RealMessage(char *message, ...);
|
||||
extern void ST_Progress(void);
|
||||
extern void ST_NetProgress(void);
|
||||
extern void ST_NetDone(void);
|
||||
|
||||
// PUBLIC DATA DECLARATIONS ------------------------------------------------
|
1756
Hexen Source/SV_SAVE.C
Normal file
1756
Hexen Source/SV_SAVE.C
Normal file
File diff suppressed because it is too large
Load diff
162
Hexen Source/T.BAT
Normal file
162
Hexen Source/T.BAT
Normal file
|
@ -0,0 +1,162 @@
|
|||
@REM Hexen startup batch file
|
||||
@echo off
|
||||
|
||||
echo :
|
||||
call castoff
|
||||
echo :
|
||||
|
||||
if "%1x"=="x" goto badargs
|
||||
|
||||
set hticargs=-devmaps dev.txt -warp %1
|
||||
set hticwads=-file
|
||||
set hticnplay=
|
||||
|
||||
:parseloop
|
||||
if "%2x"=="x" goto doneparse
|
||||
if "%2"=="m" goto nomonsters
|
||||
if "%2"=="M" goto nomonsters
|
||||
if "%2"=="s1" goto skill1
|
||||
if "%2"=="S1" goto skill1
|
||||
if "%2"=="s2" goto skill2
|
||||
if "%2"=="S2" goto skill2
|
||||
if "%2"=="s3" goto skill3
|
||||
if "%2"=="S3" goto skill3
|
||||
if "%2"=="s4" goto skill4
|
||||
if "%2"=="S4" goto skill4
|
||||
if "%2"=="s5" goto skill5
|
||||
if "%2"=="S5" goto skill5
|
||||
if "%2"=="n1" goto nplay1
|
||||
if "%2"=="N1" goto nplay1
|
||||
if "%2"=="n2" goto nplay2
|
||||
if "%2"=="N2" goto nplay2
|
||||
if "%2"=="n3" goto nplay3
|
||||
if "%2"=="N3" goto nplay3
|
||||
if "%2"=="n4" goto nplay4
|
||||
if "%2"=="N4" goto nplay4
|
||||
if "%2"=="p" goto altport
|
||||
if "%2"=="P" goto altport
|
||||
if "%2"=="c0" goto class0
|
||||
if "%2"=="C0" goto class0
|
||||
if "%2"=="c1" goto class1
|
||||
if "%2"=="C1" goto class1
|
||||
if "%2"=="c2" goto class2
|
||||
if "%2"=="C2" goto class2
|
||||
if "%2"=="r" goto randclass
|
||||
if "%2"=="R" goto randclass
|
||||
goto addwad
|
||||
|
||||
:nomonsters
|
||||
set hticargs=%hticargs% -nomonsters
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:skill1
|
||||
set hticargs=%hticargs% -skill 1
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:skill2
|
||||
set hticargs=%hticargs% -skill 2
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:skill3
|
||||
set hticargs=%hticargs% -skill 3
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:skill4
|
||||
set hticargs=%hticargs% -skill 4
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:skill5
|
||||
set hticargs=%hticargs% -skill 5
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:nplay1
|
||||
set hticnplay=1
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:nplay2
|
||||
set hticnplay=2
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:nplay3
|
||||
set hticnplay=3
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:nplay4
|
||||
set hticnplay=4
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:altport
|
||||
set hticargs=%hticargs% -port 2
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:class0
|
||||
set hticargs=%hticargs% -class 0
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:class1
|
||||
set hticargs=%hticargs% -class 1
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:class2
|
||||
set hticargs=%hticargs% -class 2
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:randclass
|
||||
set hticargs=%hticargs% -randclass
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:addwad
|
||||
set hticwads=%hticwads% %3.wad
|
||||
shift
|
||||
goto parseloop
|
||||
|
||||
:badargs
|
||||
echo HEXEN STARTUP
|
||||
echo Usage: H map [s?] [m] [n?] [p] [wadfile [wadfile ...] ]
|
||||
echo.
|
||||
echo [s?] = skill (1-5)
|
||||
echo [m] = no monsters
|
||||
echo [n?] = net play (1-4)
|
||||
echo [p] = use alternate port setting
|
||||
echo [r] = random player class
|
||||
echo [wadfile] = add external wadfile (.WAD is implicit)
|
||||
echo.
|
||||
goto end
|
||||
|
||||
:doneparse
|
||||
if "%hticwads%" == "-file" goto startgame
|
||||
set hticargs=%hticargs% %hticwads%
|
||||
:startgame
|
||||
if "%hticnplay%x" == "x" goto normalplay
|
||||
echo -nodes %hticnplay% -deathmatch %hticargs%
|
||||
hexipx -nodes %hticnplay% -deathmatch %hticargs%
|
||||
goto end
|
||||
|
||||
:normalplay
|
||||
echo %hticargs%
|
||||
hexen %hticargs%
|
||||
goto end
|
||||
|
||||
:end
|
||||
set hticargs=
|
||||
set hticwads=
|
||||
set hticnplay=
|
||||
|
||||
echo :
|
||||
@call caston
|
||||
echo :
|
2074
Hexen Source/TABLES.C
Normal file
2074
Hexen Source/TABLES.C
Normal file
File diff suppressed because it is too large
Load diff
32
Hexen Source/TEMPLATE.C
Normal file
32
Hexen Source/TEMPLATE.C
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** TEMPLATE.C
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
167
Hexen Source/TEXTDEFS.H
Normal file
167
Hexen Source/TEXTDEFS.H
Normal file
|
@ -0,0 +1,167 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** textdefs.h : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: textdefs.h,v $
|
||||
//** $Revision: 1.34 $
|
||||
//** $Date: 96/01/05 23:33:22 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// MN_menu.c ---------------------------------------------------------------
|
||||
|
||||
#define PRESSKEY "press a key."
|
||||
#define PRESSYN "press y or n."
|
||||
#define TXT_PAUSED "PAUSED"
|
||||
#define QUITMSG "are you sure you want to\nquit this great game?"
|
||||
#define LOADNET "you can't do load while in a net game!\n\n"PRESSKEY
|
||||
#define QLOADNET "you can't quickload during a netgame!\n\n"PRESSKEY
|
||||
#define QSAVESPOT "you haven't picked a quicksave slot yet!\n\n"PRESSKEY
|
||||
#define SAVEDEAD "you can't save if you aren't playing!\n\n"PRESSKEY
|
||||
#define QSPROMPT "quicksave over your game named\n\n'%s'?\n\n"PRESSYN
|
||||
#define QLPROMPT "do you want to quickload the game named"\
|
||||
"\n\n'%s'?\n\n"PRESSYN
|
||||
#define NEWGAME "you can't start a new game\n"\
|
||||
"while in a network game.\n\n"PRESSKEY
|
||||
#define MSGOFF "Messages OFF"
|
||||
#define MSGON "Messages ON"
|
||||
#define NETEND "you can't end a netgame!\n\n"PRESSKEY
|
||||
#define ENDGAME "are you sure you want to end the game?\n\n"PRESSYN
|
||||
#define DOSY "(press y to quit to dos.)"
|
||||
#define TXT_GAMMA_LEVEL_OFF "GAMMA CORRECTION OFF"
|
||||
#define TXT_GAMMA_LEVEL_1 "GAMMA CORRECTION LEVEL 1"
|
||||
#define TXT_GAMMA_LEVEL_2 "GAMMA CORRECTION LEVEL 2"
|
||||
#define TXT_GAMMA_LEVEL_3 "GAMMA CORRECTION LEVEL 3"
|
||||
#define TXT_GAMMA_LEVEL_4 "GAMMA CORRECTION LEVEL 4"
|
||||
#define EMPTYSTRING "empty slot"
|
||||
|
||||
// P_inter.c ---------------------------------------------------------------
|
||||
|
||||
// Mana
|
||||
|
||||
#define TXT_MANA_1 "BLUE MANA"
|
||||
#define TXT_MANA_2 "GREEN MANA"
|
||||
#define TXT_MANA_BOTH "COMBINED MANA"
|
||||
|
||||
// Keys
|
||||
|
||||
#define TXT_KEY_STEEL "STEEL KEY"
|
||||
#define TXT_KEY_CAVE "CAVE KEY"
|
||||
#define TXT_KEY_AXE "AXE KEY"
|
||||
#define TXT_KEY_FIRE "FIRE KEY"
|
||||
#define TXT_KEY_EMERALD "EMERALD KEY"
|
||||
#define TXT_KEY_DUNGEON "DUNGEON KEY"
|
||||
#define TXT_KEY_SILVER "SILVER KEY"
|
||||
#define TXT_KEY_RUSTED "RUSTED KEY"
|
||||
#define TXT_KEY_HORN "HORN KEY"
|
||||
#define TXT_KEY_SWAMP "SWAMP KEY"
|
||||
#define TXT_KEY_CASTLE "CASTLE KEY"
|
||||
|
||||
// Artifacts
|
||||
|
||||
#define TXT_ARTIINVULNERABILITY "ICON OF THE DEFENDER"
|
||||
#define TXT_ARTIHEALTH "QUARTZ FLASK"
|
||||
#define TXT_ARTISUPERHEALTH "MYSTIC URN"
|
||||
#define TXT_ARTISUMMON "DARK SERVANT"
|
||||
#define TXT_ARTITORCH "TORCH"
|
||||
#define TXT_ARTIEGG "PORKALATOR"
|
||||
#define TXT_ARTIFLY "WINGS OF WRATH"
|
||||
#define TXT_ARTITELEPORT "CHAOS DEVICE"
|
||||
#define TXT_ARTIPOISONBAG "FLECHETTE"
|
||||
#define TXT_ARTITELEPORTOTHER "BANISHMENT DEVICE"
|
||||
#define TXT_ARTISPEED "BOOTS OF SPEED"
|
||||
#define TXT_ARTIBOOSTMANA "KRATER OF MIGHT"
|
||||
#define TXT_ARTIBOOSTARMOR "DRAGONSKIN BRACERS"
|
||||
#define TXT_ARTIBLASTRADIUS "DISC OF REPULSION"
|
||||
#define TXT_ARTIHEALINGRADIUS "MYSTIC AMBIT INCANT"
|
||||
|
||||
// Puzzle artifacts
|
||||
|
||||
#define TXT_ARTIPUZZSKULL "YORICK'S SKULL"
|
||||
#define TXT_ARTIPUZZGEMBIG "HEART OF D'SPARIL"
|
||||
#define TXT_ARTIPUZZGEMRED "RUBY PLANET"
|
||||
#define TXT_ARTIPUZZGEMGREEN1 "EMERALD PLANET"
|
||||
#define TXT_ARTIPUZZGEMGREEN2 "EMERALD PLANET"
|
||||
#define TXT_ARTIPUZZGEMBLUE1 "SAPPHIRE PLANET"
|
||||
#define TXT_ARTIPUZZGEMBLUE2 "SAPPHIRE PLANET"
|
||||
#define TXT_ARTIPUZZBOOK1 "DAEMON CODEX"
|
||||
#define TXT_ARTIPUZZBOOK2 "LIBER OSCURA"
|
||||
#define TXT_ARTIPUZZSKULL2 "FLAME MASK"
|
||||
#define TXT_ARTIPUZZFWEAPON "GLAIVE SEAL"
|
||||
#define TXT_ARTIPUZZCWEAPON "HOLY RELIC"
|
||||
#define TXT_ARTIPUZZMWEAPON "SIGIL OF THE MAGUS"
|
||||
#define TXT_ARTIPUZZGEAR "CLOCK GEAR"
|
||||
#define TXT_USEPUZZLEFAILED "YOU CANNOT USE THIS HERE"
|
||||
|
||||
// Items
|
||||
|
||||
#define TXT_ITEMHEALTH "CRYSTAL VIAL"
|
||||
#define TXT_ITEMBAGOFHOLDING "BAG OF HOLDING"
|
||||
#define TXT_ITEMSHIELD1 "SILVER SHIELD"
|
||||
#define TXT_ITEMSHIELD2 "ENCHANTED SHIELD"
|
||||
#define TXT_ITEMSUPERMAP "MAP SCROLL"
|
||||
#define TXT_ARMOR1 "MESH ARMOR"
|
||||
#define TXT_ARMOR2 "FALCON SHIELD"
|
||||
#define TXT_ARMOR3 "PLATINUM HELMET"
|
||||
#define TXT_ARMOR4 "AMULET OF WARDING"
|
||||
|
||||
// Weapons
|
||||
|
||||
#define TXT_WEAPON_F2 "TIMON'S AXE"
|
||||
#define TXT_WEAPON_F3 "HAMMER OF RETRIBUTION"
|
||||
#define TXT_WEAPON_F4 "QUIETUS ASSEMBLED"
|
||||
#define TXT_WEAPON_C2 "SERPENT STAFF"
|
||||
#define TXT_WEAPON_C3 "FIRESTORM"
|
||||
#define TXT_WEAPON_C4 "WRAITHVERGE ASSEMBLED"
|
||||
#define TXT_WEAPON_M2 "FROST SHARDS"
|
||||
#define TXT_WEAPON_M3 "ARC OF DEATH"
|
||||
#define TXT_WEAPON_M4 "BLOODSCOURGE ASSEMBLED"
|
||||
#define TXT_QUIETUS_PIECE "SEGMENT OF QUIETUS"
|
||||
#define TXT_WRAITHVERGE_PIECE "SEGMENT OF WRAITHVERGE"
|
||||
#define TXT_BLOODSCOURGE_PIECE "SEGMENT OF BLOODSCOURGE"
|
||||
|
||||
// SB_bar.c ----------------------------------------------------------------
|
||||
|
||||
#define TXT_CHEATGODON "GOD MODE ON"
|
||||
#define TXT_CHEATGODOFF "GOD MODE OFF"
|
||||
#define TXT_CHEATNOCLIPON "NO CLIPPING ON"
|
||||
#define TXT_CHEATNOCLIPOFF "NO CLIPPING OFF"
|
||||
#define TXT_CHEATWEAPONS "ALL WEAPONS"
|
||||
#define TXT_CHEATHEALTH "FULL HEALTH"
|
||||
#define TXT_CHEATKEYS "ALL KEYS"
|
||||
#define TXT_CHEATSOUNDON "SOUND DEBUG ON"
|
||||
#define TXT_CHEATSOUNDOFF "SOUND DEBUG OFF"
|
||||
#define TXT_CHEATTICKERON "TICKER ON"
|
||||
#define TXT_CHEATTICKEROFF "TICKER OFF"
|
||||
#define TXT_CHEATARTIFACTS3 "ALL ARTIFACTS"
|
||||
#define TXT_CHEATARTIFACTSFAIL "BAD INPUT"
|
||||
#define TXT_CHEATWARP "LEVEL WARP"
|
||||
#define TXT_CHEATSCREENSHOT "SCREENSHOT"
|
||||
#define TXT_CHEATIDDQD "TRYING TO CHEAT, EH? NOW YOU DIE!"
|
||||
#define TXT_CHEATIDKFA "CHEATER - YOU DON'T DESERVE WEAPONS"
|
||||
#define TXT_CHEATBADINPUT "BAD INPUT"
|
||||
#define TXT_CHEATNOMAP "CAN'T FIND MAP"
|
||||
|
||||
// G_game.c ----------------------------------------------------------------
|
||||
|
||||
#define TXT_GAMESAVED "GAME SAVED"
|
||||
|
||||
// M_misc.c ----------------------------------------------------------------
|
||||
|
||||
#define HUSTR_CHATMACRO1 "I'm ready to kick butt!"
|
||||
#define HUSTR_CHATMACRO2 "I'm OK."
|
||||
#define HUSTR_CHATMACRO3 "I'm not looking too good!"
|
||||
#define HUSTR_CHATMACRO4 "Help!"
|
||||
#define HUSTR_CHATMACRO5 "You suck!"
|
||||
#define HUSTR_CHATMACRO6 "Next time, scumbag..."
|
||||
#define HUSTR_CHATMACRO7 "Come here!"
|
||||
#define HUSTR_CHATMACRO8 "I'll take care of it."
|
||||
#define HUSTR_CHATMACRO9 "Yes"
|
||||
#define HUSTR_CHATMACRO0 "No"
|
||||
|
||||
// AM_map.c ----------------------------------------------------------------
|
||||
|
||||
#define AMSTR_FOLLOWON "FOLLOW MODE ON"
|
||||
#define AMSTR_FOLLOWOFF "FOLLOW MODE OFF"
|
34
Hexen Source/VGAVIEW.H
Normal file
34
Hexen Source/VGAVIEW.H
Normal file
|
@ -0,0 +1,34 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** VGAView.h : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: VGAView.h,v $
|
||||
//** $Revision: 1.1 $
|
||||
//** $Date: 95/05/11 00:19:48 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#import <appkit/appkit.h>
|
||||
#import "h2def.h"
|
||||
|
||||
// a few globals
|
||||
extern byte *bytebuffer;
|
||||
|
||||
|
||||
@interface VGAView:View
|
||||
{
|
||||
id game;
|
||||
int nextpalette[256]; // color lookup table
|
||||
int *nextimage; // palette expanded and scaled
|
||||
unsigned scale;
|
||||
NXWindowDepth depth;
|
||||
}
|
||||
|
||||
- updateView;
|
||||
- (unsigned)scale;
|
||||
- setPalette:(byte *)pal;
|
||||
- setScale:(int)newscale;
|
||||
|
||||
@end
|
261
Hexen Source/V_VIDEO.C
Normal file
261
Hexen Source/V_VIDEO.C
Normal file
|
@ -0,0 +1,261 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** v_video.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: v_video.c,v $
|
||||
//** $Revision: 1.2 $
|
||||
//** $Date: 95/09/11 14:58:16 $
|
||||
//** $Author: cjr $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include "h2def.h"
|
||||
|
||||
#define SC_INDEX 0x3c4
|
||||
|
||||
byte *screen;
|
||||
int dirtybox[4];
|
||||
int usegamma;
|
||||
|
||||
byte gammatable[5][256] =
|
||||
{
|
||||
{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,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255},
|
||||
|
||||
{2,4,5,7,8,10,11,12,14,15,16,18,19,20,21,23,24,25,26,27,29,30,31,32,33,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,54,55,56,57,58,59,60,61,62,63,64,65,66,67,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,163,164,165,166,167,168,169,170,171,172,173,174,175,175,176,177,178,179,180,181,182,183,184,185,186,186,187,188,189,190,191,192,193,194,195,196,196,197,198,199,200,201,202,203,204,205,205,206,207,208,209,210,211,212,213,214,214,215,216,217,218,219,220,221,222,222,223,224,225,226,227,228,229,230,230,231,232,233,234,235,236,237,237,238,239,240,241,242,243,244,245,245,246,247,248,249,250,251,252,252,253,254,255},
|
||||
|
||||
{4,7,9,11,13,15,17,19,21,22,24,26,27,29,30,32,33,35,36,38,39,40,42,43,45,46,47,48,50,51,52,54,55,56,57,59,60,61,62,63,65,66,67,68,69,70,72,73,74,75,76,77,78,79,80,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,133,134,135,136,137,138,139,140,141,142,143,144,144,145,146,147,148,149,150,151,152,153,153,154,155,156,157,158,159,160,160,161,162,163,164,165,166,166,167,168,169,170,171,172,172,173,174,175,176,177,178,178,179,180,181,182,183,183,184,185,186,187,188,188,189,190,191,192,193,193,194,195,196,197,197,198,199,200,201,201,202,203,204,205,206,206,207,208,209,210,210,211,212,213,213,214,215,216,217,217,218,219,220,221,221,222,223,224,224,225,226,227,228,228,229,230,231,231,232,233,234,235,235,236,237,238,238,239,240,241,241,242,243,244,244,245,246,247,247,248,249,250,251,251,252,253,254,254,255},
|
||||
|
||||
{8,12,16,19,22,24,27,29,31,34,36,38,40,41,43,45,47,49,50,52,53,55,57,58,60,61,63,64,65,67,68,70,71,72,74,75,76,77,79,80,81,82,84,85,86,87,88,90,91,92,93,94,95,96,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,135,136,137,138,139,140,141,142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,155,156,157,158,159,160,160,161,162,163,164,165,165,166,167,168,169,169,170,171,172,173,173,174,175,176,176,177,178,179,180,180,181,182,183,183,184,185,186,186,187,188,189,189,190,191,192,192,193,194,195,195,196,197,197,198,199,200,200,201,202,202,203,204,205,205,206,207,207,208,209,210,210,211,212,212,213,214,214,215,216,216,217,218,219,219,220,221,221,222,223,223,224,225,225,226,227,227,228,229,229,230,231,231,232,233,233,234,235,235,236,237,237,238,238,239,240,240,241,242,242,243,244,244,245,246,246,247,247,248,249,249,250,251,251,252,253,253,254,254,255},
|
||||
|
||||
{16,23,28,32,36,39,42,45,48,50,53,55,57,60,62,64,66,68,69,71,73,75,76,78,80,81,83,84,86,87,89,90,92,93,94,96,97,98,100,101,102,103,105,106,107,108,109,110,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,128,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,155,156,157,158,159,159,160,161,162,163,163,164,165,166,166,167,168,169,169,170,171,172,172,173,174,175,175,176,177,177,178,179,180,180,181,182,182,183,184,184,185,186,187,187,188,189,189,190,191,191,192,193,193,194,195,195,196,196,197,198,198,199,200,200,201,202,202,203,203,204,205,205,206,207,207,208,208,209,210,210,211,211,212,213,213,214,214,215,216,216,217,217,218,219,219,220,220,221,221,222,223,223,224,224,225,225,226,227,227,228,228,229,229,230,230,231,232,232,233,233,234,234,235,235,236,236,237,237,238,239,239,240,240,241,241,242,242,243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,251,252,252,253,254,254,255,255}
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC V_DrawPatch
|
||||
//
|
||||
// Draws a column based masked pic to the screen.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void V_DrawPatch(int x, int y, patch_t *patch)
|
||||
{
|
||||
int count;
|
||||
int col;
|
||||
column_t *column;
|
||||
byte *desttop;
|
||||
byte *dest;
|
||||
byte *source;
|
||||
int w;
|
||||
|
||||
y -= SHORT(patch->topoffset);
|
||||
x -= SHORT(patch->leftoffset);
|
||||
if(x < 0 || x+SHORT(patch->width) > SCREENWIDTH || y < 0
|
||||
|| y+SHORT(patch->height) > SCREENHEIGHT)
|
||||
{
|
||||
I_Error("Bad V_DrawPatch");
|
||||
}
|
||||
col = 0;
|
||||
desttop = screen+y*SCREENWIDTH+x;
|
||||
w = SHORT(patch->width);
|
||||
for(; col < w; x++, col++, desttop++)
|
||||
{
|
||||
column = (column_t *)((byte *)patch+LONG(patch->columnofs[col]));
|
||||
// Step through the posts in a column
|
||||
while(column->topdelta != 0xff)
|
||||
{
|
||||
source = (byte *)column+3;
|
||||
dest = desttop+column->topdelta*SCREENWIDTH;
|
||||
count = column->length;
|
||||
while(count--)
|
||||
{
|
||||
*dest = *source++;
|
||||
dest += SCREENWIDTH;
|
||||
}
|
||||
column = (column_t *)((byte *)column+column->length+4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
=
|
||||
= V_DrawFuzzPatch
|
||||
=
|
||||
= Masks a column based translucent masked pic to the screen.
|
||||
=
|
||||
==================
|
||||
*/
|
||||
extern byte *tinttable;
|
||||
|
||||
void V_DrawFuzzPatch (int x, int y, patch_t *patch)
|
||||
{
|
||||
int count,col;
|
||||
column_t *column;
|
||||
byte *desttop, *dest, *source;
|
||||
int w;
|
||||
|
||||
y -= SHORT(patch->topoffset);
|
||||
x -= SHORT(patch->leftoffset);
|
||||
|
||||
if (x<0||x+SHORT(patch->width) >SCREENWIDTH || y<0 || y+SHORT(patch->height)>SCREENHEIGHT
)
|
||||
I_Error ("Bad V_DrawPatch");
|
||||
|
||||
col = 0;
|
||||
desttop = screen+y*SCREENWIDTH+x;
|
||||
|
||||
w = SHORT(patch->width);
|
||||
for ( ; col<w ; x++, col++, desttop++)
|
||||
{
|
||||
column = (column_t *)((byte *)patch + LONG(patch->columnofs[col]));
|
||||
|
||||
// step through the posts in a column
|
||||
|
||||
while (column->topdelta != 0xff )
|
||||
{
|
||||
source = (byte *)column + 3;
|
||||
dest = desttop + column->topdelta*SCREENWIDTH;
|
||||
count = column->length;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
*dest = tinttable[*dest + ((*source++)<<8)];
|
||||
dest += SCREENWIDTH;
|
||||
}
|
||||
column = (column_t *)((byte *)column+column->length+4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
=
|
||||
= V_DrawAltFuzzPatch
|
||||
=
|
||||
= Masks a column based translucent masked pic to the screen.
|
||||
=
|
||||
==================
|
||||
*/
|
||||
extern byte *tinttable;
|
||||
|
||||
void V_DrawAltFuzzPatch (int x, int y, patch_t *patch)
|
||||
{
|
||||
int count,col;
|
||||
column_t *column;
|
||||
byte *desttop, *dest, *source;
|
||||
int w;
|
||||
|
||||
y -= SHORT(patch->topoffset);
|
||||
x -= SHORT(patch->leftoffset);
|
||||
|
||||
if (x<0||x+SHORT(patch->width) >SCREENWIDTH || y<0
|
||||
|| y+SHORT(patch->height)>SCREENHEIGHT
)
|
||||
{
|
||||
I_Error ("Bad V_DrawPatch");
|
||||
}
|
||||
|
||||
col = 0;
|
||||
desttop = screen+y*SCREENWIDTH+x;
|
||||
|
||||
w = SHORT(patch->width);
|
||||
for ( ; col<w ; x++, col++, desttop++)
|
||||
{
|
||||
column = (column_t *)((byte *)patch + LONG(patch->columnofs[col]));
|
||||
|
||||
// step through the posts in a column
|
||||
|
||||
while (column->topdelta != 0xff )
|
||||
{
|
||||
source = (byte *)column + 3;
|
||||
dest = desttop + column->topdelta*SCREENWIDTH;
|
||||
count = column->length;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
*dest = tinttable[((*dest)<<8) + *source++];
|
||||
dest += SCREENWIDTH;
|
||||
}
|
||||
column = (column_t *)((byte *)column+column->length+4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
=
|
||||
= V_DrawShadowedPatch
|
||||
=
|
||||
= Masks a column based masked pic to the screen.
|
||||
=
|
||||
==================
|
||||
*/
|
||||
|
||||
void V_DrawShadowedPatch(int x, int y, patch_t *patch)
|
||||
{
|
||||
int count,col;
|
||||
column_t *column;
|
||||
byte *desttop, *dest, *source;
|
||||
byte *desttop2, *dest2;
|
||||
int w;
|
||||
|
||||
y -= SHORT(patch->topoffset);
|
||||
x -= SHORT(patch->leftoffset);
|
||||
|
||||
if (x<0||x+SHORT(patch->width) >SCREENWIDTH || y<0 || y+SHORT(patch->height)>SCREENHEIGHT
)
|
||||
I_Error ("Bad V_DrawPatch");
|
||||
|
||||
col = 0;
|
||||
desttop = screen+y*SCREENWIDTH+x;
|
||||
desttop2 = screen+(y+2)*SCREENWIDTH+x+2;
|
||||
|
||||
w = SHORT(patch->width);
|
||||
for ( ; col<w ; x++, col++, desttop++, desttop2++)
|
||||
{
|
||||
column = (column_t *)((byte *)patch + LONG(patch->columnofs[col]));
|
||||
|
||||
// step through the posts in a column
|
||||
|
||||
while (column->topdelta != 0xff )
|
||||
{
|
||||
source = (byte *)column + 3;
|
||||
dest = desttop + column->topdelta*SCREENWIDTH;
|
||||
dest2 = desttop2 + column->topdelta*SCREENWIDTH;
|
||||
count = column->length;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
*dest2 = tinttable[((*dest2)<<8)];
|
||||
dest2 += SCREENWIDTH;
|
||||
*dest = *source++;
|
||||
dest += SCREENWIDTH;
|
||||
|
||||
}
|
||||
column = (column_t *)( (byte *)column + column->length
|
||||
+ 4 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC V_DrawRawScreen
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void V_DrawRawScreen(byte *raw)
|
||||
{
|
||||
memcpy(screen, raw, SCREENWIDTH*SCREENHEIGHT);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC V_Init
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void V_Init(void)
|
||||
{
|
||||
// I_AllocLow will put screen in low dos memory on PCs.
|
||||
screen = I_AllocLow(SCREENWIDTH*SCREENHEIGHT);
|
||||
}
|
6
Hexen Source/W.BAT
Normal file
6
Hexen Source/W.BAT
Normal file
|
@ -0,0 +1,6 @@
|
|||
@echo off
|
||||
echo Making HEXEN.WAD
|
||||
echo Preprocessing: wadlink.txt to wadlink.wl
|
||||
wcc386 /dNOMAPS /dREGISTERED /p /fo=wadlink.wl \data\wadlink.txt
|
||||
echo wadlinking ...
|
||||
\tools\exe\wadlink
|
265
Hexen Source/WADLINK.WL
Normal file
265
Hexen Source/WADLINK.WL
Normal file
|
@ -0,0 +1,265 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; WAD NAME
|
||||
|
||||
$WADNAME HEXEN
|
||||
|
||||
; VERSION ID
|
||||
|
||||
\data\xxtic.lmp
|
||||
|
||||
; STARTUP SCREEN
|
||||
|
||||
\art\startup\startup.lmp
|
||||
|
||||
; PALETTES AND COLOR MAPS
|
||||
|
||||
\art\palette\playpal.lmp
|
||||
\art\palette\colormap.lmp
|
||||
\art\palette\fogmap.lmp
|
||||
\art\palette\tinttab.lmp
|
||||
|
||||
; TRANSLATION TABLES
|
||||
|
||||
$shootwad \art\palette\trans-8.wad
|
||||
|
||||
; DEMOS
|
||||
|
||||
\data\demos\demo1.lmp
|
||||
\data\demos\demo2.lmp
|
||||
\data\demos\demo3.lmp
|
||||
|
||||
; SCREENS
|
||||
|
||||
$shootwad \art\screens\screens.wad
|
||||
; \data\txtscrn2\endtext.bin
|
||||
|
||||
; LEVEL MAPS
|
||||
|
||||
|
||||
|
||||
; CLUSTER CONCLUSION MESSAGES
|
||||
|
||||
\data\text\clus1msg.txt
|
||||
\data\text\clus2msg.txt
|
||||
\data\text\clus3msg.txt
|
||||
\data\text\clus4msg.txt
|
||||
|
||||
; WIN GAME MESSAGES
|
||||
|
||||
\data\text\win1msg.txt
|
||||
\data\text\win2msg.txt
|
||||
\data\text\win3msg.txt
|
||||
|
||||
; TEXTURE INFO AND PATCH NAMES
|
||||
|
||||
\maps\pnames.lmp
|
||||
\maps\texture1.lmp
|
||||
|
||||
\maps\texture2.lmp
|
||||
|
||||
|
||||
; SCRIPTS
|
||||
|
||||
\data\scripts\animdefs.txt
|
||||
\data\scripts\mapinfo.txt
|
||||
\data\scripts\sndinfo.txt
|
||||
\data\scripts\sndseq.txt
|
||||
|
||||
; AUTOMAP
|
||||
|
||||
$shootwad \art\automap\automap
|
||||
|
||||
; STATUS BAR
|
||||
|
||||
|
||||
$shootwad \art\statbar\statbar
|
||||
|
||||
|
||||
; MENU
|
||||
|
||||
$shootwad \art\menu\menu
|
||||
|
||||
; FONTS
|
||||
|
||||
$label fonta_s
|
||||
$shootwad \art\fonts\fonta
|
||||
$label fonta_e
|
||||
$label fontay_s
|
||||
$shootwad \art\fonts\fonta_y
|
||||
$label fontay_e
|
||||
$label fontb_s
|
||||
$shootwad \art\fonts\fontb
|
||||
$label fontb_e
|
||||
|
||||
; START SPRITES
|
||||
|
||||
$label s_start
|
||||
|
||||
; Fighter weapons
|
||||
$shootwad \art\weapons\fighter\punch\punch.wad
|
||||
$shootwad \art\weapons\fighter\axe\axe.wad
|
||||
$shootwad \art\weapons\fighter\hammer\hammer.wad
|
||||
$shootwad \art\weapons\fighter\sword\sword.wad
|
||||
|
||||
; Cleric weapons
|
||||
$shootwad \art\weapons\cleric\mace\mace.wad
|
||||
$shootwad \art\weapons\cleric\sstaff\sstaff.wad
|
||||
$shootwad \art\weapons\cleric\flame\flame.wad
|
||||
$shootwad \art\weapons\cleric\holy\holy.wad
|
||||
|
||||
; Mage weapons
|
||||
$shootwad \art\weapons\mage\wand\wand.wad
|
||||
$shootwad \art\weapons\mage\cone\cone.wad
|
||||
$shootwad \art\weapons\mage\lightng\lightng.wad
|
||||
$shootwad \art\weapons\mage\staff\mstaff.wad
|
||||
|
||||
; Morphed player weapons
|
||||
; $shootwad \art\weapons\beak\beak.wad
|
||||
$shootwad \art\weapons\snout\snout.wad
|
||||
|
||||
|
||||
; PLAYER
|
||||
|
||||
$shootwad \art\player\fighter\fighter
|
||||
$shootwad \art\player\fighter\fighter2
|
||||
|
||||
$shootwad \art\player\mage\mage
|
||||
$shootwad \art\player\mage\mage2
|
||||
$shootwad \art\player\mage\mage3
|
||||
|
||||
$shootwad \art\player\cleric\cleric
|
||||
$shootwad \art\player\cleric\cleric2
|
||||
$shootwad \art\player\cleric\cleric3
|
||||
|
||||
|
||||
; MONSTERS
|
||||
|
||||
; Sea Serpent
|
||||
$shootwad \art\monsters\serpent\serpent
|
||||
|
||||
; Centaur
|
||||
$shootwad \art\monsters\centaur\centaur
|
||||
$shootwad \art\monsters\centaur\centaur2
|
||||
$shootwad \art\monsters\centaur\centaur3
|
||||
$shootwad \art\monsters\centaur\centfx
|
||||
|
||||
; Demon
|
||||
$shootwad \art\monsters\demon\demon
|
||||
|
||||
; Demon2
|
||||
$shootwad \art\monsters\demon2\demon2
|
||||
|
||||
; Wraith
|
||||
$shootwad \art\monsters\wraith\wraith
|
||||
|
||||
; Dragon Lich
|
||||
$shootwad \art\monsters\dragon\dragon
|
||||
|
||||
; Bishop
|
||||
$shootwad \art\monsters\bishop\bishop
|
||||
|
||||
; Ettin
|
||||
$shootwad \art\monsters\ettin\ettin
|
||||
|
||||
; Fire Demon
|
||||
$shootwad \art\monsters\firedemn\fired
|
||||
|
||||
; Ice Guy
|
||||
$shootwad \art\monsters\ice\iceguy
|
||||
|
||||
; Sorcerer Boss Guy
|
||||
$shootwad \art\monsters\boss1\sorc
|
||||
|
||||
; Korax
|
||||
$shootwad \art\monsters\korax\korax
|
||||
|
||||
; Chicken
|
||||
; $shootwad \art\monsters\chicken\chicken
|
||||
|
||||
; Pig
|
||||
$shootwad \art\monsters\pig\pig
|
||||
|
||||
; Maulotaur
|
||||
$shootwad \art\monsters\minotaur\walk
|
||||
$shootwad \art\monsters\minotaur\pain
|
||||
;$shootwad \art\monsters\minotaur\death
|
||||
$shootwad \art\monsters\minotaur\attack
|
||||
$shootwad \art\monsters\minotaur\fx
|
||||
|
||||
|
||||
; STATIC SPRITES
|
||||
|
||||
$shootwad \art\sprites\e1spr
|
||||
$shootwad \art\sprites\s\sprite_s
|
||||
|
||||
; World projectile sprites
|
||||
$shootwad \art\sprites\prjtile\prjtile
|
||||
|
||||
$shootwad \art\sprites\r\sprite_r
|
||||
|
||||
$shootwad \art\sprites\fogpatch\fogpatch.wad
|
||||
|
||||
|
||||
$shootwad \art\weapons\images\images
|
||||
$shootwad \art\artifcts\artifcts
|
||||
$shootwad \art\items\items
|
||||
; $shootwad \art\ammo\ammo
|
||||
|
||||
|
||||
; Mana
|
||||
$shootwad \art\mana\mana
|
||||
|
||||
; END SPRITES
|
||||
|
||||
$label s_end
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; WALL PATCHES
|
||||
|
||||
$label p_start
|
||||
; Shareware wall patches
|
||||
$label p1_start
|
||||
$shootwad \art\walls\s\walls_s
|
||||
$shootwad \art\backdrop\sky_s
|
||||
$label p1_end
|
||||
|
||||
; Registered wall patches
|
||||
$label p2_start
|
||||
$shootwad \art\walls\r\walls_r
|
||||
$shootwad \art\backdrop\sky_r
|
||||
$label p2_end
|
||||
|
||||
$label p_end
|
||||
|
||||
;---------------------------------------------------------------------------
|
||||
; FLATS
|
||||
|
||||
$label f_start
|
||||
; Shareware flats
|
||||
$label f1_start
|
||||
$shootwad \art\flats\s\flats_s
|
||||
$label f1_end
|
||||
|
||||
; Registered flats
|
||||
$label f2_start
|
||||
$shootwad \art\flats\r\flats_r
|
||||
$label f2_end
|
||||
|
||||
$label f_end
|
||||
|
||||
; SOUND
|
||||
|
||||
\sound\misc\genmidi.op2
|
||||
\sound\misc\dmxgus.lmp
|
||||
\sound\misc\sndcurve.lmp
|
||||
|
||||
|
||||
$shootwad \sound\archive\sndwad_r
|
||||
|
596
Hexen Source/W_WAD.C
Normal file
596
Hexen Source/W_WAD.C
Normal file
|
@ -0,0 +1,596 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** w_wad.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: w_wad.c,v $
|
||||
//** $Revision: 1.6 $
|
||||
//** $Date: 95/10/06 20:56:47 $
|
||||
//** $Author: cjr $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#ifdef NeXT
|
||||
#include <libc.h>
|
||||
#include <ctype.h>
|
||||
#else
|
||||
#include <malloc.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include "h2def.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
#ifdef NeXT
|
||||
// NeXT doesn't need a binary flag in open call
|
||||
#define O_BINARY 0
|
||||
#define strcmpi strcasecmp
|
||||
#endif
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char identification[4];
|
||||
int numlumps;
|
||||
int infotableofs;
|
||||
} wadinfo_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int filepos;
|
||||
int size;
|
||||
char name[8];
|
||||
} filelump_t;
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
lumpinfo_t *lumpinfo;
|
||||
int numlumps;
|
||||
void **lumpcache;
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static lumpinfo_t *PrimaryLumpInfo;
|
||||
static int PrimaryNumLumps;
|
||||
static void **PrimaryLumpCache;
|
||||
static lumpinfo_t *AuxiliaryLumpInfo;
|
||||
static int AuxiliaryNumLumps;
|
||||
static void **AuxiliaryLumpCache;
|
||||
static int AuxiliaryHandle = 0;
|
||||
boolean AuxiliaryOpened = false;
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
#ifdef NeXT
|
||||
//==========================================================================
|
||||
//
|
||||
// strupr
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void strupr(char *s)
|
||||
{
|
||||
while(*s)
|
||||
*s++ = toupper(*s);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// filelength
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int filelength(int handle)
|
||||
{
|
||||
struct stat fileinfo;
|
||||
|
||||
if(fstat(handle, &fileinfo) == -1)
|
||||
{
|
||||
I_Error("Error fstating");
|
||||
}
|
||||
return fileinfo.st_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_AddFile
|
||||
//
|
||||
// Files with a .wad extension are wadlink files with multiple lumps,
|
||||
// other files are single lumps with the base filename for the lump name.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void W_AddFile(char *filename)
|
||||
{
|
||||
wadinfo_t header;
|
||||
lumpinfo_t *lump_p;
|
||||
unsigned i;
|
||||
int handle, length;
|
||||
int startlump;
|
||||
filelump_t *fileinfo, singleinfo;
|
||||
filelump_t *freeFileInfo;
|
||||
|
||||
if((handle = open(filename, O_RDONLY|O_BINARY)) == -1)
|
||||
{ // Didn't find file
|
||||
return;
|
||||
}
|
||||
startlump = numlumps;
|
||||
if(strcmpi(filename+strlen(filename)-3, "wad"))
|
||||
{ // Single lump file
|
||||
fileinfo = &singleinfo;
|
||||
freeFileInfo = NULL;
|
||||
singleinfo.filepos = 0;
|
||||
singleinfo.size = LONG(filelength(handle));
|
||||
M_ExtractFileBase(filename, singleinfo.name);
|
||||
numlumps++;
|
||||
}
|
||||
else
|
||||
{ // WAD file
|
||||
read(handle, &header, sizeof(header));
|
||||
if(strncmp(header.identification, "IWAD", 4))
|
||||
{
|
||||
if(strncmp(header.identification, "PWAD", 4))
|
||||
{ // Bad file id
|
||||
I_Error("Wad file %s doesn't have IWAD or PWAD id\n",
|
||||
filename);
|
||||
}
|
||||
}
|
||||
header.numlumps = LONG(header.numlumps);
|
||||
header.infotableofs = LONG(header.infotableofs);
|
||||
length = header.numlumps*sizeof(filelump_t);
|
||||
// fileinfo = alloca(length);
|
||||
if(!(fileinfo = malloc(length)))
|
||||
{
|
||||
I_Error("W_AddFile: fileinfo malloc failed\n");
|
||||
}
|
||||
freeFileInfo = fileinfo;
|
||||
lseek(handle, header.infotableofs, SEEK_SET);
|
||||
read(handle, fileinfo, length);
|
||||
numlumps += header.numlumps;
|
||||
}
|
||||
|
||||
// Fill in lumpinfo
|
||||
lumpinfo = realloc(lumpinfo, numlumps*sizeof(lumpinfo_t));
|
||||
if(!lumpinfo)
|
||||
{
|
||||
I_Error("Couldn't realloc lumpinfo");
|
||||
}
|
||||
lump_p = &lumpinfo[startlump];
|
||||
for(i = startlump; i < numlumps; i++, lump_p++, fileinfo++)
|
||||
{
|
||||
lump_p->handle = handle;
|
||||
lump_p->position = LONG(fileinfo->filepos);
|
||||
lump_p->size = LONG(fileinfo->size);
|
||||
strncpy(lump_p->name, fileinfo->name, 8);
|
||||
}
|
||||
if(freeFileInfo)
|
||||
{
|
||||
free(freeFileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_InitMultipleFiles
|
||||
//
|
||||
// Pass a null terminated list of files to use. All files are optional,
|
||||
// but at least one file must be found. Lump names can appear multiple
|
||||
// times. The name searcher looks backwards, so a later file can
|
||||
// override an earlier one.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void W_InitMultipleFiles(char **filenames)
|
||||
{
|
||||
int size;
|
||||
|
||||
// Open all the files, load headers, and count lumps
|
||||
numlumps = 0;
|
||||
lumpinfo = malloc(1); // Will be realloced as lumps are added
|
||||
|
||||
for(; *filenames; filenames++)
|
||||
{
|
||||
W_AddFile(*filenames);
|
||||
}
|
||||
if(!numlumps)
|
||||
{
|
||||
I_Error("W_InitMultipleFiles: no files found");
|
||||
}
|
||||
|
||||
// Set up caching
|
||||
size = numlumps*sizeof(*lumpcache);
|
||||
lumpcache = malloc(size);
|
||||
if(!lumpcache)
|
||||
{
|
||||
I_Error("Couldn't allocate lumpcache");
|
||||
}
|
||||
memset(lumpcache, 0, size);
|
||||
|
||||
PrimaryLumpInfo = lumpinfo;
|
||||
PrimaryLumpCache = lumpcache;
|
||||
PrimaryNumLumps = numlumps;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_InitFile
|
||||
//
|
||||
// Initialize the primary from a single file.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void W_InitFile(char *filename)
|
||||
{
|
||||
char *names[2];
|
||||
|
||||
names[0] = filename;
|
||||
names[1] = NULL;
|
||||
W_InitMultipleFiles(names);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_OpenAuxiliary
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void W_OpenAuxiliary(char *filename)
|
||||
{
|
||||
int i;
|
||||
int size;
|
||||
wadinfo_t header;
|
||||
int handle;
|
||||
int length;
|
||||
filelump_t *fileinfo;
|
||||
filelump_t *sourceLump;
|
||||
lumpinfo_t *destLump;
|
||||
|
||||
if(AuxiliaryOpened)
|
||||
{
|
||||
W_CloseAuxiliary();
|
||||
}
|
||||
if((handle = open(filename, O_RDONLY|O_BINARY)) == -1)
|
||||
{
|
||||
I_Error("W_OpenAuxiliary: %s not found.", filename);
|
||||
return;
|
||||
}
|
||||
AuxiliaryHandle = handle;
|
||||
read(handle, &header, sizeof(header));
|
||||
if(strncmp(header.identification, "IWAD", 4))
|
||||
{
|
||||
if(strncmp(header.identification, "PWAD", 4))
|
||||
{ // Bad file id
|
||||
I_Error("Wad file %s doesn't have IWAD or PWAD id\n",
|
||||
filename);
|
||||
}
|
||||
}
|
||||
header.numlumps = LONG(header.numlumps);
|
||||
header.infotableofs = LONG(header.infotableofs);
|
||||
length = header.numlumps*sizeof(filelump_t);
|
||||
fileinfo = Z_Malloc(length, PU_STATIC, 0);
|
||||
lseek(handle, header.infotableofs, SEEK_SET);
|
||||
read(handle, fileinfo, length);
|
||||
numlumps = header.numlumps;
|
||||
|
||||
// Init the auxiliary lumpinfo array
|
||||
lumpinfo = Z_Malloc(numlumps*sizeof(lumpinfo_t), PU_STATIC, 0);
|
||||
sourceLump = fileinfo;
|
||||
destLump = lumpinfo;
|
||||
for(i = 0; i < numlumps; i++, destLump++, sourceLump++)
|
||||
{
|
||||
destLump->handle = handle;
|
||||
destLump->position = LONG(sourceLump->filepos);
|
||||
destLump->size = LONG(sourceLump->size);
|
||||
strncpy(destLump->name, sourceLump->name, 8);
|
||||
}
|
||||
Z_Free(fileinfo);
|
||||
|
||||
// Allocate the auxiliary lumpcache array
|
||||
size = numlumps*sizeof(*lumpcache);
|
||||
lumpcache = Z_Malloc(size, PU_STATIC, 0);
|
||||
memset(lumpcache, 0, size);
|
||||
|
||||
AuxiliaryLumpInfo = lumpinfo;
|
||||
AuxiliaryLumpCache = lumpcache;
|
||||
AuxiliaryNumLumps = numlumps;
|
||||
AuxiliaryOpened = true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_CloseAuxiliary
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void W_CloseAuxiliary(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(AuxiliaryOpened)
|
||||
{
|
||||
W_UseAuxiliary();
|
||||
for(i = 0; i < numlumps; i++)
|
||||
{
|
||||
if(lumpcache[i])
|
||||
{
|
||||
Z_Free(lumpcache[i]);
|
||||
}
|
||||
}
|
||||
Z_Free(AuxiliaryLumpInfo);
|
||||
Z_Free(AuxiliaryLumpCache);
|
||||
W_CloseAuxiliaryFile();
|
||||
AuxiliaryOpened = false;
|
||||
}
|
||||
W_UsePrimary();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_CloseAuxiliaryFile
|
||||
//
|
||||
// WARNING: W_CloseAuxiliary() must be called before any further
|
||||
// auxiliary lump processing.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void W_CloseAuxiliaryFile(void)
|
||||
{
|
||||
if(AuxiliaryHandle)
|
||||
{
|
||||
close(AuxiliaryHandle);
|
||||
AuxiliaryHandle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_UsePrimary
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void W_UsePrimary(void)
|
||||
{
|
||||
lumpinfo = PrimaryLumpInfo;
|
||||
numlumps = PrimaryNumLumps;
|
||||
lumpcache = PrimaryLumpCache;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_UseAuxiliary
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void W_UseAuxiliary(void)
|
||||
{
|
||||
if(AuxiliaryOpened == false)
|
||||
{
|
||||
I_Error("W_UseAuxiliary: WAD not opened.");
|
||||
}
|
||||
lumpinfo = AuxiliaryLumpInfo;
|
||||
numlumps = AuxiliaryNumLumps;
|
||||
lumpcache = AuxiliaryLumpCache;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_NumLumps
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int W_NumLumps(void)
|
||||
{
|
||||
return numlumps;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_CheckNumForName
|
||||
//
|
||||
// Returns -1 if name not found.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int W_CheckNumForName(char *name)
|
||||
{
|
||||
char name8[9];
|
||||
int v1, v2;
|
||||
lumpinfo_t *lump_p;
|
||||
|
||||
// Make the name into two integers for easy compares
|
||||
strncpy(name8, name, 8);
|
||||
name8[8] = 0; // in case the name was a full 8 chars
|
||||
strupr(name8); // case insensitive
|
||||
v1 = *(int *)name8;
|
||||
v2 = *(int *)&name8[4];
|
||||
|
||||
// Scan backwards so patch lump files take precedence
|
||||
lump_p = lumpinfo+numlumps;
|
||||
while(lump_p-- != lumpinfo)
|
||||
{
|
||||
if(*(int *)lump_p->name == v1 && *(int *)&lump_p->name[4] == v2)
|
||||
{
|
||||
return lump_p-lumpinfo;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_GetNumForName
|
||||
//
|
||||
// Calls W_CheckNumForName, but bombs out if not found.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int W_GetNumForName (char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = W_CheckNumForName(name);
|
||||
if(i != -1)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
I_Error("W_GetNumForName: %s not found!", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_LumpLength
|
||||
//
|
||||
// Returns the buffer size needed to load the given lump.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int W_LumpLength(int lump)
|
||||
{
|
||||
if(lump >= numlumps)
|
||||
{
|
||||
I_Error("W_LumpLength: %i >= numlumps", lump);
|
||||
}
|
||||
return lumpinfo[lump].size;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_ReadLump
|
||||
//
|
||||
// Loads the lump into the given buffer, which must be >= W_LumpLength().
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void W_ReadLump(int lump, void *dest)
|
||||
{
|
||||
int c;
|
||||
lumpinfo_t *l;
|
||||
|
||||
if(lump >= numlumps)
|
||||
{
|
||||
I_Error("W_ReadLump: %i >= numlumps", lump);
|
||||
}
|
||||
l = lumpinfo+lump;
|
||||
//I_BeginRead();
|
||||
lseek(l->handle, l->position, SEEK_SET);
|
||||
c = read(l->handle, dest, l->size);
|
||||
if(c < l->size)
|
||||
{
|
||||
I_Error("W_ReadLump: only read %i of %i on lump %i",
|
||||
c, l->size, lump);
|
||||
}
|
||||
//I_EndRead();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_CacheLumpNum
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void *W_CacheLumpNum(int lump, int tag)
|
||||
{
|
||||
byte *ptr;
|
||||
|
||||
if((unsigned)lump >= numlumps)
|
||||
{
|
||||
I_Error("W_CacheLumpNum: %i >= numlumps", lump);
|
||||
}
|
||||
if(!lumpcache[lump])
|
||||
{ // Need to read the lump in
|
||||
ptr = Z_Malloc(W_LumpLength(lump), tag, &lumpcache[lump]);
|
||||
W_ReadLump(lump, lumpcache[lump]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Z_ChangeTag(lumpcache[lump], tag);
|
||||
}
|
||||
return lumpcache[lump];
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_CacheLumpName
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void *W_CacheLumpName(char *name, int tag)
|
||||
{
|
||||
return W_CacheLumpNum(W_GetNumForName(name), tag);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// W_Profile
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
// Ripped out for Heretic
|
||||
/*
|
||||
int info[2500][10];
|
||||
int profilecount;
|
||||
|
||||
void W_Profile (void)
|
||||
{
|
||||
int i;
|
||||
memblock_t *block;
|
||||
void *ptr;
|
||||
char ch;
|
||||
FILE *f;
|
||||
int j;
|
||||
char name[9];
|
||||
|
||||
|
||||
for (i=0 ; i<numlumps ; i++)
|
||||
{
|
||||
ptr = lumpcache[i];
|
||||
if (!ptr)
|
||||
{
|
||||
ch = ' ';
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
|
||||
if (block->tag < PU_PURGELEVEL)
|
||||
ch = 'S';
|
||||
else
|
||||
ch = 'P';
|
||||
}
|
||||
info[i][profilecount] = ch;
|
||||
}
|
||||
profilecount++;
|
||||
|
||||
f = fopen ("waddump.txt","w");
|
||||
name[8] = 0;
|
||||
for (i=0 ; i<numlumps ; i++)
|
||||
{
|
||||
memcpy (name,lumpinfo[i].name,8);
|
||||
for (j=0 ; j<8 ; j++)
|
||||
if (!name[j])
|
||||
break;
|
||||
for ( ; j<8 ; j++)
|
||||
name[j] = ' ';
|
||||
fprintf (f,"%s ",name);
|
||||
for (j=0 ; j<profilecount ; j++)
|
||||
fprintf (f," %c",info[i][j]);
|
||||
fprintf (f,"\n");
|
||||
}
|
||||
fclose (f);
|
||||
}
|
||||
*/
|
231
Hexen Source/XDDEFS.H
Normal file
231
Hexen Source/XDDEFS.H
Normal file
|
@ -0,0 +1,231 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** xddefs.h : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: xddefs.h,v $
|
||||
//** $Revision: 1.4 $
|
||||
//** $Date: 95/08/11 10:22:08 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#ifndef __XDDEFS__
|
||||
#define __XDDEFS__
|
||||
|
||||
#ifndef __BYTEBOOL__
|
||||
#define __BYTEBOOL__
|
||||
typedef enum {false, true} boolean;
|
||||
typedef unsigned char byte;
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Map level types
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// lump order in a map wad
|
||||
enum
|
||||
{
|
||||
ML_LABEL,
|
||||
ML_THINGS,
|
||||
ML_LINEDEFS,
|
||||
ML_SIDEDEFS,
|
||||
ML_VERTEXES,
|
||||
ML_SEGS,
|
||||
ML_SSECTORS,
|
||||
ML_NODES,
|
||||
ML_SECTORS,
|
||||
ML_REJECT,
|
||||
ML_BLOCKMAP,
|
||||
ML_BEHAVIOR
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short x;
|
||||
short y;
|
||||
} mapvertex_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short textureoffset;
|
||||
short rowoffset;
|
||||
char toptexture[8];
|
||||
char bottomtexture[8];
|
||||
char midtexture[8];
|
||||
short sector; // on viewer's side
|
||||
} mapsidedef_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short v1;
|
||||
short v2;
|
||||
short flags;
|
||||
byte special;
|
||||
byte arg1;
|
||||
byte arg2;
|
||||
byte arg3;
|
||||
byte arg4;
|
||||
byte arg5;
|
||||
short sidenum[2]; // sidenum[1] will be -1 if one sided
|
||||
} maplinedef_t;
|
||||
|
||||
#define ML_BLOCKING 0x0001
|
||||
#define ML_BLOCKMONSTERS 0x0002
|
||||
#define ML_TWOSIDED 0x0004
|
||||
#define ML_DONTPEGTOP 0x0008
|
||||
#define ML_DONTPEGBOTTOM 0x0010
|
||||
#define ML_SECRET 0x0020 // don't map as two sided: IT'S A SECRET!
|
||||
#define ML_SOUNDBLOCK 0x0040 // don't let sound cross two of these
|
||||
#define ML_DONTDRAW 0x0080 // don't draw on the automap
|
||||
#define ML_MAPPED 0x0100 // set if already drawn in automap
|
||||
#define ML_REPEAT_SPECIAL 0x0200 // special is repeatable
|
||||
#define ML_SPAC_SHIFT 10
|
||||
#define ML_SPAC_MASK 0x1c00
|
||||
#define GET_SPAC(flags) ((flags&ML_SPAC_MASK)>>ML_SPAC_SHIFT)
|
||||
|
||||
// Special activation types
|
||||
#define SPAC_CROSS 0 // when player crosses line
|
||||
#define SPAC_USE 1 // when player uses line
|
||||
#define SPAC_MCROSS 2 // when monster crosses line
|
||||
#define SPAC_IMPACT 3 // when projectile hits line
|
||||
#define SPAC_PUSH 4 // when player/monster pushes line
|
||||
#define SPAC_PCROSS 5 // when projectile crosses line
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short floorheight;
|
||||
short ceilingheight;
|
||||
char floorpic[8];
|
||||
char ceilingpic[8];
|
||||
short lightlevel;
|
||||
short special;
|
||||
short tag;
|
||||
} mapsector_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short numsegs;
|
||||
short firstseg; // segs are stored sequentially
|
||||
} mapsubsector_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short v1;
|
||||
short v2;
|
||||
short angle;
|
||||
short linedef;
|
||||
short side;
|
||||
short offset;
|
||||
} mapseg_t;
|
||||
|
||||
enum
|
||||
{ // bbox coordinates
|
||||
BOXTOP,
|
||||
BOXBOTTOM,
|
||||
BOXLEFT,
|
||||
BOXRIGHT
|
||||
};
|
||||
|
||||
#define NF_SUBSECTOR 0x8000
|
||||
typedef struct
|
||||
{
|
||||
short x,y,dx,dy; // partition line
|
||||
short bbox[2][4]; // bounding box for each child
|
||||
unsigned short children[2]; // if NF_SUBSECTOR its a subsector
|
||||
} mapnode_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short tid;
|
||||
short x;
|
||||
short y;
|
||||
short height;
|
||||
short angle;
|
||||
short type;
|
||||
short options;
|
||||
byte special;
|
||||
byte arg1;
|
||||
byte arg2;
|
||||
byte arg3;
|
||||
byte arg4;
|
||||
byte arg5;
|
||||
} mapthing_t;
|
||||
|
||||
#define MTF_EASY 1
|
||||
#define MTF_NORMAL 2
|
||||
#define MTF_HARD 4
|
||||
#define MTF_AMBUSH 8
|
||||
#define MTF_DORMANT 16
|
||||
#define MTF_FIGHTER 32
|
||||
#define MTF_CLERIC 64
|
||||
#define MTF_MAGE 128
|
||||
#define MTF_GSINGLE 256
|
||||
#define MTF_GCOOP 512
|
||||
#define MTF_GDEATHMATCH 1024
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Texture definition
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short originx;
|
||||
short originy;
|
||||
short patch;
|
||||
short stepdir;
|
||||
short colormap;
|
||||
} mappatch_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[8];
|
||||
boolean masked;
|
||||
short width;
|
||||
short height;
|
||||
void **columndirectory; // OBSOLETE
|
||||
short patchcount;
|
||||
mappatch_t patches[1];
|
||||
} maptexture_t;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Graphics
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// posts are runs of non masked source pixels
|
||||
typedef struct
|
||||
{
|
||||
byte topdelta; // -1 is the last post in a column
|
||||
byte length;
|
||||
// length data bytes follows
|
||||
} post_t;
|
||||
|
||||
// column_t is a list of 0 or more post_t, (byte)-1 terminated
|
||||
typedef post_t column_t;
|
||||
|
||||
// a patch holds one or more columns
|
||||
// patches are used for sprites and all masked pictures
|
||||
typedef struct
|
||||
{
|
||||
short width; // bounding box size
|
||||
short height;
|
||||
short leftoffset; // pixels to the left of origin
|
||||
short topoffset; // pixels below the origin
|
||||
int columnofs[8]; // only [width] used
|
||||
// the [0] is &columnofs[width]
|
||||
} patch_t;
|
||||
|
||||
// a pic is an unmasked block of pixels
|
||||
typedef struct
|
||||
{
|
||||
byte width,height;
|
||||
byte data;
|
||||
} pic_t;
|
||||
|
||||
#endif // __XDDEFS__
|
396
Hexen Source/Z_ZONE.C
Normal file
396
Hexen Source/Z_ZONE.C
Normal file
|
@ -0,0 +1,396 @@
|
|||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** z_zone.c : Heretic 2 : Raven Software, Corp.
|
||||
//**
|
||||
//** $RCSfile: z_zone.c,v $
|
||||
//** $Revision: 1.2 $
|
||||
//** $Date: 96/01/06 03:23:53 $
|
||||
//** $Author: bgokey $
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "h2def.h"
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
ZONE MEMORY ALLOCATION
|
||||
|
||||
There is never any space between memblocks, and there will never be two
|
||||
contiguous free memblocks.
|
||||
|
||||
The rover can be left pointing at a non-empty block
|
||||
|
||||
It is of no value to free a cachable block, because it will get overwritten
|
||||
automatically if needed
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#define ZONEID 0x1d4a11
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int size; // total bytes malloced, including header
|
||||
memblock_t blocklist; // start / end cap for linked list
|
||||
memblock_t *rover;
|
||||
} memzone_t;
|
||||
|
||||
memzone_t *mainzone;
|
||||
|
||||
/*
|
||||
========================
|
||||
=
|
||||
= Z_ClearZone
|
||||
=
|
||||
========================
|
||||
*/
|
||||
|
||||
/*
|
||||
void Z_ClearZone (memzone_t *zone)
|
||||
{
|
||||
memblock_t *block;
|
||||
|
||||
// set the entire zone to one free block
|
||||
|
||||
zone->blocklist.next = zone->blocklist.prev = block =
|
||||
(memblock_t *)( (byte *)zone + sizeof(memzone_t) );
|
||||
zone->blocklist.user = (void *)zone;
|
||||
zone->blocklist.tag = PU_STATIC;
|
||||
zone->rover = block;
|
||||
|
||||
block->prev = block->next = &zone->blocklist;
|
||||
block->user = NULL; // free block
|
||||
block->size = zone->size - sizeof(memzone_t);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
=
|
||||
= Z_Init
|
||||
=
|
||||
========================
|
||||
*/
|
||||
|
||||
void Z_Init (void)
|
||||
{
|
||||
memblock_t *block;
|
||||
int size;
|
||||
|
||||
mainzone = (memzone_t *)I_ZoneBase (&size);
|
||||
mainzone->size = size;
|
||||
|
||||
// set the entire zone to one free block
|
||||
|
||||
mainzone->blocklist.next = mainzone->blocklist.prev = block =
|
||||
(memblock_t *)( (byte *)mainzone + sizeof(memzone_t) );
|
||||
mainzone->blocklist.user = (void *)mainzone;
|
||||
mainzone->blocklist.tag = PU_STATIC;
|
||||
mainzone->rover = block;
|
||||
|
||||
block->prev = block->next = &mainzone->blocklist;
|
||||
block->user = NULL; // free block
|
||||
block->size = mainzone->size - sizeof(memzone_t);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
=
|
||||
= Z_Free
|
||||
=
|
||||
========================
|
||||
*/
|
||||
|
||||
void Z_Free (void *ptr)
|
||||
{
|
||||
memblock_t *block, *other;
|
||||
|
||||
block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
|
||||
if (block->id != ZONEID)
|
||||
I_Error ("Z_Free: freed a pointer without ZONEID");
|
||||
|
||||
if (block->user > (void **)0x100) // smaller values are not pointers
|
||||
*block->user = 0; // clear the user's mark
|
||||
block->user = NULL; // mark as free
|
||||
block->tag = 0;
|
||||
block->id = 0;
|
||||
|
||||
other = block->prev;
|
||||
if (!other->user)
|
||||
{ // merge with previous free block
|
||||
other->size += block->size;
|
||||
other->next = block->next;
|
||||
other->next->prev = other;
|
||||
if (block == mainzone->rover)
|
||||
mainzone->rover = other;
|
||||
block = other;
|
||||
}
|
||||
|
||||
other = block->next;
|
||||
if (!other->user)
|
||||
{ // merge the next free block onto the end
|
||||
block->size += other->size;
|
||||
block->next = other->next;
|
||||
block->next->prev = block;
|
||||
if (other == mainzone->rover)
|
||||
mainzone->rover = block;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
=
|
||||
= Z_Malloc
|
||||
=
|
||||
= You can pass a NULL user if the tag is < PU_PURGELEVEL
|
||||
========================
|
||||
*/
|
||||
|
||||
#define MINFRAGMENT 64
|
||||
|
||||
void *Z_Malloc (int size, int tag, void *user)
|
||||
{
|
||||
int extra;
|
||||
memblock_t *start, *rover, *new, *base;
|
||||
|
||||
//
|
||||
// scan through the block list looking for the first free block
|
||||
// of sufficient size, throwing out any purgable blocks along the way
|
||||
//
|
||||
size += sizeof(memblock_t); // account for size of block header
|
||||
|
||||
|
||||
//
|
||||
// if there is a free block behind the rover, back up over them
|
||||
//
|
||||
base = mainzone->rover;
|
||||
if (!base->prev->user)
|
||||
base = base->prev;
|
||||
|
||||
rover = base;
|
||||
start = base->prev;
|
||||
|
||||
do
|
||||
{
|
||||
if (rover == start) // scaned all the way around the list
|
||||
I_Error ("Z_Malloc: failed on allocation of %i bytes",size);
|
||||
if (rover->user)
|
||||
{
|
||||
if (rover->tag < PU_PURGELEVEL)
|
||||
// hit a block that can't be purged, so move base past it
|
||||
base = rover = rover->next;
|
||||
else
|
||||
{
|
||||
// free the rover block (adding the size to base)
|
||||
base = base->prev; // the rover can be the base block
|
||||
Z_Free ((byte *)rover+sizeof(memblock_t));
|
||||
base = base->next;
|
||||
rover = base->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
rover = rover->next;
|
||||
} while (base->user || base->size < size);
|
||||
|
||||
//
|
||||
// found a block big enough
|
||||
//
|
||||
extra = base->size - size;
|
||||
if (extra > MINFRAGMENT)
|
||||
{ // there will be a free fragment after the allocated block
|
||||
new = (memblock_t *) ((byte *)base + size );
|
||||
new->size = extra;
|
||||
new->user = NULL; // free block
|
||||
new->tag = 0;
|
||||
new->prev = base;
|
||||
new->next = base->next;
|
||||
new->next->prev = new;
|
||||
base->next = new;
|
||||
base->size = size;
|
||||
}
|
||||
|
||||
if (user)
|
||||
{
|
||||
base->user = user; // mark as an in use block
|
||||
*(void **)user = (void *) ((byte *)base + sizeof(memblock_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tag >= PU_PURGELEVEL)
|
||||
I_Error ("Z_Malloc: an owner is required for purgable blocks");
|
||||
base->user = (void *)2; // mark as in use, but unowned
|
||||
}
|
||||
base->tag = tag;
|
||||
|
||||
mainzone->rover = base->next; // next allocation will start looking here
|
||||
|
||||
base->id = ZONEID;
|
||||
return (void *) ((byte *)base + sizeof(memblock_t));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
=
|
||||
= Z_FreeTags
|
||||
=
|
||||
========================
|
||||
*/
|
||||
|
||||
void Z_FreeTags (int lowtag, int hightag)
|
||||
{
|
||||
memblock_t *block, *next;
|
||||
|
||||
for (block = mainzone->blocklist.next ; block != &mainzone->blocklist
|
||||
; block = next)
|
||||
{
|
||||
next = block->next; // get link before freeing
|
||||
if (!block->user)
|
||||
continue; // free block
|
||||
if (block->tag >= lowtag && block->tag <= hightag)
|
||||
Z_Free ( (byte *)block+sizeof(memblock_t));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
=
|
||||
= Z_DumpHeap
|
||||
=
|
||||
========================
|
||||
*/
|
||||
|
||||
/*
|
||||
void Z_DumpHeap (int lowtag, int hightag)
|
||||
{
|
||||
memblock_t *block;
|
||||
|
||||
printf ("zone size: %i location: %p\n",mainzone->size,mainzone);
|
||||
printf ("tag range: %i to %i\n",lowtag, hightag);
|
||||
|
||||
for (block = mainzone->blocklist.next ; ; block = block->next)
|
||||
{
|
||||
if (block->tag >= lowtag && block->tag <= hightag)
|
||||
printf ("block:%p size:%7i user:%p tag:%3i\n",
|
||||
block, block->size, block->user, block->tag);
|
||||
|
||||
if (block->next == &mainzone->blocklist)
|
||||
break; // all blocks have been hit
|
||||
if ( (byte *)block + block->size != (byte *)block->next)
|
||||
printf ("ERROR: block size does not touch the next block\n");
|
||||
if ( block->next->prev != block)
|
||||
printf ("ERROR: next block doesn't have proper back link\n");
|
||||
if (!block->user && !block->next->user)
|
||||
printf ("ERROR: two consecutive free blocks\n");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
========================
|
||||
=
|
||||
= Z_FileDumpHeap
|
||||
=
|
||||
========================
|
||||
*/
|
||||
|
||||
/*
|
||||
void Z_FileDumpHeap (FILE *f)
|
||||
{
|
||||
memblock_t *block;
|
||||
|
||||
fprintf (f,"zone size: %i location: %p\n",mainzone->size,mainzone);
|
||||
|
||||
for (block = mainzone->blocklist.next ; ; block = block->next)
|
||||
{
|
||||
fprintf (f,"block:%p size:%7i user:%p tag:%3i\n",
|
||||
block, block->size, block->user, block->tag);
|
||||
|
||||
if (block->next == &mainzone->blocklist)
|
||||
break; // all blocks have been hit
|
||||
if ( (byte *)block + block->size != (byte *)block->next)
|
||||
fprintf (f,"ERROR: block size does not touch the next block\n");
|
||||
if ( block->next->prev != block)
|
||||
fprintf (f,"ERROR: next block doesn't have proper back link\n");
|
||||
if (!block->user && !block->next->user)
|
||||
fprintf (f,"ERROR: two consecutive free blocks\n");
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
========================
|
||||
=
|
||||
= Z_CheckHeap
|
||||
=
|
||||
========================
|
||||
*/
|
||||
|
||||
void Z_CheckHeap (void)
|
||||
{
|
||||
memblock_t *block;
|
||||
|
||||
for (block = mainzone->blocklist.next ; ; block = block->next)
|
||||
{
|
||||
if (block->next == &mainzone->blocklist)
|
||||
break; // all blocks have been hit
|
||||
if ( (byte *)block + block->size != (byte *)block->next)
|
||||
I_Error ("Z_CheckHeap: block size does not touch the next block\n");
|
||||
if ( block->next->prev != block)
|
||||
I_Error ("Z_CheckHeap: next block doesn't have proper back link\n");
|
||||
if (!block->user && !block->next->user)
|
||||
I_Error ("Z_CheckHeap: two consecutive free blocks\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
=
|
||||
= Z_ChangeTag
|
||||
=
|
||||
========================
|
||||
*/
|
||||
|
||||
void Z_ChangeTag2 (void *ptr, int tag)
|
||||
{
|
||||
memblock_t *block;
|
||||
|
||||
block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t));
|
||||
if (block->id != ZONEID)
|
||||
I_Error ("Z_ChangeTag: freed a pointer without ZONEID");
|
||||
if (tag >= PU_PURGELEVEL && (unsigned)block->user < 0x100)
|
||||
I_Error ("Z_ChangeTag: an owner is required for purgable blocks");
|
||||
block->tag = tag;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
========================
|
||||
=
|
||||
= Z_FreeMemory
|
||||
=
|
||||
========================
|
||||
*/
|
||||
|
||||
/*
|
||||
int Z_FreeMemory (void)
|
||||
{
|
||||
memblock_t *block;
|
||||
int free;
|
||||
|
||||
free = 0;
|
||||
for (block = mainzone->blocklist.next ; block != &mainzone->blocklist
|
||||
; block = block->next)
|
||||
if (!block->user || block->tag >= PU_PURGELEVEL)
|
||||
free += block->size;
|
||||
return free;
|
||||
}
|
||||
*/
|
339
LICENSE.txt
Normal file
339
LICENSE.txt
Normal file
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
7
SourceReadme.txt
Normal file
7
SourceReadme.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
Activision and Raven are releasing this code for people to learn from and play with.
|
||||
This code is copyright Activision 1996-1998
|
||||
[edit 2 Sep 2008] The code is release under GNU GPLv2 (see LICENSE)
|
||||
|
||||
Issues:
|
||||
The DMX sound library is not included with the source due to license issues,
|
||||
so you won't be able to link until those sound calls are replaced or removed.
|
Loading…
Reference in a new issue