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:
Spoike 2005-05-13 10:42:48 +00:00
parent a366a4d90a
commit e348dc30a2
44 changed files with 2031 additions and 1159 deletions

View file

@ -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

View file

@ -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);

View file

@ -483,6 +483,7 @@ void CL_SendConnectPacket (
NET_SendPacket (NS_CLIENT, strlen(data), data, adr);
cl.splitclients = 0;
CL_RegisterSplitCommands();
}
/*

View file

@ -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);

View file

@ -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 ();

View file

@ -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 ();

View file

@ -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
}

View file

@ -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

View file

@ -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)

View file

@ -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,11 +1069,16 @@ 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. :)
@ -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

View file

@ -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

View file

@ -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);

View file

@ -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");
}
}
}

View file

@ -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

View file

@ -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}

View file

@ -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

View file

@ -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
};

View file

@ -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);
@ -2352,12 +2353,7 @@ void CModQ3_LoadRFaces (lump_t *l)
int numverts, numindexes;
int fv;
mesh_t *mesh;
extern cvar_t gl_shadeq3;
int shaders = gl_shadeq3.value;
mesh_t *mesh;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
@ -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);
@ -2494,10 +2488,6 @@ void CModRBSP_LoadRFaces (lump_t *l)
int fv;
mesh_t *mesh;
extern cvar_t gl_shadeq3;
int shaders = gl_shadeq3.value;
in = (void *)(mod_base + l->fileofs);
@ -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

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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;
}

View file

@ -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"

View file

@ -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

View file

@ -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 );

View file

@ -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)
{

View file

@ -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);
}
else
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);
@ -2944,7 +2966,28 @@ void GLMod_LoadSpriteModel (model_t *mod, void *buffer)
mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2;
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);
}
}

View file

@ -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;

View file

@ -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)
{
@ -4173,4 +4378,6 @@ void PPL_CreateShaderObjects(void)
PPL_CreateLightTexturesProgram();
#endif
PPL_LoadSpecularFragmentProgram();
}
}
#endif

View file

@ -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;

View file

@ -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;

View file

@ -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();

View file

@ -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");

View file

@ -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;

View file

@ -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 = &sectorm[sidedefsm[ld->sidedef[1]].sector];
else
sec2 = &sectorm[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 = &sectorm[sidedefsm[ld->sidedef[0]].sector];
else
sec2 = &sectorm[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)
{

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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}
};

View file

@ -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] <= ' ')
@ -3405,15 +3401,16 @@ 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

View file

@ -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)
{

View file

@ -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");

View file

@ -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;
}
}
*/

View file

@ -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