Changed vec4_t down to vec3_t, got the server browser integrated with the menu.dat. csqc is having fun, and nexuiz should work better. Enjoy.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1011 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
a366a4d90a
commit
e348dc30a2
44 changed files with 2031 additions and 1159 deletions
|
@ -482,9 +482,9 @@ void CL_ParsePacketEntities (qboolean delta)
|
|||
|
||||
if ((from & UPDATE_MASK) != (oldpacket & UPDATE_MASK)) {
|
||||
Con_DPrintf ("WARNING: from mismatch\n");
|
||||
FlushEntityPacket ();
|
||||
cl.validsequence = 0;
|
||||
return;
|
||||
// FlushEntityPacket ();
|
||||
// cl.validsequence = 0;
|
||||
// return;
|
||||
}
|
||||
|
||||
if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP - 1) {
|
||||
|
@ -1502,7 +1502,7 @@ void CL_LinkPacketEntities (void)
|
|||
a1 -= 360;
|
||||
if (a1 - a2 < -180)
|
||||
a1 += 360;
|
||||
angles[i] = a2 + f * (a1 - a2);
|
||||
angles[i] = a1 + f * (a2 - a1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1516,7 +1516,11 @@ void CL_LinkPacketEntities (void)
|
|||
CL_RotateAroundTag(ent, s1->number, cl.lerpents[s1->number].tagent, cl.lerpents[s1->number].tagindex);
|
||||
}
|
||||
|
||||
if (ent->keynum <= MAX_CLIENTS && cls.demoplayback != DPB_NETQUAKE && (!cls.netcon || cls.netcon->qwprotocol))
|
||||
if (ent->keynum <= MAX_CLIENTS
|
||||
#ifdef NQPROT
|
||||
&& cls.demoplayback != DPB_NETQUAKE && (!cls.netcon || cls.netcon->qwprotocol)
|
||||
#endif
|
||||
)
|
||||
ent->keynum += MAX_EDICTS;
|
||||
|
||||
// add automatic particle trails
|
||||
|
|
|
@ -1456,6 +1456,131 @@ static char *VARGS vahunk(char *format, ...)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void CL_RegisterSplitCommands(void)
|
||||
{
|
||||
static int oldsplit;
|
||||
char spn[8];
|
||||
int sp;
|
||||
for (sp = 0; sp < MAX_SPLITS; sp++)
|
||||
{
|
||||
if (sp)
|
||||
sprintf(spn, "%i", sp+1);
|
||||
else
|
||||
*spn = '\0';
|
||||
if (sp < cl.splitclients)
|
||||
{
|
||||
if (oldsplit & (1<<sp))
|
||||
continue;
|
||||
oldsplit |= (1<<sp);
|
||||
|
||||
Cmd_AddRemCommand (vahunk("+moveup%s", spn), IN_UpDown);
|
||||
Cmd_AddRemCommand (vahunk("-moveup%s", spn), IN_UpUp);
|
||||
Cmd_AddRemCommand (vahunk("+movedown%s", spn), IN_DownDown);
|
||||
Cmd_AddRemCommand (vahunk("-movedown%s", spn), IN_DownUp);
|
||||
Cmd_AddRemCommand (vahunk("+left%s", spn), IN_LeftDown);
|
||||
Cmd_AddRemCommand (vahunk("-left%s", spn), IN_LeftUp);
|
||||
Cmd_AddRemCommand (vahunk("+right%s", spn), IN_RightDown);
|
||||
Cmd_AddRemCommand (vahunk("-right%s", spn), IN_RightUp);
|
||||
Cmd_AddRemCommand (vahunk("+forward%s", spn), IN_ForwardDown);
|
||||
Cmd_AddRemCommand (vahunk("-forward%s", spn), IN_ForwardUp);
|
||||
Cmd_AddRemCommand (vahunk("+back%s", spn), IN_BackDown);
|
||||
Cmd_AddRemCommand (vahunk("-back%s", spn), IN_BackUp);
|
||||
Cmd_AddRemCommand (vahunk("+lookup%s", spn), IN_LookupDown);
|
||||
Cmd_AddRemCommand (vahunk("-lookup%s", spn), IN_LookupUp);
|
||||
Cmd_AddRemCommand (vahunk("+lookdown%s", spn), IN_LookdownDown);
|
||||
Cmd_AddRemCommand (vahunk("-lookdown%s", spn), IN_LookdownUp);
|
||||
Cmd_AddRemCommand (vahunk("+strafe%s", spn), IN_StrafeDown);
|
||||
Cmd_AddRemCommand (vahunk("-strafe%s", spn), IN_StrafeUp);
|
||||
Cmd_AddRemCommand (vahunk("+moveleft%s", spn), IN_MoveleftDown);
|
||||
Cmd_AddRemCommand (vahunk("-moveleft%s", spn), IN_MoveleftUp);
|
||||
Cmd_AddRemCommand (vahunk("+moveright%s", spn), IN_MoverightDown);
|
||||
Cmd_AddRemCommand (vahunk("-moveright%s", spn), IN_MoverightUp);
|
||||
Cmd_AddRemCommand (vahunk("+speed%s", spn), IN_SpeedDown);
|
||||
Cmd_AddRemCommand (vahunk("-speed%s", spn), IN_SpeedUp);
|
||||
Cmd_AddRemCommand (vahunk("+attack%s", spn), IN_AttackDown);
|
||||
Cmd_AddRemCommand (vahunk("-attack%s", spn), IN_AttackUp);
|
||||
Cmd_AddRemCommand (vahunk("+use%s", spn), IN_UseDown);
|
||||
Cmd_AddRemCommand (vahunk("-use%s", spn), IN_UseUp);
|
||||
Cmd_AddRemCommand (vahunk("+jump%s", spn), IN_JumpDown);
|
||||
Cmd_AddRemCommand (vahunk("-jump%s", spn), IN_JumpUp);
|
||||
Cmd_AddRemCommand (vahunk("impulse%s", spn), IN_Impulse);
|
||||
Cmd_AddRemCommand (vahunk("+klook%s", spn), IN_KLookDown);
|
||||
Cmd_AddRemCommand (vahunk("-klook%s", spn), IN_KLookUp);
|
||||
Cmd_AddRemCommand (vahunk("+mlook%s", spn), IN_MLookDown);
|
||||
Cmd_AddRemCommand (vahunk("-mlook%s", spn), IN_MLookUp);
|
||||
|
||||
|
||||
Cmd_AddRemCommand (vahunk("+button3%s", spn), IN_Button3Down);
|
||||
Cmd_AddRemCommand (vahunk("-button3%s", spn), IN_Button3Up);
|
||||
Cmd_AddRemCommand (vahunk("+button4%s", spn), IN_Button4Down);
|
||||
Cmd_AddRemCommand (vahunk("-button4%s", spn), IN_Button4Up);
|
||||
Cmd_AddRemCommand (vahunk("+button5%s", spn), IN_Button5Down);
|
||||
Cmd_AddRemCommand (vahunk("-button5%s", spn), IN_Button5Up);
|
||||
Cmd_AddRemCommand (vahunk("+button6%s", spn), IN_Button6Down);
|
||||
Cmd_AddRemCommand (vahunk("-button6%s", spn), IN_Button6Up);
|
||||
Cmd_AddRemCommand (vahunk("+button7%s", spn), IN_Button7Down);
|
||||
Cmd_AddRemCommand (vahunk("-button7%s", spn), IN_Button7Up);
|
||||
Cmd_AddRemCommand (vahunk("+button8%s", spn), IN_Button8Down);
|
||||
Cmd_AddRemCommand (vahunk("-button8%s", spn), IN_Button8Up);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(oldsplit & (1<<sp)))
|
||||
continue;
|
||||
oldsplit &= ~(1<<sp);
|
||||
|
||||
Cmd_RemoveCommand (vahunk("+moveup%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-moveup%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+movedown%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-movedown%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+left%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-left%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+right%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-right%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+forward%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-forward%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+back%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-back%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+lookup%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-lookup%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+lookdown%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-lookdown%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+strafe%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-strafe%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+moveleft%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-moveleft%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+moveright%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-moveright%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+speed%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-speed%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+attack%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-attack%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+use%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-use%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+jump%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-jump%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("impulse%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+klook%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-klook%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+mlook%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-mlook%s", spn));
|
||||
|
||||
|
||||
Cmd_RemoveCommand (vahunk("+button3%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-button3%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+button4%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-button4%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+button5%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-button5%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+button6%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-button6%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+button7%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-button7%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("+button8%s", spn));
|
||||
Cmd_RemoveCommand (vahunk("-button8%s", spn));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
|
@ -1464,72 +1589,8 @@ CL_InitInput
|
|||
*/
|
||||
void CL_InitInput (void)
|
||||
{
|
||||
int sp;
|
||||
char spn[8];
|
||||
qboolean nosplits = COM_CheckParm("-nosplit");
|
||||
#define inputnetworkcvargroup "client networking options"
|
||||
//controls for player2
|
||||
for (sp = MAX_SPLITS-1; sp >=0; sp--)
|
||||
{
|
||||
if (sp)
|
||||
{
|
||||
if (nosplits)
|
||||
continue;
|
||||
sprintf(spn, "%i", sp+1);
|
||||
}
|
||||
else
|
||||
*spn = '\0';
|
||||
|
||||
Cmd_AddCommand (vahunk("+moveup%s", spn), IN_UpDown);
|
||||
Cmd_AddCommand (vahunk("-moveup%s", spn), IN_UpUp);
|
||||
Cmd_AddCommand (vahunk("+movedown%s", spn), IN_DownDown);
|
||||
Cmd_AddCommand (vahunk("-movedown%s", spn), IN_DownUp);
|
||||
Cmd_AddCommand (vahunk("+left%s", spn), IN_LeftDown);
|
||||
Cmd_AddCommand (vahunk("-left%s", spn), IN_LeftUp);
|
||||
Cmd_AddCommand (vahunk("+right%s", spn), IN_RightDown);
|
||||
Cmd_AddCommand (vahunk("-right%s", spn), IN_RightUp);
|
||||
Cmd_AddCommand (vahunk("+forward%s", spn), IN_ForwardDown);
|
||||
Cmd_AddCommand (vahunk("-forward%s", spn), IN_ForwardUp);
|
||||
Cmd_AddCommand (vahunk("+back%s", spn), IN_BackDown);
|
||||
Cmd_AddCommand (vahunk("-back%s", spn), IN_BackUp);
|
||||
Cmd_AddCommand (vahunk("+lookup%s", spn), IN_LookupDown);
|
||||
Cmd_AddCommand (vahunk("-lookup%s", spn), IN_LookupUp);
|
||||
Cmd_AddCommand (vahunk("+lookdown%s", spn), IN_LookdownDown);
|
||||
Cmd_AddCommand (vahunk("-lookdown%s", spn), IN_LookdownUp);
|
||||
Cmd_AddCommand (vahunk("+strafe%s", spn), IN_StrafeDown);
|
||||
Cmd_AddCommand (vahunk("-strafe%s", spn), IN_StrafeUp);
|
||||
Cmd_AddCommand (vahunk("+moveleft%s", spn), IN_MoveleftDown);
|
||||
Cmd_AddCommand (vahunk("-moveleft%s", spn), IN_MoveleftUp);
|
||||
Cmd_AddCommand (vahunk("+moveright%s", spn), IN_MoverightDown);
|
||||
Cmd_AddCommand (vahunk("-moveright%s", spn), IN_MoverightUp);
|
||||
Cmd_AddCommand (vahunk("+speed%s", spn), IN_SpeedDown);
|
||||
Cmd_AddCommand (vahunk("-speed%s", spn), IN_SpeedUp);
|
||||
Cmd_AddCommand (vahunk("+attack%s", spn), IN_AttackDown);
|
||||
Cmd_AddCommand (vahunk("-attack%s", spn), IN_AttackUp);
|
||||
Cmd_AddCommand (vahunk("+use%s", spn), IN_UseDown);
|
||||
Cmd_AddCommand (vahunk("-use%s", spn), IN_UseUp);
|
||||
Cmd_AddCommand (vahunk("+jump%s", spn), IN_JumpDown);
|
||||
Cmd_AddCommand (vahunk("-jump%s", spn), IN_JumpUp);
|
||||
Cmd_AddCommand (vahunk("impulse%s", spn), IN_Impulse);
|
||||
Cmd_AddCommand (vahunk("+klook%s", spn), IN_KLookDown);
|
||||
Cmd_AddCommand (vahunk("-klook%s", spn), IN_KLookUp);
|
||||
Cmd_AddCommand (vahunk("+mlook%s", spn), IN_MLookDown);
|
||||
Cmd_AddCommand (vahunk("-mlook%s", spn), IN_MLookUp);
|
||||
|
||||
|
||||
Cmd_AddCommand (vahunk("+button3%s", spn), IN_Button3Down);
|
||||
Cmd_AddCommand (vahunk("-button3%s", spn), IN_Button3Up);
|
||||
Cmd_AddCommand (vahunk("+button4%s", spn), IN_Button4Down);
|
||||
Cmd_AddCommand (vahunk("-button4%s", spn), IN_Button4Up);
|
||||
Cmd_AddCommand (vahunk("+button5%s", spn), IN_Button5Down);
|
||||
Cmd_AddCommand (vahunk("-button5%s", spn), IN_Button5Up);
|
||||
Cmd_AddCommand (vahunk("+button6%s", spn), IN_Button6Down);
|
||||
Cmd_AddCommand (vahunk("-button6%s", spn), IN_Button6Up);
|
||||
Cmd_AddCommand (vahunk("+button7%s", spn), IN_Button7Down);
|
||||
Cmd_AddCommand (vahunk("-button7%s", spn), IN_Button7Up);
|
||||
Cmd_AddCommand (vahunk("+button8%s", spn), IN_Button8Down);
|
||||
Cmd_AddCommand (vahunk("-button8%s", spn), IN_Button8Up);
|
||||
}
|
||||
CL_RegisterSplitCommands();
|
||||
|
||||
Cmd_AddCommand("rotate", IN_Rotate_f);
|
||||
|
||||
|
|
|
@ -483,6 +483,7 @@ void CL_SendConnectPacket (
|
|||
NET_SendPacket (NS_CLIENT, strlen(data), data, adr);
|
||||
|
||||
cl.splitclients = 0;
|
||||
CL_RegisterSplitCommands();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -18,6 +18,31 @@
|
|||
#define MT_MASTERQ2 8 //query
|
||||
|
||||
|
||||
typedef enum{
|
||||
SLKEY_PING,
|
||||
SLKEY_MAP,
|
||||
SLKEY_NAME,
|
||||
SLKEY_ADDRESS,
|
||||
SLKEY_NUMPLAYERS,
|
||||
SLKEY_MAXPLAYERS,
|
||||
SLKEY_GAMEDIR,
|
||||
|
||||
SLKEY_TOOMANY,
|
||||
SLKEY_CUSTOM
|
||||
} hostcachekey_t;
|
||||
|
||||
typedef enum {
|
||||
SLIST_TEST_CONTAINS,
|
||||
SLIST_TEST_NOTCONTAIN,
|
||||
SLIST_TEST_LESSEQUAL,
|
||||
SLIST_TEST_LESS,
|
||||
SLIST_TEST_EQUAL,
|
||||
SLIST_TEST_GREATER,
|
||||
SLIST_TEST_GREATEREQUAL,
|
||||
SLIST_TEST_NOTEQUAL
|
||||
} slist_test_t;
|
||||
|
||||
|
||||
//contains info about a server in greater detail. Could be too mem intensive.
|
||||
typedef struct serverdetailedinfo_s {
|
||||
char info[MAX_SERVERINFO_STRING];
|
||||
|
@ -41,8 +66,13 @@ typedef struct serverinfo_s {
|
|||
char name[64]; //hostname.
|
||||
netadr_t adr;
|
||||
|
||||
short players;
|
||||
short maxplayers;
|
||||
unsigned char players;
|
||||
unsigned char maxplayers;
|
||||
qbyte special; //flags
|
||||
qbyte sends;
|
||||
qbyte insortedlist;
|
||||
|
||||
unsigned short ping;
|
||||
|
||||
short tl;
|
||||
short fl;
|
||||
|
@ -50,9 +80,6 @@ typedef struct serverinfo_s {
|
|||
char map[8+1];
|
||||
|
||||
float refreshtime;
|
||||
qbyte special; //flags
|
||||
unsigned short ping;
|
||||
int sends;
|
||||
|
||||
serverdetailedinfo_t *moreinfo;
|
||||
|
||||
|
@ -99,3 +126,15 @@ serverinfo_t *Master_InfoForNum (int num);
|
|||
int Master_TotalCount(void);
|
||||
void Master_QueryServer(serverinfo_t *server);
|
||||
void MasterInfo_WriteServers(void);
|
||||
|
||||
int Master_KeyForName(char *keyname);
|
||||
float Master_ReadKeyFloat(serverinfo_t *server, int keynum);
|
||||
char *Master_ReadKeyString(serverinfo_t *server, int keynum);
|
||||
|
||||
void Master_SetSortField(hostcachekey_t field, qboolean descending);
|
||||
hostcachekey_t Master_GetSortField(void);
|
||||
qboolean Master_GetSortDescending(void);
|
||||
|
||||
int Master_NumSorted(void);
|
||||
void Master_ClearMasks(void);
|
||||
serverinfo_t *Master_SortedServer(int idx);
|
||||
|
|
|
@ -1258,6 +1258,7 @@ void CL_ParseServerData (void)
|
|||
cl.frames[i].playerstate[cl.playernum[0]].pm_type = PM_SPECTATOR;
|
||||
|
||||
cl.splitclients = 1;
|
||||
CL_RegisterSplitCommands();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1284,6 +1285,7 @@ void CL_ParseServerData (void)
|
|||
Host_EndGame("Server sent us too many alternate clients\n");
|
||||
}
|
||||
cl.splitclients = clnum+1;
|
||||
CL_RegisterSplitCommands();
|
||||
}
|
||||
|
||||
// get the full level name
|
||||
|
@ -1389,6 +1391,7 @@ void CLQ2_ParseServerData (void)
|
|||
// parse player entity number
|
||||
cl.playernum[0] = MSG_ReadShort ();
|
||||
cl.splitclients = 1;
|
||||
CL_RegisterSplitCommands();
|
||||
cl.spectator = false;
|
||||
|
||||
// get the full level name
|
||||
|
@ -1475,6 +1478,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
|
|||
}
|
||||
|
||||
cl.splitclients = 1;
|
||||
CL_RegisterSplitCommands();
|
||||
|
||||
/*cl.gametype =*/ MSG_ReadByte ();
|
||||
|
||||
|
|
|
@ -935,6 +935,25 @@ void CL_ParseTEnt (void)
|
|||
CLQ2_RailTrail (pos, pos2);
|
||||
break;
|
||||
|
||||
case DPTE_SMOKE:
|
||||
//org
|
||||
pos[0] = MSG_ReadCoord ();
|
||||
pos[0] = MSG_ReadCoord ();
|
||||
pos[0] = MSG_ReadCoord ();
|
||||
|
||||
//dir
|
||||
pos2[0] = MSG_ReadCoord ();
|
||||
pos2[0] = MSG_ReadCoord ();
|
||||
pos2[0] = MSG_ReadCoord ();
|
||||
|
||||
//count
|
||||
cnt = MSG_ReadByte ();
|
||||
{
|
||||
extern int pt_smoke;
|
||||
P_RunParticleEffectType(pos, pos2, cnt, pt_smoke);
|
||||
}
|
||||
break;
|
||||
|
||||
case 79:
|
||||
pos[0] = MSG_ReadCoord ();
|
||||
pos[1] = MSG_ReadCoord ();
|
||||
|
|
|
@ -1213,6 +1213,13 @@ void Key_Event (int key, qboolean down)
|
|||
if (key == K_SHIFT)
|
||||
shift_down = down;
|
||||
|
||||
#ifdef CSQC_DAT
|
||||
//yes, csqc is allowed to steal the escape key.
|
||||
if (key_dest == key_game)
|
||||
if (CSQC_KeyPress(key, down)) //give csqc a chance to handle it.
|
||||
return;
|
||||
#endif
|
||||
|
||||
//
|
||||
// handle escape specialy, so the user can never unbind it
|
||||
//
|
||||
|
@ -1221,14 +1228,10 @@ void Key_Event (int key, qboolean down)
|
|||
#ifdef TEXTEDITOR
|
||||
if (key_dest != key_editor)
|
||||
#endif
|
||||
if (UI_KeyPress(key, down)) //Allow the UI to see the escape key. It is possible that a developer may get stuck at a menu.
|
||||
return;
|
||||
|
||||
#ifdef CSQC_DAT
|
||||
if (key_dest == key_game)
|
||||
if (CSQC_KeyPress(key, down)) //give csqc a chance to handle it.
|
||||
{
|
||||
if (UI_KeyPress(key, down)) //Allow the UI to see the escape key. It is possible that a developer may get stuck at a menu.
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!down)
|
||||
{
|
||||
|
@ -1322,10 +1325,6 @@ void Key_Event (int key, qboolean down)
|
|||
{
|
||||
if (UI_KeyPress(key, down) && down) //UI is allowed to take these keydowns. Keyups are always maintained.
|
||||
return;
|
||||
#ifdef CSQC_DAT
|
||||
if (CSQC_KeyPress(key, down)) //give csqc a chance to handle it.
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -57,6 +57,41 @@ master_t *master;
|
|||
player_t *mplayers;
|
||||
serverinfo_t *firstserver;
|
||||
|
||||
static serverinfo_t **visibleservers;
|
||||
static int numvisibleservers;
|
||||
static int maxvisibleservers;
|
||||
|
||||
static qboolean needsort;
|
||||
|
||||
static hostcachekey_t sortfield;
|
||||
static qboolean decreasingorder;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
hostcachekey_t fieldindex;
|
||||
|
||||
float operandi;
|
||||
char *operands;
|
||||
|
||||
qboolean or;
|
||||
int compareop;
|
||||
} visrules_t;
|
||||
#define MAX_VISRULES 8
|
||||
visrules_t visrules[MAX_VISRULES];
|
||||
int numvisrules;
|
||||
|
||||
|
||||
|
||||
|
||||
#define SLIST_MAXKEYS 64
|
||||
char slist_keyname[SLIST_MAXKEYS][MAX_INFO_KEY];
|
||||
int slist_customkeys;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define POLLUDPSOCKETS 64 //it's big so we can have lots of messages when behind a firewall. Basically if a firewall only allows replys, and only remembers 3 servers per socket, we need this big cos it can take a while for a packet to find a fast optimised route and we might be waiting for a few secs for a reply the first time around.
|
||||
SOCKET pollsocketsUDP[POLLUDPSOCKETS];
|
||||
|
@ -73,6 +108,374 @@ int lastpollsockIPX;
|
|||
|
||||
void NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s);
|
||||
|
||||
void Master_HideServer(serverinfo_t *server)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < numvisibleservers;)
|
||||
{
|
||||
if (visibleservers[i] == server)
|
||||
{
|
||||
for (j = i; j < numvisibleservers-1; j++)
|
||||
visibleservers[j] = visibleservers[j+1];
|
||||
visibleservers--;
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
server->insortedlist = false;
|
||||
}
|
||||
|
||||
void Master_InsertAt(serverinfo_t *server, int pos)
|
||||
{
|
||||
int i;
|
||||
for (i = numvisibleservers; i > pos; i--)
|
||||
{
|
||||
visibleservers[i] = visibleservers[i-1];
|
||||
}
|
||||
visibleservers[pos] = server;
|
||||
numvisibleservers++;
|
||||
|
||||
server->insortedlist = true;
|
||||
}
|
||||
|
||||
qboolean Master_CompareInteger(int a, int b, slist_test_t rule)
|
||||
{
|
||||
switch(rule)
|
||||
{
|
||||
case SLIST_TEST_CONTAINS:
|
||||
return a&b;
|
||||
case SLIST_TEST_NOTCONTAIN:
|
||||
return !(a&b);
|
||||
case SLIST_TEST_LESSEQUAL:
|
||||
return a<=b;
|
||||
case SLIST_TEST_LESS:
|
||||
return a<b;
|
||||
case SLIST_TEST_EQUAL:
|
||||
return a==b;
|
||||
case SLIST_TEST_GREATER:
|
||||
return a>b;
|
||||
case SLIST_TEST_GREATEREQUAL:
|
||||
return a>=b;
|
||||
case SLIST_TEST_NOTEQUAL:
|
||||
return a!=b;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
qboolean Master_CompareString(char *a, char *b, slist_test_t rule)
|
||||
{
|
||||
switch(rule)
|
||||
{
|
||||
case SLIST_TEST_CONTAINS:
|
||||
return !!strstr(a, b);
|
||||
case SLIST_TEST_NOTCONTAIN:
|
||||
return !strstr(a, b);
|
||||
case SLIST_TEST_LESSEQUAL:
|
||||
return strcmp(a, b)<=0;
|
||||
case SLIST_TEST_LESS:
|
||||
return strcmp(a, b)<0;
|
||||
case SLIST_TEST_EQUAL:
|
||||
return strcmp(a, b)==0;
|
||||
case SLIST_TEST_GREATER:
|
||||
return strcmp(a, b)>0;
|
||||
case SLIST_TEST_GREATEREQUAL:
|
||||
return strcmp(a, b)>=0;
|
||||
case SLIST_TEST_NOTEQUAL:
|
||||
return strcmp(a, b)!=0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean Master_ServerIsGreater(serverinfo_t *a, serverinfo_t *b)
|
||||
{
|
||||
switch(sortfield)
|
||||
{
|
||||
case SLKEY_PING:
|
||||
return Master_CompareInteger(a->ping, b->ping, SLIST_TEST_LESS);
|
||||
case SLKEY_NUMPLAYERS:
|
||||
return Master_CompareInteger(a->players, b->players, SLIST_TEST_LESS);
|
||||
case SLKEY_MAXPLAYERS:
|
||||
return Master_CompareInteger(a->maxplayers, b->maxplayers, SLIST_TEST_LESS);
|
||||
case SLKEY_MAP:
|
||||
return Master_CompareString(a->map, b->map, SLIST_TEST_LESS);
|
||||
case SLKEY_GAMEDIR:
|
||||
return Master_CompareString(a->gamedir, b->gamedir, SLIST_TEST_LESS);
|
||||
case SLKEY_NAME:
|
||||
return Master_CompareString(a->name, b->name, SLIST_TEST_LESS);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean Master_PassesMasks(serverinfo_t *a)
|
||||
{
|
||||
int i;
|
||||
//always filter out dead unresponsive servers.
|
||||
if (!a->ping)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < numvisrules; i++)
|
||||
{
|
||||
switch(visrules[i].fieldindex)
|
||||
{
|
||||
case SLKEY_PING:
|
||||
if (!Master_CompareInteger(a->ping, visrules[i].operandi, visrules[i].compareop))
|
||||
return false;
|
||||
break;
|
||||
case SLKEY_NUMPLAYERS:
|
||||
if (!Master_CompareInteger(a->players, visrules[i].operandi, visrules[i].compareop))
|
||||
return false;
|
||||
break;
|
||||
case SLKEY_MAXPLAYERS:
|
||||
if (!Master_CompareInteger(a->maxplayers, visrules[i].operandi, visrules[i].compareop))
|
||||
return false;
|
||||
break;
|
||||
|
||||
case SLKEY_MAP:
|
||||
if (!Master_CompareString(a->map, visrules[i].operands, visrules[i].compareop))
|
||||
return false;
|
||||
break;
|
||||
case SLKEY_NAME:
|
||||
if (!Master_CompareString(a->name, visrules[i].operands, visrules[i].compareop))
|
||||
return false;
|
||||
break;
|
||||
case SLKEY_GAMEDIR:
|
||||
if (!Master_CompareString(a->gamedir, visrules[i].operands, visrules[i].compareop))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Master_ClearMasks(void)
|
||||
{
|
||||
numvisrules = 0;
|
||||
}
|
||||
|
||||
void Master_SetMaskString(qboolean or, hostcachekey_t field, char *param, slist_test_t testop)
|
||||
{
|
||||
if (numvisrules == MAX_VISRULES)
|
||||
return; //just don't add it.
|
||||
|
||||
visrules[numvisrules].fieldindex = field;
|
||||
visrules[numvisrules].compareop = testop;
|
||||
visrules[numvisrules].operands = param;
|
||||
visrules[numvisrules].or = or;
|
||||
numvisrules++;
|
||||
}
|
||||
void Master_SetMaskInteger(qboolean or, hostcachekey_t field, int param, slist_test_t testop)
|
||||
{
|
||||
if (numvisrules == MAX_VISRULES)
|
||||
return; //just don't add it.
|
||||
|
||||
visrules[numvisrules].fieldindex = field;
|
||||
visrules[numvisrules].compareop = testop;
|
||||
visrules[numvisrules].operandi = param;
|
||||
visrules[numvisrules].or = or;
|
||||
numvisrules++;
|
||||
}
|
||||
void Master_SetSortField(hostcachekey_t field, qboolean descending)
|
||||
{
|
||||
sortfield = field;
|
||||
decreasingorder = descending;
|
||||
}
|
||||
hostcachekey_t Master_GetSortField(void)
|
||||
{
|
||||
return sortfield;
|
||||
}
|
||||
qboolean Master_GetSortDescending(void)
|
||||
{
|
||||
return decreasingorder;
|
||||
}
|
||||
|
||||
void Master_ShowServer(serverinfo_t *server)
|
||||
{
|
||||
int i;
|
||||
if (!numvisibleservers)
|
||||
{
|
||||
Master_InsertAt(server, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!decreasingorder)
|
||||
{
|
||||
for (i = 0; i < numvisibleservers; i++)
|
||||
{
|
||||
if (!Master_ServerIsGreater(server, visibleservers[i]))
|
||||
{
|
||||
Master_InsertAt(server, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < numvisibleservers; i++)
|
||||
{
|
||||
if (Master_ServerIsGreater(server, visibleservers[i]))
|
||||
{
|
||||
Master_InsertAt(server, i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Master_InsertAt(server, numvisibleservers);
|
||||
}
|
||||
|
||||
void Master_ResortServer(serverinfo_t *server)
|
||||
{
|
||||
if (server->insortedlist)
|
||||
{
|
||||
if (!Master_PassesMasks(server))
|
||||
Master_HideServer(server);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Master_PassesMasks(server))
|
||||
Master_ShowServer(server);
|
||||
}
|
||||
}
|
||||
|
||||
void Master_SortServers(void)
|
||||
{
|
||||
serverinfo_t *server;
|
||||
|
||||
int total = Master_TotalCount();
|
||||
if (maxvisibleservers < total)
|
||||
{
|
||||
maxvisibleservers = total;
|
||||
visibleservers = BZ_Realloc(visibleservers, maxvisibleservers*sizeof(serverinfo_t*));
|
||||
}
|
||||
|
||||
{
|
||||
numvisibleservers = 0;
|
||||
for (server = firstserver; server; server = server->next)
|
||||
server->insortedlist = false;
|
||||
}
|
||||
|
||||
for (server = firstserver; server; server = server->next)
|
||||
{
|
||||
Master_ResortServer(server);
|
||||
}
|
||||
|
||||
needsort = false;
|
||||
}
|
||||
|
||||
serverinfo_t *Master_SortedServer(int idx)
|
||||
{
|
||||
if (needsort)
|
||||
Master_SortServers();
|
||||
|
||||
if (idx < 0 || idx >= numvisibleservers)
|
||||
return NULL;
|
||||
|
||||
return visibleservers[idx];
|
||||
}
|
||||
|
||||
int Master_NumSorted(void)
|
||||
{
|
||||
// if (needsort)
|
||||
Master_SortServers();
|
||||
|
||||
return numvisibleservers;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float Master_ReadKeyFloat(serverinfo_t *server, int keynum)
|
||||
{
|
||||
if (!server)
|
||||
return -1;
|
||||
else if (keynum < SLKEY_CUSTOM)
|
||||
{
|
||||
switch(keynum)
|
||||
{
|
||||
case SLKEY_PING:
|
||||
return server->ping;
|
||||
case SLKEY_NUMPLAYERS:
|
||||
return server->players;
|
||||
case SLKEY_MAXPLAYERS:
|
||||
return server->maxplayers;
|
||||
|
||||
default:
|
||||
return atof(Master_ReadKeyString(server, keynum));
|
||||
}
|
||||
}
|
||||
else if (server->moreinfo)
|
||||
return atof(Info_ValueForKey(server->moreinfo->info, slist_keyname[keynum-SLKEY_CUSTOM]));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *Master_ReadKeyString(serverinfo_t *server, int keynum)
|
||||
{
|
||||
if (keynum < SLKEY_CUSTOM)
|
||||
{
|
||||
switch(keynum)
|
||||
{
|
||||
case SLKEY_MAP:
|
||||
return server->map;
|
||||
case SLKEY_NAME:
|
||||
return server->name;
|
||||
case SLKEY_ADDRESS:
|
||||
return NET_AdrToString(server->adr);
|
||||
case SLKEY_GAMEDIR:
|
||||
return server->gamedir;
|
||||
|
||||
default:
|
||||
{
|
||||
static char s[64];
|
||||
sprintf(s, "%f", Master_ReadKeyFloat(server, keynum));
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (server->moreinfo)
|
||||
return Info_ValueForKey(server->moreinfo->info, slist_keyname[keynum-SLKEY_CUSTOM]);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
int Master_KeyForName(char *keyname)
|
||||
{
|
||||
int i;
|
||||
if (!strcmp(keyname, "map"))
|
||||
return SLKEY_MAP;
|
||||
else if (!strcmp(keyname, "ping"))
|
||||
return SLKEY_PING;
|
||||
else if (!strcmp(keyname, "name"))
|
||||
return SLKEY_NAME;
|
||||
else if (!strcmp(keyname, "address") || !strcmp(keyname, "cname"))
|
||||
return SLKEY_ADDRESS;
|
||||
else if (!strcmp(keyname, "maxplayers"))
|
||||
return SLKEY_MAXPLAYERS;
|
||||
else if (!strcmp(keyname, "numplayers"))
|
||||
return SLKEY_NUMPLAYERS;
|
||||
else if (!strcmp(keyname, "gamedir") || !strcmp(keyname, "game") || !strcmp(keyname, "*gamedir") || !strcmp(keyname, "mod"))
|
||||
return SLKEY_GAMEDIR;
|
||||
|
||||
else if (slist_customkeys == SLIST_MAXKEYS)
|
||||
return SLKEY_TOOMANY;
|
||||
else
|
||||
{
|
||||
for (i = 0; i < slist_customkeys; i++)
|
||||
{
|
||||
if (!strcmp(slist_keyname[i], keyname))
|
||||
{
|
||||
return i + SLKEY_CUSTOM;
|
||||
}
|
||||
}
|
||||
Q_strncpyz(slist_keyname[slist_customkeys], keyname, MAX_INFO_KEY);
|
||||
|
||||
slist_customkeys++;
|
||||
|
||||
return slist_customkeys-1 + SLKEY_CUSTOM;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Master_AddMaster (char *address, int type, char *description)
|
||||
|
@ -641,7 +1044,7 @@ void MasterInfo_Begin(void)
|
|||
void Master_QueryServer(serverinfo_t *server)
|
||||
{
|
||||
char data[2048];
|
||||
server->sends++;
|
||||
server->sends--;
|
||||
server->refreshtime = Sys_DoubleTime();
|
||||
sprintf(data, "%c%c%c%cstatus", 255, 255, 255, 255);
|
||||
NET_SendPollPacket (strlen(data), data, server->adr);
|
||||
|
@ -665,7 +1068,7 @@ void CL_QueryServers(void)
|
|||
|
||||
if (op == 0)
|
||||
{
|
||||
if (server->sends < 1)
|
||||
if (server->sends > 0)
|
||||
{
|
||||
Master_QueryServer(server);
|
||||
}
|
||||
|
@ -967,7 +1370,7 @@ void CL_MasterListParse(qboolean isq2)
|
|||
info->adr.port = (int)((short)(p1 + (p2<<8)));
|
||||
if ((old = Master_InfoForServer(info->adr))) //remove if the server already exists.
|
||||
{
|
||||
old->sends = 0; //reset.
|
||||
old->sends = 1; //reset.
|
||||
Z_Free(info);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -601,29 +601,77 @@ static void PF_CopyEntity (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|||
memcpy(out->fields, in->fields, menuentsize);
|
||||
}
|
||||
|
||||
#ifdef CL_MASTER
|
||||
#include "cl_master.h"
|
||||
|
||||
typedef enum{
|
||||
SLIST_HOSTCACHEVIEWCOUNT,
|
||||
SLIST_HOSTCACHETOTALCOUNT,
|
||||
SLIST_MASTERQUERYCOUNT,
|
||||
SLIST_MASTERREPLYCOUNT,
|
||||
SLIST_SERVERQUERYCOUNT,
|
||||
SLIST_SERVERREPLYCOUNT,
|
||||
SLIST_SORTFIELD,
|
||||
SLIST_SORTDESCENDING
|
||||
} hostcacheglobal_t;
|
||||
|
||||
void PF_gethostcachevalue (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
#pragma message ("PF_gethostcachevalue: stub")
|
||||
hostcacheglobal_t hcg = G_FLOAT(OFS_PARM0);
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
}
|
||||
switch(hcg)
|
||||
{
|
||||
case SLIST_HOSTCACHEVIEWCOUNT:
|
||||
G_FLOAT(OFS_RETURN) = Master_NumSorted();
|
||||
return;
|
||||
case SLIST_HOSTCACHETOTALCOUNT:
|
||||
CL_QueryServers();
|
||||
NET_CheckPollSockets();
|
||||
G_FLOAT(OFS_RETURN) = Master_TotalCount();
|
||||
return;
|
||||
|
||||
void PF_gethostcachestring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
#pragma message ("PF_gethostcachestring: stub")
|
||||
G_INT(OFS_RETURN) = 0;
|
||||
case SLIST_MASTERQUERYCOUNT:
|
||||
case SLIST_MASTERREPLYCOUNT:
|
||||
case SLIST_SERVERQUERYCOUNT:
|
||||
case SLIST_SERVERREPLYCOUNT:
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
return;
|
||||
|
||||
case SLIST_SORTFIELD:
|
||||
G_FLOAT(OFS_RETURN) = Master_GetSortField();
|
||||
return;
|
||||
case SLIST_SORTDESCENDING:
|
||||
G_FLOAT(OFS_RETURN) = Master_GetSortDescending();
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//void resethostcachemasks(void) = #615;
|
||||
void PF_M_resethostcachemasks(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
Master_ClearMasks();
|
||||
}
|
||||
//void sethostcachemaskstring(float mask, float fld, string str, float op) = #616;
|
||||
void PF_M_sethostcachemaskstring(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int mask = G_FLOAT(OFS_PARM0);
|
||||
int field = G_FLOAT(OFS_PARM1);
|
||||
char *str = PR_GetStringOfs(prinst, OFS_PARM2);
|
||||
int op = G_FLOAT(OFS_PARM3);
|
||||
|
||||
Master_SetMaskString(mask, field, str, op);
|
||||
}
|
||||
//void sethostcachemasknumber(float mask, float fld, float num, float op) = #617;
|
||||
void PF_M_sethostcachemasknumber(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int mask = G_FLOAT(OFS_PARM0);
|
||||
int field = G_FLOAT(OFS_PARM1);
|
||||
int str = G_FLOAT(OFS_PARM2);
|
||||
int op = G_FLOAT(OFS_PARM3);
|
||||
|
||||
Master_SetMaskInteger(mask, field, str, op);
|
||||
}
|
||||
//void resorthostcache(void) = #618;
|
||||
void PF_M_resorthostcache(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
@ -632,24 +680,77 @@ void PF_M_resorthostcache(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|||
//void sethostcachesort(float fld, float descending) = #619;
|
||||
void PF_M_sethostcachesort(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
Master_SetSortField(G_FLOAT(OFS_PARM0), G_FLOAT(OFS_PARM1));
|
||||
}
|
||||
//void refreshhostcache(void) = #620;
|
||||
void PF_M_refreshhostcache(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
MasterInfo_Begin();
|
||||
}
|
||||
//float gethostcachenumber(float fld, float hostnr) = #621;
|
||||
void PF_M_gethostcachenumber(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
float ret = 0;
|
||||
int keynum = G_FLOAT(OFS_PARM0);
|
||||
int svnum = G_FLOAT(OFS_PARM1);
|
||||
serverinfo_t *sv;
|
||||
sv = Master_SortedServer(svnum);
|
||||
|
||||
ret = Master_ReadKeyFloat(sv, keynum);
|
||||
|
||||
G_FLOAT(OFS_RETURN) = ret;
|
||||
}
|
||||
void PF_gethostcachestring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
char *keyname = PF_TempStr();
|
||||
char *ret = "";
|
||||
int keynum = G_FLOAT(OFS_PARM0);
|
||||
int svnum = G_FLOAT(OFS_PARM1);
|
||||
serverinfo_t *sv;
|
||||
sv = Master_SortedServer(svnum);
|
||||
|
||||
ret = Master_ReadKeyString(sv, keynum);
|
||||
|
||||
Q_strncpyz(keyname, ret, MAXTEMPBUFFERLEN);
|
||||
RETURN_SSTRING(keyname);
|
||||
}
|
||||
|
||||
//float gethostcacheindexforkey(string key) = #622;
|
||||
void PF_M_gethostcacheindexforkey(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
int i;
|
||||
char *keyname = PR_GetStringOfs(prinst, OFS_PARM0);
|
||||
|
||||
G_FLOAT(OFS_RETURN) = Master_KeyForName(keyname);
|
||||
}
|
||||
//void addwantedhostcachekey(string key) = #623;
|
||||
void PF_M_addwantedhostcachekey(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
PF_M_gethostcacheindexforkey(prinst, pr_globals);
|
||||
}
|
||||
#else
|
||||
|
||||
void PF_gethostcachevalue (progfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;}
|
||||
void PF_gethostcachestring (progfuncs_t *prinst, struct globalvars_s *pr_globals) {G_INT(OFS_RETURN) = 0;}
|
||||
//void resethostcachemasks(void) = #615;
|
||||
void PF_M_resethostcachemasks(progfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
||||
//void sethostcachemaskstring(float mask, float fld, string str, float op) = #616;
|
||||
void PF_M_sethostcachemaskstring(progfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
||||
//void sethostcachemasknumber(float mask, float fld, float num, float op) = #617;
|
||||
void PF_M_sethostcachemasknumber(progfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
||||
//void resorthostcache(void) = #618;
|
||||
void PF_M_resorthostcache(progfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
||||
//void sethostcachesort(float fld, float descending) = #619;
|
||||
void PF_M_sethostcachesort(progfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
||||
//void refreshhostcache(void) = #620;
|
||||
void PF_M_refreshhostcache(progfuncs_t *prinst, struct globalvars_s *pr_globals) {}
|
||||
//float gethostcachenumber(float fld, float hostnr) = #621;
|
||||
void PF_M_gethostcachenumber(progfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;}
|
||||
//float gethostcacheindexforkey(string key) = #622;
|
||||
void PF_M_gethostcacheindexforkey(progfuncs_t *prinst, struct globalvars_s *pr_globals){G_FLOAT(OFS_RETURN) = 0;}
|
||||
//void addwantedhostcachekey(string key) = #623;
|
||||
void PF_M_addwantedhostcachekey(progfuncs_t *prinst, struct globalvars_s *pr_globals){}
|
||||
#endif
|
||||
|
||||
|
||||
void PF_localsound (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
|
|
@ -55,7 +55,8 @@ int pt_explosion,
|
|||
pt_superbullet,
|
||||
pt_bullet,
|
||||
pt_spark,
|
||||
pt_plasma;
|
||||
pt_plasma,
|
||||
pt_smoke;
|
||||
|
||||
int pe_default,
|
||||
pe_size2,
|
||||
|
@ -86,21 +87,24 @@ void P_ReadPointFile_f (void);
|
|||
#define MAX_BEAMS 2048 // default max # of beam segments
|
||||
#define MAX_PARTICLES 32768 // default max # of particles at one
|
||||
// time
|
||||
#define MAX_DECALS 32768 // this is going to be expensive
|
||||
|
||||
//int ramp1[8] = {0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61};
|
||||
//int ramp2[8] = {0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66};
|
||||
//int ramp3[8] = {0x6d, 0x6b, 6, 5, 4, 3, 2, 1};
|
||||
|
||||
particle_t *free_particles;
|
||||
|
||||
particle_t *particles; //contains the initial list of alloced particles.
|
||||
int r_numparticles;
|
||||
|
||||
beamseg_t *free_beams;
|
||||
|
||||
beamseg_t *beams;
|
||||
int r_numbeams;
|
||||
|
||||
clippeddecal_t *free_decals;
|
||||
clippeddecal_t *decals;
|
||||
int r_numdecals;
|
||||
|
||||
vec3_t r_pright, r_pup, r_ppn;
|
||||
|
||||
extern cvar_t r_bouncysparks;
|
||||
|
@ -190,7 +194,7 @@ typedef struct part_type_s {
|
|||
|
||||
float offsetup; // make this into a vec3_t later with dir, possibly for mdls
|
||||
|
||||
enum {SM_BOX, SM_CIRCLE, SM_BALL, SM_SPIRAL, SM_TRACER, SM_TELEBOX, SM_LAVASPLASH, SM_UNICIRCLE, SM_FIELD} spawnmode;
|
||||
enum {SM_BOX, SM_CIRCLE, SM_BALL, SM_SPIRAL, SM_TRACER, SM_TELEBOX, SM_LAVASPLASH, SM_UNICIRCLE, SM_FIELD, SM_DECAL} spawnmode;
|
||||
//box = even spread within the area
|
||||
//circle = around edge of a circle
|
||||
//ball = filled sphere
|
||||
|
@ -212,6 +216,7 @@ typedef struct part_type_s {
|
|||
|
||||
int loaded;
|
||||
particle_t *particles;
|
||||
clippeddecal_t *clippeddecals;
|
||||
beamseg_t *beams;
|
||||
skytris_t *skytris;
|
||||
|
||||
|
@ -617,6 +622,8 @@ void P_ParticleEffect_f(void)
|
|||
ptype->spawnmode = SM_UNICIRCLE;
|
||||
else if (!strcmp(value, "syncfield"))
|
||||
ptype->spawnmode = SM_FIELD;
|
||||
else if (!strcmp(value, "decal"))
|
||||
ptype->spawnmode = SM_DECAL;
|
||||
else
|
||||
ptype->spawnmode = SM_BOX;
|
||||
|
||||
|
@ -1062,12 +1069,17 @@ void P_InitParticles (void)
|
|||
|
||||
r_numbeams = MAX_BEAMS;
|
||||
|
||||
r_numdecals = MAX_DECALS;
|
||||
|
||||
particles = (particle_t *)
|
||||
Hunk_AllocName (r_numparticles * sizeof(particle_t), "particles");
|
||||
|
||||
beams = (beamseg_t *)
|
||||
Hunk_AllocName (r_numbeams * sizeof(beamseg_t), "beams");
|
||||
|
||||
decals = (clippeddecal_t *)
|
||||
Hunk_AllocName (r_numdecals * sizeof(clippeddecal_t), "decals");
|
||||
|
||||
Cmd_AddCommand("pointfile", P_ReadPointFile_f); //load the leak info produced from qbsp into the particle system to show a line. :)
|
||||
|
||||
Cmd_AddCommand("r_part", P_ParticleEffect_f);
|
||||
|
@ -1123,6 +1135,7 @@ void P_InitParticles (void)
|
|||
|
||||
pt_spark = P_AllocateParticleType("te_spark");
|
||||
pt_plasma = P_AllocateParticleType("te_plasma");
|
||||
pt_smoke = P_AllocateParticleType("te_smoke");
|
||||
|
||||
pe_default = P_AllocateParticleType("pe_default");
|
||||
pe_size2 = P_AllocateParticleType("pe_size2");
|
||||
|
@ -1140,13 +1153,16 @@ void P_ClearParticles (void)
|
|||
int i;
|
||||
|
||||
free_particles = &particles[0];
|
||||
|
||||
for (i=0 ;i<r_numparticles ; i++)
|
||||
particles[i].next = &particles[i+1];
|
||||
particles[r_numparticles-1].next = NULL;
|
||||
|
||||
free_beams = &beams[0];
|
||||
free_decals = &decals[0];
|
||||
for (i=0 ;i<r_numdecals ; i++)
|
||||
decals[i].next = &decals[i+1];
|
||||
decals[r_numdecals-1].next = NULL;
|
||||
|
||||
free_beams = &beams[0];
|
||||
for (i=0 ;i<r_numbeams ; i++)
|
||||
{
|
||||
beams[i].p = NULL;
|
||||
|
@ -1675,6 +1691,7 @@ int P_RunParticleEffectTypeString (vec3_t org, vec3_t dir, float count, char *na
|
|||
return P_RunParticleEffectType(org, dir, count, type);
|
||||
}
|
||||
|
||||
int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent, float size, float **out);
|
||||
int P_RunParticleEffectType (vec3_t org, vec3_t dir, float count, int typenum)
|
||||
{
|
||||
part_type_t *ptype = &part_type[typenum];
|
||||
|
@ -1690,6 +1707,88 @@ int P_RunParticleEffectType (vec3_t org, vec3_t dir, float count, int typenum)
|
|||
if (!ptype->loaded)
|
||||
return 1;
|
||||
|
||||
if (ptype->spawnmode == SM_DECAL)
|
||||
{
|
||||
clippeddecal_t *d;
|
||||
int decalcount;
|
||||
float dist;
|
||||
vec3_t tangent, t2;
|
||||
vec3_t vec={0.5, 0.5, 0.5};
|
||||
static vec3_t up = {0,0.73,-0.73};
|
||||
float *decverts;
|
||||
int i;
|
||||
|
||||
if (!free_decals)
|
||||
return 0;
|
||||
|
||||
if (!dir)
|
||||
dir = up;
|
||||
|
||||
VectorNormalize(vec);
|
||||
CrossProduct(dir, vec, tangent);
|
||||
CrossProduct(dir, tangent, t2);
|
||||
|
||||
decalcount = Q1BSP_ClipDecal(org, dir, tangent, ptype->scale, &decverts);
|
||||
while(decalcount)
|
||||
{
|
||||
if (!free_decals)
|
||||
break;
|
||||
|
||||
d = free_decals;
|
||||
free_decals = d->next;
|
||||
d->next = ptype->clippeddecals;
|
||||
ptype->clippeddecals = d;
|
||||
|
||||
VectorCopy((decverts+0), d->vertex[0]);
|
||||
VectorCopy((decverts+3), d->vertex[1]);
|
||||
VectorCopy((decverts+6), d->vertex[2]);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
VectorSubtract(d->vertex[i], org, vec);
|
||||
dist = DotProduct(vec, dir)/ptype->scale;
|
||||
d->texcoords[i][0] = ((DotProduct(vec, t2)*(1-dist))/ptype->scale)+0.5;
|
||||
d->texcoords[i][1] = ((DotProduct(vec, tangent)*(1-dist))/ptype->scale)+0.5;
|
||||
}
|
||||
|
||||
d->die = ptype->randdie*frandom();
|
||||
|
||||
if (ptype->die)
|
||||
d->alpha = ptype->alpha-d->die*(ptype->alpha/ptype->die)*ptype->alphachange;
|
||||
else
|
||||
d->alpha = ptype->alpha;
|
||||
|
||||
if (ptype->colorindex >= 0)
|
||||
{
|
||||
int cidx;
|
||||
cidx = ptype->colorrand > 0 ? rand() % ptype->colorrand : 0;
|
||||
cidx = ptype->colorindex + cidx;
|
||||
if (cidx > 255)
|
||||
d->alpha = d->alpha / 2; // Hexen 2 style transparency
|
||||
cidx = d_8to24rgbtable[cidx & 0xff];
|
||||
d->rgb[0] = (cidx & 0xff) * (1/255.0);
|
||||
d->rgb[1] = (cidx >> 8 & 0xff) * (1/255.0);
|
||||
d->rgb[2] = (cidx >> 16 & 0xff) * (1/255.0);
|
||||
}
|
||||
else
|
||||
VectorCopy(ptype->rgb, d->rgb);
|
||||
vec[2] = frandom();
|
||||
vec[0] = vec[2]*ptype->rgbrandsync[0] + frandom()*(1-ptype->rgbrandsync[0]);
|
||||
vec[1] = vec[2]*ptype->rgbrandsync[1] + frandom()*(1-ptype->rgbrandsync[1]);
|
||||
vec[2] = vec[2]*ptype->rgbrandsync[2] + frandom()*(1-ptype->rgbrandsync[2]);
|
||||
d->rgb[0] += vec[0]*ptype->rgbrand[0] + ptype->rgbchange[0]*d->die;
|
||||
d->rgb[1] += vec[1]*ptype->rgbrand[1] + ptype->rgbchange[1]*d->die;
|
||||
d->rgb[2] += vec[2]*ptype->rgbrand[2] + ptype->rgbchange[2]*d->die;
|
||||
|
||||
d->die = particletime + ptype->die - d->die;
|
||||
|
||||
decverts += 3*3;
|
||||
decalcount--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// get msvc to shut up
|
||||
j = k = l = 0;
|
||||
m = 0;
|
||||
|
@ -3002,6 +3101,37 @@ void GL_DrawParticleBeam_Untextured(beamseg_t *b, part_type_t *type)
|
|||
// qglEnd();
|
||||
}
|
||||
|
||||
void GL_DrawClippedDecal(clippeddecal_t *d, part_type_t *type)
|
||||
{
|
||||
if (lasttype != type)
|
||||
{
|
||||
lasttype = type;
|
||||
qglEnd();
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
GL_Bind(type->texturenum);
|
||||
if (type->blendmode == BM_ADD) //addative
|
||||
qglBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
// else if (type->blendmode == BM_SUBTRACT) //subtractive
|
||||
// qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
else
|
||||
qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
qglShadeModel(GL_SMOOTH);
|
||||
qglBegin(GL_TRIANGLES);
|
||||
}
|
||||
|
||||
qglColor4f(d->rgb[0],
|
||||
d->rgb[1],
|
||||
d->rgb[2],
|
||||
d->alpha);
|
||||
|
||||
qglTexCoord2fv(d->texcoords[0]);
|
||||
qglVertex3fv(d->vertex[0]);
|
||||
qglTexCoord2fv(d->texcoords[1]);
|
||||
qglVertex3fv(d->vertex[1]);
|
||||
qglTexCoord2fv(d->texcoords[2]);
|
||||
qglVertex3fv(d->vertex[2]);
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef SWQUAKE
|
||||
void SWD_DrawParticleSpark(particle_t *p, part_type_t *type)
|
||||
|
@ -3102,7 +3232,7 @@ void SWD_DrawParticleBeam(beamseg_t *beam, part_type_t *type)
|
|||
}
|
||||
#endif
|
||||
|
||||
void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void sparklineparticles(particle_t*,part_type_t*), void sparkfanparticles(particle_t*,part_type_t*), void beamparticlest(beamseg_t*,part_type_t*), void beamparticlesut(beamseg_t*,part_type_t*))
|
||||
void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void sparklineparticles(particle_t*,part_type_t*), void sparkfanparticles(particle_t*,part_type_t*), void beamparticlest(beamseg_t*,part_type_t*), void beamparticlesut(beamseg_t*,part_type_t*), void drawdecalparticles(clippeddecal_t*,part_type_t*))
|
||||
{
|
||||
RSpeedMark();
|
||||
|
||||
|
@ -3114,11 +3244,14 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void
|
|||
vec3_t stop, normal;
|
||||
part_type_t *type;
|
||||
particle_t *p, *kill;
|
||||
clippeddecal_t *d, *dkill;
|
||||
ramp_t *ramp;
|
||||
float grav;
|
||||
vec3_t friction;
|
||||
float dist;
|
||||
particle_t *kill_list, *kill_first;
|
||||
particle_t *kill_list, *kill_first; //the kill list is to stop particles from being freed and reused whilst still in this loop
|
||||
//which is bad because beams need to find out when particles died. Reuse can do wierd things.
|
||||
//remember that they're not drawn instantly either.
|
||||
beamseg_t *b, *bkill;
|
||||
|
||||
int traces=r_particle_tracelimit.value;
|
||||
|
@ -3148,6 +3281,70 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void
|
|||
|
||||
for (i = 0, type = &part_type[i]; i < numparticletypes; i++, type++)
|
||||
{
|
||||
if (type->clippeddecals)
|
||||
{
|
||||
/* for ( ;; )
|
||||
{
|
||||
dkill = type->clippeddecals;
|
||||
if (dkill && dkill->die < particletime)
|
||||
{
|
||||
type->clippeddecals = dkill->next;
|
||||
free_decals =
|
||||
|
||||
|
||||
dkill->next = (clippeddecal_t *)kill_list;
|
||||
kill_list = (particle_t*)dkill;
|
||||
if (!kill_first)
|
||||
kill_first = kill_list;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}*/
|
||||
for (d=type->clippeddecals ; d ; d=d->next)
|
||||
{
|
||||
/* for ( ;; )
|
||||
{
|
||||
dkill = d->next;
|
||||
if (dkill && dkill->die < particletime)
|
||||
{
|
||||
d->next = dkill->next;
|
||||
dkill->next = (clippeddecal_t *)kill_list;
|
||||
kill_list = (particle_t*)dkill;
|
||||
if (!kill_first)
|
||||
kill_first = kill_list;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
switch (type->rampmode)
|
||||
{
|
||||
case RAMP_ABSOLUTE:
|
||||
ramp = type->ramp + (int)(type->rampindexes * (type->die - (d->die - particletime)) / type->die);
|
||||
VectorCopy(ramp->rgb, d->rgb);
|
||||
d->alpha = ramp->alpha;
|
||||
break;
|
||||
case RAMP_DELTA: //particle ramps
|
||||
ramp = type->ramp + (int)(type->rampindexes * (type->die - (d->die - particletime)) / type->die);
|
||||
VectorMA(d->rgb, pframetime, ramp->rgb, d->rgb);
|
||||
d->alpha -= pframetime*ramp->alpha;
|
||||
break;
|
||||
case RAMP_NONE: //particle changes acording to it's preset properties.
|
||||
if (particletime < (d->die-type->die+type->rgbchangetime))
|
||||
{
|
||||
d->rgb[0] += pframetime*type->rgbchange[0];
|
||||
d->rgb[1] += pframetime*type->rgbchange[1];
|
||||
d->rgb[2] += pframetime*type->rgbchange[2];
|
||||
}
|
||||
d->alpha -= pframetime*(type->alpha/type->die)*type->alphachange;
|
||||
}
|
||||
|
||||
drawdecalparticles(d, type);
|
||||
}
|
||||
}
|
||||
|
||||
if (!type->particles)
|
||||
continue;
|
||||
|
||||
|
@ -3457,10 +3654,6 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void
|
|||
|
||||
RSpeedEnd(RSPEED_PARTICLES);
|
||||
|
||||
RSpeedRemark();
|
||||
RQ_RenderDistAndClear();
|
||||
RSpeedEnd(RSPEED_PARTICLESDRAW);
|
||||
|
||||
// lazy delete for particles is done here
|
||||
if (kill_list)
|
||||
{
|
||||
|
@ -3478,6 +3671,8 @@ R_DrawParticles
|
|||
*/
|
||||
void P_DrawParticles (void)
|
||||
{
|
||||
RSpeedMark();
|
||||
|
||||
P_AddRainParticles();
|
||||
#if defined(RGLQUAKE)
|
||||
if (qrenderer == QR_OPENGL)
|
||||
|
@ -3490,14 +3685,23 @@ void P_DrawParticles (void)
|
|||
GL_TexEnv(GL_MODULATE);
|
||||
qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
if (qglPolygonOffset)
|
||||
qglPolygonOffset(-1, 0);
|
||||
qglEnable(GL_POLYGON_OFFSET_FILL);
|
||||
qglBegin(GL_QUADS);
|
||||
|
||||
if (r_drawflat.value == 2)
|
||||
DrawParticleTypes(GL_DrawSketchParticle, GL_DrawSketchSparkParticle, GL_DrawSketchSparkParticle, GL_DrawParticleBeam_Textured, GL_DrawParticleBeam_Untextured);//GL_DrawParticleBeam_Sketched, GL_DrawParticleBeam_Sketched);
|
||||
DrawParticleTypes(GL_DrawSketchParticle, GL_DrawSketchSparkParticle, GL_DrawSketchSparkParticle, GL_DrawParticleBeam_Textured, GL_DrawParticleBeam_Untextured, GL_DrawClippedDecal);
|
||||
else
|
||||
DrawParticleTypes(GL_DrawTexturedParticle, GL_DrawSparkedParticle, GL_DrawTrifanParticle, GL_DrawParticleBeam_Textured, GL_DrawParticleBeam_Untextured);
|
||||
|
||||
DrawParticleTypes(GL_DrawTexturedParticle, GL_DrawSparkedParticle, GL_DrawTrifanParticle, GL_DrawParticleBeam_Textured, GL_DrawParticleBeam_Untextured, GL_DrawClippedDecal);
|
||||
qglEnd();
|
||||
qglDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
RSpeedRemark();
|
||||
qglBegin(GL_QUADS);
|
||||
RQ_RenderDistAndClear();
|
||||
qglEnd();
|
||||
RSpeedEnd(RSPEED_PARTICLESDRAW);
|
||||
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
|
||||
GL_TexEnv(GL_MODULATE);
|
||||
|
@ -3510,9 +3714,13 @@ void P_DrawParticles (void)
|
|||
#ifdef SWQUAKE
|
||||
if (qrenderer == QR_SOFTWARE)
|
||||
{
|
||||
DrawParticleTypes(SWD_DrawParticleBlob, SWD_DrawParticleSpark, SWD_DrawParticleSpark, SWD_DrawParticleBeam, SWD_DrawParticleBeam, NULL);
|
||||
|
||||
RSpeedRemark();
|
||||
D_StartParticles();
|
||||
DrawParticleTypes(SWD_DrawParticleBlob, SWD_DrawParticleSpark, SWD_DrawParticleSpark, SWD_DrawParticleBeam, SWD_DrawParticleBeam);
|
||||
RQ_RenderDistAndClear();
|
||||
D_EndParticles();
|
||||
RSpeedEnd(RSPEED_PARTICLESDRAW);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -377,4 +377,7 @@ int rquant[RQUANT_MAX];
|
|||
#define RSpeedLocals() int rsp
|
||||
#define RSpeedMark() int rsp = r_speeds.value?Sys_DoubleTime()*1000000:0
|
||||
#define RSpeedRemark() rsp = r_speeds.value?Sys_DoubleTime()*1000000:0
|
||||
|
||||
//extern void (_stdcall *qglFinish) (void);
|
||||
//#define RSpeedEnd(spt) do {qglFinish(); rspeeds[spt] += r_speeds.value?Sys_DoubleTime()*1000000 - rsp:0;}while (0)
|
||||
#define RSpeedEnd(spt) rspeeds[spt] += r_speeds.value?Sys_DoubleTime()*1000000 - rsp:0
|
||||
|
|
|
@ -143,6 +143,7 @@ extern cvar_t gl_maxdist;
|
|||
cvar_t gl_specular = {"gl_specular", "0"};
|
||||
#endif
|
||||
cvar_t gl_detail = {"gl_detail", "0", NULL, CVAR_ARCHIVE};
|
||||
cvar_t gl_overbright = {"gl_overbright", "0", NULL, CVAR_ARCHIVE};
|
||||
cvar_t r_shadows = {"r_shadows", "0", NULL, CVAR_ARCHIVE|CVAR_RENDERERLATCH};
|
||||
cvar_t r_shadow_realtime_world = {"r_shadow_realtime_world", "0", NULL, CVAR_CHEAT};
|
||||
cvar_t r_noaliasshadows = {"r_noaliasshadows", "0", NULL, CVAR_ARCHIVE};
|
||||
|
@ -315,6 +316,7 @@ void GLRenderer_Init(void)
|
|||
Cvar_Register (&gl_compress, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&gl_driver, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&gl_detail, GRAPHICALNICETIES);
|
||||
Cvar_Register (&gl_overbright, GRAPHICALNICETIES);
|
||||
Cvar_Register (&gl_dither, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_fb_models, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_fb_bmodels, GRAPHICALNICETIES);
|
||||
|
|
|
@ -513,9 +513,11 @@ sndinitstat SNDDMA_InitDirect (soundcardinfo_t *sc)
|
|||
dsnd_guids=0;
|
||||
dsndguid=NULL;
|
||||
dsndcard="DirectSound";
|
||||
if (snd_multipledevices)
|
||||
if (pDirectSoundEnumerate)
|
||||
pDirectSoundEnumerate(&DSEnumCallback, NULL);
|
||||
if (!snd_multipledevices)
|
||||
dsndguid=NULL;
|
||||
|
||||
aimedforguid++;
|
||||
|
||||
if (!dsndguid) //no more...
|
||||
|
@ -523,11 +525,15 @@ sndinitstat SNDDMA_InitDirect (soundcardinfo_t *sc)
|
|||
return SIS_NOMORE;
|
||||
//EAX attempt
|
||||
#ifndef MINIMAL
|
||||
CoInitialize(NULL);
|
||||
if (FAILED(CoCreateInstance( &CLSID_EAXDirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void **)&sc->pDS )))
|
||||
sc->pDS=NULL;
|
||||
else
|
||||
IDirectSound_Initialize(sc->pDS, dsndguid);
|
||||
sc->pDS = NULL;
|
||||
if (snd_eax.value)
|
||||
{
|
||||
CoInitialize(NULL);
|
||||
if (FAILED(CoCreateInstance( &CLSID_EAXDirectSound, dsndguid, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void **)&sc->pDS )))
|
||||
sc->pDS=NULL;
|
||||
else
|
||||
IDirectSound_Initialize(sc->pDS, dsndguid);
|
||||
}
|
||||
|
||||
if (!sc->pDS)
|
||||
#endif
|
||||
|
@ -548,7 +554,7 @@ sndinitstat SNDDMA_InitDirect (soundcardinfo_t *sc)
|
|||
// {
|
||||
Con_SafePrintf (": failure\n"
|
||||
" hardware already in use\n"
|
||||
" Close the app then use snd_restart\n");
|
||||
" Close the other app then use snd_restart\n");
|
||||
return SIS_NOTAVAIL;
|
||||
// }
|
||||
}
|
||||
|
@ -1016,7 +1022,7 @@ int SNDDMA_Init(soundcardinfo_t *sc)
|
|||
sc->snd_isdirect = true;
|
||||
|
||||
if (snd_firsttime)
|
||||
Con_SafePrintf ("%s initialized\n", sc->name);
|
||||
Con_DPrintf ("%s initialized\n", sc->name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -1025,7 +1031,7 @@ int SNDDMA_Init(soundcardinfo_t *sc)
|
|||
else
|
||||
{
|
||||
sc->snd_isdirect = false;
|
||||
Con_SafePrintf ("DirectSound failed to init\n");
|
||||
Con_DPrintf ("DirectSound failed to init\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
|
||||
#define SPRITE_VERSION 1
|
||||
#define SPRITEHL_VERSION 2
|
||||
#define SPRITE32_VERSION 32
|
||||
|
||||
// must match definition in modelgen.h
|
||||
|
|
|
@ -182,7 +182,22 @@ static void VARGS Q_snprintfz (char *dest, size_t size, char *fmt, ...)
|
|||
\
|
||||
TP_CVAR(tp_name_enemy, "enemy"); \
|
||||
TP_CVAR(tp_name_teammate, ""); \
|
||||
TP_CVAR(tp_name_eyes, "eyes")
|
||||
TP_CVAR(tp_name_eyes, "eyes"); \
|
||||
\
|
||||
TP_CVAR(loc_name_seperator, "-"); \
|
||||
TP_CVAR(loc_name_ssg, "ssg"); \
|
||||
TP_CVAR(loc_name_ng, "ng"); \
|
||||
TP_CVAR(loc_name_sng, "sng"); \
|
||||
TP_CVAR(loc_name_gl, "gl"); \
|
||||
TP_CVAR(loc_name_rl, "rl"); \
|
||||
TP_CVAR(loc_name_lg, "lg"); \
|
||||
TP_CVAR(loc_name_ga, "ga"); \
|
||||
TP_CVAR(loc_name_ya, "ya"); \
|
||||
TP_CVAR(loc_name_ra, "ra"); \
|
||||
TP_CVAR(loc_name_quad, "quad"); \
|
||||
TP_CVAR(loc_name_pent, "pent"); \
|
||||
TP_CVAR(loc_name_ring, "ring"); \
|
||||
TP_CVAR(loc_name_suit, "suit")
|
||||
|
||||
//create the globals for all the TP cvars.
|
||||
#define TP_CVAR(name,def) cvar_t name = {#name, def}
|
||||
|
|
|
@ -105,7 +105,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define ZYMOTICMODELS //zymotic skeletal models.
|
||||
#define HUFFNETWORK //huffman network compression
|
||||
#define HALFLIFEMODELS //halflife model support (experimental)
|
||||
#define DOOMWADS //doom wad/map/sprite support
|
||||
// #define DOOMWADS //doom wad/map/sprite support
|
||||
//#define WOLF3DSUPPORT //wolfenstein3d map support (not started yet)
|
||||
#define Q2BSPS //quake 2 bsp support
|
||||
#define Q3BSPS //quake 3 bsp support
|
||||
|
|
|
@ -4201,6 +4201,7 @@ potentialgamepath_t pgp[] = {
|
|||
{"%s/id1/pak0.pak", "%s/id1"}, //quake1
|
||||
{"%s/baseq2/pak0.pak", "%s/baseq2"}, //quake2
|
||||
{"%s/data1/pak0.pak", "%s/data1"}, //hexen2
|
||||
{"%s/data/data.pk3", "%s/data"}, //nexuiz
|
||||
{"%s/baseq3/pak0.pk3", "%s/baseq3"}, //quake3
|
||||
{"%s/base/assets0.pk3", "%s/base"} //jk2
|
||||
};
|
||||
|
|
|
@ -332,7 +332,7 @@ int c_pointcontents;
|
|||
int c_traces, c_brush_traces;
|
||||
|
||||
|
||||
vec4_t *map_verts; //3points + pad (I'm not entirly sure of the need for the pad, maybe it's just faster)
|
||||
vec3_t *map_verts; //3points
|
||||
int numvertexes;
|
||||
|
||||
vec2_t *map_vertstmexcoords;
|
||||
|
@ -435,7 +435,7 @@ qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2
|
|||
Patch_FlatnessTest
|
||||
===============
|
||||
*/
|
||||
static int Patch_FlatnessTest ( float maxflat, vec4_t point0, vec4_t point1, vec4_t point2 )
|
||||
static int Patch_FlatnessTest ( float maxflat, const vec3_t point0, const vec3_t point1, const vec3_t point2 )
|
||||
{
|
||||
vec3_t v1, v2, v3;
|
||||
vec3_t t, n;
|
||||
|
@ -473,7 +473,7 @@ static int Patch_FlatnessTest ( float maxflat, vec4_t point0, vec4_t point1, vec
|
|||
Patch_GetFlatness
|
||||
===============
|
||||
*/
|
||||
void Patch_GetFlatness ( float maxflat, vec4_t *points, int *patch_cp, int *flat )
|
||||
void Patch_GetFlatness ( float maxflat, const vec3_t *points, int *patch_cp, int *flat )
|
||||
{
|
||||
int i, p, u, v;
|
||||
|
||||
|
@ -528,7 +528,7 @@ static void Patch_Evaluate_QuadricBezier ( float t, vec4_t point0, vec4_t point1
|
|||
Patch_Evaluate
|
||||
===============
|
||||
*/
|
||||
void Patch_Evaluate ( vec4_t *p, int *numcp, int *tess, vec4_t *dest )
|
||||
void Patch_Evaluate ( const vec4_t *p, const int *numcp, const int *tess, vec4_t *dest )
|
||||
{
|
||||
int num_patches[2], num_tess[2];
|
||||
int index[3], dstpitch, i, u, v, x, y;
|
||||
|
@ -725,10 +725,10 @@ void CM_CreateBrush ( q2cbrush_t *brush, vec3_t *verts, q2mapsurface_t *surface
|
|||
}
|
||||
}
|
||||
|
||||
void CM_CreatePatch ( q3cpatch_t *patch, int numverts, vec4_t *verts, int *patch_cp )
|
||||
void CM_CreatePatch ( q3cpatch_t *patch, int numverts, const vec3_t *verts, int *patch_cp )
|
||||
{
|
||||
int step[2], size[2], flat[2], i, u, v;
|
||||
vec4_t points[MAX_CM_PATCH_VERTS];
|
||||
vec4_t points[MAX_CM_PATCH_VERTS], pointss[MAX_CM_PATCH_VERTS];
|
||||
vec3_t tverts[4], tverts2[4];
|
||||
q2cbrush_t *brush;
|
||||
mplane_t mainplane;
|
||||
|
@ -746,8 +746,10 @@ void CM_CreatePatch ( q3cpatch_t *patch, int numverts, vec4_t *verts, int *patch
|
|||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < numverts; i++)
|
||||
VectorCopy(verts[i], pointss[i]);
|
||||
// fill in
|
||||
Patch_Evaluate ( verts, patch_cp, step, points );
|
||||
Patch_Evaluate ( pointss, patch_cp, step, points );
|
||||
|
||||
patch->brushes = brush = map_brushes + numbrushes;
|
||||
patch->numbrushes = 0;
|
||||
|
@ -1857,7 +1859,7 @@ void CModQ3_LoadSubmodels (lump_t *l)
|
|||
}
|
||||
}
|
||||
|
||||
void CModQ3_LoadShaders (lump_t *l)
|
||||
void CModQ3_LoadShaders (lump_t *l, qboolean useshaders)
|
||||
{
|
||||
dq3shader_t *in;
|
||||
q2mapsurface_t *out;
|
||||
|
@ -1889,8 +1891,7 @@ void CModQ3_LoadShaders (lump_t *l)
|
|||
loadmodel->texinfo[i].texture = Hunk_Alloc(sizeof(texture_t));
|
||||
Q_strncpyz(loadmodel->texinfo[i].texture->name, in->shadername, sizeof(loadmodel->texinfo[i].texture->name));
|
||||
#ifdef RGLQUAKE
|
||||
#ifndef Q3SHADERS
|
||||
if (qrenderer == QR_OPENGL)
|
||||
if (qrenderer == QR_OPENGL && !useshaders)
|
||||
{
|
||||
loadmodel->texinfo[i].texture->gl_texturenum = Mod_LoadHiResTexture(in->shadername, loadname, true, false, true);
|
||||
if (!loadmodel->texinfo[i].texture->gl_texturenum)
|
||||
|
@ -1898,7 +1899,6 @@ void CModQ3_LoadShaders (lump_t *l)
|
|||
loadmodel->texinfo[i].texture->gl_texturenumfb = 0;
|
||||
loadmodel->texinfo[i].texture->gl_texturenumbumpmap = 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
loadmodel->textures[i] = loadmodel->texinfo[i].texture;
|
||||
|
||||
|
@ -1918,7 +1918,7 @@ void CModQ3_LoadShaders (lump_t *l)
|
|||
void CModQ3_LoadVertexes (lump_t *l)
|
||||
{
|
||||
q3dvertex_t *in;
|
||||
vec4_t *out;
|
||||
vec3_t *out;
|
||||
vec3_t *nout;
|
||||
int i, count, j;
|
||||
vec2_t *lmout, *stout;
|
||||
|
@ -1966,7 +1966,7 @@ void CModQ3_LoadVertexes (lump_t *l)
|
|||
void CModRBSP_LoadVertexes (lump_t *l)
|
||||
{
|
||||
rbspvertex_t *in;
|
||||
vec4_t *out;
|
||||
vec3_t *out;
|
||||
vec3_t *nout;
|
||||
int i, count, j;
|
||||
vec2_t *lmout, *stout;
|
||||
|
@ -2222,7 +2222,7 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in
|
|||
int numindexes, patch_cp[2], step[2], size[2], flat[2], i, u, v, p;
|
||||
vec4_t colors[MAX_ARRAY_VERTS], points[MAX_ARRAY_VERTS], normals[MAX_ARRAY_VERTS],
|
||||
lm_st[MAX_ARRAY_VERTS], tex_st[MAX_ARRAY_VERTS];
|
||||
vec4_t c, colors2[MAX_ARRAY_VERTS], normals2[MAX_ARRAY_VERTS], lm_st2[MAX_ARRAY_VERTS], tex_st2[MAX_ARRAY_VERTS];
|
||||
vec4_t c, colors2[MAX_ARRAY_VERTS], points2[MAX_ARRAY_VERTS], normals2[MAX_ARRAY_VERTS], lm_st2[MAX_ARRAY_VERTS], tex_st2[MAX_ARRAY_VERTS];
|
||||
mesh_t *mesh;
|
||||
index_t *indexes;
|
||||
float subdivlevel;
|
||||
|
@ -2247,7 +2247,7 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in
|
|||
}
|
||||
|
||||
// find the degree of subdivision in the u and v directions
|
||||
Patch_GetFlatness ( subdivlevel, points, patch_cp, flat );
|
||||
Patch_GetFlatness ( subdivlevel, map_verts+firstvert, patch_cp, flat );
|
||||
|
||||
// allocate space for mesh
|
||||
step[0] = (1 << flat[0]);
|
||||
|
@ -2263,7 +2263,7 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in
|
|||
mesh = (mesh_t *)Hunk_TempAllocMore ( sizeof(mesh_t));
|
||||
|
||||
mesh->numvertexes = numverts;
|
||||
mesh->xyz_array = Hunk_TempAllocMore ( numverts * sizeof(vec4_t));
|
||||
mesh->xyz_array = Hunk_TempAllocMore ( numverts * sizeof(vec3_t));
|
||||
mesh->normals_array = Hunk_TempAllocMore ( numverts * sizeof(vec3_t));
|
||||
mesh->st_array = Hunk_TempAllocMore ( numverts * sizeof(vec2_t));
|
||||
mesh->lmst_array = Hunk_TempAllocMore ( numverts * sizeof(vec2_t));
|
||||
|
@ -2273,7 +2273,7 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in
|
|||
mesh->patchHeight = size[1];
|
||||
|
||||
// fill in
|
||||
Patch_Evaluate ( points, patch_cp, step, mesh->xyz_array );
|
||||
Patch_Evaluate ( points, patch_cp, step, points2 );
|
||||
Patch_Evaluate ( colors, patch_cp, step, colors2 );
|
||||
Patch_Evaluate ( normals, patch_cp, step, normals2 );
|
||||
Patch_Evaluate ( lm_st, patch_cp, step, lm_st2 );
|
||||
|
@ -2281,6 +2281,7 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in
|
|||
|
||||
for (i = 0; i < numverts; i++)
|
||||
{
|
||||
VectorCopy ( points2[i], mesh->xyz_array[i] );
|
||||
VectorNormalize2 ( normals2[i], mesh->normals_array[i] );
|
||||
ColorNormalize ( colors2[i], c );
|
||||
Vector4Scale ( c, 255.0, mesh->colors_array[i] );
|
||||
|
@ -2333,8 +2334,8 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
void CModQ3_LoadRFaces (lump_t *l)
|
||||
mesh_t nullmesh;
|
||||
void CModQ3_LoadRFaces (lump_t *l, qboolean useshaders)
|
||||
{
|
||||
#ifndef Q3SHADERS
|
||||
int polysize = sizeof(glpoly_t) - VERTEXSIZE*sizeof(float);
|
||||
|
@ -2354,11 +2355,6 @@ void CModQ3_LoadRFaces (lump_t *l)
|
|||
|
||||
mesh_t *mesh;
|
||||
|
||||
extern cvar_t gl_shadeq3;
|
||||
|
||||
int shaders = gl_shadeq3.value;
|
||||
|
||||
|
||||
in = (void *)(mod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
Host_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
|
||||
|
@ -2405,7 +2401,7 @@ continue;
|
|||
out->flags |= SURF_DRAWSKY;
|
||||
|
||||
#ifdef Q3SHADERS
|
||||
if (!out->texinfo->texture->shader && shaders)
|
||||
if (!out->texinfo->texture->shader && useshaders)
|
||||
{
|
||||
extern cvar_t r_vertexlight;
|
||||
if (in->facetype == MST_FLARE)
|
||||
|
@ -2423,9 +2419,7 @@ continue;
|
|||
#endif
|
||||
if (map_surfaces[in->shadernum].c.flags & (Q3SURF_NODRAW | Q3SURF_SKIP))
|
||||
{
|
||||
if (map_surfaces[in->shadernum].c.flags & Q3SURF_SKIP)
|
||||
Con_Printf("Surface skip\n");
|
||||
out->mesh = NULL;
|
||||
out->mesh = &nullmesh;
|
||||
}
|
||||
else if (in->facetype == MST_PATCH)
|
||||
{
|
||||
|
@ -2455,7 +2449,7 @@ continue;
|
|||
extern index_t r_quad_indexes[6];
|
||||
|
||||
mesh = out->mesh = (mesh_t *)Hunk_Alloc ( sizeof(mesh_t));
|
||||
mesh->xyz_array = (vec4_t *)Hunk_Alloc ( sizeof(vec4_t));
|
||||
mesh->xyz_array = (vec3_t *)Hunk_Alloc ( sizeof(vec3_t));
|
||||
mesh->numvertexes = 1;
|
||||
mesh->indexes = r_quad_indexes;
|
||||
mesh->numindexes = 6;
|
||||
|
@ -2475,7 +2469,7 @@ continue;
|
|||
}
|
||||
}
|
||||
|
||||
void CModRBSP_LoadRFaces (lump_t *l)
|
||||
void CModRBSP_LoadRFaces (lump_t *l, qboolean useshaders)
|
||||
{
|
||||
#ifndef Q3SHADERS
|
||||
int polysize = sizeof(glpoly_t) - VERTEXSIZE*sizeof(float);
|
||||
|
@ -2495,10 +2489,6 @@ void CModRBSP_LoadRFaces (lump_t *l)
|
|||
|
||||
mesh_t *mesh;
|
||||
|
||||
extern cvar_t gl_shadeq3;
|
||||
|
||||
int shaders = gl_shadeq3.value;
|
||||
|
||||
|
||||
in = (void *)(mod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
|
@ -2546,7 +2536,7 @@ continue;
|
|||
out->flags |= SURF_DRAWSKY;
|
||||
|
||||
#ifdef Q3SHADERS
|
||||
if (!out->texinfo->texture->shader && shaders)
|
||||
if (!out->texinfo->texture->shader && useshaders)
|
||||
{
|
||||
extern cvar_t r_vertexlight;
|
||||
if (in->facetype == MST_FLARE)
|
||||
|
@ -2596,7 +2586,7 @@ continue;
|
|||
extern index_t r_quad_indexes[6];
|
||||
|
||||
mesh = out->mesh = (mesh_t *)Hunk_Alloc ( sizeof(mesh_t));
|
||||
mesh->xyz_array = (vec4_t *)Hunk_Alloc ( sizeof(vec4_t));
|
||||
mesh->xyz_array = (vec3_t *)Hunk_Alloc ( sizeof(vec3_t));
|
||||
mesh->numvertexes = 1;
|
||||
mesh->indexes = r_quad_indexes;
|
||||
mesh->numindexes = 6;
|
||||
|
@ -3121,6 +3111,8 @@ void CMQ3_CalcPHS (void)
|
|||
|
||||
map_q3phs->rowsize = map_q3pvs->rowsize;
|
||||
map_q3phs->numclusters = numclusters = map_q3pvs->numclusters;
|
||||
if (!numclusters)
|
||||
return;
|
||||
|
||||
vcount = 0;
|
||||
for (i=0 ; i<numclusters ; i++)
|
||||
|
@ -3327,6 +3319,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
|
|||
q2dheader_t header;
|
||||
int length;
|
||||
static unsigned last_checksum;
|
||||
qboolean useshaders;
|
||||
|
||||
// free old stuff
|
||||
numplanes = 0;
|
||||
|
@ -3377,6 +3370,16 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
|
|||
case 1: //rbsp
|
||||
case Q3BSPVERSION+1: //rtcw
|
||||
case Q3BSPVERSION:
|
||||
|
||||
#ifdef Q3SHADERS
|
||||
{
|
||||
extern cvar_t gl_shadeq3;
|
||||
useshaders = gl_shadeq3.value;
|
||||
}
|
||||
#else
|
||||
useshaders = false;
|
||||
#endif
|
||||
|
||||
mapisq3 = true;
|
||||
loadmodel->fromgame = fg_quake3;
|
||||
for (i=0 ; i<Q3LUMPS_TOTAL ; i++)
|
||||
|
@ -3417,7 +3420,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
|
|||
#endif
|
||||
case QR_NONE: //dedicated only
|
||||
mapisq3 = true;
|
||||
CModQ3_LoadShaders (&header.lumps[Q3LUMP_SHADERS]);
|
||||
CModQ3_LoadShaders (&header.lumps[Q3LUMP_SHADERS], useshaders);
|
||||
CModQ3_LoadPlanes (&header.lumps[Q3LUMP_PLANES]);
|
||||
CModQ3_LoadLeafBrushes (&header.lumps[Q3LUMP_LEAFBRUSHES]);
|
||||
CModQ3_LoadBrushes (&header.lumps[Q3LUMP_BRUSHES]);
|
||||
|
@ -3451,9 +3454,9 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
|
|||
map_numfogs = 0;
|
||||
#endif
|
||||
if (header.version == 1)
|
||||
CModRBSP_LoadRFaces (&header.lumps[Q3LUMP_SURFACES]);
|
||||
CModRBSP_LoadRFaces (&header.lumps[Q3LUMP_SURFACES], useshaders);
|
||||
else
|
||||
CModQ3_LoadRFaces (&header.lumps[Q3LUMP_SURFACES]);
|
||||
CModQ3_LoadRFaces (&header.lumps[Q3LUMP_SURFACES], useshaders);
|
||||
CModQ3_LoadMarksurfaces (&header.lumps[Q3LUMP_LEAFSURFACES]); //fixme: duplicated loading.
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -59,32 +59,46 @@ extern int rt_rocket_trail,
|
|||
// !!! if this is changed, it must be changed in d_ifacea.h too !!!
|
||||
typedef struct particle_s
|
||||
{
|
||||
struct particle_s *next;
|
||||
float die;
|
||||
|
||||
// driver-usable fields
|
||||
vec3_t org;
|
||||
float color;
|
||||
float color; //used by sw renderer. To be removed.
|
||||
vec3_t rgb;
|
||||
float alpha;
|
||||
float scale;
|
||||
|
||||
vec3_t vel;
|
||||
vec3_t vel; //renderer uses for sparks
|
||||
float angle;
|
||||
float rotationspeed;
|
||||
float nextemit;
|
||||
|
||||
// drivers never touch the following fields
|
||||
|
||||
struct particle_s *next;
|
||||
float die;
|
||||
float rotationspeed;
|
||||
} particle_t;
|
||||
|
||||
typedef struct clippeddecal_s
|
||||
{
|
||||
struct clippeddecal_s *next;
|
||||
float die;
|
||||
|
||||
vec3_t center;
|
||||
vec3_t vertex[3];
|
||||
vec2_t texcoords[3];
|
||||
|
||||
vec3_t rgb;
|
||||
float alpha;
|
||||
} clippeddecal_t;
|
||||
|
||||
#define BS_LASTSEG 0x1 // no draw to next, no delete
|
||||
#define BS_DEAD 0x2 // segment is dead
|
||||
#define BS_NODRAW 0x4 // only used for lerp switching
|
||||
|
||||
typedef struct beamseg_s
|
||||
{
|
||||
particle_t *p;
|
||||
struct beamseg_s *next; // next in beamseg list
|
||||
|
||||
particle_t *p;
|
||||
int flags; // flags for beamseg
|
||||
vec3_t dir;
|
||||
|
||||
|
|
|
@ -440,7 +440,7 @@ enum clcq2_ops_e
|
|||
#ifdef PEXT_BIGORIGINS
|
||||
#define U_ORIGINDBL (1<<10) //use an extra qbyte for origin parts, cos one of them is off
|
||||
#endif
|
||||
|
||||
#define U_VIEWMODEL (1<<11) //glue to the player's view
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -605,6 +605,8 @@ enum {
|
|||
#define DPTE_FLAMEJET 74
|
||||
#define DPTE_PLASMABURN 75
|
||||
|
||||
#define DPTE_SMOKE 77
|
||||
|
||||
#define TE_SEEF_BRIGHTFIELD 200
|
||||
#define TE_SEEF_DARKLIGHT 201
|
||||
#define TE_SEEF_DARKFIELD 202
|
||||
|
|
|
@ -260,6 +260,486 @@ void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node)
|
|||
Q1BSP_MarkLights (light, bit, node->children[1]);
|
||||
}
|
||||
|
||||
#define MAXFRAGMENTTRIS 256
|
||||
vec3_t decalfragmentverts[MAXFRAGMENTTRIS*3];
|
||||
|
||||
typedef struct {
|
||||
vec3_t center;
|
||||
|
||||
vec3_t normal;
|
||||
vec3_t tangent1;
|
||||
vec3_t tangent2;
|
||||
|
||||
vec3_t planenorm[6];
|
||||
float planedist[6];
|
||||
|
||||
vec_t radius;
|
||||
int numtris;
|
||||
|
||||
} fragmentdecal_t;
|
||||
|
||||
#define FloatInterpolate(a, bness, b, c) (c) = (a)*(1-bness) + (b)*bness
|
||||
#define VectorInterpolate(a, bness, b, c) FloatInterpolate((a)[0], bness, (b)[0], (c)[0]),FloatInterpolate((a)[1], bness, (b)[1], (c)[1]),FloatInterpolate((a)[2], bness, (b)[2], (c)[2])
|
||||
|
||||
//#define SHOWCLIPS
|
||||
//#define FRAGMENTASTRIANGLES //works, but produces more fragments.
|
||||
|
||||
#ifdef FRAGMENTASTRIANGLES
|
||||
|
||||
//if the triangle is clipped away, go recursive if there are tris left.
|
||||
void Fragment_ClipTriToPlane(int trinum, float *plane, float planedist, fragmentdecal_t *dec)
|
||||
{
|
||||
float *point[3];
|
||||
float dotv[3];
|
||||
|
||||
vec3_t impact1, impact2;
|
||||
float t;
|
||||
|
||||
int i, i2, i3;
|
||||
int clippedverts = 0;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
point[i] = decalfragmentverts[trinum*3+i];
|
||||
dotv[i] = DotProduct(point[i], plane)-planedist;
|
||||
clippedverts += dotv[i] < 0;
|
||||
}
|
||||
|
||||
//if they're all clipped away, scrap the tri
|
||||
switch (clippedverts)
|
||||
{
|
||||
case 0:
|
||||
return; //plane does not clip the triangle.
|
||||
|
||||
case 1: //split into 3, disregard the clipped vert
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (dotv[i] < 0)
|
||||
{ //This is the vertex that's getting clipped.
|
||||
|
||||
if (dotv[i] > -DIST_EPSILON)
|
||||
return; //it's only over the line by a tiny ammount.
|
||||
|
||||
i2 = (i+1)%3;
|
||||
i3 = (i+2)%3;
|
||||
|
||||
if (dotv[i2] < DIST_EPSILON)
|
||||
return;
|
||||
if (dotv[i3] < DIST_EPSILON)
|
||||
return;
|
||||
|
||||
//work out where the two lines impact the plane
|
||||
t = (dotv[i]) / (dotv[i]-dotv[i2]);
|
||||
VectorInterpolate(point[i], t, point[i2], impact1);
|
||||
|
||||
t = (dotv[i]) / (dotv[i]-dotv[i3]);
|
||||
VectorInterpolate(point[i], t, point[i3], impact2);
|
||||
|
||||
#ifdef SHOWCLIPS
|
||||
if (dec->numtris != MAXFRAGMENTTRIS)
|
||||
{
|
||||
VectorCopy(impact2, decalfragmentverts[dec->numtris*3+0]);
|
||||
VectorCopy(decalfragmentverts[trinum*3+i], decalfragmentverts[dec->numtris*3+1]);
|
||||
VectorCopy(impact1, decalfragmentverts[dec->numtris*3+2]);
|
||||
dec->numtris++;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//shrink the tri, putting the impact into the killed vertex.
|
||||
VectorCopy(impact2, point[i]);
|
||||
|
||||
|
||||
if (dec->numtris == MAXFRAGMENTTRIS)
|
||||
return; //:(
|
||||
|
||||
//build the second tri
|
||||
VectorCopy(impact1, decalfragmentverts[dec->numtris*3+0]);
|
||||
VectorCopy(decalfragmentverts[trinum*3+i2], decalfragmentverts[dec->numtris*3+1]);
|
||||
VectorCopy(impact2, decalfragmentverts[dec->numtris*3+2]);
|
||||
dec->numtris++;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
Sys_Error("Fragment_ClipTriToPlane: Clipped vertex not founc\n");
|
||||
return; //can't handle it
|
||||
case 2: //split into 3, disregarding both the clipped.
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (!(dotv[i] < 0))
|
||||
{ //This is the vertex that's staying.
|
||||
|
||||
if (dotv[i] < DIST_EPSILON)
|
||||
break; //only just inside
|
||||
|
||||
i2 = (i+1)%3;
|
||||
i3 = (i+2)%3;
|
||||
|
||||
//work out where the two lines impact the plane
|
||||
t = (dotv[i]) / (dotv[i]-dotv[i2]);
|
||||
VectorInterpolate(point[i], t, point[i2], impact1);
|
||||
|
||||
t = (dotv[i]) / (dotv[i]-dotv[i3]);
|
||||
VectorInterpolate(point[i], t, point[i3], impact2);
|
||||
|
||||
//shrink the tri, putting the impact into the killed vertex.
|
||||
|
||||
#ifdef SHOWCLIPS
|
||||
if (dec->numtris != MAXFRAGMENTTRIS)
|
||||
{
|
||||
VectorCopy(impact1, decalfragmentverts[dec->numtris*3+0]);
|
||||
VectorCopy(point[i2], decalfragmentverts[dec->numtris*3+1]);
|
||||
VectorCopy(point[i3], decalfragmentverts[dec->numtris*3+2]);
|
||||
dec->numtris++;
|
||||
}
|
||||
if (dec->numtris != MAXFRAGMENTTRIS)
|
||||
{
|
||||
VectorCopy(impact1, decalfragmentverts[dec->numtris*3+0]);
|
||||
VectorCopy(point[i3], decalfragmentverts[dec->numtris*3+1]);
|
||||
VectorCopy(impact2, decalfragmentverts[dec->numtris*3+2]);
|
||||
dec->numtris++;
|
||||
}
|
||||
#endif
|
||||
|
||||
VectorCopy(impact1, point[i2]);
|
||||
VectorCopy(impact2, point[i3]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
case 3://scrap it
|
||||
//fill the verts with the verts of the last and go recursive (due to the nature of Fragment_ClipTriangle, which doesn't actually know if we clip them away)
|
||||
#ifndef SHOWCLIPS
|
||||
dec->numtris--;
|
||||
VectorCopy(decalfragmentverts[dec->numtris*3+0], decalfragmentverts[trinum*3+0]);
|
||||
VectorCopy(decalfragmentverts[dec->numtris*3+1], decalfragmentverts[trinum*3+1]);
|
||||
VectorCopy(decalfragmentverts[dec->numtris*3+2], decalfragmentverts[trinum*3+2]);
|
||||
if (trinum < dec->numtris)
|
||||
Fragment_ClipTriToPlane(trinum, plane, planedist, dec);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Fragment_ClipTriangle(fragmentdecal_t *dec, float *a, float *b, float *c)
|
||||
{
|
||||
//emit the triangle, and clip it's fragments.
|
||||
int start, i;
|
||||
|
||||
int p;
|
||||
|
||||
if (dec->numtris == MAXFRAGMENTTRIS)
|
||||
return; //:(
|
||||
|
||||
start = dec->numtris;
|
||||
|
||||
VectorCopy(a, decalfragmentverts[dec->numtris*3+0]);
|
||||
VectorCopy(b, decalfragmentverts[dec->numtris*3+1]);
|
||||
VectorCopy(c, decalfragmentverts[dec->numtris*3+2]);
|
||||
dec->numtris++;
|
||||
|
||||
//clip all the fragments to all of the planes.
|
||||
//This will produce a quad if the source triangle was big enough.
|
||||
|
||||
for (p = 0; p < 6; p++)
|
||||
{
|
||||
for (i = start; i < dec->numtris; i++)
|
||||
Fragment_ClipTriToPlane(i, dec->planenorm[p], dec->plantdist[p], dec);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define MAXFRAGMENTVERTS 128
|
||||
int Fragment_ClipPolyToPlane(float *inverts, float *outverts, int incount, float *plane, float planedist)
|
||||
{
|
||||
float dotv[MAXFRAGMENTVERTS];
|
||||
int i, i2, i3;
|
||||
int outcount = 0;
|
||||
int clippedcount = 0;
|
||||
vec3_t impact;
|
||||
|
||||
float *lastvalid; //the reason these arn't just an index is because it'd need to be a special case for the first vert.
|
||||
float lastvaliddot;
|
||||
|
||||
for (i = 0; i < incount; i++)
|
||||
{
|
||||
dotv[i] = DotProduct((inverts+i*3), plane) - planedist;
|
||||
if (dotv[i]<-DIST_EPSILON)
|
||||
clippedcount++;
|
||||
else
|
||||
{
|
||||
lastvalid = inverts+i*3;
|
||||
lastvaliddot = dotv[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (clippedcount == incount)
|
||||
return 0; //all were clipped
|
||||
if (clippedcount == 0)
|
||||
{
|
||||
memcpy(outverts, inverts, sizeof(float)*3*incount);
|
||||
return incount;
|
||||
}
|
||||
|
||||
for (i = 0; i < incount; )
|
||||
{
|
||||
if (dotv[i] < -DIST_EPSILON) //clipped
|
||||
{
|
||||
//work out where the line impacts the plane
|
||||
lastvaliddot = (dotv[i]) / (dotv[i]-lastvaliddot);
|
||||
VectorInterpolate((inverts+i*3), lastvaliddot, lastvalid, impact);
|
||||
|
||||
if (outcount+1 >= MAXFRAGMENTVERTS) //bum
|
||||
break;
|
||||
|
||||
outverts[outcount*3 + 0] = impact[0];
|
||||
outverts[outcount*3 + 1] = impact[1];
|
||||
outverts[outcount*3 + 2] = impact[2];
|
||||
outcount++;
|
||||
|
||||
i3 = (i+1);
|
||||
while (dotv[i3%incount] < -DIST_EPSILON) //clipped
|
||||
i3++;
|
||||
i = (i3-1)%incount;
|
||||
i2=i3%incount;
|
||||
|
||||
lastvaliddot = (dotv[i]) / (dotv[i]-dotv[i2]);
|
||||
VectorInterpolate((inverts+i*3), lastvaliddot, (inverts+i2*3), impact);
|
||||
|
||||
outverts[outcount*3 + 0] = impact[0];
|
||||
outverts[outcount*3 + 1] = impact[1];
|
||||
outverts[outcount*3 + 2] = impact[2];
|
||||
outcount++;
|
||||
lastvalid = outverts+outcount*3;
|
||||
lastvaliddot = 0; // :)
|
||||
|
||||
i = i3;
|
||||
}
|
||||
else
|
||||
{ //this vertex wasn't clipped. Just copy to the output.
|
||||
|
||||
if (outcount == MAXFRAGMENTVERTS) //bum
|
||||
break;
|
||||
|
||||
outverts[outcount*3 + 0] = inverts[i*3 + 0];
|
||||
outverts[outcount*3 + 1] = inverts[i*3 + 1];
|
||||
outverts[outcount*3 + 2] = inverts[i*3 + 2];
|
||||
lastvalid = inverts+i*3;
|
||||
lastvaliddot = dotv[i];
|
||||
|
||||
outcount++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return outcount;
|
||||
}
|
||||
|
||||
void Fragment_ClipTriangle(fragmentdecal_t *dec, float *a, float *b, float *c)
|
||||
{
|
||||
//emit the triangle, and clip it's fragments.
|
||||
int start, i;
|
||||
int p;
|
||||
float verts[MAXFRAGMENTVERTS*3];
|
||||
float verts2[MAXFRAGMENTVERTS*3];
|
||||
int numverts;
|
||||
|
||||
|
||||
if (dec->numtris == MAXFRAGMENTTRIS)
|
||||
return; //don't bother
|
||||
|
||||
VectorCopy(a, (verts+0*3));
|
||||
VectorCopy(b, (verts+1*3));
|
||||
VectorCopy(c, (verts+2*3));
|
||||
numverts = 3;
|
||||
|
||||
//clip the triangle to the 6 planes.
|
||||
for (p = 0; p < 6; p+=2)
|
||||
{
|
||||
numverts = Fragment_ClipPolyToPlane(verts, verts2, numverts, dec->planenorm[p], dec->planedist[p]);
|
||||
if (numverts < 3) //totally clipped.
|
||||
return;
|
||||
|
||||
numverts = Fragment_ClipPolyToPlane(verts2, verts, numverts, dec->planenorm[p+1], dec->planedist[p+1]);
|
||||
if (numverts < 3) //totally clipped.
|
||||
return;
|
||||
}
|
||||
|
||||
//decompose the resultant polygon into triangles.
|
||||
|
||||
while(numverts>2)
|
||||
{
|
||||
if (dec->numtris == MAXFRAGMENTTRIS)
|
||||
return;
|
||||
|
||||
numverts--;
|
||||
|
||||
VectorCopy((verts+3*0), decalfragmentverts[dec->numtris*3+0]);
|
||||
VectorCopy((verts+3*(numverts-1)), decalfragmentverts[dec->numtris*3+1]);
|
||||
VectorCopy((verts+3*numverts), decalfragmentverts[dec->numtris*3+2]);
|
||||
dec->numtris++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//this could be inlined, but I'm lazy.
|
||||
void Q1BSP_FragmentToMesh (fragmentdecal_t *dec, mesh_t *mesh)
|
||||
{
|
||||
int i;
|
||||
|
||||
float *a, *b, *c;
|
||||
|
||||
for (i = 0; i < mesh->numindexes; i+=3)
|
||||
{
|
||||
if (dec->numtris == MAXFRAGMENTTRIS)
|
||||
break;
|
||||
a = mesh->xyz_array[mesh->indexes[i+0]];
|
||||
b = mesh->xyz_array[mesh->indexes[i+1]];
|
||||
c = mesh->xyz_array[mesh->indexes[i+2]];
|
||||
|
||||
Fragment_ClipTriangle(dec, a, b, c);
|
||||
}
|
||||
}
|
||||
|
||||
#include "glquake.h"
|
||||
void Q1BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node)
|
||||
{
|
||||
mplane_t *splitplane;
|
||||
float dist;
|
||||
msurface_t *surf;
|
||||
int i;
|
||||
|
||||
if (node->contents < 0)
|
||||
return;
|
||||
|
||||
splitplane = node->plane;
|
||||
dist = DotProduct (dec->center, splitplane->normal) - splitplane->dist;
|
||||
|
||||
if (dist > dec->radius)
|
||||
{
|
||||
Q1BSP_ClipDecalToNodes (dec, node->children[0]);
|
||||
return;
|
||||
}
|
||||
if (dist < -dec->radius)
|
||||
{
|
||||
Q1BSP_ClipDecalToNodes (dec, node->children[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
// mark the polygons
|
||||
surf = cl.worldmodel->surfaces + node->firstsurface;
|
||||
for (i=0 ; i<node->numsurfaces ; i++, surf++)
|
||||
{
|
||||
Q1BSP_FragmentToMesh(dec, surf->mesh);
|
||||
}
|
||||
|
||||
Q1BSP_ClipDecalToNodes (dec, node->children[0]);
|
||||
Q1BSP_ClipDecalToNodes (dec, node->children[1]);
|
||||
}
|
||||
|
||||
int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent, float size, float **out)
|
||||
{ //quad marks a full, independant quad
|
||||
int p;
|
||||
fragmentdecal_t dec;
|
||||
|
||||
VectorCopy(center, dec.center);
|
||||
VectorCopy(normal, dec.normal);
|
||||
VectorCopy(tangent, dec.tangent1);
|
||||
CrossProduct(tangent, normal, dec.tangent2);
|
||||
dec.radius = size/2;
|
||||
dec.numtris = 0;
|
||||
|
||||
VectorCopy(dec.tangent1, dec.planenorm[0]);
|
||||
VectorNegate(dec.tangent1, dec.planenorm[1]);
|
||||
VectorCopy(dec.tangent2, dec.planenorm[2]);
|
||||
VectorNegate(dec.tangent2, dec.planenorm[3]);
|
||||
VectorCopy(dec.normal, dec.planenorm[4]);
|
||||
VectorNegate(dec.normal, dec.planenorm[5]);
|
||||
for (p = 0; p < 6; p++)
|
||||
dec.planedist[p] = -(dec.radius - DotProduct(dec.center, dec.planenorm[p]));
|
||||
|
||||
Q1BSP_ClipDecalToNodes(&dec, cl.worldmodel->nodes);
|
||||
|
||||
*out = (float *)decalfragmentverts;
|
||||
return dec.numtris;
|
||||
}
|
||||
|
||||
//This is spike's testing function, and is only usable by gl. :)
|
||||
void Q1BSP_TestClipDecal(void)
|
||||
{
|
||||
/*
|
||||
int i;
|
||||
int numtris;
|
||||
vec3_t fwd;
|
||||
vec3_t start;
|
||||
vec3_t center, normal, tangent;
|
||||
float *verts;
|
||||
|
||||
if (cls.state != ca_active)
|
||||
return;
|
||||
|
||||
VectorCopy(cl.simorg[0], start);
|
||||
start[2]+=22;
|
||||
VectorMA(start, 10000, vpn, fwd);
|
||||
|
||||
TraceLineN(start, fwd, center, normal);
|
||||
|
||||
CrossProduct(fwd, normal, tangent);
|
||||
VectorNormalize(tangent);
|
||||
|
||||
numtris = Q1BSP_ClipDecal(center, normal, tangent, 128, &verts);
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
qglDisable(GL_BLEND);
|
||||
qglDisable(GL_DEPTH_TEST);
|
||||
|
||||
qglColor3f(1, 0, 0);
|
||||
qglShadeModel(GL_SMOOTH);
|
||||
qglBegin(GL_TRIANGLES);
|
||||
for (i = 0; i < numtris; i++)
|
||||
{
|
||||
qglVertex3fv(verts+i*9+0);
|
||||
qglVertex3fv(verts+i*9+3);
|
||||
qglVertex3fv(verts+i*9+6);
|
||||
}
|
||||
qglEnd();
|
||||
|
||||
qglColor3f(1, 1, 1);
|
||||
qglBegin(GL_LINES);
|
||||
for (i = 0; i < numtris; i++)
|
||||
{
|
||||
qglVertex3fv(verts+i*9+0);
|
||||
qglVertex3fv(verts+i*9+3);
|
||||
qglVertex3fv(verts+i*9+3);
|
||||
qglVertex3fv(verts+i*9+6);
|
||||
qglVertex3fv(verts+i*9+6);
|
||||
qglVertex3fv(verts+i*9+0);
|
||||
}
|
||||
|
||||
qglVertex3fv(center);
|
||||
VectorMA(center, 10, normal, fwd);
|
||||
qglVertex3fv(fwd);
|
||||
|
||||
qglColor3f(0, 1, 0);
|
||||
qglVertex3fv(center);
|
||||
VectorMA(center, 10, tangent, fwd);
|
||||
qglVertex3fv(fwd);
|
||||
|
||||
qglColor3f(0, 0, 1);
|
||||
qglVertex3fv(center);
|
||||
CrossProduct(tangent, normal, fwd);
|
||||
VectorMA(center, 10, fwd, fwd);
|
||||
qglVertex3fv(fwd);
|
||||
|
||||
qglColor3f(1, 1, 1);
|
||||
|
||||
qglEnd();
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
qglEnable(GL_DEPTH_TEST);
|
||||
*/
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
Rendering functions (Client only)
|
||||
|
@ -328,6 +808,10 @@ void Q1BSP_FatPVS (vec3_t org, qboolean add)
|
|||
qboolean Q1BSP_EdictInFatPVS(edict_t *ent)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (ent->num_leafs == MAX_ENT_LEAFS+1)
|
||||
return true; //it's in too many leafs for us to cope with. Just trivially accept it.
|
||||
|
||||
for (i=0 ; i < ent->num_leafs ; i++)
|
||||
if (fatpvs[ent->leafnums[i] >> 3] & (1 << (ent->leafnums[i]&7) ))
|
||||
return true; //we might be able to see this one.
|
||||
|
@ -356,8 +840,11 @@ void Q1BSP_RFindTouchedLeafs (edict_t *ent, mnode_t *node)
|
|||
|
||||
if ( node->contents < 0)
|
||||
{
|
||||
if (ent->num_leafs == MAX_ENT_LEAFS)
|
||||
if (ent->num_leafs >= MAX_ENT_LEAFS)
|
||||
{
|
||||
ent->num_leafs = MAX_ENT_LEAFS+1; //too many. mark it as such so we can trivially accept huge mega-big brush models.
|
||||
return;
|
||||
}
|
||||
|
||||
leaf = (mleaf_t *)node;
|
||||
leafnum = leaf - sv.worldmodel->leafs - 1;
|
||||
|
|
|
@ -963,7 +963,7 @@ vm_t *VM_Create(vm_t *vm, const char *name, sys_call_t syscall, sys_callex_t sys
|
|||
{
|
||||
if((vm->hInst=Sys_LoadDLL(name, (void**)&vm->vmMain, syscall)))
|
||||
{
|
||||
Con_Printf("Creating native machine \"%s\"\n", name);
|
||||
Con_DPrintf("Creating native machine \"%s\"\n", name);
|
||||
vm->type=VM_NATIVE;
|
||||
return vm;
|
||||
}
|
||||
|
@ -972,7 +972,7 @@ vm_t *VM_Create(vm_t *vm, const char *name, sys_call_t syscall, sys_callex_t sys
|
|||
|
||||
if((vm->hInst=QVM_Load(name, syscallex)))
|
||||
{
|
||||
Con_Printf("Creating virtual machine \"%s\"\n", name);
|
||||
Con_DPrintf("Creating virtual machine \"%s\"\n", name);
|
||||
vm->type=VM_BYTECODE;
|
||||
return vm;
|
||||
}
|
||||
|
|
|
@ -2571,6 +2571,14 @@ SOURCE=..\client\zqtp.c
|
|||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\gl\doomclip.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\gl\doommap.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\gl\gl_alias.c
|
||||
|
||||
!IF "$(CFG)" == "ftequake - Win32 Release"
|
||||
|
|
|
@ -58,7 +58,7 @@ int numTempColours;
|
|||
byte_vec4_t *tempColours;
|
||||
|
||||
int numTempVertexCoords;
|
||||
vec4_t *tempVertexCoords;
|
||||
vec3_t *tempVertexCoords;
|
||||
|
||||
int numTempNormals;
|
||||
vec3_t *tempNormals;
|
||||
|
@ -179,14 +179,11 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float
|
|||
if (p1v == p2v || r_nolerp.value)
|
||||
{
|
||||
mesh->normals_array = (vec3_t*)((char *)p1 + p1->ofsnormals);
|
||||
mesh->xyz_array = p1v;
|
||||
if (r_nolightdir.value)
|
||||
{
|
||||
for (i = 0; i < mesh->numvertexes; i++)
|
||||
{
|
||||
mesh->xyz_array[i][0] = p1v[i][0];
|
||||
mesh->xyz_array[i][1] = p1v[i][1];
|
||||
mesh->xyz_array[i][2] = p1v[i][2];
|
||||
|
||||
mesh->colors_array[i][0] = /*ambientlight[0]/2*/+shadelight[0];
|
||||
mesh->colors_array[i][1] = /*ambientlight[1]/2*/+shadelight[1];
|
||||
mesh->colors_array[i][2] = /*ambientlight[2]/2*/+shadelight[2];
|
||||
|
@ -197,10 +194,6 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float
|
|||
{
|
||||
for (i = 0; i < mesh->numvertexes; i++)
|
||||
{
|
||||
mesh->xyz_array[i][0] = p1v[i][0];
|
||||
mesh->xyz_array[i][1] = p1v[i][1];
|
||||
mesh->xyz_array[i][2] = p1v[i][2];
|
||||
|
||||
l = DotProduct(mesh->normals_array[i], shadevector);
|
||||
|
||||
temp = l*ambientlight[0]+shadelight[0];
|
||||
|
@ -276,11 +269,25 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float
|
|||
}
|
||||
if (expand)
|
||||
{
|
||||
for (i = 0; i < mesh->numvertexes; i++)
|
||||
if (mesh->xyz_array == p1v)
|
||||
{
|
||||
mesh->xyz_array[i][0] += mesh->normals_array[i][0]*expand;
|
||||
mesh->xyz_array[i][1] += mesh->normals_array[i][1]*expand;
|
||||
mesh->xyz_array[i][2] += mesh->normals_array[i][2]*expand;
|
||||
mesh->xyz_array = tempVertexCoords;
|
||||
for (i = 0; i < mesh->numvertexes; i++)
|
||||
{
|
||||
mesh->xyz_array[i][0] = p1v[i][0] + mesh->normals_array[i][0]*expand;
|
||||
mesh->xyz_array[i][1] = p1v[i][1] + mesh->normals_array[i][1]*expand;
|
||||
mesh->xyz_array[i][2] = p1v[i][2] + mesh->normals_array[i][2]*expand;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < mesh->numvertexes; i++)
|
||||
{
|
||||
mesh->xyz_array[i][0] += mesh->normals_array[i][0]*expand;
|
||||
mesh->xyz_array[i][1] += mesh->normals_array[i][1]*expand;
|
||||
mesh->xyz_array[i][2] += mesh->normals_array[i][2]*expand;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -341,7 +348,7 @@ static void R_BuildSkeletalMesh(mesh_t *mesh, float *plerp, float **pose, int po
|
|||
v = weights;
|
||||
for (i = 0;i < numweights;i++, v++)
|
||||
{
|
||||
out = outhead + v->vertexindex * 4;
|
||||
out = outhead + v->vertexindex * 3;
|
||||
matrix = bonepose[v->boneindex];
|
||||
// FIXME: this can very easily be optimized with SSE or 3DNow
|
||||
out[0] += v->org[0] * matrix[0] + v->org[1] * matrix[1] + v->org[2] * matrix[ 2] + v->org[3] * matrix[ 3];
|
||||
|
@ -893,7 +900,7 @@ static void R_ProjectShadowVolume(mesh_t *mesh, vec3_t lightpos)
|
|||
{
|
||||
int numverts = mesh->numvertexes;
|
||||
int i;
|
||||
vec4_t *input = mesh->xyz_array;
|
||||
vec3_t *input = mesh->xyz_array;
|
||||
vec3_t *projected;
|
||||
if (numProjectedShadowVerts < numverts)
|
||||
{
|
||||
|
@ -915,7 +922,7 @@ static void R_DrawShadowVolume(mesh_t *mesh)
|
|||
{
|
||||
int t;
|
||||
vec3_t *proj = ProjectedShadowVerts;
|
||||
vec4_t *verts = mesh->xyz_array;
|
||||
vec3_t *verts = mesh->xyz_array;
|
||||
index_t *indexes = mesh->indexes;
|
||||
int *neighbours = mesh->trneighbors;
|
||||
int numtris = mesh->numindexes/3;
|
||||
|
@ -990,7 +997,7 @@ void GL_DrawAliasMesh_Sketch (mesh_t *mesh)
|
|||
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
|
||||
qglVertexPointer(3, GL_FLOAT, 16, mesh->xyz_array);
|
||||
qglVertexPointer(3, GL_FLOAT, 0, mesh->xyz_array);
|
||||
qglEnableClientState( GL_VERTEX_ARRAY );
|
||||
|
||||
if (mesh->normals_array && qglNormalPointer) //d3d wrapper doesn't support normals, and this is only really needed for truform
|
||||
|
@ -1075,7 +1082,7 @@ void GL_DrawAliasMesh (mesh_t *mesh, int texnum)
|
|||
|
||||
GL_TexEnv(GL_MODULATE);
|
||||
|
||||
qglVertexPointer(3, GL_FLOAT, 16, mesh->xyz_array);
|
||||
qglVertexPointer(3, GL_FLOAT, 0, mesh->xyz_array);
|
||||
qglEnableClientState( GL_VERTEX_ARRAY );
|
||||
|
||||
if (mesh->normals_array && qglNormalPointer) //d3d wrapper doesn't support normals, and this is only really needed for truform
|
||||
|
@ -1595,7 +1602,7 @@ void GL_LightMesh (mesh_t *mesh, vec3_t lightpos, vec3_t colours, float radius)
|
|||
vec3_t dir;
|
||||
int i;
|
||||
float dot;
|
||||
vec4_t *xyz = mesh->xyz_array;
|
||||
vec3_t *xyz = mesh->xyz_array;
|
||||
vec3_t *normals = mesh->normals_array;
|
||||
byte_vec4_t *out = mesh->colors_array;
|
||||
|
||||
|
@ -1924,6 +1931,7 @@ static void *Q1_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps)
|
|||
|
||||
pframetype = (daliasframetype_t *)&pinframe[pq1inmodel->numverts];
|
||||
break;
|
||||
|
||||
case ALIAS_GROUP:
|
||||
case ALIAS_GROUP_SWAPPED: // prerelease
|
||||
ingroup = (daliasgroup_t *)(pframetype+1);
|
||||
|
@ -2003,6 +2011,7 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha)
|
|||
outskin->skinheight = pq1inmodel->skinheight;
|
||||
|
||||
//LH's naming scheme ("models" is likly to be ignored)
|
||||
fbtexture = 0;
|
||||
_snprintf(skinname, sizeof(skinname), "%s_%i", loadmodel->name, i);
|
||||
texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true);
|
||||
if (texture)
|
||||
|
@ -2019,8 +2028,6 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha)
|
|||
sprintf(skinname, "%s_%i_luma", loadname, i);
|
||||
fbtexture = Mod_LoadReplacementTexture(skinname, "models", true, true, true);
|
||||
}
|
||||
else
|
||||
fbtexture = 0;
|
||||
}
|
||||
|
||||
if (!texture)
|
||||
|
@ -2933,12 +2940,12 @@ void GL_LoadQ3Model(model_t *mod, void *buffer)
|
|||
texnum->shader = R_RegisterSkin(inshader->name);
|
||||
#else
|
||||
|
||||
texnum->base = Mod_LoadHiResTexture(inshader->name, true, true, true);
|
||||
texnum->base = Mod_LoadHiResTexture(inshader->name, "models", true, true, true);
|
||||
if (!texnum->base)
|
||||
{
|
||||
strcpy(name, loadmodel->name);
|
||||
strcpy(COM_SkipPath(name), COM_SkipPath(inshader->name)); //eviile eh?
|
||||
texnum->base = Mod_LoadHiResTexture(name, true, true, true);
|
||||
texnum->base = Mod_LoadHiResTexture(name, "models", true, true, true);
|
||||
}
|
||||
|
||||
texnum->bump = 0;
|
||||
|
@ -2946,25 +2953,25 @@ void GL_LoadQ3Model(model_t *mod, void *buffer)
|
|||
{
|
||||
COM_StripExtension(inshader->name, name); //go for the normalmap
|
||||
strcat(name, "_norm");
|
||||
texnum->bump = Mod_LoadHiResTexture(name, true, true, false);
|
||||
texnum->bump = Mod_LoadHiResTexture(name, "models", true, true, false);
|
||||
if (!texnum->bump)
|
||||
{
|
||||
strcpy(name, loadmodel->name);
|
||||
COM_StripExtension(COM_SkipPath(inshader->name), COM_SkipPath(name));
|
||||
strcat(name, "_norm");
|
||||
texnum->bump = Mod_LoadHiResTexture(name, true, true, false);
|
||||
texnum->bump = Mod_LoadHiResTexture(name, "models", true, true, false);
|
||||
if (!texnum->bump)
|
||||
{
|
||||
COM_StripExtension(inshader->name, name); //bother, go for heightmap and convert
|
||||
strcat(name, "_bump");
|
||||
texnum->bump = Mod_LoadBumpmapTexture(name);
|
||||
texnum->bump = Mod_LoadBumpmapTexture(name, "models");
|
||||
if (!texnum->bump)
|
||||
{
|
||||
strcpy(name, loadmodel->name);
|
||||
strcpy(COM_SkipPath(name), COM_SkipPath(inshader->name)); //eviile eh?
|
||||
COM_StripExtension(name, name);
|
||||
strcat(name, "_bump");
|
||||
texnum->bump = Mod_LoadBumpmapTexture(name);
|
||||
texnum->bump = Mod_LoadBumpmapTexture(name, "models");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2973,14 +2980,14 @@ void GL_LoadQ3Model(model_t *mod, void *buffer)
|
|||
{
|
||||
COM_StripExtension(inshader->name, name); //go for the normalmap
|
||||
strcat(name, "_luma");
|
||||
texnum->fullbright = Mod_LoadHiResTexture(name, true, true, true);
|
||||
texnum->fullbright = Mod_LoadHiResTexture(name, "models", true, true, true);
|
||||
if (!texnum->base)
|
||||
{
|
||||
strcpy(name, loadmodel->name);
|
||||
strcpy(COM_SkipPath(name), COM_SkipPath(inshader->name)); //eviile eh?
|
||||
COM_StripExtension(name, name);
|
||||
strcat(name, "_luma");
|
||||
texnum->fullbright = Mod_LoadBumpmapTexture(name);
|
||||
texnum->fullbright = Mod_LoadBumpmapTexture(name, "models");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -223,10 +223,10 @@ vec3_t *trNormalsArray;
|
|||
vec2_t *coordsArray;
|
||||
vec2_t *lightmapCoordsArray;
|
||||
|
||||
vec4_t vertexArray[MAX_ARRAY_VERTS*2];
|
||||
vec3_t vertexArray[MAX_ARRAY_VERTS*2];
|
||||
vec3_t normalsArray[MAX_ARRAY_VERTS];
|
||||
|
||||
vec4_t tempVertexArray[MAX_ARRAY_VERTS];
|
||||
vec3_t tempVertexArray[MAX_ARRAY_VERTS];
|
||||
vec3_t tempNormalsArray[MAX_ARRAY_VERTS];
|
||||
index_t tempIndexesArray[MAX_ARRAY_INDEXES];
|
||||
|
||||
|
@ -362,8 +362,8 @@ void R_PushMesh ( mesh_t *mesh, int features )
|
|||
numverts = MAX_ARRAY_VERTS - numVerts;
|
||||
}
|
||||
|
||||
memcpy ( currentVertex, mesh->xyz_array, numverts * sizeof(vec4_t) );
|
||||
currentVertex += numverts * 4;
|
||||
memcpy ( currentVertex, mesh->xyz_array, numverts * sizeof(vec3_t) );
|
||||
currentVertex += numverts * 3;
|
||||
|
||||
if ( mesh->normals_array && (features & MF_NORMALS) ) {
|
||||
memcpy ( currentNormal, mesh->normals_array, numverts * sizeof(vec3_t) );
|
||||
|
@ -402,6 +402,14 @@ void R_PushMesh ( mesh_t *mesh, int features )
|
|||
}
|
||||
|
||||
|
||||
qboolean R_MeshWillExceed(mesh_t *mesh)
|
||||
{
|
||||
if (numVerts + mesh->numvertexes > MAX_ARRAY_VERTS)
|
||||
return true;
|
||||
if (numIndexes + mesh->numindexes > MAX_ARRAY_INDEXES)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
extern index_t r_quad_indexes[6];// = { 0, 1, 2, 0, 2, 3 };
|
||||
|
||||
|
@ -487,7 +495,7 @@ qboolean varrayactive;
|
|||
void R_IBrokeTheArrays(void)
|
||||
{
|
||||
varrayactive = true;
|
||||
qglVertexPointer( 3, GL_FLOAT, 16, vertexArray ); // padded for SIMD
|
||||
qglVertexPointer( 3, GL_FLOAT, 0, vertexArray );
|
||||
qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray );
|
||||
|
||||
qglEnableClientState( GL_VERTEX_ARRAY );
|
||||
|
|
|
@ -31,7 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
int glx, gly, glwidth, glheight;
|
||||
|
||||
mesh_t draw_mesh;
|
||||
vec4_t draw_mesh_xyz[4];
|
||||
vec3_t draw_mesh_xyz[4];
|
||||
vec2_t draw_mesh_st[4];
|
||||
byte_vec4_t draw_mesh_colors[4];
|
||||
|
||||
|
@ -3247,6 +3247,30 @@ void GL_Upload8Pal24 (qbyte *data, qbyte *pal, int width, int height, qboolean
|
|||
}
|
||||
GL_Upload32 (NULL, (unsigned*)trans, width, height, mipmap, alpha);
|
||||
}
|
||||
void GL_Upload8Pal32 (qbyte *data, qbyte *pal, int width, int height, qboolean mipmap, qboolean alpha)
|
||||
{
|
||||
qbyte *trans = uploadmemorybufferintermediate;
|
||||
int i, s;
|
||||
qboolean noalpha;
|
||||
int p;
|
||||
extern qbyte gammatable[256];
|
||||
|
||||
s = width*height;
|
||||
if (s > sizeofuploadmemorybufferintermediate/4)
|
||||
Sys_Error("GL_Upload8Pal32: image too big (%i*%i)", width, height);
|
||||
|
||||
if (s&3)
|
||||
Sys_Error ("GL_Upload8: s&3");
|
||||
for (i=0 ; i<s ; i+=1)
|
||||
{
|
||||
trans[(i<<2)+0] = gammatable[pal[data[i]*4+0]];
|
||||
trans[(i<<2)+1] = gammatable[pal[data[i]*4+1]];
|
||||
trans[(i<<2)+2] = gammatable[pal[data[i]*4+2]];
|
||||
trans[(i<<2)+3] = gammatable[pal[data[i]*4+3]];
|
||||
}
|
||||
|
||||
GL_Upload32 (NULL, (unsigned*)trans, width, height, mipmap, true);
|
||||
}
|
||||
/*
|
||||
================
|
||||
GL_LoadTexture
|
||||
|
@ -3368,6 +3392,40 @@ int GL_LoadTexture8Pal24 (char *identifier, int width, int height, qbyte *data,
|
|||
|
||||
return texture_extension_number-1;
|
||||
}
|
||||
int GL_LoadTexture8Pal32 (char *identifier, int width, int height, qbyte *data, qbyte *palette32, qboolean mipmap, qboolean alpha)
|
||||
{
|
||||
gltexture_t *glt;
|
||||
|
||||
// see if the texture is allready present
|
||||
if (identifier[0])
|
||||
{
|
||||
glt = GL_MatchTexture(identifier, 32, width, height);
|
||||
if (glt)
|
||||
return glt->texnum;
|
||||
}
|
||||
|
||||
glt = BZ_Malloc(sizeof(*glt)+sizeof(bucket_t));
|
||||
glt->next = gltextures;
|
||||
gltextures = glt;
|
||||
|
||||
|
||||
strcpy (glt->identifier, identifier);
|
||||
glt->texnum = texture_extension_number;
|
||||
glt->width = width;
|
||||
glt->height = height;
|
||||
glt->bpp = 32;
|
||||
glt->mipmap = mipmap;
|
||||
|
||||
Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1));
|
||||
|
||||
GL_Bind(texture_extension_number );
|
||||
|
||||
GL_Upload8Pal32 (data, palette32, width, height, mipmap, alpha);
|
||||
|
||||
texture_extension_number++;
|
||||
|
||||
return texture_extension_number-1;
|
||||
}
|
||||
|
||||
int GL_LoadTexture32 (char *identifier, int width, int height, unsigned *data, qboolean mipmap, qboolean alpha)
|
||||
{
|
||||
|
|
|
@ -669,7 +669,7 @@ couldntload:
|
|||
|
||||
case 30: //hl
|
||||
case 29: //q1
|
||||
case 28:
|
||||
case 28: //prerel
|
||||
GLMod_LoadBrushModel (mod, buf);
|
||||
break;
|
||||
#ifdef ZYMOTICMODELS
|
||||
|
@ -2807,7 +2807,7 @@ void GLMod_FloodFillSkin( qbyte *skin, int skinwidth, int skinheight )
|
|||
Mod_LoadSpriteFrame
|
||||
=================
|
||||
*/
|
||||
void * GLMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum, int version)
|
||||
void * GLMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum, int version, unsigned char *palette)
|
||||
{
|
||||
dspriteframe_t *pinframe;
|
||||
mspriteframe_t *pspriteframe;
|
||||
|
@ -2839,15 +2839,25 @@ void * GLMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum
|
|||
COM_StripExtension(loadmodel->name, name);
|
||||
strcat(name, va("_%i", framenum));
|
||||
pspriteframe->gl_texturenum = Mod_LoadReplacementTexture(name, "sprites", true, true, true);
|
||||
|
||||
if (version == SPRITE32_VERSION)
|
||||
{
|
||||
size *= 4;
|
||||
if (!pspriteframe->gl_texturenum) pspriteframe->gl_texturenum = GL_LoadTexture32 (name, width, height, (unsigned *)(pinframe + 1), true, true);
|
||||
if (!pspriteframe->gl_texturenum)
|
||||
pspriteframe->gl_texturenum = GL_LoadTexture32 (name, width, height, (unsigned *)(pinframe + 1), true, true);
|
||||
}
|
||||
else if (version == SPRITEHL_VERSION)
|
||||
{
|
||||
if (!pspriteframe->gl_texturenum)
|
||||
pspriteframe->gl_texturenum = GL_LoadTexture8Pal32 (name, width, height, (unsigned *)(pinframe + 1), palette, true, true);
|
||||
}
|
||||
else
|
||||
if (!pspriteframe->gl_texturenum) pspriteframe->gl_texturenum = GL_LoadTexture (name, width, height, (qbyte *)(pinframe + 1), true, true);
|
||||
{
|
||||
if (!pspriteframe->gl_texturenum)
|
||||
pspriteframe->gl_texturenum = GL_LoadTexture (name, width, height, (qbyte *)(pinframe + 1), true, true);
|
||||
}
|
||||
|
||||
return (void *)((qbyte *)pinframe + sizeof (dspriteframe_t) + size);
|
||||
return (void *)((qbyte *)(pinframe+1) + size);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2856,7 +2866,7 @@ void * GLMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum
|
|||
Mod_LoadSpriteGroup
|
||||
=================
|
||||
*/
|
||||
void * GLMod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum, int version)
|
||||
void * GLMod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum, int version, unsigned char *palette)
|
||||
{
|
||||
dspritegroup_t *pingroup;
|
||||
mspritegroup_t *pspritegroup;
|
||||
|
@ -2896,7 +2906,7 @@ void * GLMod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum
|
|||
|
||||
for (i=0 ; i<numframes ; i++)
|
||||
{
|
||||
ptemp = GLMod_LoadSpriteFrame (ptemp, &pspritegroup->frames[i], framenum * 100 + i, version);
|
||||
ptemp = GLMod_LoadSpriteFrame (ptemp, &pspritegroup->frames[i], framenum * 100 + i, version, palette);
|
||||
}
|
||||
|
||||
return ptemp;
|
||||
|
@ -2916,15 +2926,27 @@ void GLMod_LoadSpriteModel (model_t *mod, void *buffer)
|
|||
int numframes;
|
||||
int size;
|
||||
dspriteframetype_t *pframetype;
|
||||
int rendertype=0;
|
||||
unsigned char pal[256*4];
|
||||
int sptype;
|
||||
|
||||
pin = (dsprite_t *)buffer;
|
||||
|
||||
version = LittleLong (pin->version);
|
||||
if (version != SPRITE32_VERSION)
|
||||
if (version != SPRITE_VERSION)
|
||||
if (version != SPRITE32_VERSION)
|
||||
if (version != SPRITEHL_VERSION)
|
||||
Sys_Error ("%s has wrong version number "
|
||||
"(%i should be %i)", mod->name, version, SPRITE_VERSION);
|
||||
|
||||
sptype = LittleLong (pin->type);
|
||||
|
||||
if (pin->version == SPRITEHL_VERSION)
|
||||
{
|
||||
pin = (dsprite_t*)((char*)pin + 4);
|
||||
rendertype = LittleLong (pin->type);
|
||||
}
|
||||
|
||||
numframes = LittleLong (pin->numframes);
|
||||
|
||||
size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames);
|
||||
|
@ -2932,8 +2954,8 @@ void GLMod_LoadSpriteModel (model_t *mod, void *buffer)
|
|||
psprite = Hunk_AllocName (size, loadname);
|
||||
|
||||
mod->cache.data = psprite;
|
||||
psprite->type = sptype;
|
||||
|
||||
psprite->type = LittleLong (pin->type);
|
||||
psprite->maxwidth = LittleLong (pin->width);
|
||||
psprite->maxheight = LittleLong (pin->height);
|
||||
psprite->beamlength = LittleFloat (pin->beamlength);
|
||||
|
@ -2945,6 +2967,27 @@ void GLMod_LoadSpriteModel (model_t *mod, void *buffer)
|
|||
mod->mins[2] = -psprite->maxheight/2;
|
||||
mod->maxs[2] = psprite->maxheight/2;
|
||||
|
||||
if (pin->version == SPRITEHL_VERSION)
|
||||
{
|
||||
int i;
|
||||
short *numi = (short*)(pin+1);
|
||||
unsigned char *src = (unsigned char *)(numi+1);
|
||||
if (*numi != 256)
|
||||
Sys_Error("%s has wrong number of palette indexes (we only support 256)\n", mod->name);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
pal[i*4+0] = *src++;
|
||||
pal[i*4+1] = *src++;
|
||||
pal[i*4+2] = *src++;
|
||||
pal[i*4+3] = 255;
|
||||
}
|
||||
|
||||
pframetype = (dspriteframetype_t *)(src);
|
||||
}
|
||||
else
|
||||
pframetype = (dspriteframetype_t *)(pin + 1);
|
||||
|
||||
//
|
||||
// load the frames
|
||||
//
|
||||
|
@ -2953,8 +2996,6 @@ void GLMod_LoadSpriteModel (model_t *mod, void *buffer)
|
|||
|
||||
mod->numframes = numframes;
|
||||
|
||||
pframetype = (dspriteframetype_t *)(pin + 1);
|
||||
|
||||
for (i=0 ; i<numframes ; i++)
|
||||
{
|
||||
spriteframetype_t frametype;
|
||||
|
@ -2966,13 +3007,13 @@ void GLMod_LoadSpriteModel (model_t *mod, void *buffer)
|
|||
{
|
||||
pframetype = (dspriteframetype_t *)
|
||||
GLMod_LoadSpriteFrame (pframetype + 1,
|
||||
&psprite->frames[i].frameptr, i, version);
|
||||
&psprite->frames[i].frameptr, i, version, pal);
|
||||
}
|
||||
else
|
||||
{
|
||||
pframetype = (dspriteframetype_t *)
|
||||
GLMod_LoadSpriteGroup (pframetype + 1,
|
||||
&psprite->frames[i].frameptr, i, version);
|
||||
&psprite->frames[i].frameptr, i, version, pal);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ typedef int index_t;
|
|||
typedef struct mesh_s
|
||||
{
|
||||
int numvertexes;
|
||||
vec4_t *xyz_array;
|
||||
vec3_t *xyz_array;
|
||||
vec3_t *normals_array;
|
||||
vec2_t *st_array;
|
||||
vec2_t *lmst_array;
|
||||
|
@ -73,7 +73,7 @@ struct meshbuffer_s;
|
|||
|
||||
void R_PushMesh ( mesh_t *mesh, int features );
|
||||
void R_RenderMeshBuffer ( struct meshbuffer_s *mb, qboolean shadowpass );
|
||||
|
||||
qboolean R_MeshWillExceed(mesh_t *mesh);
|
||||
|
||||
extern int gl_canbumpmap;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ extern int *lightmap_textures;
|
|||
extern int lightmap_bytes; // 1, 2, or 4
|
||||
|
||||
extern cvar_t gl_detail;
|
||||
extern cvar_t gl_overbright;
|
||||
extern cvar_t r_fb_bmodels;
|
||||
extern cvar_t gl_part_flame;
|
||||
|
||||
|
@ -31,6 +32,8 @@ extern cvar_t r_drawflat;
|
|||
extern cvar_t r_wallcolour;
|
||||
extern cvar_t r_floorcolour;
|
||||
|
||||
int overbright;
|
||||
|
||||
extern lightmapinfo_t **lightmap;
|
||||
|
||||
extern model_t *currentmodel;
|
||||
|
@ -277,9 +280,10 @@ static void PPL_BaseChain_NoBump_2TMU(msurface_t *s, texture_t *tex)
|
|||
qglClientActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
qglTexCoordPointer(2, GL_FLOAT, 0, s->mesh->lmst_array);
|
||||
|
||||
qglVertexPointer(3, GL_FLOAT, sizeof(vec4_t), s->mesh->xyz_array);
|
||||
qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array);
|
||||
|
||||
qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
|
||||
qglDrawRangeElements(GL_TRIANGLES, 0, s->mesh->numvertexes, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
|
||||
//qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
|
||||
}
|
||||
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
|
@ -289,6 +293,195 @@ static void PPL_BaseChain_NoBump_2TMU(msurface_t *s, texture_t *tex)
|
|||
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
static void PPL_BaseChain_NoBump_2TMU_Overbright(msurface_t *s, texture_t *tex)
|
||||
{ //doesn't merge surfaces, but tells gl to do each vertex arrayed surface individually, which means no vertex copying.
|
||||
int vi;
|
||||
glRect_t *theRect;
|
||||
|
||||
PPL_EnableVertexArrays();
|
||||
|
||||
if (tex->alphaed)
|
||||
{
|
||||
qglEnable(GL_BLEND);
|
||||
GL_TexEnv(GL_MODULATE);
|
||||
}
|
||||
else
|
||||
{
|
||||
qglDisable(GL_BLEND);
|
||||
GL_TexEnv(GL_REPLACE);
|
||||
}
|
||||
|
||||
|
||||
GL_MBind(GL_TEXTURE0_ARB, tex->gl_texturenum);
|
||||
qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
GL_SelectTexture(GL_TEXTURE1_ARB);
|
||||
qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
|
||||
if (overbright != 1)
|
||||
{
|
||||
GL_TexEnv(GL_COMBINE_ARB);
|
||||
qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
|
||||
qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
|
||||
qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
|
||||
qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, overbright); //this is the key
|
||||
}
|
||||
|
||||
vi = -1;
|
||||
for (; s ; s=s->texturechain)
|
||||
{
|
||||
if (vi != s->lightmaptexturenum)
|
||||
{
|
||||
if (vi<0)
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
vi = s->lightmaptexturenum;
|
||||
|
||||
if (vi>=0)
|
||||
{
|
||||
GL_Bind(lightmap_textures[vi] );
|
||||
if (lightmap[vi]->modified)
|
||||
{
|
||||
lightmap[vi]->modified = false;
|
||||
theRect = &lightmap[vi]->rectchange;
|
||||
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
|
||||
LMBLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE,
|
||||
lightmap[vi]->lightmaps+(theRect->t) *LMBLOCK_WIDTH*lightmap_bytes);
|
||||
theRect->l = LMBLOCK_WIDTH;
|
||||
theRect->t = LMBLOCK_HEIGHT;
|
||||
theRect->h = 0;
|
||||
theRect->w = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
qglClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
qglTexCoordPointer(2, GL_FLOAT, 0, s->mesh->st_array);
|
||||
qglClientActiveTextureARB(GL_TEXTURE1_ARB);
|
||||
qglTexCoordPointer(2, GL_FLOAT, 0, s->mesh->lmst_array);
|
||||
|
||||
qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array);
|
||||
|
||||
qglDrawRangeElements(GL_TRIANGLES, 0, s->mesh->numvertexes, s->mesh->numindexes, GL_UNSIGNED_INT, s->mesh->indexes);
|
||||
}
|
||||
|
||||
if (overbright != 1)
|
||||
{
|
||||
qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1); //just in case
|
||||
GL_TexEnv(GL_MODULATE);
|
||||
}
|
||||
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
GL_SelectTexture(GL_TEXTURE0_ARB);
|
||||
qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
/*
|
||||
static void PPL_BaseChain_NoBump_2TMU_TEST(msurface_t *s, texture_t *tex)
|
||||
{ //this was just me testing efficiency between arrays/glbegin.
|
||||
int vi, i;
|
||||
glRect_t *theRect;
|
||||
|
||||
PPL_EnableVertexArrays();
|
||||
|
||||
if (tex->alphaed)
|
||||
{
|
||||
qglEnable(GL_BLEND);
|
||||
GL_TexEnv(GL_MODULATE);
|
||||
}
|
||||
else
|
||||
{
|
||||
qglDisable(GL_BLEND);
|
||||
GL_TexEnv(GL_REPLACE);
|
||||
}
|
||||
|
||||
qglCullFace(GL_BACK);
|
||||
|
||||
|
||||
GL_MBind(GL_TEXTURE0_ARB, tex->gl_texturenum);
|
||||
|
||||
GL_SelectTexture(GL_TEXTURE1_ARB);
|
||||
GL_TexEnv(GL_MODULATE);
|
||||
|
||||
vi = -1;
|
||||
for (; s ; s=s->texturechain)
|
||||
{
|
||||
if (vi != s->lightmaptexturenum)
|
||||
{
|
||||
if (vi<0)
|
||||
qglEnable(GL_TEXTURE_2D);
|
||||
vi = s->lightmaptexturenum;
|
||||
|
||||
if (vi>=0)
|
||||
{
|
||||
GL_Bind(lightmap_textures[vi] );
|
||||
if (lightmap[vi]->modified)
|
||||
{
|
||||
lightmap[vi]->modified = false;
|
||||
theRect = &lightmap[vi]->rectchange;
|
||||
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t,
|
||||
LMBLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE,
|
||||
lightmap[vi]->lightmaps+(theRect->t) *LMBLOCK_WIDTH*lightmap_bytes);
|
||||
theRect->l = LMBLOCK_WIDTH;
|
||||
theRect->t = LMBLOCK_HEIGHT;
|
||||
theRect->h = 0;
|
||||
theRect->w = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
qglBegin(GL_POLYGON);
|
||||
switch(s->mesh->numvertexes)
|
||||
{
|
||||
default:
|
||||
for (i = s->mesh->numvertexes-1; i >= 6; i--)
|
||||
{
|
||||
qglMultiTexCoord2fARB(GL_TEXTURE0_ARB, s->mesh->st_array[i][0], s->mesh->st_array[i][1]);
|
||||
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, s->mesh->lmst_array[i][0], s->mesh->lmst_array[i][1]);
|
||||
qglVertex3fv(s->mesh->xyz_array[i]);
|
||||
}
|
||||
case 6:
|
||||
qglMultiTexCoord2fARB(GL_TEXTURE0_ARB, s->mesh->st_array[5][0], s->mesh->st_array[5][1]);
|
||||
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, s->mesh->lmst_array[5][0], s->mesh->lmst_array[5][1]);
|
||||
qglVertex3fv(s->mesh->xyz_array[5]);
|
||||
case 5:
|
||||
qglMultiTexCoord2fARB(GL_TEXTURE0_ARB, s->mesh->st_array[4][0], s->mesh->st_array[4][1]);
|
||||
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, s->mesh->lmst_array[4][0], s->mesh->lmst_array[4][1]);
|
||||
qglVertex3fv(s->mesh->xyz_array[4]);
|
||||
case 4:
|
||||
qglMultiTexCoord2fARB(GL_TEXTURE0_ARB, s->mesh->st_array[3][0], s->mesh->st_array[3][1]);
|
||||
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, s->mesh->lmst_array[3][0], s->mesh->lmst_array[3][1]);
|
||||
qglVertex3fv(s->mesh->xyz_array[3]);
|
||||
case 3:
|
||||
qglMultiTexCoord2fARB(GL_TEXTURE0_ARB, s->mesh->st_array[2][0], s->mesh->st_array[2][1]);
|
||||
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, s->mesh->lmst_array[2][0], s->mesh->lmst_array[2][1]);
|
||||
qglVertex3fv(s->mesh->xyz_array[2]);
|
||||
case 2:
|
||||
qglMultiTexCoord2fARB(GL_TEXTURE0_ARB, s->mesh->st_array[1][0], s->mesh->st_array[1][1]);
|
||||
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, s->mesh->lmst_array[1][0], s->mesh->lmst_array[1][1]);
|
||||
qglVertex3fv(s->mesh->xyz_array[1]);
|
||||
case 1:
|
||||
qglMultiTexCoord2fARB(GL_TEXTURE0_ARB, s->mesh->st_array[0][0], s->mesh->st_array[0][1]);
|
||||
qglMultiTexCoord2fARB(GL_TEXTURE1_ARB, s->mesh->lmst_array[0][0], s->mesh->lmst_array[0][1]);
|
||||
qglVertex3fv(s->mesh->xyz_array[0]);
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
qglEnd();
|
||||
}
|
||||
|
||||
qglDisable(GL_TEXTURE_2D);
|
||||
|
||||
GL_SelectTexture(GL_TEXTURE0_ARB);
|
||||
}
|
||||
*/
|
||||
|
||||
static void PPL_BaseChain_Bump_2TMU(msurface_t *first, texture_t *tex)
|
||||
{
|
||||
int vi;
|
||||
|
@ -1194,9 +1387,9 @@ static void PPL_BaseTextureChain(msurface_t *first)
|
|||
|
||||
if (s->mesh)
|
||||
{
|
||||
redraw = mb.fog != s->fog || mb.infokey != vi|| mb.shader->flags&SHADER_DEFORMV_BULGE;
|
||||
redraw = mb.fog != s->fog || mb.infokey != vi|| mb.shader->flags&SHADER_DEFORMV_BULGE || R_MeshWillExceed(s->mesh);
|
||||
|
||||
if (redraw)// || numIndexes + s->mesh->numindexes > MAX_ARRAY_INDEXES)
|
||||
if (redraw)
|
||||
{
|
||||
if (mb.mesh)
|
||||
R_RenderMeshBuffer ( &mb, false );
|
||||
|
@ -1265,7 +1458,9 @@ static void PPL_BaseTextureChain(msurface_t *first)
|
|||
}
|
||||
else
|
||||
{
|
||||
PPL_BaseChain_NoBump_2TMU(first, t);
|
||||
// PPL_BaseChain_NoBump_2TMU_TEST(first, t);
|
||||
// PPL_BaseChain_NoBump_2TMU(first, t);
|
||||
PPL_BaseChain_NoBump_2TMU_Overbright(first, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1326,6 +1521,13 @@ void PPL_BaseTextures(model_t *model)
|
|||
|
||||
qglShadeModel(GL_FLAT);
|
||||
|
||||
if (gl_overbright.value>=2)
|
||||
overbright = 4;
|
||||
else if (gl_overbright.value)
|
||||
overbright = 2;
|
||||
else
|
||||
overbright = 1;
|
||||
|
||||
currentmodel = model;
|
||||
currententity->alpha = 1;
|
||||
|
||||
|
@ -2477,6 +2679,9 @@ void PPL_SchematicsTextureChain(msurface_t *first)
|
|||
float frow, fcol;
|
||||
int e, en;
|
||||
|
||||
if (!cl.worldmodel->surfedges)
|
||||
return;
|
||||
|
||||
qglEnable(GL_ALPHA_TEST);
|
||||
|
||||
if (qglPolygonOffset)
|
||||
|
@ -4010,13 +4215,14 @@ void PPL_DrawWorld (void)
|
|||
vec3_t mins, maxs;
|
||||
|
||||
int maxshadowlights = gl_maxshadowlights.value;
|
||||
|
||||
/*
|
||||
if (!lightmap)
|
||||
{
|
||||
R_PreNewMap();
|
||||
R_NewMap();
|
||||
return; // :/
|
||||
}
|
||||
*/
|
||||
|
||||
if (maxshadowlights < 1)
|
||||
maxshadowlights = 1;
|
||||
|
@ -4165,7 +4371,6 @@ void PPL_DrawWorld (void)
|
|||
|
||||
R_IBrokeTheArrays();
|
||||
}
|
||||
#endif
|
||||
|
||||
void PPL_CreateShaderObjects(void)
|
||||
{
|
||||
|
@ -4174,3 +4379,5 @@ void PPL_CreateShaderObjects(void)
|
|||
#endif
|
||||
PPL_LoadSpecularFragmentProgram();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1908,9 +1908,6 @@ void GLR_RenderView (void)
|
|||
qglPNTrianglesfATI(GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, gl_ati_truform_tesselation.value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (gl_finish.value)
|
||||
{
|
||||
RSpeedMark();
|
||||
|
@ -2011,12 +2008,10 @@ void GLR_RenderView (void)
|
|||
if (qglGetError())
|
||||
Con_Printf("GL Error drawing scene\n");
|
||||
|
||||
if (!scenepp_ww_program)
|
||||
return;
|
||||
|
||||
// SCENE POST PROCESSING
|
||||
// we check if we need to use any shaders - currently it's just waterwarp
|
||||
if ( (r_waterwarp.value && r_viewleaf && r_viewleaf->contents <= Q1CONTENTS_WATER))
|
||||
if (scenepp_ww_program)
|
||||
if ((r_waterwarp.value && r_viewleaf && r_viewleaf->contents <= Q1CONTENTS_WATER))
|
||||
{
|
||||
float vwidth = 1, vheight = 1;
|
||||
float vs, vt;
|
||||
|
|
|
@ -3077,10 +3077,10 @@ static void GLR_LeafWorldNode (void)
|
|||
// check for door connected areas
|
||||
// if ( areabits )
|
||||
{
|
||||
if (! (areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
|
||||
{
|
||||
continue; // not visible
|
||||
}
|
||||
// if (! (areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
|
||||
// {
|
||||
// continue; // not visible
|
||||
// }
|
||||
}
|
||||
|
||||
clipflags = 15; // 1 | 2 | 4 | 8
|
||||
|
@ -3509,11 +3509,11 @@ void BuildSurfaceDisplayList (msurface_t *fa)
|
|||
//#ifdef Q3SHADERS
|
||||
// if (fa->texinfo->texture->shader)
|
||||
{ //build a nice mesh instead of a poly.
|
||||
int size = sizeof(mesh_t) + sizeof(index_t)*(lnumverts-2)*3 + (sizeof(vec4_t) + sizeof(vec3_t) + 2*sizeof(vec2_t) + sizeof(byte_vec4_t))*lnumverts;
|
||||
int size = sizeof(mesh_t) + sizeof(index_t)*(lnumverts-2)*3 + (sizeof(vec3_t) + sizeof(vec3_t) + 2*sizeof(vec2_t) + sizeof(byte_vec4_t))*lnumverts;
|
||||
mesh_t *mesh;
|
||||
|
||||
fa->mesh = mesh = Hunk_Alloc(size);
|
||||
mesh->xyz_array = (vec4_t*)(mesh + 1);
|
||||
mesh->xyz_array = (vec3_t*)(mesh + 1);
|
||||
mesh->normals_array = (vec3_t*)(mesh->xyz_array + lnumverts);
|
||||
mesh->st_array = (vec2_t*)(mesh->normals_array + lnumverts);
|
||||
mesh->lmst_array = (vec2_t*)(mesh->st_array + lnumverts);
|
||||
|
@ -3704,7 +3704,7 @@ void GL_CreateSurfaceLightmap (msurface_t *surf)
|
|||
smax = (surf->extents[0]>>4)+1;
|
||||
tmax = (surf->extents[1]>>4)+1;
|
||||
|
||||
if (smax > LMBLOCK_WIDTH || tmax > LMBLOCK_HEIGHT || smax <= 0 || tmax <= 0)
|
||||
if (smax > LMBLOCK_WIDTH || tmax > LMBLOCK_HEIGHT || smax < 0 || tmax < 0)
|
||||
{ //whoa, buggy.
|
||||
surf->lightmaptexturenum = -1;
|
||||
return;
|
||||
|
|
|
@ -97,6 +97,8 @@ void RSpeedShow(void)
|
|||
s = va("%i %-30s", samplerquant[i], RQntNames[i]);
|
||||
Draw_String(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s);
|
||||
}
|
||||
s = va("%f %-30s", 100000000.0f/samplerspeeds[RSPEED_TOTALREFRESH], "Framerate");
|
||||
Draw_String(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s);
|
||||
|
||||
if (framecount++>=100)
|
||||
{
|
||||
|
@ -269,7 +271,10 @@ void GLSCR_UpdateScreen (void)
|
|||
else
|
||||
#endif
|
||||
if (cl.worldmodel && uimenu != 1)
|
||||
{
|
||||
V_RenderView ();
|
||||
Q1BSP_TestClipDecal();
|
||||
}
|
||||
else
|
||||
GL_DoSwap();
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ void (APIENTRY *qglVertex3fv) (const GLfloat *v);
|
|||
void (APIENTRY *qglViewport) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
void (APIENTRY *qglGetTexLevelParameteriv) (GLenum target, GLint level, GLenum pname, GLint *params);
|
||||
|
||||
void (APIENTRY *qglDrawRangeElements) (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *);
|
||||
void (APIENTRY *qglDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
|
||||
void (APIENTRY *qglArrayElement) (GLint i);
|
||||
void (APIENTRY *qglVertexPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
||||
|
@ -524,6 +525,8 @@ void GL_Init(void *(*getglfunction) (char *name))
|
|||
qglEnableClientState = (void *)getglcore("glEnableClientState");
|
||||
qglDisableClientState = (void *)getglcore("glDisableClientState");
|
||||
|
||||
qglDrawRangeElements = (void *)getglext("glDrawRangeElements");
|
||||
|
||||
//fixme: definatly make non-core
|
||||
qglStencilOp = (void *)getglcore("glStencilOp");
|
||||
qglStencilFunc = (void *)getglcore("glStencilFunc");
|
||||
|
|
|
@ -207,7 +207,7 @@ void R_DrawSkyChain (msurface_t *s)
|
|||
qglDisableClientState( GL_COLOR_ARRAY );
|
||||
for (fa=s ; fa ; fa=fa->texturechain)
|
||||
{
|
||||
qglVertexPointer(3, GL_FLOAT, 16, fa->mesh->xyz_array);
|
||||
qglVertexPointer(3, GL_FLOAT, 0, fa->mesh->xyz_array);
|
||||
qglDrawElements(GL_TRIANGLES, fa->mesh->numindexes, GL_UNSIGNED_INT, fa->mesh->indexes);
|
||||
}
|
||||
R_IBrokeTheArrays();
|
||||
|
@ -591,7 +591,7 @@ void R_DrawSkyBoxChain (msurface_t *s)
|
|||
#define skygridyrecip (1.0f / (skygridy))
|
||||
#define skysphere_numverts (skygridx1 * skygridy1)
|
||||
#define skysphere_numtriangles (skygridx * skygridy * 2)
|
||||
static float skysphere_vertex4f[skysphere_numverts * 4];
|
||||
static float skysphere_vertex3f[skysphere_numverts * 3];
|
||||
static float skysphere_texcoord2f[skysphere_numverts * 2];
|
||||
static int skysphere_element3i[skysphere_numtriangles * 3];
|
||||
mesh_t skymesh;
|
||||
|
@ -621,7 +621,7 @@ static void skyspherecalc(int skytype)
|
|||
skymesh.indexes = skysphere_element3i;
|
||||
skymesh.st_array = (void*)skysphere_texcoord2f;
|
||||
skymesh.lmst_array = (void*)skysphere_texcoord2f;
|
||||
skymesh.xyz_array = (void*)skysphere_vertex4f;
|
||||
skymesh.xyz_array = (void*)skysphere_vertex3f;
|
||||
|
||||
skymesh.numindexes = skysphere_numtriangles * 3;
|
||||
skymesh.numvertexes = skysphere_numverts;
|
||||
|
@ -629,7 +629,7 @@ static void skyspherecalc(int skytype)
|
|||
dx = 16;
|
||||
dy = 16;
|
||||
dz = 16 / 3;
|
||||
vertex3f = skysphere_vertex4f;
|
||||
vertex3f = skysphere_vertex3f;
|
||||
texcoord2f = skysphere_texcoord2f;
|
||||
for (j = 0;j <= skygridy;j++)
|
||||
{
|
||||
|
@ -649,7 +649,6 @@ static void skyspherecalc(int skytype)
|
|||
*vertex3f++ = v[0];
|
||||
*vertex3f++ = v[1];
|
||||
*vertex3f++ = v[2];
|
||||
vertex3f++;
|
||||
}
|
||||
}
|
||||
e = skysphere_element3i;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "quakedef.h"
|
||||
#include "glquake.h"
|
||||
|
||||
#include "doommap.h"
|
||||
|
||||
#ifdef DOOMWADS
|
||||
|
||||
vec_t VectorNormalize2 (vec3_t v, vec3_t out);
|
||||
|
@ -18,14 +20,6 @@ int PlaneTypeForNormal ( vec3_t normal );
|
|||
void Doom_SetHullFuncs(hull_t *hull);
|
||||
void Doom_SetModelFunc(model_t *mod);
|
||||
|
||||
//expand to Quake style ent lump
|
||||
typedef struct {
|
||||
short xpos;
|
||||
short ypos;
|
||||
short angle;
|
||||
unsigned short type;
|
||||
unsigned short flags;
|
||||
} dthing_t;
|
||||
//skill/dm is appears in rather than quake's excuded in.
|
||||
#define THING_EASY 1
|
||||
#define THING_MEDIUM 2
|
||||
|
@ -62,168 +56,31 @@ enum {
|
|||
|
||||
} THING_TYPES;
|
||||
|
||||
typedef struct {
|
||||
short xpos;
|
||||
short ypos;
|
||||
} ddoomvertex_t;
|
||||
|
||||
typedef struct {
|
||||
float xpos;
|
||||
float ypos;
|
||||
} mdoomvertex_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned short vert[2];
|
||||
unsigned short flags;
|
||||
short types;
|
||||
short tag;
|
||||
unsigned short sidedef[2]; //(0xffff is none for sidedef[1])
|
||||
} dlinedef_t;
|
||||
#define LINEDEF_IMPASSABLE 1
|
||||
#define LINEDEF_BLOCKMONSTERS 2
|
||||
#define LINEDEF_TWOSIDED 4
|
||||
#define LINEDEF_UPPERUNPEGGED 8
|
||||
#define LINEDEF_LOWERUNPEGGED 16
|
||||
#define LINEDEF_SECRET 32 //seen as singlesided on automap, does nothing else.
|
||||
#define LINEDEF_BLOCKSOUND 64
|
||||
#define LINEDEF_NOTONMAP 128 //doesn't appear on automap.
|
||||
#define LINEDEF_STARTONMAP 256
|
||||
//others are ignored.
|
||||
|
||||
typedef struct {
|
||||
char name[8];
|
||||
short width;
|
||||
short height;
|
||||
int gltexture;
|
||||
// shader_t *glshader; // :o)
|
||||
} gldoomtexture_t;
|
||||
|
||||
static gldoomtexture_t *gldoomtextures;
|
||||
static int numgldoomtextures;
|
||||
|
||||
typedef struct {
|
||||
short texx;
|
||||
short texy;
|
||||
char uppertex[8];
|
||||
char lowertex[8];
|
||||
char middletex[8];
|
||||
unsigned short sector;
|
||||
} dsidedef_t;
|
||||
typedef struct {
|
||||
unsigned short texx;
|
||||
unsigned short texy;
|
||||
|
||||
unsigned short uppertex;
|
||||
unsigned short lowertex;
|
||||
unsigned short middletex;
|
||||
|
||||
unsigned short sector;
|
||||
} msidedef_t;
|
||||
|
||||
typedef struct { //figure out which linedef to use and throw the rest away.
|
||||
unsigned short vert[2];
|
||||
short angle;
|
||||
unsigned short linedef;
|
||||
short direction;
|
||||
short offset;
|
||||
} dseg_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned short vert[2];
|
||||
unsigned short linedef;
|
||||
short direction;
|
||||
unsigned short Partner; //the one on the other side of the owner's linedef
|
||||
} dgl_seg1_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned int vert[2];
|
||||
unsigned short linedef;
|
||||
short direction;
|
||||
unsigned int Partner; //the one on the other side of the owner's linedef
|
||||
} dgl_seg3_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned short segcount;
|
||||
unsigned short first;
|
||||
} dssector_t;
|
||||
|
||||
typedef struct {
|
||||
short x;
|
||||
short y;
|
||||
short dx;
|
||||
short dy;
|
||||
short y1upper;
|
||||
short y1lower;
|
||||
short x1lower;
|
||||
short x1upper;
|
||||
short y2upper;
|
||||
short y2lower;
|
||||
short x2lower;
|
||||
short x2upper;
|
||||
unsigned short node1;
|
||||
unsigned short node2;
|
||||
} ddoomnode_t;
|
||||
#define NODE_IS_SSECTOR 0x8000
|
||||
|
||||
typedef struct {
|
||||
short floorheight;
|
||||
short ceilingheight;
|
||||
char floortexture[8];
|
||||
char ceilingtexture[8];
|
||||
short lightlevel;
|
||||
short specialtype;
|
||||
short tag;
|
||||
} dsector_t;
|
||||
|
||||
typedef struct {
|
||||
int visframe;
|
||||
int floortex;
|
||||
int ceilingtex;
|
||||
|
||||
short floorheight;
|
||||
short ceilingheight;
|
||||
|
||||
qbyte lightlev;
|
||||
qbyte pad;
|
||||
int numflattris;
|
||||
short tag;
|
||||
short specialtype;
|
||||
|
||||
unsigned short *flats;
|
||||
} msector_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
short xorg;
|
||||
short yorg;
|
||||
short columns;
|
||||
short rows;
|
||||
} blockmapheader_t;
|
||||
|
||||
|
||||
|
||||
extern ddoomnode_t *nodel;
|
||||
extern dssector_t *ssectorsl;
|
||||
extern dthing_t *thingsl;
|
||||
extern mdoomvertex_t *vertexesl;
|
||||
extern dgl_seg3_t *segsl;
|
||||
extern dlinedef_t *linedefsl;
|
||||
extern msidedef_t *sidedefsm;
|
||||
extern msector_t *sectorm;
|
||||
extern plane_t *nodeplanes;
|
||||
extern plane_t *lineplanes;
|
||||
extern blockmapheader_t *blockmapl;
|
||||
extern unsigned short *blockmapofs;
|
||||
extern unsigned int nodec;
|
||||
extern unsigned int sectorc;
|
||||
extern unsigned int segsc;
|
||||
extern unsigned int ssectorsc;
|
||||
extern unsigned int thingsc;
|
||||
extern unsigned int linedefsc;
|
||||
extern unsigned int sidedefsc;
|
||||
extern unsigned int vertexesc;
|
||||
extern unsigned int vertexsglbase;
|
||||
|
||||
static ddoomnode_t *nodel;
|
||||
static dssector_t *ssectorsl;
|
||||
static dthing_t *thingsl;
|
||||
static mdoomvertex_t *vertexesl;
|
||||
static dgl_seg3_t *segsl;
|
||||
static dlinedef_t *linedefsl;
|
||||
static msidedef_t *sidedefsm;
|
||||
static msector_t *sectorm;
|
||||
static plane_t *nodeplanes;
|
||||
static plane_t *lineplanes;
|
||||
static blockmapheader_t *blockmapl;
|
||||
static unsigned short *blockmapofs;
|
||||
static unsigned int nodec;
|
||||
static unsigned int sectorc;
|
||||
static unsigned int segsc;
|
||||
static unsigned int ssectorsc;
|
||||
static unsigned int thingsc;
|
||||
static unsigned int linedefsc;
|
||||
static unsigned int sidedefsc;
|
||||
static unsigned int vertexesc;
|
||||
static unsigned int vertexsglbase;
|
||||
extern model_t *loadmodel;
|
||||
extern char loadname[];
|
||||
|
||||
|
@ -1684,715 +1541,7 @@ qboolean Mod_LoadDoomLevel(model_t *mod)
|
|||
return true;
|
||||
}
|
||||
|
||||
int Doom_SectorNearPoint(vec3_t p)
|
||||
{
|
||||
ddoomnode_t *node;
|
||||
plane_t *plane;
|
||||
int num;
|
||||
int seg;
|
||||
float d;
|
||||
num = nodec-1;
|
||||
while (1)
|
||||
{
|
||||
if (num & NODE_IS_SSECTOR)
|
||||
{
|
||||
num -= NODE_IS_SSECTOR;
|
||||
for (seg = ssectorsl[num].first; seg < ssectorsl[num].first + ssectorsl[num].segcount; seg++)
|
||||
if (segsl[seg].linedef != 0xffff)
|
||||
break;
|
||||
|
||||
return sidedefsm[linedefsl[segsl[seg].linedef].sidedef[segsl[seg].direction]].sector;
|
||||
}
|
||||
|
||||
node = nodel + num;
|
||||
plane = nodeplanes + num;
|
||||
|
||||
// if (plane->type < 3)
|
||||
// d = p[plane->type] - plane->dist;
|
||||
// else
|
||||
d = DotProduct (plane->normal, p) - plane->dist;
|
||||
if (d < 0)
|
||||
num = node->node2;
|
||||
else
|
||||
num = node->node1;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int Doom_PointContents(hull_t *hull, vec3_t p)
|
||||
{
|
||||
int sec = Doom_SectorNearPoint(p);
|
||||
if (p[2] < sectorm[sec].floorheight-hull->clip_mins[2])
|
||||
return FTECONTENTS_SOLID;
|
||||
if (p[2] > sectorm[sec].ceilingheight-hull->clip_maxs[2])
|
||||
return FTECONTENTS_SOLID;
|
||||
return FTECONTENTS_EMPTY;
|
||||
}
|
||||
|
||||
//#define NEWTRACES
|
||||
#ifdef NEWTRACES
|
||||
static qboolean ispoint;
|
||||
static void ClipToBlockMap(hull_t *hull, int block, vec3_t start, vec3_t end, trace_t *trace)
|
||||
{
|
||||
unsigned short *linedefs;
|
||||
dlinedef_t *ld;
|
||||
plane_t *lp;
|
||||
float planedist;
|
||||
|
||||
float d1, d2; //distance start, end
|
||||
|
||||
if (block < 0 || block >= blockmapl->columns*blockmapl->rows)
|
||||
{
|
||||
trace->fraction = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
trace->endpos[0] = end[0];
|
||||
trace->endpos[1] = end[1];
|
||||
trace->endpos[2] = end[2];
|
||||
|
||||
trace->fraction = 1;
|
||||
|
||||
for(linedefs = (short*)blockmapl + blockmapofs[block]+1; *linedefs != 0xffff; linedefs++)
|
||||
{
|
||||
ld = linedefsl + *linedefs;
|
||||
|
||||
lp = lineplanes + *linedefs;
|
||||
|
||||
if (ispoint)
|
||||
planedist = lp->dist;
|
||||
else
|
||||
{ //figure out how far to move the plane out by (tracebox instead of tracecylinder
|
||||
vec3_t ofs;
|
||||
int j;
|
||||
for (j=0 ; j<2 ; j++)
|
||||
{
|
||||
if (lp->normal[j] < 0)
|
||||
ofs[j] = hull->clip_maxs[j];
|
||||
else
|
||||
ofs[j] = hull->clip_mins[j];
|
||||
}
|
||||
ofs[2] = 0;
|
||||
planedist = lp->dist - DotProduct (ofs, lp->normal);
|
||||
}
|
||||
|
||||
d1 = DotProduct(lp->normal, start) - (planedist);
|
||||
d2 = DotProduct(lp->normal, end) - (planedist);
|
||||
if (d1 > 0 && d2 > 0)
|
||||
continue; //both points on the front side.
|
||||
|
||||
if (d1 < 0 && d2 < 0)
|
||||
continue; //both points on the back side.
|
||||
|
||||
//line crossed plane
|
||||
|
||||
if (d1<0) //moved onto backside
|
||||
{
|
||||
|
||||
LeaveSector(sidedefsm[ld->sidedef[0]].sector);
|
||||
EnterSector(sidedefsm[ld->sidedef[1]].sector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int numinsectors;
|
||||
static int insector[8];
|
||||
static trace_t *trace_trace;
|
||||
static hull_t *trace_hull;
|
||||
static vec3_t trace_end;
|
||||
static vec3_t trace_start;
|
||||
static qboolean EnterSector(int secnum, float z)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < numinsectors; i++)
|
||||
if (insector[i] == secnum)
|
||||
return true; //erm. already in this one
|
||||
|
||||
if (i == sizeof(insector)/sizeof(insector[0]))
|
||||
{
|
||||
Con_DPrintf("Trace was in too many sectors\n");
|
||||
return false; //you're not allowed to enter
|
||||
}
|
||||
if (z + trace_hull->clip_mins[2] < sectorm[secnum].floorheight) //was outside
|
||||
return false;
|
||||
if (z + trace_hull->clip_mins[2] > sectorm[secnum].ceilingheight) //was outside
|
||||
return false;
|
||||
|
||||
insector[i] = secnum;
|
||||
return true; //yay, the trace entered a big enough hole!
|
||||
}
|
||||
void LeaveSector(int secnum, float x, float y)
|
||||
{
|
||||
float z;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < numinsectors; i++)
|
||||
if (insector[i] == secnum)
|
||||
{
|
||||
//switch with last.
|
||||
insector[i] = insector[numinsectors-1];
|
||||
numinsectors--;
|
||||
|
||||
//z at x,y
|
||||
if (trace_end[0]-trace_start[0])
|
||||
z = (trace_end[2]-trace_start[2])/(trace_end[0]-trace_start[0]);
|
||||
else if (trace_end[1]-trace_start[1])
|
||||
z = (trace_end[2]-trace_start[2])/(trace_end[1]-trace_start[1]);
|
||||
else
|
||||
{ //was a vertical trace.
|
||||
z = trace_end[2];
|
||||
}
|
||||
if (z > sectorm[secnum].ceilingheight)
|
||||
{
|
||||
z = sectorm[secnum].ceilingheight;
|
||||
if (z < trace_trace->endpos[2])
|
||||
{
|
||||
trace_trace->endpos[0] -= (trace_end[0]-trace_start[0])/(z-trace_start[0]);
|
||||
trace_trace->endpos[1] -= (trace_end[1]-trace_start[1])/(z-trace_start[1]);
|
||||
trace_trace->endpos[2] = z;
|
||||
}
|
||||
}
|
||||
if (z < sectorm[secnum].floorheight)
|
||||
{
|
||||
z = sectorm[secnum].floorheight;
|
||||
if (z < trace_trace->endpos[2])
|
||||
{
|
||||
trace_trace->endpos[0] -= (trace_end[0]-trace_start[0])/(z-trace_start[0]);
|
||||
trace_trace->endpos[1] -= (trace_end[1]-trace_start[1])/(z-trace_start[1]);
|
||||
trace_trace->endpos[2] = z;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Con_DPrintf("Trace wasn't in sector\n");
|
||||
}
|
||||
|
||||
void Doom_ClipToInitialNode(int nodenum)
|
||||
{
|
||||
int s;
|
||||
int seg;
|
||||
ddoomnode_t *node;
|
||||
if (nodenum & NODE_IS_SSECTOR)
|
||||
{
|
||||
nodenum -= NODE_IS_SSECTOR;
|
||||
for (seg = ssectorsl[nodenum].first; seg < ssectorsl[nodenum].first + ssectorsl[nodenum].segcount; seg++)
|
||||
if (segsl[seg].linedef != 0xffff)
|
||||
break;
|
||||
|
||||
s = sidedefsm[linedefsl[segsl[seg].linedef].sidedef[segsl[seg].direction]].sector;
|
||||
|
||||
if (!EnterSector(s, trace_start[2]))
|
||||
{ //clipped by floor
|
||||
trace_trace->fraction = 0;
|
||||
trace_trace->allsolid = trace_trace->startsolid = true;
|
||||
trace_trace->endpos[0] = trace_start[0];
|
||||
trace_trace->endpos[1] = trace_start[1];
|
||||
trace_trace->endpos[2] = trace_start[2]; //yeah, we do mean this - startsolid
|
||||
// if (IS_NAN(trace->endpos[2]))
|
||||
// Con_Printf("Nanny\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
node = nodel + nodenum;
|
||||
|
||||
if (node->x1lower+trace_hull->clip_mins[0] <= trace_start[0] && node->x1upper+trace_hull->clip_maxs[0] >= trace_start[0])
|
||||
if (node->y1lower+trace_hull->clip_mins[1] <= trace_start[1] && node->y1upper+trace_hull->clip_maxs[1] >= trace_start[1])
|
||||
Doom_ClipToInitialNode(node->node1);
|
||||
|
||||
if (node->x2lower+trace_hull->clip_mins[0] <= trace_start[0] && node->x2upper+trace_hull->clip_maxs[0] >= trace_start[0])
|
||||
if (node->y2lower+trace_hull->clip_mins[1] <= trace_start[1] && node->y2upper+trace_hull->clip_maxs[1] >= trace_start[1])
|
||||
Doom_ClipToInitialNode(node->node2);
|
||||
|
||||
}
|
||||
|
||||
void Doom_ClipToInitialSectors(void)
|
||||
{
|
||||
Doom_ClipToInitialNode(nodec-1);
|
||||
/*
|
||||
ddoomnode_t *node;
|
||||
plane_t *plane;
|
||||
int num;
|
||||
int seg;
|
||||
float d;
|
||||
num = nodec-1;
|
||||
while (1)
|
||||
{
|
||||
if (num & NODE_IS_SSECTOR)
|
||||
{
|
||||
num -= NODE_IS_SSECTOR;
|
||||
for (seg = ssectorsl[num].first; seg < ssectorsl[num].first + ssectorsl[num].segcount; seg++)
|
||||
if (segsl[seg].linedef != 0xffff)
|
||||
break;
|
||||
|
||||
return sidedefsm[linedefsl[segsl[seg].linedef].sidedef[segsl[seg].direction]].sector;
|
||||
}
|
||||
|
||||
node = nodel + num;
|
||||
plane = nodeplanes + num;
|
||||
|
||||
// if (plane->type < 3)
|
||||
// d = p[plane->type] - plane->dist;
|
||||
// else
|
||||
d = DotProduct (plane->normal, p) - plane->dist;
|
||||
if (d < 0)
|
||||
num = node->node2;
|
||||
else
|
||||
num = node->node1;
|
||||
}
|
||||
|
||||
return num;
|
||||
*/
|
||||
}
|
||||
qboolean Doom_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t start, vec3_t end, trace_t *trace)
|
||||
{
|
||||
int bmi;
|
||||
ispoint = !hull->clip_mins[0] && !hull->clip_mins[1] && !hull->clip_maxs[0] && !hull->clip_maxs[1];
|
||||
|
||||
trace->allsolid = trace->startsolid = false;
|
||||
trace->contents = FTECONTENTS_EMPTY;
|
||||
|
||||
|
||||
trace_trace = trace;
|
||||
trace_hull = hull;
|
||||
trace_end[0] = end[0];
|
||||
trace_end[1] = end[1];
|
||||
trace_end[2] = end[2];
|
||||
trace_start[0] = start[0];
|
||||
trace_start[1] = start[1];
|
||||
trace_start[2] = start[2];
|
||||
|
||||
|
||||
|
||||
Doom_ClipToInitialNode(nodec-1);
|
||||
|
||||
if (trace->allsolid) //started outside gamespace
|
||||
return trace->fraction==1;
|
||||
|
||||
//clip to the blockmap.
|
||||
//blockmap is 128*128
|
||||
bmi = ((int)start[0] - blockmapl->xorg)/128 + (((int)start[1] - blockmapl->yorg)/128)*blockmapl->columns;
|
||||
if (end[0] - start[0] > 0)
|
||||
{
|
||||
if (end[1] - start[1] > 0)
|
||||
{
|
||||
ClipToBlockMap(hull, bmi, start, end, trace);
|
||||
}
|
||||
else
|
||||
{
|
||||
trace->endpos[0] = start[0];
|
||||
trace->endpos[1] = start[1];
|
||||
trace->endpos[2] = start[2];
|
||||
|
||||
trace->fraction = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
trace->endpos[0] = start[0];
|
||||
trace->endpos[1] = start[1];
|
||||
trace->endpos[2] = start[2];
|
||||
|
||||
trace->fraction = 0;
|
||||
}
|
||||
|
||||
return trace->fraction==1;
|
||||
}
|
||||
|
||||
#else
|
||||
qboolean Doom_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t start, vec3_t p2, trace_t *trace)
|
||||
{
|
||||
#define TRACESTEP 16
|
||||
unsigned short *linedefs;
|
||||
dlinedef_t *ld;
|
||||
int bmi, obmi;
|
||||
vec3_t delta;
|
||||
int sec1 = Doom_SectorNearPoint(start);
|
||||
vec3_t p1, pointonplane, ofs;
|
||||
float d1, d2, c1, c2, planedist;
|
||||
plane_t *lp;
|
||||
mdoomvertex_t *v1, *v2;
|
||||
int j;
|
||||
|
||||
float clipfrac;
|
||||
qboolean ispoint;
|
||||
#define DIST_EPSILON (0.03125)
|
||||
|
||||
ispoint = !hull->clip_mins[0] && !hull->clip_mins[1] && !hull->clip_maxs[0] && !hull->clip_maxs[1];
|
||||
|
||||
// Con_Printf("%i\n", sec1);
|
||||
|
||||
if (start[2] < sectorm[sec1].floorheight-hull->clip_mins[2]) //whoops, started outside... ?
|
||||
{
|
||||
trace->fraction = 0;
|
||||
trace->allsolid = trace->startsolid = true;
|
||||
trace->endpos[0] = start[0];
|
||||
trace->endpos[1] = start[1];
|
||||
trace->endpos[2] = start[2]; //yeah, we do mean this - startsolid
|
||||
// if (IS_NAN(trace->endpos[2]))
|
||||
// Con_Printf("Nanny\n");
|
||||
trace->plane.normal[0] = 0;
|
||||
trace->plane.normal[1] = 0;
|
||||
trace->plane.normal[2] = 1;
|
||||
trace->plane.dist = sectorm[sec1].floorheight-hull->clip_mins[2];
|
||||
|
||||
return false;
|
||||
}
|
||||
if (start[2] > sectorm[sec1].ceilingheight-hull->clip_maxs[2]) //whoops, started outside... ?
|
||||
{
|
||||
trace->fraction = 0;
|
||||
trace->allsolid = trace->startsolid = true;
|
||||
trace->endpos[0] = start[0];
|
||||
trace->endpos[1] = start[1];
|
||||
trace->endpos[2] = start[2];
|
||||
trace->plane.normal[0] = 0;
|
||||
trace->plane.normal[1] = 0;
|
||||
trace->plane.normal[2] = -1;
|
||||
trace->plane.dist = -(sectorm[sec1].ceilingheight-hull->clip_maxs[2]);
|
||||
return false;
|
||||
}
|
||||
|
||||
VectorCopy(start, p1);
|
||||
obmi = -1;
|
||||
VectorSubtract(p2, p1, delta);
|
||||
p2f = Length(delta)+DIST_EPSILON;
|
||||
if (IS_NAN(p2f) || p2f > 100000)
|
||||
p2f = 100000;
|
||||
VectorNormalize(delta);
|
||||
|
||||
trace->endpos[0] = p2[0];
|
||||
trace->endpos[1] = p2[1];
|
||||
trace->endpos[2] = p2[2];
|
||||
|
||||
trace->fraction = 1;
|
||||
while(1)
|
||||
{
|
||||
bmi = ((int)p1[0] - blockmapl->xorg)/128 + (((int)p1[1] - blockmapl->yorg)/128)*blockmapl->columns;
|
||||
// Con_Printf("%i of %i ", bmi, blockmapl->rows*blockmapl->columns);
|
||||
if (bmi >= 0 && bmi < blockmapl->rows*blockmapl->columns)
|
||||
if (bmi != obmi)
|
||||
{
|
||||
#if 1
|
||||
short dummy;
|
||||
linedefs = &dummy;
|
||||
for (dummy = 0; dummy < linedefsc; dummy++)
|
||||
#else
|
||||
for(linedefs = (short*)blockmapl + blockmapofs[bmi]+1; *linedefs != 0xffff; linedefs++)
|
||||
#endif
|
||||
{
|
||||
ld = linedefsl + *linedefs;
|
||||
if (ld->sidedef[1] != 0xffff)
|
||||
{
|
||||
if (sectorm[sidedefsm[ld->sidedef[0]].sector].floorheight == sectorm[sidedefsm[ld->sidedef[1]].sector].floorheight &&
|
||||
sectorm[sidedefsm[ld->sidedef[0]].sector].ceilingheight == sectorm[sidedefsm[ld->sidedef[1]].sector].ceilingheight)
|
||||
continue;
|
||||
}
|
||||
|
||||
lp = lineplanes + *linedefs;
|
||||
|
||||
if (!ispoint)
|
||||
{ //figure out how far to move the plane out by
|
||||
for (j=0 ; j<2 ; j++)
|
||||
{
|
||||
if (lp->normal[j] < 0)
|
||||
ofs[j] = hull->clip_maxs[j];
|
||||
else
|
||||
ofs[j] = hull->clip_mins[j];
|
||||
}
|
||||
ofs[2] = 0;
|
||||
planedist = lp->dist - DotProduct (ofs, lp->normal);
|
||||
}
|
||||
else
|
||||
planedist = lp->dist;
|
||||
|
||||
d1 = DotProduct(lp->normal, start) - (planedist);
|
||||
d2 = DotProduct(lp->normal, p2) - (planedist);
|
||||
if (d1 > 0 && d2 > 0)
|
||||
continue; //both points on the front side.
|
||||
if (d1 < 0) //start on back side
|
||||
{
|
||||
if (ld->sidedef[1] != 0xffff) //two sided (optimisation)
|
||||
{
|
||||
planedist = -planedist+lp->dist;
|
||||
if (/*d1 < planedist*-1 &&*/ d1 > planedist*2)
|
||||
{ //right, we managed to end up just on the other side of a wall's plane.
|
||||
v1 = &vertexesl[ld->vert[0]];
|
||||
v2 = &vertexesl[ld->vert[1]];
|
||||
if (!(d1 - d2))
|
||||
continue;
|
||||
if (d1<0) //back to front.
|
||||
c1 = (d1+DIST_EPSILON) / (d1 - d2);
|
||||
else
|
||||
c1 = (d1-DIST_EPSILON) / (d1 - d2);
|
||||
c2 = 1-c1;
|
||||
pointonplane[0] = start[0]*c2 + p2[0]*c1;
|
||||
/* if (pointonplane[0] > v1->xpos+DIST_EPSILON*2+hull->clip_maxs[0] && pointonplane[0] > v2->xpos+DIST_EPSILON*2+hull->clip_maxs[0])
|
||||
continue;
|
||||
if (pointonplane[0] < v1->xpos-DIST_EPSILON*2+hull->clip_mins[0] && pointonplane[0] < v2->xpos-DIST_EPSILON*2+hull->clip_mins[0])
|
||||
continue;
|
||||
*/ pointonplane[1] = start[1]*c2 + p2[1]*c1;
|
||||
/* if (pointonplane[1] > v1->ypos+DIST_EPSILON*2+hull->clip_maxs[1] && pointonplane[1] > v2->ypos+DIST_EPSILON*2+hull->clip_maxs[1])
|
||||
continue;
|
||||
if (pointonplane[1] < v1->ypos-DIST_EPSILON*2+hull->clip_mins[1] && pointonplane[1] < v2->ypos-DIST_EPSILON*2+hull->clip_mins[1])
|
||||
continue;
|
||||
*/
|
||||
pointonplane[2] = start[2]*c2 + p2[2]*c1;
|
||||
|
||||
Con_Printf("Started in wall\n");
|
||||
j = sidedefsm[ld->sidedef[d1 < planedist]].sector;
|
||||
//yup, we are in the thing
|
||||
//prevent ourselves from entering the back-sector's floor/ceiling
|
||||
if (pointonplane[2] < sectorm[j].floorheight-hull->clip_mins[2]) //whoops, started outside... ?
|
||||
{
|
||||
Con_Printf("Started in floor\n");
|
||||
trace->allsolid = trace->startsolid = false;
|
||||
trace->endpos[2] = sectorm[j].floorheight-hull->clip_mins[2];
|
||||
trace->fraction = fabs(trace->endpos[2] - start[2]) / fabs(p2[2] - start[2]);
|
||||
trace->endpos[0] = start[0]+delta[0]*trace->fraction*p2f;
|
||||
trace->endpos[1] = start[1]+delta[1]*trace->fraction*p2f;
|
||||
// if (IS_NAN(trace->endpos[2]))
|
||||
// Con_Printf("Nanny\n");
|
||||
trace->plane.normal[0] = 0;
|
||||
trace->plane.normal[1] = 0;
|
||||
trace->plane.normal[2] = 1;
|
||||
trace->plane.dist = sectorm[j].floorheight-hull->clip_mins[2];
|
||||
|
||||
continue;
|
||||
}
|
||||
if (pointonplane[2] > sectorm[j].ceilingheight-hull->clip_maxs[2]) //whoops, started outside... ?
|
||||
{
|
||||
Con_Printf("Started in ceiling\n");
|
||||
trace->allsolid = trace->startsolid = false;
|
||||
trace->endpos[0] = pointonplane[0];
|
||||
trace->endpos[1] = pointonplane[1];
|
||||
trace->endpos[2] = sectorm[j].ceilingheight-hull->clip_maxs[2];
|
||||
trace->fraction = fabs(trace->endpos[2] - start[2]) / fabs(p2[2] - start[2]);
|
||||
trace->plane.normal[0] = 0;
|
||||
trace->plane.normal[1] = 0;
|
||||
trace->plane.normal[2] = -1;
|
||||
trace->plane.dist = -(sectorm[j].ceilingheight-hull->clip_maxs[2]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (d2 < 0)
|
||||
continue; //both points on the reverse side.
|
||||
}
|
||||
|
||||
//line crosses plane.
|
||||
|
||||
v1 = &vertexesl[ld->vert[0]];
|
||||
v2 = &vertexesl[ld->vert[1]];
|
||||
|
||||
if (d1<0) //back to front.
|
||||
{
|
||||
if (ld->sidedef[1] == 0xffff)
|
||||
continue; //hack to allow them to pass
|
||||
c1 = (d1+DIST_EPSILON) / (d1 - d2);
|
||||
}
|
||||
else
|
||||
c1 = (d1-DIST_EPSILON) / (d1 - d2);
|
||||
c2 = 1-c1;
|
||||
pointonplane[0] = start[0]*c2 + p2[0]*c1;
|
||||
if (pointonplane[0] > v1->xpos+DIST_EPSILON*2+hull->clip_maxs[0] && pointonplane[0] > v2->xpos+DIST_EPSILON*2+hull->clip_maxs[0])
|
||||
continue;
|
||||
if (pointonplane[0] < v1->xpos-DIST_EPSILON*2+hull->clip_mins[0] && pointonplane[0] < v2->xpos-DIST_EPSILON*2+hull->clip_mins[0])
|
||||
continue;
|
||||
pointonplane[1] = start[1]*c2 + p2[1]*c1;
|
||||
if (pointonplane[1] > v1->ypos+DIST_EPSILON*2+hull->clip_maxs[1] && pointonplane[1] > v2->ypos+DIST_EPSILON*2+hull->clip_maxs[1])
|
||||
continue;
|
||||
if (pointonplane[1] < v1->ypos-DIST_EPSILON*2+hull->clip_mins[1] && pointonplane[1] < v2->ypos-DIST_EPSILON*2+hull->clip_mins[1])
|
||||
continue;
|
||||
pointonplane[2] = start[2]*c2 + p2[2]*c1;
|
||||
|
||||
if (ld->flags & LINEDEF_IMPASSABLE || ld->sidedef[1] == 0xffff) //unconditionally unpassable.
|
||||
{ //unconditionally clipped.
|
||||
}
|
||||
else
|
||||
{ //ensure that the side we are passing on to passes the clip (no ceiling/floor clips happened first)
|
||||
msector_t *sec2;
|
||||
|
||||
if (d1<0)
|
||||
sec2 = §orm[sidedefsm[ld->sidedef[1]].sector];
|
||||
else
|
||||
sec2 = §orm[sidedefsm[ld->sidedef[0]].sector];
|
||||
|
||||
if (pointonplane[2] < sec2->floorheight-hull->clip_mins[2])
|
||||
{ //hit the floor first.
|
||||
c1 = fabs(sectorm[sec1].floorheight-hull->clip_mins[2] - start[2]);
|
||||
c2 = fabs(p2[2] - start[2]);
|
||||
if (!c2)
|
||||
c1 = 1;
|
||||
else
|
||||
c1 = (c1-DIST_EPSILON) / c2;
|
||||
if (trace->fraction > c1)
|
||||
{
|
||||
// Con_Printf("Hit floor\n");
|
||||
trace->fraction = c1;
|
||||
trace->allsolid = trace->startsolid = true;
|
||||
trace->endpos[0] = start[0] + trace->fraction*(p2[0]-start[0]);
|
||||
trace->endpos[1] = start[1] + trace->fraction*(p2[1]-start[1]);
|
||||
trace->endpos[2] = start[2] + trace->fraction*(p2[2]-start[2]);
|
||||
trace->plane.normal[0] = 0;
|
||||
trace->plane.normal[1] = 0;
|
||||
trace->plane.normal[2] = 1;
|
||||
trace->plane.dist = sectorm[sec1].floorheight-hull->clip_mins[2];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pointonplane[2] > sec2->ceilingheight-hull->clip_maxs[2])
|
||||
{ //hit the floor first.
|
||||
c1 = fabs((sectorm[sec1].ceilingheight-hull->clip_maxs[2]) - start[2]);
|
||||
c2 = fabs(p2[2] - start[2]);
|
||||
if (!c2)
|
||||
c1 = 1;
|
||||
else
|
||||
c1 = (c1-DIST_EPSILON) / c2;
|
||||
|
||||
|
||||
if (trace->fraction > c1)
|
||||
{
|
||||
// Con_Printf("Hit ceiling\n");
|
||||
trace->fraction = c1;
|
||||
trace->allsolid = trace->startsolid = true;
|
||||
trace->endpos[0] = start[0] + trace->fraction*(p2[0]-start[0]);
|
||||
trace->endpos[1] = start[1] + trace->fraction*(p2[1]-start[1]);
|
||||
trace->endpos[2] = start[2] + trace->fraction*(p2[2]-start[2]);
|
||||
trace->plane.normal[0] = 0;
|
||||
trace->plane.normal[1] = 0;
|
||||
trace->plane.normal[2] = -1;
|
||||
trace->plane.dist = -(sectorm[sec1].ceilingheight-hull->clip_maxs[2]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (d1<0)
|
||||
sec2 = §orm[sidedefsm[ld->sidedef[0]].sector];
|
||||
else
|
||||
sec2 = §orm[sidedefsm[ld->sidedef[1]].sector];
|
||||
|
||||
if(sec2->ceilingheight == sec2->floorheight)
|
||||
sec2->ceilingheight += 64;
|
||||
|
||||
if (pointonplane[2] > sec2->floorheight-hull->clip_mins[2] &&
|
||||
pointonplane[2] < sec2->ceilingheight-hull->clip_maxs[2])
|
||||
{
|
||||
Con_Printf("Two sided passed\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Con_Printf("blocked by two sided line\n");
|
||||
// sec2->floorheight--;
|
||||
}
|
||||
|
||||
if (d1<0) //back to front.
|
||||
c1 = (d1+DIST_EPSILON) / (d1 - d2);
|
||||
else
|
||||
c1 = (d1-DIST_EPSILON) / (d1 - d2);
|
||||
|
||||
|
||||
clipfrac = c1;
|
||||
|
||||
if (clipfrac < 0)
|
||||
clipfrac = 0;
|
||||
if (clipfrac > 1)
|
||||
clipfrac = 1;
|
||||
|
||||
if (trace->fraction > clipfrac)
|
||||
{
|
||||
trace->fraction = clipfrac;
|
||||
VectorMA(pointonplane, 0, lp->normal, trace->endpos);
|
||||
VectorMA(trace->endpos, -0.1, delta, trace->endpos);
|
||||
// if (IS_NAN(trace->endpos[2]))
|
||||
// Con_Printf("Buggy clipping\n");
|
||||
VectorCopy(lp->normal, trace->plane.normal);
|
||||
trace->plane.dist = planedist;
|
||||
// if (IS_NAN(trace->plane.normal[2]))
|
||||
// Con_Printf("Buggy clipping\n");
|
||||
|
||||
if (clipfrac)
|
||||
Con_Printf("Clip Wall %f\n", clipfrac);
|
||||
}
|
||||
}
|
||||
|
||||
obmi = bmi;
|
||||
}
|
||||
|
||||
p1f += TRACESTEP;
|
||||
if (p1f >= p2f)
|
||||
break;
|
||||
|
||||
VectorMA(p1, TRACESTEP, delta, p1);
|
||||
}
|
||||
|
||||
// VectorMA(start, p2f*trace->fraction, delta, p2);
|
||||
|
||||
if (p2[2] != start[2])
|
||||
{
|
||||
if (sec1 == Doom_SectorNearPoint(p2)) //special test.
|
||||
{
|
||||
if (p2[2] <= sectorm[sec1].floorheight-hull->clip_mins[2]) //whoops, started outside... ?
|
||||
{
|
||||
p1f = fabs(sectorm[sec1].floorheight-hull->clip_mins[2] - start[2]);
|
||||
p2f = fabs(p2[2] - start[2]);
|
||||
if (!p2f)
|
||||
c1 = 1;
|
||||
else
|
||||
c1 = (p1f-DIST_EPSILON) / p2f;
|
||||
if (trace->fraction > c1)
|
||||
{
|
||||
trace->fraction = c1;
|
||||
trace->allsolid = trace->startsolid = false;
|
||||
trace->endpos[0] = start[0] + trace->fraction*(p2[0]-start[0]);
|
||||
trace->endpos[1] = start[1] + trace->fraction*(p2[1]-start[1]);
|
||||
trace->endpos[2] = start[2] + trace->fraction*(p2[2]-start[2]);
|
||||
trace->plane.normal[0] = 0;
|
||||
trace->plane.normal[1] = 0;
|
||||
trace->plane.normal[2] = 1;
|
||||
trace->plane.dist = sectorm[sec1].floorheight-hull->clip_mins[2];
|
||||
}
|
||||
|
||||
// if (IS_NAN(trace->endpos[2]))
|
||||
// Con_Printf("Nanny\n");
|
||||
}
|
||||
if (p2[2] >= sectorm[sec1].ceilingheight-hull->clip_maxs[2]) //whoops, started outside... ?
|
||||
{
|
||||
p1f = fabs(sectorm[sec1].ceilingheight-hull->clip_maxs[2] - start[2]);
|
||||
p2f = fabs(p2[2] - start[2]);
|
||||
if (!p2f)
|
||||
c1 = 1;
|
||||
else
|
||||
c1 = (p1f-DIST_EPSILON) / p2f;
|
||||
if (trace->fraction > c1)
|
||||
{
|
||||
trace->fraction = c1;
|
||||
trace->allsolid = trace->startsolid = false;
|
||||
trace->endpos[0] = start[0] + trace->fraction*(p2[0]-start[0]);
|
||||
trace->endpos[1] = start[1] + trace->fraction*(p2[1]-start[1]);
|
||||
trace->endpos[2] = start[2] + trace->fraction*(p2[2]-start[2]);
|
||||
trace->plane.normal[0] = 0;
|
||||
trace->plane.normal[1] = 0;
|
||||
trace->plane.normal[2] = -1;
|
||||
trace->plane.dist = -(sectorm[sec1].ceilingheight-hull->clip_maxs[2]);
|
||||
}
|
||||
|
||||
// if (IS_NAN(trace->endpos[2]))
|
||||
// Con_Printf("Nanny\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//we made it all the way through. yay.
|
||||
|
||||
trace->allsolid = trace->startsolid = false;
|
||||
//Con_Printf("total = %f\n", trace->fraction);
|
||||
return trace->fraction==1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Doom_SetHullFuncs(hull_t *hull)
|
||||
{
|
||||
|
|
|
@ -712,6 +712,8 @@ extern BOOL (WINAPI *qwglMakeCurrent)(HDC, HGLRC);
|
|||
extern BOOL (WINAPI *qSwapBuffers)(HDC);
|
||||
#endif
|
||||
|
||||
extern void (APIENTRY *qglDrawRangeElements) (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *);
|
||||
|
||||
/*
|
||||
extern qboolean gl_arb_fragment_program;
|
||||
extern PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#define HLPOLYHEADER (('T' << 24) + ('S' << 16) + ('D' << 8) + 'I') /* little-endian "IDST" */
|
||||
#define HLMDLHEADER "IDST"
|
||||
|
||||
typedef vec_t vec4_t[4];
|
||||
/*
|
||||
-----------------------------------------------------------------------------------------------------------------------
|
||||
main model header
|
||||
|
@ -207,7 +208,7 @@ typedef struct
|
|||
int frame; /* Current animation sequence and frame */
|
||||
float frametime; /* Time of last frame drawn */
|
||||
float controller[4]; /* Position of bone controllers */
|
||||
vec4_t adjust;
|
||||
float adjust[4];
|
||||
|
||||
/* Static pointers */
|
||||
hlmdl_header_t *header;
|
||||
|
|
|
@ -594,7 +594,7 @@ char *PR_UglyValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val)
|
|||
_snprintf (line, sizeof(line), "%s", val->string+progfuncs->stringtable);
|
||||
break;
|
||||
case ev_entity:
|
||||
sprintf (line, "%i", NUM_FOR_EDICT(progfuncs, (struct edict_s *)PROG_TO_EDICT(progfuncs, val->edict)));
|
||||
sprintf (line, "%i", val->_int);
|
||||
break;
|
||||
case ev_function:
|
||||
i = (val->function & 0xff000000)>>24;
|
||||
|
@ -1049,7 +1049,7 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s,
|
|||
break;
|
||||
|
||||
case ev_entity:
|
||||
*(int *)d = EDICT_TO_PROG(progfuncs, EDICT_NUM(progfuncs, atoi (s)));
|
||||
*(int *)d = atoi (s);
|
||||
break;
|
||||
|
||||
case ev_field:
|
||||
|
@ -2093,7 +2093,7 @@ char *SaveEnt (progfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed)
|
|||
if (name[strlen(name)-2] == '_')
|
||||
continue; // skip _x, _y, _z vars
|
||||
|
||||
v = (int *)(((char *)ed + externs->edictsize) + d->ofs*4);
|
||||
v = (int*)((edictrun_t*)ed)->fields + d->ofs;
|
||||
|
||||
// if the value is still all 0, skip the field
|
||||
type = d->type & ~DEF_SAVEGLOBAL;
|
||||
|
|
|
@ -166,12 +166,12 @@ optimisations_t optimisations[] =
|
|||
{&opt_overlaptemps, "r", 1, FLAG_ASDEFAULT, "overlaptemps", "Optimises the pr_globals count by overlapping temporaries. In QC, every multiplication, division or operation in general produces a temporary variable. This optimisation prevents excess, and in the case of Hexen2's gamecode, reduces the count by 50k. This is the most important optimisation, ever."},
|
||||
{&opt_constantarithmatic, "a", 1, FLAG_ASDEFAULT, "constantarithmatic", "5*6 actually emits an operation into the progs. This prevents that happening, effectivly making the compiler see 30"},
|
||||
{&opt_precache_file, "pf", 2, 0, "precache_file", "Strip out stuff wasted used in function calls and strings to the precache_file builtin (which is actually a stub in quake)."},
|
||||
{&opt_return_only, "ro", 3, 0, "return_only", "Functions ending in a return statement do not need a done statement at the end of the function. This can confuse some decompilers, making functions appear larger than they were."},
|
||||
{&opt_compound_jumps, "cj", 3, 0, "compound_jumps", "This optimisation plays an effect mostly with nested if/else statements, instead of jumping to an unconditional jump statement, it'll jump to the final destination instead. This will bewilder decompilers."},
|
||||
{&opt_return_only, "ro", 3, FLAG_KILLSDEBUGGERS, "return_only", "Functions ending in a return statement do not need a done statement at the end of the function. This can confuse some decompilers, making functions appear larger than they were."},
|
||||
{&opt_compound_jumps, "cj", 3, FLAG_KILLSDEBUGGERS, "compound_jumps", "This optimisation plays an effect mostly with nested if/else statements, instead of jumping to an unconditional jump statement, it'll jump to the final destination instead. This will bewilder decompilers."},
|
||||
// {&opt_comexprremoval, "cer", 4, 0, "expression_removal", "Eliminate common sub-expressions"}, //this would be too hard...
|
||||
{&opt_stripfunctions, "sf", 3, 0, "strip_functions", "Strips out the 'defs' of functions that were only ever called directly. This does not affect saved games."},
|
||||
{&opt_locals_marshalling, "lm", 4, FLAG_HIDDENINGUI|FLAG_KILLSDEBUGGERS, "locals_marshalling", "Store all locals in one section of the pr_globals. Vastly reducing it. This effectivly does the job of overlaptemps. It's been noticed as buggy by a few, however, and the curcumstances where it causes problems are not yet known."},
|
||||
{&opt_vectorcalls, "vc", 4, 0, "vectorcalls", "Where a function is called with just a vector, this causes the function call to store three floats instead of one vector. This can save a good number of pr_globals where those vectors contain many duplicate coordinates but do not match entirly."},
|
||||
{&opt_locals_marshalling, "lm", 4, FLAG_KILLSDEBUGGERS, "locals_marshalling", "Store all locals in one section of the pr_globals. Vastly reducing it. This effectivly does the job of overlaptemps. It's been noticed as buggy by a few, however, and the curcumstances where it causes problems are not yet known."},
|
||||
{&opt_vectorcalls, "vc", 4, FLAG_KILLSDEBUGGERS, "vectorcalls", "Where a function is called with just a vector, this causes the function call to store three floats instead of one vector. This can save a good number of pr_globals where those vectors contain many duplicate coordinates but do not match entirly."},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -2695,10 +2695,7 @@ static void PF_traceboxh2 (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|||
pr_global_struct->trace_fraction = trace.fraction;
|
||||
pr_global_struct->trace_inwater = trace.inwater;
|
||||
pr_global_struct->trace_inopen = trace.inopen;
|
||||
// if (trace.fraction != 1)
|
||||
// VectorMA (trace.endpos, 4, trace.plane.normal, P_VEC(trace_endpos));
|
||||
// else
|
||||
VectorCopy (trace.endpos, P_VEC(trace_endpos));
|
||||
VectorCopy (trace.endpos, P_VEC(trace_endpos));
|
||||
VectorCopy (trace.plane.normal, P_VEC(trace_plane_normal));
|
||||
pr_global_struct->trace_plane_dist = trace.plane.dist;
|
||||
if (trace.ent)
|
||||
|
@ -3053,9 +3050,7 @@ static void PF_cvar (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|||
void PF_cvar_string (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
char *str;
|
||||
|
||||
str = PR_GetStringOfs(prinst, OFS_PARM0);
|
||||
|
||||
RETURN_CSTRING(Cvar_VariableString (str));
|
||||
}
|
||||
|
||||
|
@ -3373,13 +3368,14 @@ void PF_precache_sound (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|||
char *s;
|
||||
int i;
|
||||
|
||||
s = PR_GetStringOfs(prinst, OFS_PARM0);
|
||||
/*
|
||||
if (sv.state != ss_loading)
|
||||
{
|
||||
PR_BIError (prinst, "PF_Precache_*: Precache can only be done in spawn functions");
|
||||
PR_BIError (prinst, "PF_Precache_*: Precache can only be done in spawn functions (%s)", s);
|
||||
return;
|
||||
}
|
||||
|
||||
s = PR_GetStringOfs(prinst, OFS_PARM0);
|
||||
*/
|
||||
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
|
||||
|
||||
if (s[0] <= ' ')
|
||||
|
@ -3406,14 +3402,15 @@ void PF_precache_model (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|||
char *s;
|
||||
int i;
|
||||
|
||||
s = PR_GetStringOfs(prinst, OFS_PARM0);
|
||||
/*
|
||||
if (sv.state != ss_loading)
|
||||
{
|
||||
PR_BIError (prinst, "PF_Precache_*: Precache can only be done in spawn functions");
|
||||
PR_BIError (prinst, "PF_Precache_*: Precache can only be done in spawn functions (%s)", s);
|
||||
G_FLOAT(OFS_RETURN) = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
s = PR_GetStringOfs(prinst, OFS_PARM0);
|
||||
*/
|
||||
G_INT(OFS_RETURN) = G_INT(OFS_PARM0);
|
||||
|
||||
if (s[0] <= ' ')
|
||||
|
@ -8260,7 +8257,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
//FIXME: distinguish between qw and nq parameters here?
|
||||
{"sprint", PF_sprint, 24, 24, 24}, // void(entity client, string s) sprint = #24;
|
||||
{"dprint", PF_dprint, 25, 0, 25}, // void(string s) dprint = #25;
|
||||
{"print", PF_print, 0, 25, 25}, // void(string s) print = #25;
|
||||
{"print", PF_print, 0, 25, 0}, // void(string s) print = #25;
|
||||
{"ftos", PF_ftos, 26, 26, 26}, // void(string s) ftos = #26;
|
||||
{"vtos", PF_vtos, 27, 27, 27}, // void(string s) vtos = #27;
|
||||
{"coredump", PF_coredump, 28, 28, 28}, //28
|
||||
|
|
|
@ -698,6 +698,8 @@ void SV_SaveLevelCache(qboolean dontharmgame)
|
|||
sprintf (name, "%s/saves/%s", com_gamedir, cache->mapname);
|
||||
COM_DefaultExtension (name, ".lvc");
|
||||
|
||||
COM_CreatePath(name);
|
||||
|
||||
if (!dontharmgame) //save game in progress
|
||||
Con_TPrintf (STL_SAVEGAMETO, name);
|
||||
|
||||
|
@ -713,7 +715,6 @@ void SV_SaveLevelCache(qboolean dontharmgame)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
f = fopen (name, "wb");
|
||||
if (!f)
|
||||
{
|
||||
|
|
|
@ -432,6 +432,7 @@ void SV_Map_f (void)
|
|||
qboolean issamelevel = false;
|
||||
qboolean newunit = false;
|
||||
qboolean cinematic = false;
|
||||
qboolean waschangelevel = false;
|
||||
int i;
|
||||
char *startspot;
|
||||
|
||||
|
@ -444,6 +445,8 @@ void SV_Map_f (void)
|
|||
strcpy (level, Cmd_Argv(1));
|
||||
startspot = ((Cmd_Argc() == 2)?NULL:Cmd_Argv(2));
|
||||
|
||||
waschangelevel = !strcmp(Cmd_Argv(0), "changelevel");
|
||||
|
||||
nextserver = strchr(level, '+');
|
||||
if (nextserver)
|
||||
{
|
||||
|
@ -545,7 +548,11 @@ void SV_Map_f (void)
|
|||
#endif
|
||||
|
||||
if (newunit || !startspot || !SV_LoadLevelCache(level, startspot, false))
|
||||
{
|
||||
if (waschangelevel && !startspot)
|
||||
startspot = "";
|
||||
SV_SpawnServer (level, startspot, false, cinematic);
|
||||
}
|
||||
|
||||
SV_BroadcastCommand ("reconnect\n");
|
||||
|
||||
|
|
|
@ -2145,7 +2145,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
|
|||
}
|
||||
}
|
||||
|
||||
if (!ignorepvs)
|
||||
/* if (!ignorepvs)
|
||||
{
|
||||
//branch out to the pvs testing.
|
||||
if (ent->tagent)
|
||||
|
@ -2165,7 +2165,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
|
|||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1010,14 +1010,25 @@ void SV_PreSpawn_f (void)
|
|||
else
|
||||
{
|
||||
if (sv.democausesreconnect)
|
||||
SZ_Write (&host_client->netchan.message,
|
||||
sv.demosignon_buffers[buf],
|
||||
sv.demosignon_buffer_size[buf]);
|
||||
{
|
||||
if (host_client->netchan.message.cursize+sv.signon_buffer_size[buf] < host_client->netchan.message.maxsize)
|
||||
{
|
||||
SZ_Write (&host_client->netchan.message,
|
||||
sv.demosignon_buffers[buf],
|
||||
sv.demosignon_buffer_size[buf]);
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
else
|
||||
SZ_Write (&host_client->netchan.message,
|
||||
sv.signon_buffers[buf],
|
||||
sv.signon_buffer_size[buf]);
|
||||
buf++;
|
||||
{
|
||||
if (host_client->netchan.message.cursize+sv.signon_buffer_size[buf] < host_client->netchan.message.maxsize)
|
||||
{
|
||||
SZ_Write (&host_client->netchan.message,
|
||||
sv.signon_buffers[buf],
|
||||
sv.signon_buffer_size[buf]);
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (buf == bufs+sv.numextrastatics+sv.num_edicts+255)
|
||||
{ // all done prespawning
|
||||
|
|
Loading…
Reference in a new issue