Track areas properly, so we don't bug out when a client has multiple cameras in different areas.

Fix up r_ignoreentpvs 0 to check areas properly.
checkpvs builtin can no longer mess up area checks elsewhere.
Write out foo.db files for release builds, in the hopes of at least getting function names from release-build crashes.
Implement _skyroom worldspawn field, still needs a few tweaks though.
Try to fix android surface-related crashes, AGAIN.
Separate parsing of connect requests, in preparation for formal logins (and removal of the old ranking code).
A few tweaks to try to improve compatibility with q3 mods.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5484 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2019-07-02 04:12:20 +00:00
parent 6c7220324e
commit 8197e0875f
64 changed files with 1336 additions and 959 deletions

View File

@ -1006,7 +1006,7 @@ ifeq ($(FTE_TARGET),nacl)
CC=
CXX=
STRIP=
STRIP=@echo SKIP: strip
NACLLIBC=glibc
ifeq ($(NARCH),x86_32)
CC=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_x86_$(NACLLIBC)/bin/i686-nacl-gcc -DNACL -m32
@ -1187,7 +1187,7 @@ ifeq ($(FTE_TARGET),vc)
JPEGLIB=libs/jpeg.lib
endif
endif
STRIP=@echo strip
STRIP=@echo SKIP: strip
EXEPOSTFIX=.exe
CC=PATH="C:\Program Files (x86)\$(MSVCDIR)\Common7\IDE" "$(MSVCPATH)cl" $(SDKINC) $(MSVCINC) -D_CRT_SECURE_NO_WARNINGS
@ -1640,7 +1640,7 @@ ifeq ($(FTE_TARGET),web)
#SV_LDFLAGS=
STRIP=echo
STRIP=@echo SKIP: strip
#GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) cd_null.o
#GL_LDFLAGS=$(GLLDFLAGS)
GLB_DIR=gl_web
@ -1786,9 +1786,21 @@ DO_LD ?= $(DO_ECHO) $(LDCC) -o $@ $(LTO_LD) $(WCFLAGS) $(BRANDFLAGS) $(CFLAGS)
$(OUT_DIR)/$(EXE_NAME): $(PRECOMPHEADERS) $(foreach fn, $(CUSTOMOBJS) $(foreach ol, $(OBJS), $($(ol))),$(if $(findstring ltox,$(fn)),,$(OUT_DIR)/$(fn)))
$(DO_LD) $(foreach fn, $(CUSTOMOBJS) $(foreach ol, $(OBJS) $(LTO_END), $($(ol))),$(if $(findstring ltox,$(fn)),$(subst ltox,-x ,$(fn)),$(NATIVE_OUT_DIR)/$(fn)) ) $(LDFLAGS)
$(OUT_DIR)/$(EXE_NAME).db: $(PRECOMPHEADERS) $(foreach fn, $(CUSTOMOBJS) $(foreach ol, $(OBJS), $($(ol))),$(if $(findstring ltox,$(fn)),,$(OUT_DIR)/$(fn)))
$(DO_LD) $(foreach fn, $(CUSTOMOBJS) $(foreach ol, $(OBJS) $(LTO_END), $($(ol))),$(if $(findstring ltox,$(fn)),$(subst ltox,-x ,$(fn)),$(NATIVE_OUT_DIR)/$(fn)) ) $(LDFLAGS)
ifeq (,$(findstring SKIP,$(STRIP)))
#link to a .db file
#then strip its debug data to the non-.db release binary
_out-rel: $(ARCH_PREDEP)
@$(MAKE) $(OUT_DIR)/$(EXE_NAME).db EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(WCFLAGS) $(RELEASE_CFLAGS)" LDFLAGS="$(BASELDFLAGS) $(LDFLAGS) $(RELEASE_LDFLAGS)" OBJS="$(OBJS)"
@$(STRIP) $(STRIPFLAGS) $(OUT_DIR)/$(EXE_NAME).db -o $(OUT_DIR)/$(EXE_NAME)
else
#STRIP macro won't work, don't do the .db thing and don't expect strip -o to work.
_out-rel: $(ARCH_PREDEP)
@$(MAKE) $(OUT_DIR)/$(EXE_NAME) EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(WCFLAGS) $(RELEASE_CFLAGS)" LDFLAGS="$(BASELDFLAGS) $(LDFLAGS) $(RELEASE_LDFLAGS)" OBJS="$(OBJS)"
$(STRIP) $(STRIPFLAGS) $(OUT_DIR)/$(EXE_NAME)
@echo not stripping $(OUT_DIR)/$(EXE_NAME)
endif
_out-dbg: $(ARCH_PREDEP)
@$(MAKE) $(OUT_DIR)/$(EXE_NAME) EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(WCFLAGS) $(DEBUG_CFLAGS)" LDFLAGS="$(BASELDFLAGS) $(LDFLAGS) $(DEBUG_LDFLAGS)" OBJS="$(OBJS)"

View File

@ -313,15 +313,6 @@ int CG_GetGameState(gameState_t *gs)
return sizeof(gameState_t);
}
typedef struct {
int serverTime;
int angles[3];
int buttons;
qbyte weapon; // weapon
signed char forwardmove, rightmove, upmove;
} q3usercmd_t;
#define CMD_BACKUP countof(cl.outframes)
#define CMD_MASK (CMD_BACKUP-1)
static int CGQ3_GetCurrentCmdNumber(void)
{ //Q3 sequences are 1-based, so 1<=idx<=latestsequence are valid
//FTE's sequences are 0-based, so 0<=idx<latestsequence are valid
@ -338,11 +329,11 @@ static qboolean CGQ3_GetUserCmd(int cmdNumber, q3usercmd_t *ucmd)
if (cmdNumber >= cl.movesequence)
Host_EndGame("CLQ3_GetUserCmd: %i >= %i", cmdNumber, cl.movesequence);
if (cl.movesequence - (cmdNumber+1) > CMD_BACKUP)
if (cl.movesequence - (cmdNumber+1) > Q3CMD_BACKUP)
return false;
//note: frames and commands are desynced in q3.
cmd = &cl.outframes[(cmdNumber) & CMD_MASK].cmd[0];
cmd = &cl.outframes[(cmdNumber) & Q3CMD_MASK].cmd[0];
ucmd->angles[0] = cmd->angles[0];
ucmd->angles[1] = cmd->angles[1];
ucmd->angles[2] = cmd->angles[2];
@ -359,31 +350,32 @@ static qboolean CGQ3_GetUserCmd(int cmdNumber, q3usercmd_t *ucmd)
static vm_t *cgvm;
extern int keycatcher;
char bigconfigstring[65536];
qboolean CG_GetServerCommand(int cmdnum)
{
static char bigconfigstring[65536];
//quote from cgame code:
// get the gamestate from the client system, which will have the
// new configstring already integrated
char *str = ccs.serverCommands[cmdnum & TEXTCMD_MASK];
char *str = ccs.serverCommands[cmdnum & Q3TEXTCMD_MASK];
Con_DPrintf("Dispaching %s\n", str);
Cmd_TokenizeString(str, false, false);
if (!strcmp(Cmd_Argv(0), "bcs0"))
{
{ //start
Q_snprintfz(bigconfigstring, sizeof(bigconfigstring), "cs %s \"%s", Cmd_Argv(1), Cmd_Argv(2));
return false;
}
if (!strcmp(Cmd_Argv(0), "bcs1"))
{
{ //continuation
Q_strncatz(bigconfigstring, Cmd_Argv(2), sizeof(bigconfigstring));
return false;
}
if (!strcmp(Cmd_Argv(0), "bcs2"))
{
{ //end
Q_strncatz(bigconfigstring, Cmd_Argv(2), sizeof(bigconfigstring));
Q_strncatz(bigconfigstring, "\"", sizeof(bigconfigstring));
Cmd_TokenizeString(bigconfigstring, false, false);
@ -1154,9 +1146,8 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
VM_LONG(ret) = Sys_Milliseconds();
break;
case CG_REAL_TIME:
//really local time
VM_LONG(ret) = Sys_Milliseconds();
break;
VALIDATEPOINTER(arg[0], sizeof(q3time_t));
return Q3VM_GetRealtime(VM_POINTER(arg[0]));
case CG_SNAPVECTOR: // ( float *v )
VALIDATEPOINTER(arg[0], sizeof(vec3_t));

View File

@ -2622,7 +2622,7 @@ void CL_DrawDebugPlane(float *normal, float dist, float r, float g, float b, qbo
{
// int oldents = cl_numvisedicts;
// cl_numvisedicts = 0;
r_refdef.scenevis = NULL;
r_refdef.scenevis = NULL;
BE_DrawWorld(NULL);
cl_numstris = 0;
// cl_numvisedicts = oldents;
@ -3277,7 +3277,7 @@ void CL_ClearLerpEntsParticleState(void)
}
}
void CL_LinkStaticEntities(void *pvs)
void CL_LinkStaticEntities(void *pvs, int *areas)
{
int i;
entity_t *ent;
@ -3347,7 +3347,7 @@ void CL_LinkStaticEntities(void *pvs)
}
/*pvs test*/
if (pvs && !cl.worldmodel->funcs.EdictInFatPVS(cl.worldmodel, &stat->ent.pvscache, pvs))
if (pvs && !cl.worldmodel->funcs.EdictInFatPVS(cl.worldmodel, &stat->ent.pvscache, pvs, areas))
continue;
@ -3376,6 +3376,43 @@ void CL_LinkStaticEntities(void *pvs)
}
}
//returns cos(angle)
static float CompareAngles (const vec3_t angles1, const vec3_t angles2)
{
float angle;
vec3_t dir1, dir2;
angle = angles1[YAW] * (M_PI*2 / 360);
dir1[1] = sin(angle);
dir1[0] = cos(angle);
if (angles1[PITCH])
{
angle = angles1[PITCH] * (M_PI*2 / 360);
dir1[2] = -sin(angle);
angle = cos(angle);
dir1[0] *= angle;
dir1[1] *= angle;
}
else
dir1[2] = 0;
angle = angles2[YAW] * (M_PI*2 / 360);
dir2[1] = sin(angle);
dir2[0] = cos(angle);
if (angles2[PITCH])
{
angle = angles2[PITCH] * (M_PI*2 / 360);
dir2[2] = -sin(angle);
angle = cos(angle);
dir2[0] *= angle;
dir2[1] *= angle;
}
else
dir2[2] = 0;
return DotProduct(dir1,dir2);
}
/*
===============
CL_LinkPacketEntities
@ -3395,6 +3432,7 @@ static void CL_TransitionPacketEntities(int newsequence, packet_entities_t *newp
int oldpnum, newpnum;
float *snew__origin;
float *sold__origin;
float cos_theta;
int oldsequence;
extern cvar_t r_nolerp;
@ -3520,14 +3558,17 @@ static void CL_TransitionPacketEntities(int newsequence, packet_entities_t *newp
snew__origin = snew->u.q1.predorg;
sold__origin = sold->u.q1.predorg;
cos_theta = 1; //don't cut off lerping when the player spins too fast.
}
else
{
snew__origin = snew->origin;
sold__origin = sold->origin;
cos_theta = CompareAngles(sold->angles, snew->angles);
}
VectorSubtract(snew__origin, sold__origin, move);
if (DotProduct(move, move) > 200*200 || snew->modelindex != sold->modelindex || ((sold->effects ^ snew->effects) & EF_TELEPORT_BIT))
if (DotProduct(move, move) > 200*200 || cos_theta < 0.707 || snew->modelindex != sold->modelindex || ((sold->effects ^ snew->effects) & EF_TELEPORT_BIT))
{
isnew = true; //disable lerping (and indirectly trails)
// VectorClear(move);
@ -3857,6 +3898,8 @@ void CL_LinkPacketEntities (void)
int modelflags;
struct itemtimer_s *timer, **timerlink;
float timestep = cl.time-cl.lastlinktime;
extern cvar_t r_ignoreentpvs;
vec3_t absmin, absmax;
cl.lastlinktime = cl.time;
timestep = bound(0, timestep, 0.1);
@ -3919,12 +3962,6 @@ void CL_LinkPacketEntities (void)
le = &cl.lerpents[state->number];
ent = &cl_visedicts[cl_numvisedicts];
ent->pvscache.num_leafs = 0;
#if defined(Q2BSPS) || defined(Q3BSPS) || defined(TERRAIN)
ent->pvscache.areanum = 0;
ent->pvscache.areanum2 = 0;
ent->pvscache.headnode = 0;
#endif
ent->rtype = RT_MODEL;
ent->playerindex = -1;
@ -4097,6 +4134,24 @@ void CL_LinkPacketEntities (void)
else
model2 = NULL;
if (r_ignoreentpvs.ival || !model)
{
ent->pvscache.num_leafs = 0;
#if defined(Q2BSPS) || defined(Q3BSPS) || defined(TERRAIN)
ent->pvscache.areanum = 0;
ent->pvscache.areanum2 = 0;
ent->pvscache.headnode = 0;
#endif
}
else
{
/*bsp model size*/
VectorAdd(model->mins, ent->origin, absmin);
VectorAdd(model->maxs, ent->origin, absmax);
cl.worldmodel->funcs.FindTouchedLeafs(cl.worldmodel, &ent->pvscache, absmin, absmax);
}
cl_numvisedicts++;
ent->forcedshader = NULL;

View File

@ -637,7 +637,8 @@ void CL_SendConnectPacket (netadr_t *to, int mtu,
//fixme: we shouldn't cycle these so much
connectinfo.qport = qport.value;
Cvar_SetValue(&qport, (connectinfo.qport+1)&0xffff);
if (connectinfo.adr.type != NA_LOOPBACK)
Cvar_SetValue(&qport, (connectinfo.qport+1)&0xffff);
if (connectinfo.protocol == CP_QUAKE2 && (connectinfo.subprotocol == PROTOCOL_VERSION_R1Q2 || connectinfo.subprotocol == PROTOCOL_VERSION_Q2PRO))
connectinfo.qport &= 0xff;
@ -759,11 +760,16 @@ void CL_CheckForResend (void)
extern cvar_t dpcompat_nopreparse;
#endif
extern cvar_t sv_guidhash;
if (connectinfo.time && realtime - connectinfo.time < 1.0)
return;
memset(&connectinfo, 0, sizeof(connectinfo));
connectinfo.time = realtime;
Q_strncpyz (cls.servername, "internalserver", sizeof(cls.servername));
Cvar_ForceSet(&cl_servername, cls.servername);
if (!NET_StringToAdr(cls.servername, 0, &connectinfo.adr))
return; //erk?
if (*cl_disconnectreason.string)
Cvar_Set(&cl_disconnectreason, "");
connectinfo.trying = true;
@ -967,35 +973,35 @@ void CL_CheckForResend (void)
net_from = connectinfo.adr;
Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\"", NQ_NETCHAN_VERSION, 0, SV_NewChallenge()), false, false);
SVC_DirectConnect();
SVC_DirectConnect(0);
}
else if (connectinfo.subprotocol == CPNQ_BJP3)
{
net_from = connectinfo.adr;
Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\\mod\\%i\"", NQ_NETCHAN_VERSION, 0, SV_NewChallenge(), PROTOCOL_VERSION_BJP3), false, false);
SVC_DirectConnect();
SVC_DirectConnect(0);
}
else if (connectinfo.subprotocol == CPNQ_FITZ666)
{
net_from = connectinfo.adr;
Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\\mod\\%i\"", NQ_NETCHAN_VERSION, 0, SV_NewChallenge(), PROTOCOL_VERSION_FITZ), false, false);
SVC_DirectConnect();
SVC_DirectConnect(0);
}
else if (proquakeangles)
{
net_from = connectinfo.adr;
Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\\mod\\1\"", NQ_NETCHAN_VERSION, 0, SV_NewChallenge()), false, false);
SVC_DirectConnect();
SVC_DirectConnect(0);
}
else if (1)
{
net_from = connectinfo.adr;
Q_snprintfz(net_message.data, net_message.maxsize, "xxxxconnect\\protocol\\darkplaces 3\\protocols\\DP7 DP6 DP5 RMQ FITZ NEHAHRABJP2 NEHAHRABJP NEHAHRABJP3 QUAKE\\challenge\\0x%x\\name\\%s", SV_NewChallenge(), name.string);
Cmd_TokenizeString (net_message.data+4, false, false);
SVC_DirectConnect();
SVC_DirectConnect(0);
}
else
CL_ConnectToDarkPlaces("", &connectinfo.adr);
@ -5954,7 +5960,17 @@ double Host_Frame (double time)
#ifndef CLIENTONLY
if (isDedicated) //someone changed it.
{
if (sv.state)
{
float ohft = host_frametime;
RSpeedRemark();
SV_Frame();
RSpeedEnd(RSPEED_SERVER);
host_frametime = ohft;
}
return 0;
}
#endif
cls.framecount++;

View File

@ -101,7 +101,8 @@ int Script_Read(int handle, struct pc_token_s *token)
}
}
sc->filestack[sc->stackdepth-1] = s;
if (com_tokentype == TTP_LINEENDING)
continue; //apparently we shouldn't stop on linebreaks
if (!strcmp(readstring, "#include"))
{
@ -188,7 +189,7 @@ int Script_Read(int handle, struct pc_token_s *token)
}
// Con_Printf("Found %s (%i, %i)\n", token->string, token->type, token->subtype);
return !!*token->string || com_tokentype == TTP_STRING;
return com_tokentype != TTP_EOF;
}
int Script_LoadFile(char *filename)
@ -1236,8 +1237,8 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break;
case UI_REAL_TIME:
VM_FLOAT(ret) = realtime;
break;
VALIDATEPOINTER(arg[0], sizeof(q3time_t));
return Q3VM_GetRealtime(VM_POINTER(arg[0]));
#ifdef CL_MASTER
case UI_LAN_GETSERVERCOUNT: //LAN Get server count

View File

@ -330,7 +330,7 @@ typedef struct dlight_s
float coronascale;
unsigned int flags;
char cubemapname[64];
char cubemapname[MAX_QPATH];
char *customstyle;
int coronaocclusionquery;
@ -1370,7 +1370,7 @@ void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, vec3_t orientationup, struct m
//
void CL_SetSolidPlayers (void);
void CL_SetUpPlayerPrediction(qboolean dopred);
void CL_LinkStaticEntities(void *pvs);
void CL_LinkStaticEntities(void *pvs, int *areas);
void CL_TransitionEntities (void); /*call at the start of the frame*/
void CL_EmitEntities (void);
void CL_ClearProjectiles (void);

View File

@ -8,9 +8,6 @@
#include "clq3defs.h"
#define CMD_BACKUP UPDATE_BACKUP
#define CMD_MASK UPDATE_MASK
#define SHOWSTRING(s) if(cl_shownet.value==2)Con_Printf ("%s\n", s);
#define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
#define SHOWNET2(x, y) if(cl_shownet.value==2)Con_Printf ("%3i:%3i:%s\n", msg_readcount-1, y, x);
@ -86,14 +83,14 @@ void CLQ3_ParseServerCommand(void)
ccs.lastServerCommandNum++;
if( number > ccs.lastServerCommandNum+TEXTCMD_MASK-1 )
if( number > ccs.lastServerCommandNum+Q3TEXTCMD_MASK-1 )
{
Con_Printf("Warning: Lost %i reliable serverCommands\n",
number - ccs.lastServerCommandNum );
}
// archive the command to be processed by cgame later
Q_strncpyz( ccs.serverCommands[number & TEXTCMD_MASK], string, sizeof( ccs.serverCommands[0] ) );
Q_strncpyz( ccs.serverCommands[number & Q3TEXTCMD_MASK], string, sizeof( ccs.serverCommands[0] ) );
}
/*
@ -333,9 +330,9 @@ void CLQ3_ParseSnapshot(void)
// Find last usercmd server has processed and calculate snap.ping
snap.ping = 3;
for (i=cls.netchan.outgoing_sequence-1 ; i>cls.netchan.outgoing_sequence-CMD_BACKUP ; i--)
for (i=cls.netchan.outgoing_sequence-1 ; i>cls.netchan.outgoing_sequence-Q3CMD_BACKUP ; i--)
{
frame = &cl.outframes[i & CMD_MASK];
frame = &cl.outframes[i & Q3CMD_MASK];
if (frame->server_message_num == snap.deltaFrame)
{
snap.ping = Sys_Milliseconds() - frame->client_time;
@ -641,7 +638,6 @@ void CLQ3_ParseGameState(void)
}
#define TEXTCMD_BACKUP 64
void CLQ3_ParseServerMessage (void)
{
int cmd;
@ -661,9 +657,9 @@ void CLQ3_ParseServerMessage (void)
// read last client command number server received
ccs.lastClientCommandNum = MSG_ReadLong();
if( ccs.lastClientCommandNum <= ccs.numClientCommands - TEXTCMD_BACKUP )
if( ccs.lastClientCommandNum <= ccs.numClientCommands - Q3TEXTCMD_BACKUP )
{
ccs.lastClientCommandNum = ccs.numClientCommands - TEXTCMD_BACKUP + 1;
ccs.lastClientCommandNum = ccs.numClientCommands - Q3TEXTCMD_BACKUP + 1;
}
else if( ccs.lastClientCommandNum > ccs.numClientCommands )
{
@ -749,7 +745,7 @@ qboolean CLQ3_Netchan_Process(void)
// calculate bitmask
bitmask = (sequence ^ cls.challenge) & 0xff;
string = ccs.clientCommands[lastClientCommandNum & TEXTCMD_MASK];
string = ccs.clientCommands[lastClientCommandNum & Q3TEXTCMD_MASK];
#ifndef Q3_NOENCRYPT
// decrypt the packet
@ -800,7 +796,7 @@ void CL_Netchan_Transmit( int length, const qbyte *data )
// calculate bitmask
bitmask = (lastSequence ^ serverid ^ cls.challenge) & 0xff;
string = ccs.serverCommands[lastServerCommandNum & TEXTCMD_MASK];
string = ccs.serverCommands[lastServerCommandNum & Q3TEXTCMD_MASK];
#ifndef Q3_NOENCRYPT
// encrypt the packet
@ -887,10 +883,10 @@ void VARGS CLQ3_SendClientCommand(const char *fmt, ...)
ccs.numClientCommands++;
// check if server will lose some of our clientCommands
if(ccs.numClientCommands - ccs.lastClientCommandNum >= TEXTCMD_BACKUP)
if(ccs.numClientCommands - ccs.lastClientCommandNum >= Q3TEXTCMD_BACKUP)
Host_EndGame("Client command overflow");
Q_strncpyz(ccs.clientCommands[ccs.numClientCommands & TEXTCMD_MASK], command, sizeof(ccs.clientCommands[0]));
Q_strncpyz(ccs.clientCommands[ccs.numClientCommands & Q3TEXTCMD_MASK], command, sizeof(ccs.clientCommands[0]));
Con_DPrintf("Sending %s\n", command);
}
@ -934,13 +930,13 @@ void CLQ3_SendCmd(usercmd_t *cmd)
if (Key_Dest_Has(~kdm_game) || (keycatcher&3))
cmd->buttons |= 2; //add in the 'at console' button
cl.outframes[cl.movesequence&CMD_MASK].cmd[0] = *cmd;
cl.outframes[cl.movesequence&Q3CMD_MASK].cmd[0] = *cmd;
cl.movesequence++;
//FIXME: q3 generates a new command every video frame, but a new packet at a more limited rate.
//FIXME: we should return here if its not yet time for a network frame.
frame = &cl.outframes[cls.netchan.outgoing_sequence & CMD_MASK];
frame = &cl.outframes[cls.netchan.outgoing_sequence & Q3CMD_MASK];
frame->cmd_sequence = cl.movesequence;
frame->server_message_num = ccs.serverMessageNum;
frame->server_time = cl.gametime;
@ -960,7 +956,7 @@ void CLQ3_SendCmd(usercmd_t *cmd)
{
MSG_WriteBits(&msg, clcq3_clientCommand, 8);
MSG_WriteBits(&msg, i, 32);
string = ccs.clientCommands[i & TEXTCMD_MASK];
string = ccs.clientCommands[i & Q3TEXTCMD_MASK];
while(*string)
MSG_WriteBits(&msg, *string++, 8);
MSG_WriteBits(&msg, 0, 8);
@ -969,12 +965,12 @@ void CLQ3_SendCmd(usercmd_t *cmd)
i = cls.netchan.outgoing_sequence;
i -= bound(0, cl_c2sdupe.ival, 5); //extra age, if desired
i--;
if (i < cls.netchan.outgoing_sequence-CMD_MASK)
i = cls.netchan.outgoing_sequence-CMD_MASK;
oldframe = &cl.outframes[i & CMD_MASK];
if (i < cls.netchan.outgoing_sequence-Q3CMD_MASK)
i = cls.netchan.outgoing_sequence-Q3CMD_MASK;
oldframe = &cl.outframes[i & Q3CMD_MASK];
cmdcount = cl.movesequence - oldframe->cmd_sequence;
if (cmdcount > CMD_MASK)
cmdcount = CMD_MASK;
if (cmdcount > Q3CMD_MASK)
cmdcount = Q3CMD_MASK;
// begin a client move command, if any
if (cmdcount)
@ -989,7 +985,7 @@ void CLQ3_SendCmd(usercmd_t *cmd)
MSG_WriteBits(&msg, cmdcount, 8);
// calculate key
string = ccs.serverCommands[ccs.lastServerCommandNum & TEXTCMD_MASK];
string = ccs.serverCommands[ccs.lastServerCommandNum & Q3TEXTCMD_MASK];
key = ccs.fs_key ^ ccs.serverMessageNum ^ StringKey(string, 32);
//note that q3 uses timestamps so sequences are not important
@ -997,7 +993,7 @@ void CLQ3_SendCmd(usercmd_t *cmd)
from = &nullcmd;
for (i = cl.movesequence-cmdcount; i < cl.movesequence; i++)
{
to = &cl.outframes[i&CMD_MASK].cmd[0];
to = &cl.outframes[i&Q3CMD_MASK].cmd[0];
MSG_Q3_WriteDeltaUsercmd( &msg, key, from, to );
from = to;
}

View File

@ -202,12 +202,22 @@ typedef struct frame_s {
int serverTime;
} q3frame_t;
typedef struct {
int serverTime;
int angles[3];
int buttons;
qbyte weapon; // weapon
signed char forwardmove, rightmove, upmove;
} q3usercmd_t;
#define Q3CMD_BACKUP 64 //number of q3usercmd_ts that the client can queue before acks
#define Q3CMD_MASK (Q3CMD_BACKUP-1)
#define Q3MAX_PARSE_ENTITIES 2048
#define Q3PARSE_ENTITIES_MASK (Q3MAX_PARSE_ENTITIES-1)
#define MAX_STRING_CHARS 1024
#define TEXTCMD_BACKUP 64 // size of reliable text commands buffer, must be power of two
#define TEXTCMD_MASK (TEXTCMD_BACKUP-1)
#define Q3TEXTCMD_BACKUP 64 //number of reliable text commands that can be queued, must be power of two
#define Q3TEXTCMD_MASK (Q3TEXTCMD_BACKUP-1)
#define MAX_Q3_CONFIGSTRINGS 1024
#define CFGSTR_SYSINFO 1
@ -238,8 +248,8 @@ typedef struct {
q3entityState_t baselines[MAX_GENTITIES];
char clientCommands[TEXTCMD_BACKUP][MAX_STRING_CHARS];
char serverCommands[TEXTCMD_BACKUP][MAX_STRING_CHARS];
char clientCommands[Q3TEXTCMD_BACKUP][MAX_STRING_CHARS];
char serverCommands[Q3TEXTCMD_BACKUP][MAX_STRING_CHARS];
} ClientConnectionState_t;
extern ClientConnectionState_t ccs;
@ -299,7 +309,7 @@ typedef struct {
typedef struct {
glyphInfo_t glyphs [GLYPHS_PER_FONT];
float glyphScale;
char name[MAX_QPATH];
char name[OLD_MAX_QPATH];
} fontInfo_t;
void UI_RegisterFont(char *fontName, int pointSize, fontInfo_t *font);

View File

@ -2126,7 +2126,14 @@ static int M_Main_AddExtraOptions(menu_t *mainm, int y)
else if (PM_CanInstall("qi"))
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Get Quake Injector", "pkg reset; pkg add qi; pkg apply\n"); y += 20;}
if (Cmd_Exists("menu_download"))
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Updates ", "menu_download\n"); y += 20;}
{
#ifdef WEBCLIENT
MC_AddConsoleCommandQBigFont(mainm, 72, y, "Updates ", "menu_download\n"); y += 20;
#else
MC_AddConsoleCommandQBigFont(mainm, 72, y, "Packages ", "menu_download\n");
#endif
y += 20;
}
return y;
}

View File

@ -2239,6 +2239,13 @@ static qboolean Media_Roq_DecodeFrame (cin_t *cin, qboolean nosound, qboolean fo
return true;
}
void Media_Roq_GetSize(struct cin_s *cin, int *width, int *height, float *aspect)
{
*width = cin->roq.roqfilm->width;
*height = cin->roq.roqfilm->height;
*aspect = (float)cin->roq.roqfilm->width/cin->roq.roqfilm->height;
}
static cin_t *Media_RoQ_TryLoad(char *name)
{
cin_t *cin;
@ -2251,6 +2258,7 @@ static cin_t *Media_RoQ_TryLoad(char *name)
cin = Z_Malloc(sizeof(cin_t));
cin->decodeframe = Media_Roq_DecodeFrame;
cin->shutdown = Media_Roq_Shutdown;
cin->getsize = Media_Roq_GetSize;
cin->roq.roqfilm = roqfilm;

View File

@ -855,6 +855,7 @@ const char *presetexec[] =
"seta r_coronas 0;"
"seta r_shadow_realtime_dlight 0;"
"seta r_shadow_realtime_world 0;"
"seta r_shadow_realtime_dlight_shadows 1;"
"seta r_glsl_offsetmapping 0;"
"seta vid_hardwaregamma 3;" //people benchmarking against other engines with fte using glsl gamma and the other not is annoying as fuck.
// "seta gl_detail 0;"

View File

@ -1238,9 +1238,6 @@ void M_Init_Internal (void)
Cmd_AddCommand ("help", M_Menu_Help_f);
Cmd_AddCommand ("menu_quit", M_Menu_Quit_f);
Cmd_AddCommand ("menu_mods", M_Menu_Mods_f);
#ifndef MINIMAL
Cmd_AddCommandAD ("modelviewer", M_Menu_ModelViewer_f, M_Menu_ModelViewer_c, "View a model...");
#endif
#ifdef CL_MASTER
Cmd_AddCommand ("menu_slist", M_Menu_ServerList2_f);
@ -1298,6 +1295,7 @@ void M_DeInit_Internal (void)
Cmd_RemoveCommand ("menu_keys");
Cmd_RemoveCommand ("help");
Cmd_RemoveCommand ("menu_quit");
Cmd_RemoveCommand ("menu_mods");
#ifdef CL_MASTER
Cmd_RemoveCommand ("menu_slist");
@ -1325,6 +1323,7 @@ void M_DeInit_Internal (void)
Cmd_RemoveCommand ("menu_lighting");
Cmd_RemoveCommand ("menu_textures");
Cmd_RemoveCommand ("menu_particles");
Cmd_RemoveCommand ("menu_network");
Cmd_RemoveCommand ("menu_main"); //I've moved main to last because that way tab gives us main and not quit.
@ -1377,6 +1376,9 @@ void M_Init (void)
//downloads menu needs sandboxing, so cannot be provided by qc.
#ifdef PACKAGEMANAGER
Cmd_AddCommand ("menu_download", Menu_DownloadStuff_f);
#endif
#ifndef MINIMAL
Cmd_AddCommandAD ("modelviewer", M_Menu_ModelViewer_f, M_Menu_ModelViewer_c, "View a model...");
#endif
//demo menu is allowed to see outside of the quakedir. you can't replicate that in qc's sandbox.
Cmd_AddCommand ("menu_demo", M_Menu_Demos_f);

View File

@ -170,6 +170,7 @@ enum mlverbosity_e
MLV_ERROR
};
extern struct model_s *mod_known; //for evil people that want to do evil indexing.
const char *Mod_GetEntitiesString(struct model_s *mod);
void Mod_SetEntitiesStringLen(struct model_s *mod, const char *str, size_t strsize);
void Mod_SetEntitiesString(struct model_s *mod, const char *str, qboolean docopy);

View File

@ -2648,6 +2648,7 @@ void Surf_SetupFrame(void)
R_UpdateHDR(r_refdef.vieworg);
}
r_viewarea = 0;
viewcontents = 0;
if (r_refdef.flags & RDF_NOWORLDMODEL)
{
@ -2661,6 +2662,7 @@ void Surf_SetupFrame(void)
else if (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3)
{
leaf = Mod_PointInLeaf (cl.worldmodel, pvsorg);
r_viewarea = leaf->area;
viewcontents = cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, pvsorg);
r_viewcluster = r_viewcluster2 = leaf->cluster;
@ -3210,6 +3212,7 @@ void Surf_DrawWorld (void)
{
//surfvis vs entvis - the key difference is that surfvis is surfaces while entvis is volume. though surfvis should be frustum culled also for lighting. entvis doesn't care.
qbyte *surfvis, *entvis;
int areas[2];
RSpeedLocals();
if (r_refdef.flags & RDF_NOWORLDMODEL)
@ -3351,9 +3354,11 @@ void Surf_DrawWorld (void)
RSpeedEnd(RSPEED_WORLDNODE);
CL_LinkStaticEntities(entvis);
areas[0] = 1;
areas[1] = r_viewarea;
CL_LinkStaticEntities(entvis, areas);
TRACE(("dbg: calling R_DrawParticles\n"));
if (!r_refdef.recurse)
if (!r_refdef.recurse && !(r_refdef.flags & RDF_DISABLEPARTICLES))
P_DrawParticles ();
TRACE(("dbg: calling BE_DrawWorld\n"));
@ -3471,11 +3476,14 @@ void Surf_DrawWorld (void)
RSpeedEnd(RSPEED_WORLDNODE);
areas[0] = 1;
areas[1] = r_viewarea;
r_refdef.sceneareas = areas;
if (!(r_refdef.flags & RDF_NOWORLDMODEL))
{
CL_LinkStaticEntities(entvis);
CL_LinkStaticEntities(entvis, r_refdef.sceneareas);
TRACE(("dbg: calling R_DrawParticles\n"));
if (!r_refdef.recurse)
if (!r_refdef.recurse && !(r_refdef.flags & RDF_DISABLEPARTICLES))
P_DrawParticles ();
}

View File

@ -283,6 +283,7 @@ typedef struct
float m_projection_view[16]; //projection matrix for the viewmodel. because people are weird.
float m_view[16];
qbyte *scenevis; /*this is the vis that's currently being draw*/
int *sceneareas; /*this is the area info for the camera (should normally be count+one area, but could be two areas near an opaque water plane)*/
mplane_t frustum[MAXFRUSTUMPLANES];
int frustum_numworldplanes; //all but far, which isn't culled because this wouldn't cover the entire screen.
@ -324,7 +325,7 @@ extern struct texture_s *r_notexture_mip;
extern entity_t r_worldentity;
void BE_GenModelBatches(struct batch_s **batches, const struct dlight_s *dl, unsigned int bemode, qbyte *worldpvs); //if dl, filters based upon the dlight.
void BE_GenModelBatches(struct batch_s **batches, const struct dlight_s *dl, unsigned int bemode, const qbyte *worldpvs, const int *worldareas); //if dl, filters based upon the dlight.
//gl_alias.c
void R_GAliasFlushSkinCache(qboolean final);

View File

@ -49,7 +49,9 @@ static qboolean sys_wantshutdown;
static JavaVM* sys_javavm;
static jobject *sys_activity;
static jobject *sys_cursurface; //surface we're currently trying to draw to
static jobject *sys_cursholder; //silly android junk
static jobject *sys_newsurface; //surface we're meant to be switching our gl context to
static jobject *sys_newsholder; //silly android junk
static void *sys_mainthread;
static void *sys_mainconditional;
@ -663,10 +665,13 @@ static int FTEDroid_MainThread(void *arg)
if (r_forcevidrestart)
{
ANativeWindow *oldwnd = NULL;
jobject oldholder = NULL;
jobject oldsurf = NULL;
JNIEnv *env = NULL;
if (JNI_OK == (*sys_javavm)->AttachCurrentThread(sys_javavm, &env, NULL))
{
oldholder = sys_cursholder;
sys_cursholder = (*env)->NewGlobalRef(env, sys_newsholder);
oldsurf = sys_cursurface;
sys_cursurface = (*env)->NewGlobalRef(env, sys_newsurface);
@ -687,10 +692,12 @@ static int FTEDroid_MainThread(void *arg)
LOGI("Video Restarted...\n");
//main thread can wake up now.
if (oldsurf)
(*env)->DeleteGlobalRef(env, oldsurf);
if (oldwnd)
ANativeWindow_release(oldwnd);
if (oldsurf)
(*env)->DeleteGlobalRef(env, oldsurf);
if (oldholder)
(*env)->DeleteGlobalRef(env, oldholder);
if (env)
(*sys_javavm)->DetachCurrentThread(sys_javavm);
@ -752,6 +759,25 @@ static int FTEDroid_MainThread(void *arg)
if (sleeptime)
Sys_Sleep(sleeptime);
}
//don't permanently hold these when there's no active activity.
//(hopefully there's no gl context active right now...)
JNIEnv *env = NULL;
if (JNI_OK == (*sys_javavm)->AttachCurrentThread(sys_javavm, &env, NULL))
{
if (sys_nativewindow)
ANativeWindow_release(sys_nativewindow);
sys_nativewindow = NULL;
if (sys_cursurface)
(*env)->DeleteGlobalRef(env, sys_cursurface);
sys_cursurface = NULL;
if (sys_cursholder)
(*env)->DeleteGlobalRef(env, sys_cursholder);
sys_cursholder = NULL;
if (env)
(*sys_javavm)->DetachCurrentThread(sys_javavm);
}
return 0;
}
@ -1171,7 +1197,7 @@ static jboolean FTENativeActivity_startup(JNIEnv *jni, jobject this, jstring ext
return false;
}
static void FTENativeActivity_surfacechange(JNIEnv *env, jobject this, jboolean teardown, jboolean recreate, jobject surface)
static void FTENativeActivity_surfacechange(JNIEnv *env, jobject this, jboolean teardown, jboolean recreate, jobject holder, jobject surface)
{
if (!(*env)->IsSameObject(env, this, sys_activity))
{
@ -1193,6 +1219,9 @@ static void FTENativeActivity_surfacechange(JNIEnv *env, jobject this, jboolean
if (sys_newsurface)
(*env)->DeleteGlobalRef(env, sys_newsurface);
sys_newsurface = surface?(*env)->NewGlobalRef(env, surface):NULL;
if (sys_newsholder)
(*env)->DeleteGlobalRef(env, sys_newsholder);
sys_newsholder = holder?(*env)->NewGlobalRef(env, holder):NULL;
//and wake up then
Sys_ConditionWait(sys_mainconditional);
//and we're done...
@ -1217,6 +1246,9 @@ static void FTENativeActivity_shutdown(JNIEnv *env, jobject this)
(*env)->DeleteGlobalRef(env, sys_newsurface);
sys_newsurface = NULL;
(*env)->DeleteGlobalRef(env, sys_newsholder);
sys_newsholder = NULL;
(*env)->DeleteGlobalRef(env, sys_activity);
sys_activity = NULL;
@ -1237,7 +1269,7 @@ static void FTENativeActivity_openfile(JNIEnv *env, jobject this, jstring filena
static JNINativeMethod methods[] = {
//
{"startup", "(Ljava/lang/String;Ljava/lang/String;)Z", FTENativeActivity_startup}, //creates our 'main' thread too
{"surfacechange", "(ZZLandroid/view/Surface;)V", FTENativeActivity_surfacechange}, //syncs
{"surfacechange", "(ZZLandroid/view/SurfaceHolder;Landroid/view/Surface;)V", FTENativeActivity_surfacechange}, //syncs
{"shutdown", "()V", FTENativeActivity_shutdown}, //joins 'main' thread.
{"openfile", "(Ljava/lang/String;)V", FTENativeActivity_openfile},

View File

@ -103,6 +103,8 @@ cvar_t crosshaircorrect = CVARFD("crosshaircorrect", "0", CVAR_SEMICHEAT, "Move
cvar_t crosshairimage = CVARD("crosshairimage", "", "Enables the use of an external/custom crosshair image");
cvar_t crosshairalpha = CVAR("crosshairalpha", "1");
cvar_t v_skyroom_origin = CVARD("r_skyroom_origin", "", "Specifies the center position of the skyroom's view. Skyrooms are drawn instead of skyboxes (typically with their own skybox around them). Entities in skyrooms will be drawn only when r_ignoreentpvs is 0. Can also be set with the _skyroom worldspawn key. This is overriden by csqc's VF_SKYROOM_CAMERA.");
static cvar_t gl_cshiftpercent = CVAR("gl_cshiftpercent", "100");
cvar_t gl_cshiftenabled = CVARFD("gl_polyblend", "1", CVAR_ARCHIVE, "Controls whether temporary whole-screen colour changes should be honoured or not. Change gl_cshiftpercent if you want to adjust the intensity.\nThis does not affect v_cshift commands sent from the server.");
cvar_t gl_cshiftborder = CVARD("gl_polyblend_edgesize", "128", "This constrains colour shifts to the edge of the screen, with the value specifying the size of those borders.");
@ -1615,6 +1617,13 @@ void V_CalcRefdef (playerview_t *pv)
VectorMA(r_refdef.vieworg, v_gunkick.value, pv->punchorigin, r_refdef.vieworg);
}
if (*v_skyroom_origin.string)
{
r_refdef.skyroom_enabled = true;
r_refdef.skyroom_pos[0] = v_skyroom_origin.vec4[0];
r_refdef.skyroom_pos[1] = v_skyroom_origin.vec4[1];
r_refdef.skyroom_pos[2] = v_skyroom_origin.vec4[2];
}
if (chase_active.ival && cls.allow_cheats) //cheat restriction might be lifted some time when any wallhacks are solved.
{
@ -2572,6 +2581,7 @@ void V_Init (void)
Cvar_Register (&v_kickpitch, VIEWVARS);
Cvar_Register (&v_deathtilt, VIEWVARS);
Cvar_Register (&v_skyroom_origin, VIEWVARS);
Cvar_Register (&scr_autoid, VIEWVARS);
Cvar_Register (&scr_autoid_team, VIEWVARS);

View File

@ -885,6 +885,11 @@ void Mod_ParseInfoFromEntityLump(model_t *wmodel) //actually, this should be in
Cvar_LockFromServer(&r_telealpha, token);
Cvar_LockFromServer(&r_telestyle, "1");
}
else if (!strcmp("skyroom", key)) // for Quake mappers that lack the proper tools
{
extern cvar_t v_skyroom_origin;
Cvar_LockFromServer(&v_skyroom_origin, token);
}
else if (!strcmp("skyname", key)) // for HalfLife maps
{
Q_strncpyz(skyname, token, sizeof(skyname));

View File

@ -801,6 +801,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MAX_QPATH 128 // max length of a quake game pathname
#define MAX_OSPATH 1024 // max length of a filesystem pathname (260 on windows, but needs to be longer for utf8)
#define OLD_MAX_QPATH 64 // it was baked into various file formats, which is unfortunate.
#define ON_EPSILON 0.1 // point on plane side epsilon

View File

@ -788,7 +788,7 @@ typedef struct
typedef struct
{
char shadername[64];
char shadername[OLD_MAX_QPATH];
int surfflags;
int contents;
} dq3shader_t;
@ -828,7 +828,7 @@ typedef struct
struct Q3FOG
{
char shadername[64] ;
char shadername[OLD_MAX_QPATH] ;
int brushnum;
int visibleside;
};

View File

@ -2930,7 +2930,6 @@ void Cmd_ExecuteString (const char *text, int level)
//a number of things check for seats if nothing else, and security says is safer to do this than to be in doubt.
int olev = Cmd_ExecLevel;
Cmd_ExecuteStringGlobalsAreEvil(text, level);
Cmd_ExecLevel = level;
Cmd_ExecLevel = olev;
}

View File

@ -1010,7 +1010,7 @@ typedef struct
float frac[FRAME_BLENDS*2]; //weight of this animation (1 if lerpcount is 1)
float *pose[FRAME_BLENDS*2]; //pointer to the raw frame data for bone 0.
} skellerps_t;
static qboolean Alias_BuildSkelLerps(skellerps_t *lerps, struct framestateregion_s *fs, int numbones, galiasinfo_t *inf)
static qboolean Alias_BuildSkelLerps(skellerps_t *lerps, const struct framestateregion_s *fs, int numbones, const galiasinfo_t *inf)
{
int frame1; //signed, because frametime might be negative...
int frame2;
@ -1129,7 +1129,7 @@ static qboolean Alias_BuildSkelLerps(skellerps_t *lerps, struct framestateregion
/*
finds the various blend info. returns number of bone blocks used.
*/
static int Alias_FindRawSkelData(galiasinfo_t *inf, framestate_t *fstate, skellerps_t *lerps, size_t firstbone, size_t lastbone)
static int Alias_FindRawSkelData(galiasinfo_t *inf, const framestate_t *fstate, skellerps_t *lerps, size_t firstbone, size_t lastbone)
{
int bonegroup;
int cbone = 0;
@ -1220,7 +1220,7 @@ static int Alias_BlendBoneData(galiasinfo_t *inf, framestate_t *fstate, float *r
only writes targetbuffer if needed. the return value is the only real buffer result.
assumes that all blended types are the same. probably buggy, but meh.
*/
static const float *Alias_GetBoneInformation(galiasinfo_t *inf, framestate_t *framestate, skeltype_t targettype, float *targetbuffer, float *targetbufferalt, size_t maxbufferbones)
static const float *Alias_GetBoneInformation(galiasinfo_t *inf, const framestate_t *framestate, skeltype_t targettype, float *targetbuffer, float *targetbufferalt, size_t maxbufferbones)
{
skellerps_t lerps[FS_COUNT], *lerp;
size_t numgroups;
@ -2215,7 +2215,7 @@ void Mod_AddSingleSurface(entity_t *ent, int surfaceidx, shader_t *shader, qbool
#endif
static float PlaneNearest(vec3_t normal, vec3_t mins, vec3_t maxs)
static float PlaneNearest(const vec3_t normal, const vec3_t mins, const vec3_t maxs)
{
float result;
#if 0
@ -2235,7 +2235,7 @@ static float PlaneNearest(vec3_t normal, vec3_t mins, vec3_t maxs)
}
void CLQ1_DrawLine(shader_t *shader, vec3_t v1, vec3_t v2, float r, float g, float b, float a);
static qboolean Mod_Trace_Trisoup(vecV_t *posedata, index_t *indexes, int numindexes, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
static qboolean Mod_Trace_Trisoup(vecV_t *posedata, index_t *indexes, int numindexes, const vec3_t start, const vec3_t end, const vec3_t mins, const vec3_t maxs, trace_t *fte_restrict trace)
{
qboolean impacted = false;
int i, j;
@ -2412,7 +2412,7 @@ static qboolean Mod_Trace_Trisoup(vecV_t *posedata, index_t *indexes, int numind
}
//The whole reason why model loading is supported in the server.
static qboolean Mod_Trace(model_t *model, int forcehullnum, framestate_t *framestate, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contentsmask, trace_t *trace)
static qboolean Mod_Trace(model_t *model, int forcehullnum, const framestate_t *framestate, const vec3_t axis[3], const vec3_t start, const vec3_t end, const vec3_t mins, const vec3_t maxs, qboolean capsule, unsigned int contentsmask, trace_t *trace)
{
galiasinfo_t *mod = Mod_Extradata(model);
@ -8166,7 +8166,7 @@ static galiasinfo_t *Mod_ParseMD5MeshModel(model_t *mod, char *buffer, char *mod
else if (!strcmp(token, "numJoints"))
{
if (numjoints)
MD5ERROR0PARAM("MD5MESH: numMeshes was already declared");
MD5ERROR0PARAM("MD5MESH: numJoints was already declared");
buffer = COM_ParseOut(buffer, token, sizeof(token));
numjoints = atoi(token);
if (numjoints <= 0)

View File

@ -224,7 +224,7 @@ typedef struct modplugfuncs_s
void (QDECL *ConcatTransforms) (const float in1[3][4], const float in2[3][4], float out[3][4]);
void (QDECL *M3x4_Invert) (const float *in1, float *out);
void (QDECL *VectorAngles)(float *forward, float *up, float *result, qboolean meshpitch);
void (QDECL *VectorAngles)(const float *forward, const float *up, float *result, qboolean meshpitch);
void (QDECL *AngleVectors)(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
void (QDECL *GenMatrixPosQuat4Scale)(const vec3_t pos, const vec4_t quat, const vec3_t scale, float result[12]);

View File

@ -57,16 +57,16 @@ void Mod_LoadEntities (model_t *loadmodel, qbyte *mod_base, lump_t *l);
extern void BuildLightMapGammaTable (float g, float c);
#if defined(Q2BSPS) || defined(Q3BSPS)
static qboolean CM_NativeTrace(model_t *model, int forcehullnum, framestate_t *framestate, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contents, trace_t *trace);
static unsigned int CM_NativeContents(struct model_s *model, int hulloverride, framestate_t *framestate, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs);
static unsigned int Q2BSP_PointContents(model_t *mod, vec3_t axis[3], vec3_t p);
static int CM_PointCluster (model_t *mod, vec3_t p);
static qboolean CM_NativeTrace(model_t *model, int forcehullnum, const framestate_t *framestate, const vec3_t axis[3], const vec3_t start, const vec3_t end, const vec3_t mins, const vec3_t maxs, qboolean capsule, unsigned int contents, trace_t *trace);
static unsigned int CM_NativeContents(struct model_s *model, int hulloverride, const framestate_t *framestate, const vec3_t axis[3], const vec3_t p, const vec3_t mins, const vec3_t maxs);
static unsigned int Q2BSP_PointContents(model_t *mod, const vec3_t axis[3], const vec3_t p);
static int CM_PointCluster (model_t *mod, const vec3_t p, int *area);
struct cminfo_s;
static struct bihnode_s *CM_BuildBIH (model_t *mod, struct cminfo_s *prv);
static unsigned int CM_PointContentsBIH (const struct bihnode_s *fte_restrict node, const vec3_t p);
#endif
float RadiusFromBounds (vec3_t mins, vec3_t maxs)
float RadiusFromBounds (const vec3_t mins, const vec3_t maxs)
{
int i;
vec3_t corner;
@ -4236,8 +4236,6 @@ static void GLR_Q2BSP_StainNode (mnode_t *node, float *parms)
#endif
void GLQ2BSP_LightPointValues(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
/*
==================
CM_LoadMap
@ -4870,8 +4868,8 @@ mplane_t box_planes[6];
model_t box_model;
q2cbrush_t box_brush;
q2cbrushside_t box_sides[6];
static qboolean BM_NativeTrace(model_t *model, int forcehullnum, framestate_t *framestate, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contents, trace_t *trace);
static unsigned int BM_NativeContents(struct model_s *model, int hulloverride, framestate_t *framestate, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs)
static qboolean BM_NativeTrace(model_t *model, int forcehullnum, const framestate_t *framestate, const vec3_t axis[3], const vec3_t start, const vec3_t end, const vec3_t mins, const vec3_t maxs, qboolean capsule, unsigned int contents, trace_t *trace);
static unsigned int BM_NativeContents(struct model_s *model, int hulloverride, const framestate_t *framestate, const vec3_t axis[3], const vec3_t p, const vec3_t mins, const vec3_t maxs)
{
unsigned int j;
q2cbrushside_t *brushside = box_sides;
@ -4947,7 +4945,7 @@ To keep everything totally uniform, bounding boxes are turned into small
BSP trees instead of being compared directly.
===================
*/
static void CM_SetTempboxSize (vec3_t mins, vec3_t maxs)
static void CM_SetTempboxSize (const vec3_t mins, const vec3_t maxs)
{
box_planes[0].dist = maxs[0];
box_planes[1].dist = maxs[1];
@ -4957,7 +4955,7 @@ static void CM_SetTempboxSize (vec3_t mins, vec3_t maxs)
box_planes[5].dist = -mins[2];
}
model_t *CM_TempBoxModel(vec3_t mins, vec3_t maxs)
model_t *CM_TempBoxModel(const vec3_t mins, const vec3_t maxs)
{
CM_SetTempboxSize(mins, maxs);
return &box_model;
@ -4969,7 +4967,7 @@ CM_PointLeafnum_r
==================
*/
static int CM_PointLeafnum_r (model_t *mod, vec3_t p, int num)
static int CM_PointLeafnum_r (model_t *mod, const vec3_t p, int num)
{
float d;
mnode_t *node;
@ -4993,18 +4991,23 @@ static int CM_PointLeafnum_r (model_t *mod, vec3_t p, int num)
return -1 - num;
}
int CM_PointLeafnum (model_t *mod, vec3_t p)
int CM_PointLeafnum (model_t *mod, const vec3_t p)
{
if (!mod || mod->loadstate != MLS_LOADED)
return 0; // sound may call this without map loaded
return CM_PointLeafnum_r (mod, p, 0);
}
static int CM_PointCluster (model_t *mod, vec3_t p)
static int CM_PointCluster (model_t *mod, const vec3_t p, int *area)
{
int leaf;
if (!mod || mod->loadstate != MLS_LOADED)
return 0; // sound may call this without map loaded
return CM_LeafCluster(mod, CM_PointLeafnum_r (mod, p, 0));
leaf = CM_PointLeafnum_r (mod, p, 0);
if (area)
*area = CM_LeafArea(mod, leaf);
return CM_LeafCluster(mod, leaf);
}
/*
@ -5016,7 +5019,7 @@ Fills in a list of all the leafs touched
*/
int leaf_count, leaf_maxcount;
int *leaf_list;
float *leaf_mins, *leaf_maxs;
const float *leaf_mins, *leaf_maxs;
int leaf_topnode;
static void CM_BoxLeafnums_r (model_t *mod, int nodenum)
@ -5057,7 +5060,7 @@ static void CM_BoxLeafnums_r (model_t *mod, int nodenum)
}
}
static int CM_BoxLeafnums_headnode (model_t *mod, vec3_t mins, vec3_t maxs, int *list, int listsize, int headnode, int *topnode)
static int CM_BoxLeafnums_headnode (model_t *mod, const vec3_t mins, const vec3_t maxs, int *list, int listsize, int headnode, int *topnode)
{
leaf_list = list;
leaf_count = 0;
@ -5075,7 +5078,7 @@ static int CM_BoxLeafnums_headnode (model_t *mod, vec3_t mins, vec3_t maxs, int
return leaf_count;
}
int CM_BoxLeafnums (model_t *mod, vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode)
int CM_BoxLeafnums (model_t *mod, const vec3_t mins, const vec3_t maxs, int *list, int listsize, int *topnode)
{
return CM_BoxLeafnums_headnode (mod, mins, maxs, list,
listsize, mod->hulls[0].firstclipnode, topnode);
@ -5089,7 +5092,7 @@ CM_PointContents
==================
*/
int CM_PointContents (model_t *mod, vec3_t p)
int CM_PointContents (model_t *mod, const vec3_t p)
{
cminfo_t *prv = (cminfo_t*)mod->meshinfo;
int i, j, contents;
@ -5146,7 +5149,7 @@ int CM_PointContents (model_t *mod, vec3_t p)
return contents;
}
unsigned int CM_NativeContents(struct model_s *model, int hulloverride, framestate_t *framestate, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs)
unsigned int CM_NativeContents(struct model_s *model, int hulloverride, const framestate_t *framestate, const vec3_t axis[3], const vec3_t p, const vec3_t mins, const vec3_t maxs)
{
cminfo_t *prv = (cminfo_t*)model->meshinfo;
int contents;
@ -5210,7 +5213,7 @@ Handles offseting and rotation of the end points for moving and
rotating entities
==================
*/
int CM_TransformedPointContents (model_t *mod, vec3_t p, int headnode, vec3_t origin, vec3_t angles)
int CM_TransformedPointContents (model_t *mod, const vec3_t p, int headnode, const vec3_t origin, const vec3_t angles)
{
vec3_t p_l;
vec3_t temp;
@ -6699,8 +6702,8 @@ static struct bihnode_s *CM_BuildBIH (model_t *mod, cminfo_t *prv)
CM_BoxTrace
==================
*/
static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
vec3_t mins, vec3_t maxs, qboolean capsule,
static trace_t CM_BoxTrace (model_t *mod, const vec3_t start, const vec3_t end,
const vec3_t mins, const vec3_t maxs, qboolean capsule,
int brushmask)
{
int i;
@ -6897,7 +6900,7 @@ static trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
return trace_trace;
}
static qboolean BM_NativeTrace(model_t *model, int forcehullnum, framestate_t *framestate, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contents, trace_t *trace)
static qboolean BM_NativeTrace(model_t *model, int forcehullnum, const framestate_t *framestate, const vec3_t axis[3], const vec3_t start, const vec3_t end, const vec3_t mins, const vec3_t maxs, qboolean capsule, unsigned int contents, trace_t *trace)
{
int i;
memset (trace, 0, sizeof(*trace));
@ -6941,7 +6944,7 @@ static qboolean BM_NativeTrace(model_t *model, int forcehullnum, framestate_t *f
}
return trace->fraction != 1;
}
static qboolean CM_NativeTrace(model_t *model, int forcehullnum, framestate_t *framestate, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contents, trace_t *trace)
static qboolean CM_NativeTrace(model_t *model, int forcehullnum, const framestate_t *framestate, const vec3_t axis[3], const vec3_t start, const vec3_t end, const vec3_t mins, const vec3_t maxs, qboolean capsule, unsigned int contents, trace_t *trace)
{
if (axis)
{
@ -7200,7 +7203,7 @@ qbyte *CM_ClusterPHS (model_t *mod, int cluster, pvsbuffer_t *buffer)
return buffer->buffer;
}
static unsigned int SV_Q2BSP_FatPVS (model_t *mod, vec3_t org, pvsbuffer_t *result, qboolean merge)
static unsigned int SV_Q2BSP_FatPVS (model_t *mod, const vec3_t org, pvsbuffer_t *result, qboolean merge)
{
int leafs[64];
int i, j, count;
@ -7249,7 +7252,7 @@ static unsigned int SV_Q2BSP_FatPVS (model_t *mod, vec3_t org, pvsbuffer_t *res
}
static int clientarea;
unsigned int Q23BSP_FatPVS(model_t *mod, vec3_t org, pvsbuffer_t *buffer, qboolean merge)
unsigned int Q23BSP_FatPVS(model_t *mod, const vec3_t org, pvsbuffer_t *fte_restrict buffer, qboolean merge)
{//fixme: this doesn't add areas
int leafnum;
leafnum = CM_PointLeafnum (mod, org);
@ -7258,21 +7261,29 @@ unsigned int Q23BSP_FatPVS(model_t *mod, vec3_t org, pvsbuffer_t *buffer, qboole
return SV_Q2BSP_FatPVS (mod, org, buffer, merge);
}
qboolean Q23BSP_EdictInFatPVS(model_t *mod, pvscache_t *ent, qbyte *pvs)
qboolean Q23BSP_EdictInFatPVS(model_t *mod, const pvscache_t *ent, const qbyte *pvs, const int *areas)
{
int i,l;
int nullarea = (mod->fromgame == fg_quake2)?0:-1;
if (clientarea == ent->areanum)
if (areas)
{
if (clientarea == nullarea)
return false;
}
else if (!CM_AreasConnected (mod, clientarea, ent->areanum))
{ // doors can legally straddle two areas, so
// we may need to check another one
if (ent->areanum2 == nullarea
|| !CM_AreasConnected (mod, clientarea, ent->areanum2))
return false; // blocked by a door
for (i = 1; ; i++)
{
if (i > areas[0])
return false; //none of the camera's areas could see the entity
if (areas[i] == ent->areanum)
{
if (areas[i] != nullarea)
break;
//else entity is fully outside the world, invisible to all...
}
else if (CM_AreasConnected (mod, areas[i], ent->areanum))
break;
// doors can legally straddle two areas, so
// we may need to check another one
else if (ent->areanum2 != nullarea && CM_AreasConnected (mod, areas[i], ent->areanum2))
break;
}
}
if (ent->num_leafs == -1)
@ -7564,7 +7575,7 @@ Returns true if any leaf under headnode has a cluster that
is potentially visible
=============
*/
qboolean CM_HeadnodeVisible (model_t *mod, int nodenum, qbyte *visbits)
qboolean CM_HeadnodeVisible (model_t *mod, int nodenum, const qbyte *visbits)
{
int leafnum;
int cluster;
@ -7587,7 +7598,7 @@ qboolean CM_HeadnodeVisible (model_t *mod, int nodenum, qbyte *visbits)
return CM_HeadnodeVisible(mod, node->childnum[1], visbits);
}
unsigned int Q2BSP_PointContents(model_t *mod, vec3_t axis[3], vec3_t p)
unsigned int Q2BSP_PointContents(model_t *mod, const vec3_t axis[3], const vec3_t p)
{
int pc;
pc = CM_PointContents (mod, p);

View File

@ -167,7 +167,7 @@ BoxOnPlaneSide
Returns 1, 2, or 1 + 2
==================
*/
int VARGS BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, mplane_t *p)
int VARGS BoxOnPlaneSide (const vec3_t emins, const vec3_t emaxs, const mplane_t *p)
{
float dist1, dist2;
int sides;
@ -291,7 +291,7 @@ void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up)
CrossProduct(right, forward, up);
}
void QDECL VectorAngles(float *forward, float *up, float *result, qboolean meshpitch) //up may be NULL
void QDECL VectorAngles(const float *forward, const float *up, float *result, qboolean meshpitch) //up may be NULL
{
float yaw, pitch, roll;
@ -583,7 +583,7 @@ void QDECL R_ConcatTransforms (const float in1[3][4], const float in2[3][4], flo
}
//R_ConcatTransforms where there's no offset values, and a transposed axis
void R_ConcatTransformsAxis (float in1[3][3], float in2[3][4], float out[3][4])
void R_ConcatTransformsAxis (const float in1[3][3], const float in2[3][4], float out[3][4])
{
out[0][0] = in1[0][0] * in2[0][0] + in1[1][0] * in2[1][0] +
in1[2][0] * in2[2][0];
@ -1910,7 +1910,7 @@ vec_t QDECL VectorNormalize2 (const vec3_t v, vec3_t out)
return length;
}
float ColorNormalize (vec3_t in, vec3_t out)
float ColorNormalize (const vec3_t in, vec3_t out)
{
float f = max (max (in[0], in[1]), in[2]);
@ -1928,7 +1928,7 @@ float ColorNormalize (vec3_t in, vec3_t out)
return f;
}
void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up)
void MakeNormalVectors (const vec3_t forward, vec3_t right, vec3_t up)
{
float d;

View File

@ -129,17 +129,17 @@ typedef struct {
void AddPointToBounds (const vec3_t v, vec3_t mins, vec3_t maxs);
float anglemod (float a);
void QDECL AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
void QDECL VectorAngles (float *forward, float *up, float *angles, qboolean meshpitch); //up may be NULL
void QDECL VectorAngles (const float *forward, const float *up, float *angles, qboolean meshpitch); //up may be NULL
void VARGS BOPS_Error (void);
int VARGS BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane);
int VARGS BoxOnPlaneSide (const vec3_t emins, const vec3_t emaxs, const struct mplane_s *plane);
void ClearBounds (vec3_t mins, vec3_t maxs);
float ColorNormalize (vec3_t in, vec3_t out);
float ColorNormalize (const vec3_t in, vec3_t out);
void CrossProduct (const vec3_t v1, const vec3_t v2, vec3_t cross);
void FloorDivMod (double numer, double denom, int *quotient, int *rem);
int GreatestCommonDivisor (int i1, int i2);
fixed16_t Invert24To16 (fixed16_t val);
vec_t Length (const vec3_t v);
void MakeNormalVectors (vec3_t forward, vec3_t right, vec3_t up);
void MakeNormalVectors (const vec3_t forward, vec3_t right, vec3_t up);
float Q_rsqrt(float number);
/*
@ -205,7 +205,8 @@ int Q_log2 (int val);
void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]);
void R_ConcatRotationsPad (float in1[3][4], float in2[3][4], float out[3][4]);
void QDECL R_ConcatTransforms (const matrix3x4 in1, const matrix3x4 in2, matrix3x4 out);
void R_ConcatTransformsAxis (float in1[3][3], float in2[3][4], float out[3][4]);
void R_ConcatTransformsAxis (const float in1[3][3], const float in2[3][4], float out[3][4]);
void PerpendicularVector(vec3_t dst, const vec3_t src);
void RotatePointAroundVector (vec3_t dst, const vec3_t dir, const vec3_t point, float degrees);
void RotateLightVector(const vec3_t *axis, const vec3_t origin, const vec3_t lightpoint, vec3_t result);
int VectorCompare (const vec3_t v1, const vec3_t v2);

View File

@ -1291,7 +1291,7 @@ static void PM_NudgePosition (void)
VectorCopy (pmove.safeorigin, pmove.origin);
else
VectorCopy (base, pmove.origin);
// Com_DPrintf ("NudgePosition: stuck\n");
// Con_DPrintf ("NudgePosition: stuck\n");
}
/*

View File

@ -5,6 +5,9 @@
#if !defined(CLIENTONLY) || defined(CSQC_DAT) || defined(MENU_DAT)
#include "pr_common.h"
#ifdef SQL
#include "sv_sql.h"
#endif
#include <ctype.h>
@ -1122,26 +1125,28 @@ void QCBUILTIN PF_getsurfacepointattribute(pubprogfuncs_t *prinst, struct global
}
}
pvsbuffer_t qcpvs;
//#240 float(vector viewpos, entity viewee) checkpvs (FTE_QC_CHECKPVS)
//note: this requires a correctly setorigined entity.
void QCBUILTIN PF_checkpvs(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
world_t *world = prinst->parms->user;
model_t *worldmodel = world->worldmodel;
float *viewpos = G_VECTOR(OFS_PARM0);
wedict_t *ent = G_WEDICT(prinst, OFS_PARM1);
int cluster;
int qcpvsarea[2];
qbyte *pvs;
if (!world->worldmodel || world->worldmodel->loadstate != MLS_LOADED)
if (!worldmodel || worldmodel->loadstate != MLS_LOADED)
G_FLOAT(OFS_RETURN) = false;
else if (!world->worldmodel->funcs.FatPVS)
else if (!worldmodel->funcs.FatPVS)
G_FLOAT(OFS_RETURN) = true;
else
{
//FIXME: Make all alternatives of FatPVS not recalulate the pvs.
//and yeah, this is overkill what with the whole fat thing and all.
world->worldmodel->funcs.FatPVS(world->worldmodel, viewpos, &qcpvs, false);
G_FLOAT(OFS_RETURN) = world->worldmodel->funcs.EdictInFatPVS(world->worldmodel, &ent->pvsinfo, qcpvs.buffer);
qcpvsarea[0] = 1;
cluster = worldmodel->funcs.ClusterForPoint(worldmodel, viewpos, &qcpvsarea[1]);
pvs = worldmodel->funcs.ClusterPVS(worldmodel, cluster, NULL, PVM_FAST);
G_FLOAT(OFS_RETURN) = worldmodel->funcs.EdictInFatPVS(worldmodel, &ent->pvsinfo, pvs, qcpvsarea);
}
}
@ -6423,6 +6428,9 @@ void PR_Common_Shutdown(pubprogfuncs_t *progs, qboolean errored)
#endif
#ifdef TEXTEDITOR
Editor_ProgsKilled(progs);
#endif
#ifdef SQL
SQL_KillServers(progs);
#endif
tokenize_flush();
}

View File

@ -637,7 +637,7 @@ typedef struct
void (QDECL *ReleaseCollisionMesh) (wedict_t *ed);
void (QDECL *LinkEdict)(world_t *w, wedict_t *ed, qboolean touchtriggers);
void (QDECL *VectorAngles)(float *forward, float *up, float *result, qboolean meshpitch);
void (QDECL *VectorAngles)(const float *forward, const float *up, float *result, qboolean meshpitch);
void (QDECL *AngleVectors)(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
} rbeplugfuncs_t;
#define RBEPLUGFUNCS_VERSION 1

View File

@ -1360,6 +1360,7 @@ typedef struct q1usercmd_s
#define RDF_ANTIALIAS (1u<<20) //fxaa, or possibly even just fsaa
#define RDF_RENDERSCALE (1u<<21)
#define RDF_SCENEGAMMA (1u<<22)
#define RDF_DISABLEPARTICLES (1u<<23) //mostly for skyrooms
#define RDF_ALLPOSTPROC (RDF_BLOOM|RDF_FISHEYE|RDF_WATERWARP|RDF_CUSTOMPOSTPROC|RDF_ANTIALIAS|RDF_SCENEGAMMA) //these flags require rendering to an fbo for the various different post-processing shaders.

View File

@ -671,7 +671,7 @@ void Q1BSP_CheckHullNodes(hull_t *hull)
}
static int Q1_ModelPointContents (mnode_t *node, vec3_t p)
static int Q1_ModelPointContents (mnode_t *node, const vec3_t p)
{
float d;
mplane_t *plane;
@ -694,7 +694,7 @@ SV_HullPointContents
==================
*/
static int Q1_HullPointContents (hull_t *hull, int num, vec3_t p)
static int Q1_HullPointContents (hull_t *hull, int num, const vec3_t p)
{
float d;
mclipnode_t *node;
@ -754,7 +754,7 @@ struct rhtctx_s
mclipnode_t *clipnodes;
mplane_t *planes;
};
static int Q1BSP_RecursiveHullTrace (struct rhtctx_s *ctx, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, trace_t *trace)
static int Q1BSP_RecursiveHullTrace (struct rhtctx_s *ctx, int num, float p1f, float p2f, const vec3_t p1, const vec3_t p2, trace_t *trace)
{
mclipnode_t *node;
mplane_t *plane;
@ -873,7 +873,7 @@ reenter:
return rht_impact;
}
qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, vec3_t p1, vec3_t p2, unsigned int hitcontents, trace_t *trace)
qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, const vec3_t p1, const vec3_t p2, unsigned int hitcontents, trace_t *trace)
{
if (VectorEquals(p1, p2))
{
@ -1222,7 +1222,7 @@ static void Q1BSP_InsertBrush(mnode_t *node, mbrush_t *brush, vec3_t bmins, vec3
}
}
}
static void Q1BSP_RecursiveBrushCheck (struct traceinfo_s *traceinfo, mnode_t *node, float p1f, float p2f, vec3_t p1, vec3_t p2)
static void Q1BSP_RecursiveBrushCheck (struct traceinfo_s *traceinfo, mnode_t *node, float p1f, float p2f, const vec3_t p1, const vec3_t p2)
{
mplane_t *plane;
float t1, t2;
@ -1366,13 +1366,13 @@ static unsigned int Q1BSP_TranslateContents(int contents)
}
}
int Q1BSP_HullPointContents(hull_t *hull, vec3_t p)
int Q1BSP_HullPointContents(hull_t *hull, const vec3_t p)
{
return Q1BSP_TranslateContents(Q1_HullPointContents(hull, hull->firstclipnode, p));
}
#ifdef Q1BSPS
unsigned int Q1BSP_PointContents(model_t *model, vec3_t axis[3], vec3_t point)
unsigned int Q1BSP_PointContents(model_t *model, const vec3_t axis[3], const vec3_t point)
{
int contents;
if (axis)
@ -1513,7 +1513,7 @@ void Q1BSP_LoadBrushes(model_t *model, bspx_header_t *bspx, void *mod_base)
model->engineflags |= MDLF_HASBRUSHES;
}
hull_t *Q1BSP_ChooseHull(model_t *model, int forcehullnum, vec3_t mins, vec3_t maxs, vec3_t offset)
hull_t *Q1BSP_ChooseHull(model_t *model, int forcehullnum, const vec3_t mins, const vec3_t maxs, vec3_t offset)
{
hull_t *hull;
vec3_t size;
@ -1559,7 +1559,7 @@ hull_t *Q1BSP_ChooseHull(model_t *model, int forcehullnum, vec3_t mins, vec3_t m
VectorSubtract (hull->clip_mins, mins, offset);
return hull;
}
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, framestate_t *framestate, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int hitcontentsmask, trace_t *trace)
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, const framestate_t *framestate, const vec3_t axis[3], const vec3_t start, const vec3_t end, const vec3_t mins, const vec3_t maxs, qboolean capsule, unsigned int hitcontentsmask, trace_t *trace)
{
hull_t *hull;
vec3_t start_l, end_l;
@ -1779,7 +1779,7 @@ Server only functions
static qbyte *Q1BSP_ClusterPVS (model_t *model, int cluster, pvsbuffer_t *buffer, pvsmerge_t merge);
//does the recursive work of Q1BSP_FatPVS
static void SV_Q1BSP_AddToFatPVS (model_t *mod, vec3_t org, mnode_t *node, pvsbuffer_t *pvsbuffer)
static void SV_Q1BSP_AddToFatPVS (model_t *mod, const vec3_t org, mnode_t *node, pvsbuffer_t *pvsbuffer)
{
mplane_t *plane;
float d;
@ -1818,7 +1818,7 @@ Calculates a PVS that is the inclusive or of all leafs within 8 pixels of the
given point.
=============
*/
static unsigned int Q1BSP_FatPVS (model_t *mod, vec3_t org, pvsbuffer_t *pvsbuffer, qboolean add)
static unsigned int Q1BSP_FatPVS (model_t *mod, const vec3_t org, pvsbuffer_t *pvsbuffer, qboolean add)
{
if (pvsbuffer->buffersize < mod->pvsbytes)
pvsbuffer->buffer = BZ_Realloc(pvsbuffer->buffer, pvsbuffer->buffersize=mod->pvsbytes);
@ -1829,10 +1829,12 @@ static unsigned int Q1BSP_FatPVS (model_t *mod, vec3_t org, pvsbuffer_t *pvsbuff
}
#endif
static qboolean Q1BSP_EdictInFatPVS(model_t *mod, struct pvscache_s *ent, qbyte *pvs)
static qboolean Q1BSP_EdictInFatPVS(model_t *mod, const struct pvscache_s *ent, const qbyte *pvs, const int *areas)
{
int i;
//if (areas)areas[0] is the area count... but q1bsp has no areas so we ignore it entirely.
if (ent->num_leafs < 0)
return true; //it's in too many leafs for us to cope with. Just trivially accept it.
@ -1850,7 +1852,7 @@ SV_FindTouchedLeafs
Links the edict to the right leafs so we can get it's potential visability.
===============
*/
static void Q1BSP_RFindTouchedLeafs (model_t *wm, struct pvscache_s *ent, mnode_t *node, float *mins, float *maxs)
static void Q1BSP_RFindTouchedLeafs (model_t *wm, struct pvscache_s *ent, mnode_t *node, const float *mins, const float *maxs)
{
mplane_t *splitplane;
mleaf_t *leaf;
@ -1891,7 +1893,7 @@ static void Q1BSP_RFindTouchedLeafs (model_t *wm, struct pvscache_s *ent, mnode_
if (sides & 2)
Q1BSP_RFindTouchedLeafs (wm, ent, node->children[1], mins, maxs);
}
static void Q1BSP_FindTouchedLeafs(model_t *mod, struct pvscache_s *ent, float *mins, float *maxs)
static void Q1BSP_FindTouchedLeafs(model_t *mod, struct pvscache_s *ent, const float *mins, const float *maxs)
{
ent->num_leafs = 0;
if (mins && maxs)
@ -2085,7 +2087,7 @@ mleaf_t *Q1BSP_LeafForPoint (model_t *model, vec3_t p)
return model->leafs + Q1BSP_LeafnumForPoint(model, p);
}
static void Q1BSP_ClustersInSphere_Union(mleaf_t *firstleaf, vec3_t center, float radius, mnode_t *node, qbyte *out, qbyte *unionwith)
static void Q1BSP_ClustersInSphere_Union(mleaf_t *firstleaf, const vec3_t center, float radius, mnode_t *node, qbyte *out, qbyte *unionwith)
{ //this is really for rtlights.
float t1, t2;
mplane_t *plane;
@ -2129,7 +2131,7 @@ static void Q1BSP_ClustersInSphere_Union(mleaf_t *firstleaf, vec3_t center, floa
continue;
}
}
static qbyte *Q1BSP_ClustersInSphere(model_t *mod, vec3_t center, float radius, pvsbuffer_t *pvsbuffer, qbyte *unionwith)
static qbyte *Q1BSP_ClustersInSphere(model_t *mod, const vec3_t center, float radius, pvsbuffer_t *fte_restrict pvsbuffer, const qbyte *unionwith)
{
if (!mod)
Sys_Error ("Mod_PointInLeaf: bad model");
@ -2145,7 +2147,7 @@ static qbyte *Q1BSP_ClustersInSphere(model_t *mod, vec3_t center, float radius,
//returns the leaf number, which is used as a direct bit index into the pvs.
//-1 for invalid
static int Q1BSP_ClusterForPoint (model_t *model, vec3_t p)
static int Q1BSP_ClusterForPoint (model_t *model, const vec3_t p, int *area)
{
mnode_t *node;
float d;
@ -2155,6 +2157,8 @@ static int Q1BSP_ClusterForPoint (model_t *model, vec3_t p)
{
Sys_Error ("Mod_PointInLeaf: bad model");
}
if (area)
*area = 0; //no areas with q1bsp.
if (!model->nodes)
return -1;

View File

@ -1722,4 +1722,26 @@ void MSG_Q3_ReadDeltaUsercmd(int key, const usercmd_t *from, usercmd_t *to)
}
}
qint64_t Q3VM_GetRealtime(q3time_t *qtime)
{ //this is useful mostly for saved games, or other weird stuff.
time_t t = time(NULL);
if (qtime)
{
struct tm *tm = localtime(&t);
if (tm)
{
qtime->tm_sec = tm->tm_sec;
qtime->tm_hour = tm->tm_hour;
qtime->tm_mday = tm->tm_mday;
qtime->tm_mon = tm->tm_mon;
qtime->tm_year = tm->tm_year;
qtime->tm_wday = tm->tm_wday;
qtime->tm_yday = tm->tm_yday;
qtime->tm_isdst = tm->tm_isdst;
}
else
memset(qtime, 0, sizeof(*qtime));
}
return t;
}
#endif

View File

@ -371,7 +371,7 @@ pubsubserver_t *Sys_ForkServer(void)
DL_DeThread();
#endif
#ifdef SQL
SQL_KillServers(); //FIXME: this is bad...
SQL_KillServers(NULL); //FIXME: this is bad...
#endif
//FIXME: we should probably use posix_atfork for those.

View File

@ -124,4 +124,17 @@ typedef struct {
int VMQ3_Cvar_Register(q3vmcvar_t *v, char *name, char *defval, int flags);
int VMQ3_Cvar_Update(q3vmcvar_t *v);
typedef struct {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
} q3time_t;
qint64_t Q3VM_GetRealtime(q3time_t *qtime);
#endif

View File

@ -361,14 +361,14 @@ typedef struct q2edict_s q2edict_t;
void VARGS WorldQ2_LinkEdict(world_t *w, q2edict_t *ent);
void VARGS WorldQ2_UnlinkEdict(world_t *w, q2edict_t *ent);
int VARGS WorldQ2_AreaEdicts (world_t *w, vec3_t mins, vec3_t maxs, q2edict_t **list,
int VARGS WorldQ2_AreaEdicts (world_t *w, const vec3_t mins, const vec3_t maxs, q2edict_t **list,
int maxcount, int areatype);
trace_t WorldQ2_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hitcontentsmask, q2edict_t *passedict);
#endif
#if defined(Q2BSPS) || defined(Q3BSPS)
unsigned int Q23BSP_FatPVS(model_t *mod, vec3_t org, pvsbuffer_t *buffer, qboolean merge);
qboolean Q23BSP_EdictInFatPVS(model_t *mod, struct pvscache_s *ent, qbyte *pvs);
void Q23BSP_FindTouchedLeafs(model_t *mod, struct pvscache_s *ent, float *mins, float *maxs);
unsigned int Q23BSP_FatPVS(model_t *mod, const vec3_t org, pvsbuffer_t *buffer, qboolean merge);
qboolean Q23BSP_EdictInFatPVS(model_t *mod, const struct pvscache_s *ent, const qbyte *pvs, const int *areas);
void Q23BSP_FindTouchedLeafs(model_t *mod, struct pvscache_s *ent, const float *mins, const float *maxs);
#endif

View File

@ -10,7 +10,7 @@ public class FTENativeActivity extends android.app.Activity implements android.v
//Native functions and stuff
private native boolean startup(String externalDataPath, String libraryPath);
private native void openfile(String url);
private native void surfacechange(boolean teardown, boolean restart, android.view.Surface surface);
private native void surfacechange(boolean teardown, boolean restart, android.view.SurfaceHolder holder, android.view.Surface surface);
private native void shutdown();
private static native void keypress(int devid, boolean down, int androidkey, int unicode);
@ -48,11 +48,11 @@ public class FTENativeActivity extends android.app.Activity implements android.v
}
public void surfaceChanged(android.view.SurfaceHolder holder, int format, int width, int height)
{
surfacechange(true, true, holder.getSurface());
surfacechange(true, true, holder, holder.getSurface());
}
public void surfaceDestroyed(android.view.SurfaceHolder holder)
{
surfacechange(true, false, null);
surfacechange(true, false, null, null);
}
//OnGlobalLayoutListener methods

View File

@ -2745,7 +2745,7 @@ static void BE_GenPolyBatches(batch_t **batches)
}
void R_HalfLife_GenerateBatches(entity_t *e, batch_t **batches);
void PR_Route_Visualise(void);
void BE_GenModelBatches(batch_t **batches, const dlight_t *dl, unsigned int bemode, qbyte *worldpvs)
void BE_GenModelBatches(batch_t **batches, const dlight_t *dl, unsigned int bemode, const qbyte *worldpvs, const int *worldareas)
{
int i;
entity_t *ent;
@ -2757,7 +2757,10 @@ void BE_GenModelBatches(batch_t **batches, const dlight_t *dl, unsigned int bemo
extern cvar_t r_ignoreentpvs; //legacy value is 1...
if (r_ignoreentpvs.ival)
{
worldpvs = NULL;
worldareas = NULL;
}
/*clear the batch list*/
for (i = 0; i < SHADER_SORT_COUNT; i++)
@ -2809,7 +2812,7 @@ void BE_GenModelBatches(batch_t **batches, const dlight_t *dl, unsigned int bemo
}
#endif
if (worldpvs && !cl.worldmodel->funcs.EdictInFatPVS(cl.worldmodel, &ent->pvscache, worldpvs))
if (worldpvs && !cl.worldmodel->funcs.EdictInFatPVS(cl.worldmodel, &ent->pvscache, worldpvs, worldareas))
continue;
switch(ent->rtype)

View File

@ -5583,12 +5583,12 @@ batch_t *GLBE_GetTempBatch(void)
/*called from shadowmapping code*/
#ifdef RTLIGHTS
void GLBE_BaseEntTextures(qbyte *worldpvs)
void GLBE_BaseEntTextures(const qbyte *worldpvs, const int *worldareas)
{
batch_t *batches[SHADER_SORT_COUNT];
batch_t **ob = shaderstate.mbatches;
shaderstate.mbatches = batches;
BE_GenModelBatches(batches, shaderstate.curdlight, shaderstate.mode, worldpvs);
BE_GenModelBatches(batches, shaderstate.curdlight, shaderstate.mode, worldpvs, worldareas);
GLBE_SubmitMeshes(NULL, SHADER_SORT_PORTAL, SHADER_SORT_SEETHROUGH+1);
GLBE_SelectEntity(&r_worldentity);
shaderstate.mbatches = ob;
@ -6255,7 +6255,7 @@ void GLBE_DrawWorld (batch_t **worldbatches)
}
//memset(batches, 0, sizeof(batches));
BE_GenModelBatches(batches, shaderstate.curdlight, BEM_STANDARD, r_refdef.scenevis);
BE_GenModelBatches(batches, shaderstate.curdlight, BEM_STANDARD, r_refdef.scenevis, r_refdef.sceneareas);
R_GenDlightBatches(batches);
shaderstate.curentity = &r_worldentity;
// if (cl.paused || cls.state < ca_active)

View File

@ -2836,7 +2836,7 @@ void Terr_DrawInBounds(struct tdibctx *ctx, int x, int y, int w, int h)
Terr_RebuildMesh(ctx->wmodel, s, x, y);
}
if (ctx->pvs && !ctx->wmodel->funcs.EdictInFatPVS(ctx->wmodel, &s->pvscache, ctx->pvs))
if (ctx->pvs && !ctx->wmodel->funcs.EdictInFatPVS(ctx->wmodel, &s->pvscache, ctx->pvs, NULL))
return; //this section isn't in any visible bsp leafs
if (s->numents)
@ -3200,7 +3200,7 @@ void Terrain_ClipDecal(fragmentdecal_t *dec, float *center, float radius, model_
#endif
unsigned int Heightmap_PointContentsHM(heightmap_t *hm, float clipmipsz, vec3_t org)
unsigned int Heightmap_PointContentsHM(heightmap_t *hm, float clipmipsz, const vec3_t org)
{
float x, y;
float z, tz;
@ -3283,7 +3283,7 @@ unsigned int Heightmap_PointContentsHM(heightmap_t *hm, float clipmipsz, vec3_t
return contents;
}
unsigned int Heightmap_PointContents(model_t *model, vec3_t axis[3], vec3_t org)
unsigned int Heightmap_PointContents(model_t *model, const vec3_t axis[3], const vec3_t org)
{
heightmap_t *hm = model->terrain;
unsigned int cont;
@ -3324,7 +3324,7 @@ unsigned int Heightmap_PointContents(model_t *model, vec3_t axis[3], vec3_t org)
return cont;
}
unsigned int Heightmap_NativeBoxContents(model_t *model, int hulloverride, framestate_t *framestate, vec3_t axis[3], vec3_t org, vec3_t mins, vec3_t maxs)
unsigned int Heightmap_NativeBoxContents(model_t *model, int hulloverride, const framestate_t *framestate, const vec3_t axis[3], const vec3_t org, const vec3_t mins, const vec3_t maxs)
{
heightmap_t *hm = model->terrain;
return Heightmap_PointContentsHM(hm, mins[2], org);
@ -4000,7 +4000,7 @@ Why is recursion good?
Obviously, we don't care all that much about 1
*/
qboolean Heightmap_Trace(struct model_s *model, int hulloverride, framestate_t *framestate, vec3_t mataxis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace)
qboolean Heightmap_Trace(struct model_s *model, int hulloverride, const framestate_t *framestate, const vec3_t mataxis[3], const vec3_t start, const vec3_t end, const vec3_t mins, const vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace)
{
vec2_t pos;
vec2_t frac;
@ -4271,7 +4271,7 @@ qboolean Heightmap_Trace(struct model_s *model, int hulloverride, framestate_t *
return trace->fraction < 1;
}
qboolean Heightmap_Trace_Test(struct model_s *model, int hulloverride, framestate_t *framestate, vec3_t mataxis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace)
qboolean Heightmap_Trace_Test(struct model_s *model, int hulloverride, const framestate_t *framestate, const vec3_t mataxis[3], const vec3_t start, const vec3_t end, const vec3_t mins, const vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace)
{
qboolean ret = Heightmap_Trace(model, hulloverride, framestate, mataxis, start, end, mins, maxs, capsule, against, trace);
@ -4301,7 +4301,7 @@ typedef struct
int id;
int min[3], max[3];
} hmpvsent_t;
unsigned int Heightmap_FatPVS (model_t *mod, vec3_t org, pvsbuffer_t *pvsbuffer, qboolean add)
unsigned int Heightmap_FatPVS (model_t *mod, const vec3_t org, pvsbuffer_t *fte_restrict pvsbuffer, qboolean add)
{
//embed the org onto the pvs
hmpvs_t *hmpvs;
@ -4314,12 +4314,12 @@ unsigned int Heightmap_FatPVS (model_t *mod, vec3_t org, pvsbuffer_t *pvsbuffer
}
#ifndef CLIENTONLY
qboolean Heightmap_EdictInFatPVS (model_t *mod, struct pvscache_s *edict, qbyte *pvsdata)
qboolean Heightmap_EdictInFatPVS (model_t *mod, const struct pvscache_s *edict, const qbyte *pvsdata, const int *areas)
{
heightmap_t *hm = mod->terrain;
int o[3], i;
hmpvs_t *hmpvs = (hmpvs_t*)pvsdata;
hmpvsent_t *hmed = (hmpvsent_t*)edict;
const hmpvs_t *hmpvs = (const hmpvs_t*)pvsdata;
const hmpvsent_t *hmed = (const hmpvsent_t*)edict;
if (!hm->culldistance)
return true;
@ -4338,7 +4338,7 @@ qboolean Heightmap_EdictInFatPVS (model_t *mod, struct pvscache_s *edict, qbyte
return DotProduct(o,o) < hm->culldistance;
}
void Heightmap_FindTouchedLeafs (model_t *mod, pvscache_t *ent, float *mins, float *maxs)
void Heightmap_FindTouchedLeafs (model_t *mod, pvscache_t *ent, const float *mins, const float *maxs)
{
hmpvsent_t *hmed = (hmpvsent_t*)ent;
@ -4347,7 +4347,7 @@ void Heightmap_FindTouchedLeafs (model_t *mod, pvscache_t *ent, float *mins, flo
}
#endif
void Heightmap_LightPointValues (model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir)
void Heightmap_LightPointValues (model_t *mod, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir)
{
res_diffuse[0] = 128;
res_diffuse[1] = 128;
@ -4373,8 +4373,10 @@ qbyte *Heightmap_ClusterPVS (model_t *model, int num, pvsbuffer_t *buffer, pvsme
// static qbyte heightmappvs = 255;
// return &heightmappvs;
}
int Heightmap_ClusterForPoint (model_t *model, vec3_t point)
int Heightmap_ClusterForPoint (model_t *model, const vec3_t point, int *area)
{
if (*area)
*area = 0;
return -1;
}

View File

@ -25,8 +25,8 @@
Nor will it work 100%
*/
qboolean HLMDL_Trace (struct model_s *model, int hulloverride, framestate_t *framestate, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace);
unsigned int HLMDL_Contents (struct model_s *model, int hulloverride, framestate_t *framestate, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs);
qboolean HLMDL_Trace (struct model_s *model, int hulloverride, const framestate_t *framestate, const vec3_t axis[3], const vec3_t p1, const vec3_t p2, const vec3_t mins, const vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace);
unsigned int HLMDL_Contents (struct model_s *model, int hulloverride, const framestate_t *framestate, const vec3_t axis[3], const vec3_t p, const vec3_t mins, const vec3_t maxs);
void QuaternionGLMatrix(float x, float y, float z, float w, vec4_t *GLM)
{
@ -921,7 +921,7 @@ int HLMDL_GetAttachment(model_t *mod, int tagnum, float *resultmatrix)
return -1;
}
static int HLMDL_GetBoneData_Internal(hlmodel_t *model, int firstbone, int lastbone, framestate_t *fstate, float *result)
static int HLMDL_GetBoneData_Internal(hlmodel_t *model, int firstbone, int lastbone, const framestate_t *fstate, float *result)
{
int b, cbone, bgroup;
@ -939,7 +939,7 @@ static int HLMDL_GetBoneData_Internal(hlmodel_t *model, int firstbone, int lastb
}
return cbone;
}
int HLMDL_GetBoneData(model_t *mod, int firstbone, int lastbone, framestate_t *fstate, float *result)
int HLMDL_GetBoneData(model_t *mod, int firstbone, int lastbone, const framestate_t *fstate, float *result)
{
return HLMDL_GetBoneData_Internal(Mod_Extradata(mod), firstbone, lastbone, fstate, result);
}
@ -966,7 +966,7 @@ qboolean HLMDL_FrameInfoForNum(model_t *mod, int surfaceidx, int seqnum, char **
qboolean HLMDL_Trace (model_t *model, int hulloverride, framestate_t *framestate, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace)
qboolean HLMDL_Trace (model_t *model, int hulloverride, const framestate_t *framestate, const vec3_t axis[3], const vec3_t p1, const vec3_t p2, const vec3_t mins, const vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace)
{
hlmodel_t *hm = Mod_Extradata(model);
float *relbones;
@ -1140,7 +1140,7 @@ nextbrush:
return trace->truefraction != 1;
}
unsigned int HLMDL_Contents (model_t *model, int hulloverride, framestate_t *framestate, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs)
unsigned int HLMDL_Contents (model_t *model, int hulloverride, const framestate_t *framestate, const vec3_t axis[3], const vec3_t p, const vec3_t mins, const vec3_t maxs)
{
trace_t tr;
HLMDL_Trace(model, hulloverride, framestate, axis, p, p, mins, maxs, false, ~0, &tr);

View File

@ -230,42 +230,35 @@ typedef struct
qbyte *buffer; //reallocated if needed.
size_t buffersize;
} pvsbuffer_t;
#if 1
typedef char *pvsmerge_t;
#define PVM_FAST ((char*)0)
#define PVM_MERGE ((char*)1)
#define PVM_REPLACE ((char*)2)
#else
typedef enum
{
PVM_FAST,
PVM_MERGE, //merge the pvs bits into the provided buffer
PVM_REPLACE,//return value is guarenteed to be the provided buffer.
} pvsmerge_t;
#endif
typedef struct {
//model is being purged from memory.
void (*PurgeModel) (struct model_s *mod);
unsigned int (*PointContents) (struct model_s *model, vec3_t axis[3], vec3_t p);
unsigned int (*BoxContents) (struct model_s *model, int hulloverride, framestate_t *framestate, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs);
unsigned int (*PointContents) (struct model_s *model, const vec3_t axis[3], const vec3_t p);
unsigned int (*BoxContents) (struct model_s *model, int hulloverride, const framestate_t *framestate, const vec3_t axis[3], const vec3_t p, const vec3_t mins, const vec3_t maxs);
//deals with whatever is native for the bsp (gamecode is expected to distinguish this).
qboolean (*NativeTrace) (struct model_s *model, int hulloverride, framestate_t *framestate, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace);
unsigned int (*NativeContents)(struct model_s *model, int hulloverride, framestate_t *framestate, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs);
qboolean (*NativeTrace) (struct model_s *model, int hulloverride, const framestate_t *framestate, const vec3_t axis[3], const vec3_t p1, const vec3_t p2, const vec3_t mins, const vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace);
unsigned int (*NativeContents)(struct model_s *model, int hulloverride, const framestate_t *framestate, const vec3_t axis[3], const vec3_t p, const vec3_t mins, const vec3_t maxs);
unsigned int (*FatPVS) (struct model_s *model, vec3_t org, pvsbuffer_t *pvsbuffer, qboolean merge);
qboolean (*EdictInFatPVS) (struct model_s *model, struct pvscache_s *edict, qbyte *pvs);
void (*FindTouchedLeafs) (struct model_s *model, struct pvscache_s *ent, vec3_t cullmins, vec3_t cullmaxs); //edict system as opposed to q2 game dll system.
unsigned int (*FatPVS) (struct model_s *model, const vec3_t org, pvsbuffer_t *pvsbuffer, qboolean merge);
qboolean (*EdictInFatPVS) (struct model_s *model, const struct pvscache_s *edict, const qbyte *pvs, const int *areas); //areas[0] is the count of accepted areas, if valid.
void (*FindTouchedLeafs) (struct model_s *model, struct pvscache_s *ent, const vec3_t cullmins, const vec3_t cullmaxs); //edict system as opposed to q2 game dll system.
void (*LightPointValues) (struct model_s *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void (*LightPointValues) (struct model_s *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void (*StainNode) (struct mnode_s *node, float *parms);
void (*MarkLights) (struct dlight_s *light, int bit, struct mnode_s *node);
int (*ClusterForPoint) (struct model_s *model, vec3_t point); //pvs index (leaf-1 for q1bsp). may be negative (ie: no pvs).
int (*ClusterForPoint) (struct model_s *model, const vec3_t point, int *areaout); //pvs index (leaf-1 for q1bsp). may be negative (ie: no pvs).
qbyte *(*ClusterPVS) (struct model_s *model, int cluster, pvsbuffer_t *pvsbuffer, pvsmerge_t merge);
qbyte *(*ClustersInSphere) (struct model_s *model, vec3_t point, float radius, pvsbuffer_t *pvsbuffer, qbyte *unionwith);
qbyte *(*ClustersInSphere) (struct model_s *model, const vec3_t point, float radius, pvsbuffer_t *pvsbuffer, const qbyte *fte_restrict unionwith);
} modelfuncs_t;
@ -571,8 +564,8 @@ size_t Fragment_ClipPlaneToBrush(vecV_t *points, size_t maxpoints, void *planes,
void Mod_ClipDecal(struct model_s *mod, vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, unsigned int surfflagmask, unsigned int surflagmatch, void (*callback)(void *ctx, vec3_t *fte_restrict points, size_t numpoints, shader_t *shader), void *ctx);
void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node);
void GLQ1BSP_LightPointValues(struct model_s *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, vec3_t p1, vec3_t p2, unsigned int hitcontents, struct trace_s *trace);
void GLQ1BSP_LightPointValues(struct model_s *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, const vec3_t p1, const vec3_t p2, unsigned int hitcontents, struct trace_s *trace);
/*
==============================================================================
@ -1077,7 +1070,7 @@ typedef struct model_s
#endif // __MODEL__
float RadiusFromBounds (vec3_t mins, vec3_t maxs);
float RadiusFromBounds (const vec3_t mins, const vec3_t maxs);
//
@ -1093,8 +1086,8 @@ void Terr_FinishTerrain(model_t *model);
void Terr_PurgeTerrainModel(model_t *hm, qboolean lightmapsonly, qboolean lightmapreusable);
void *Mod_LoadTerrainInfo(model_t *mod, char *loadname, qboolean force); //call this after loading a bsp
qboolean Terrain_LocateSection(const char *name, flocation_t *loc); //used on servers to generate sections for download.
qboolean Heightmap_Trace(model_t *model, int forcehullnum, framestate_t *framestate, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contentmask, struct trace_s *trace);
unsigned int Heightmap_PointContents(model_t *model, vec3_t axis[3], vec3_t org);
qboolean Heightmap_Trace(model_t *model, int forcehullnum, const framestate_t *framestate, const vec3_t axis[3], const vec3_t start, const vec3_t end, const vec3_t mins, const vec3_t maxs, qboolean capsule, unsigned int contentmask, struct trace_s *trace);
unsigned int Heightmap_PointContents(model_t *model, const vec3_t axis[3], const vec3_t org);
struct fragmentdecal_s;
void Terrain_ClipDecal(struct fragmentdecal_s *dec, float *center, float radius, model_t *model);
qboolean Terr_DownloadedSection(char *fname);
@ -1122,22 +1115,22 @@ void CM_InitBoxHull (void);
void CM_Init(void);
qboolean CM_SetAreaPortalState (struct model_s *mod, int portalnum, qboolean open);
qboolean CM_HeadnodeVisible (struct model_s *mod, int nodenum, qbyte *visbits);
qboolean CM_HeadnodeVisible (struct model_s *mod, int nodenum, const qbyte *visbits);
qboolean VARGS CM_AreasConnected (struct model_s *mod, unsigned int area1, unsigned int area2);
int CM_ClusterBytes (struct model_s *mod);
int CM_LeafContents (struct model_s *mod, int leafnum);
int CM_LeafCluster (struct model_s *mod, int leafnum);
int CM_LeafArea (struct model_s *mod, int leafnum);
int CM_WriteAreaBits (struct model_s *mod, qbyte *buffer, int area, qboolean merge);
int CM_PointLeafnum (struct model_s *mod, vec3_t p);
int CM_PointLeafnum (struct model_s *mod, const vec3_t p);
qbyte *CM_ClusterPVS (struct model_s *mod, int cluster, pvsbuffer_t *buffer, pvsmerge_t merge);
qbyte *CM_ClusterPHS (struct model_s *mod, int cluster, pvsbuffer_t *buffer);
int CM_BoxLeafnums (struct model_s *mod, vec3_t mins, vec3_t maxs, int *list, int listsize, int *topnode);
int CM_PointContents (struct model_s *mod, vec3_t p);
int CM_TransformedPointContents (struct model_s *mod, vec3_t p, int headnode, vec3_t origin, vec3_t angles);
int CM_HeadnodeForBox (struct model_s *mod, vec3_t mins, vec3_t maxs);
int CM_BoxLeafnums (struct model_s *mod, const vec3_t mins, const vec3_t maxs, int *list, int listsize, int *topnode);
int CM_PointContents (struct model_s *mod, const vec3_t p);
int CM_TransformedPointContents (struct model_s *mod, const vec3_t p, int headnode, const vec3_t origin, const vec3_t angles);
int CM_HeadnodeForBox (struct model_s *mod, const vec3_t mins, const vec3_t maxs);
//struct trace_s CM_TransformedBoxTrace (struct model_s *mod, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int brushmask, vec3_t origin, vec3_t angles);
struct model_s *CM_TempBoxModel(vec3_t mins, vec3_t maxs);
struct model_s *CM_TempBoxModel(const vec3_t mins, const vec3_t maxs);
//for gamecode to control portals/areas
void CMQ2_SetAreaPortalState (model_t *mod, unsigned int portalnum, qboolean open);

View File

@ -2301,7 +2301,7 @@ LIGHT SAMPLING
mplane_t *lightplane;
vec3_t lightspot;
static void GLQ3_AddLatLong(qbyte latlong[2], vec3_t dir, float mag)
static void GLQ3_AddLatLong(const qbyte latlong[2], vec3_t dir, float mag)
{
float lat = (float)latlong[0] * (2 * M_PI)*(1.0 / 255.0);
float lng = (float)latlong[1] * (2 * M_PI)*(1.0 / 255.0);
@ -2310,7 +2310,7 @@ static void GLQ3_AddLatLong(qbyte latlong[2], vec3_t dir, float mag)
dir[2] += mag * cos ( lat );
}
void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir)
void GLQ3_LightGrid(model_t *mod, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir)
{
q3lightgridinfo_t *lg = (q3lightgridinfo_t *)cl.worldmodel->lightgrid;
int index[8];
@ -2585,7 +2585,7 @@ int R_LightPoint (vec3_t p)
#ifdef PEXT_LIGHTSTYLECOL
static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, vec3_t start, vec3_t end)
static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, const vec3_t start, const vec3_t end)
{
static float l[6];
float *r;
@ -2813,7 +2813,7 @@ static float *GLRecursiveLightPoint3C (model_t *mod, mnode_t *node, vec3_t start
#endif
void GLQ1BSP_LightPointValues(model_t *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir)
void GLQ1BSP_LightPointValues(model_t *model, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir)
{
vec3_t end;
float *r;

View File

@ -1068,7 +1068,7 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
d += 0.1; //an epsilon on the far side
VectorMA(point, d, plane.normal, point);
clust = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, point);
clust = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, point, NULL);
if (i == batch->firstmesh)
r_refdef.forcedvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, clust, &newvis, PVM_REPLACE);
else
@ -1145,7 +1145,6 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
{ //q3-style portal, where a single entity provides orientation+two origins
float d;
vec3_t paxis[3], porigin, vaxis[3], vorg;
void PerpendicularVector( vec3_t dst, const vec3_t src );
oplane = plane;

View File

@ -3174,7 +3174,11 @@ static void Shaderpass_RGBGen (parsestate_t *ps, char **ptr)
else if (!Q_stricmp (token, "oneMinusEntity"))
pass->rgbgen = RGB_GEN_ONE_MINUS_ENTITY;
else if (!Q_stricmp (token, "vertex"))
{
pass->rgbgen = RGB_GEN_VERTEX_LIGHTING;
if (pass->alphagen == ALPHA_GEN_UNDEFINED) //matches Q3, and is a perf gain, even if its inconsistent.
pass->alphagen = ALPHA_GEN_VERTEX;
}
else if (!Q_stricmp (token, "oneMinusVertex"))
pass->rgbgen = RGB_GEN_ONE_MINUS_VERTEX;
else if (!Q_stricmp (token, "lightingDiffuse"))
@ -4524,7 +4528,7 @@ void Shader_Readpass (parsestate_t *ps)
pass->anim_frames[0] = r_nulltex;
pass->anim_numframes = 0;
pass->rgbgen = RGB_GEN_UNKNOWN;
pass->alphagen = ALPHA_GEN_IDENTITY;
pass->alphagen = ALPHA_GEN_UNDEFINED;
pass->tcgen = TC_GEN_UNSPECIFIED;
pass->numtcmods = 0;
pass->stagetype = ST_AMBIENT;
@ -4554,6 +4558,9 @@ void Shader_Readpass (parsestate_t *ps)
}
}
if (pass->alphagen == ALPHA_GEN_UNDEFINED)
pass->alphagen = ALPHA_GEN_IDENTITY;
//if there was no texgen, then its too late now.
if (!pass->numMergedPasses)
pass->numMergedPasses = 1;

View File

@ -1578,7 +1578,7 @@ static struct shadowmesh_s *SHM_BuildShadowMesh(dlight_t *dl, unsigned char *lvi
lvis = cl.worldmodel->funcs.ClustersInSphere(cl.worldmodel, dl->origin, dl->radius, &lvisb, NULL);
else
{
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin);
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin, NULL); //FIXME: track the lights area
lvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, clus, &lvisb, PVM_FAST);
if (cl.worldmodel->funcs.ClustersInSphere)
@ -1649,7 +1649,7 @@ static struct shadowmesh_s *SHM_BuildShadowMesh(dlight_t *dl, unsigned char *lvi
sh_shadowframe++;
{
int cluster = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin);
int cluster = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin, NULL);
if (cluster >= 0)
sh_shmesh->litleaves[cluster>>3] |= 1<<(cluster&7);
}
@ -2237,7 +2237,7 @@ static void Sh_LightFrustumPlanes(dlight_t *l, vec3_t axis[3], vec4_t *planes, i
//culling for the face happens in the caller.
//these faces should thus match Sh_LightFrustumPlanes
static void Sh_GenShadowFace(dlight_t *l, vec3_t axis[3], int lighttype, shadowmesh_t *smesh, int face, int smsize, float proj[16], qbyte *lightpvs)
static void Sh_GenShadowFace(dlight_t *l, vec3_t axis[3], int lighttype, shadowmesh_t *smesh, int face, int smsize, float proj[16], const qbyte *lightpvs)
{
vec3_t t1,t2,t3;
texture_t *tex;
@ -2379,7 +2379,7 @@ static void Sh_GenShadowFace(dlight_t *l, vec3_t axis[3], int lighttype, shadowm
break;
#ifdef GLQUAKE
case QR_OPENGL:
GLBE_BaseEntTextures(lightpvs);
GLBE_BaseEntTextures(lightpvs, NULL);
if (lighttype & LSHADER_ORTHO)
qglDisable(GL_DEPTH_CLAMP_ARB);
@ -2387,17 +2387,17 @@ static void Sh_GenShadowFace(dlight_t *l, vec3_t axis[3], int lighttype, shadowm
#endif
#ifdef D3D9QUAKE
case QR_DIRECT3D9:
D3D9BE_BaseEntTextures(lightpvs);
D3D9BE_BaseEntTextures(lightpvs, NULL);
break;
#endif
#ifdef D3D11QUAKE
case QR_DIRECT3D11:
D3D11BE_BaseEntTextures(lightpvs);
D3D11BE_BaseEntTextures(lightpvs, NULL);
break;
#endif
#ifdef VKQUAKE
case QR_VULKAN:
VKBE_BaseEntTextures(lightpvs);
VKBE_BaseEntTextures(lightpvs, NULL);
break;
#endif
}
@ -2616,7 +2616,7 @@ qboolean Sh_GenerateShadowMap(dlight_t *l, int lighttype)
else
{
int clus;
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, l->origin);
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, l->origin, NULL);
lvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, clus, &lvisb, PVM_FAST);
//FIXME: surely we can use the phs for this?
@ -2732,12 +2732,12 @@ static void Sh_DrawShadowMapLight(dlight_t *l, vec3_t colour, vec3_t axis[3], qb
else
{
int clus;
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, l->origin);
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, l->origin, NULL);
lvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, clus, &lvisb, PVM_FAST);
//FIXME: surely we can use the phs for this?
if (cl.worldmodel->funcs.ClustersInSphere)
lvis = cl.worldmodel->funcs.ClustersInSphere(cl.worldmodel, l->origin, l->radius, &lvisb2, lvis);
//FIXME: check areas
if (!Sh_VisOverlaps(lvis, vvis)) //The two viewing areas do not intersect.
{
RQuantAdd(RQUANT_RTLIGHT_CULL_PVS, 1);
@ -2856,22 +2856,22 @@ static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour, qbyte *pvs)
break;
#ifdef GLQUAKE
case QR_OPENGL:
GLBE_BaseEntTextures(pvs);
GLBE_BaseEntTextures(pvs, NULL);
break;
#endif
#ifdef VKQUAKE
case QR_VULKAN:
VKBE_BaseEntTextures(pvs);
VKBE_BaseEntTextures(pvs, NULL);
break;
#endif
#ifdef D3D9QUAKE
case QR_DIRECT3D9:
D3D9BE_BaseEntTextures(pvs);
D3D9BE_BaseEntTextures(pvs, NULL);
break;
#endif
#ifdef D3D11QUAKE
case QR_DIRECT3D11:
D3D11BE_BaseEntTextures(pvs);
D3D11BE_BaseEntTextures(pvs, NULL);
break;
#endif
}
@ -3159,7 +3159,7 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, vec3_t axis[3],
}
else
{
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin);
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin, NULL); //FIXME: check areas
lvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, clus, &lvisb, PVM_FAST);
// if (cl.worldmodel->funcs.ClustersInSphere)
// lvis = cl.worldmodel->funcs.ClustersInSphere(cl.worldmodel, dl->origin, dl->radius, &lvisb2, lvis);
@ -3388,7 +3388,7 @@ qboolean Sh_CullLight(dlight_t *dl, qbyte *vvis)
int clus;
qbyte *lvis;
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin);
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin, NULL);
lvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, clus, &lvisb, PVM_FAST);
// if (cl.worldmodel->funcs.ClustersInSphere)
// lvis = cl.worldmodel->funcs.ClustersInSphere(cl.worldmodel, dl->origin, dl->radius, &lvisb2, lvis);
@ -3433,12 +3433,12 @@ static void Sh_DrawShadowlessLight(dlight_t *dl, vec3_t colour, vec3_t axis[3],
lvis = cl.worldmodel->funcs.ClustersInSphere(cl.worldmodel, dl->origin, dl->radius, &lvisb2, NULL);
else
{
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin);
clus = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin, NULL);
lvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, clus, &lvisb, PVM_FAST);
}
SHM_BuildShadowMesh(dl, lvis, SMT_SHADOWLESS);
//FIXME: check areas
if (!Sh_VisOverlaps(lvis, vvis)) //The two viewing areas do not intersect.
{
RQuantAdd(RQUANT_RTLIGHT_CULL_PVS, 1);
@ -3645,7 +3645,7 @@ void Sh_PreGenerateLights(void)
lvis = cl.worldmodel->funcs.ClustersInSphere(cl.worldmodel, dl->origin, dl->radius, &lvisb2, NULL);
else
{ //other lights only want to use the source leaf's pvs (clamped by the sphere)
leaf = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin);
leaf = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, dl->origin, NULL);
lvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, leaf, &lvisb, PVM_FAST);
if (cl.worldmodel->funcs.ClustersInSphere)
lvis = cl.worldmodel->funcs.ClustersInSphere(cl.worldmodel, dl->origin, dl->radius, &lvisb2, lvis);

View File

@ -131,24 +131,12 @@ qboolean R_DrawSkyroom(shader_t *skyshader)
if (!r_refdef.skyroom_enabled || r_refdef.recurse >= R_MAX_RECURSE-1)
return false;
if (skyshader->numpasses)
{
shaderpass_t *pass = skyshader->passes;
if (pass->shaderbits & SBITS_ATEST_BITS) //alphatests
;
else if (pass->shaderbits & SBITS_MASK_BITS) //colormasks
;
else if ((pass->shaderbits & SBITS_BLEND_BITS) != 0 && (pass->shaderbits & SBITS_BLEND_BITS) != (SBITS_SRCBLEND_ONE|SBITS_DSTBLEND_ZERO)) //blendfunc
;
else
return false; //that shader looks like its opaque.
}
oldrefdef = r_refdef;
r_refdef.recurse+=1;
r_refdef.externalview = true;
r_refdef.skyroom_enabled = false;
r_refdef.flags |= RDF_DISABLEPARTICLES;
/*work out where the camera should be (use the same angles)*/
VectorCopy(r_refdef.skyroom_pos, r_refdef.vieworg);
@ -231,8 +219,21 @@ qboolean R_DrawSkyChain (batch_t *batch)
skyboxtex = NULL;
if (R_DrawSkyroom(skyshader))
{
{ //don't obscure the skyroom if the sky shader is opaque.
qboolean opaque = false;
if (skyshader->numpasses)
{
shaderpass_t *pass = skyshader->passes;
if (pass->shaderbits & SBITS_ATEST_BITS) //alphatests
;
else if (pass->shaderbits & SBITS_MASK_BITS) //colormasks
;
else if ((pass->shaderbits & SBITS_BLEND_BITS) != 0 && (pass->shaderbits & SBITS_BLEND_BITS) != (SBITS_SRCBLEND_ONE|SBITS_DSTBLEND_ZERO)) //blendfunc
;
else
opaque = true; //that shader looks like its opaque.
}
if (!opaque)
GL_DrawSkySphere(batch, skyshader);
}
else if (skyboxtex && TEXVALID(*skyboxtex))

View File

@ -318,6 +318,7 @@ extern vec3_t r_origin;
//
extern refdef_t r_refdef;
extern unsigned int r_viewcontents;
int r_viewarea;
extern int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; //q2
extern texture_t *r_notexture_mip;
extern int d_lightstylevalue[256]; // 8.8 fraction of base light value
@ -406,7 +407,7 @@ void R_InitFlashblends(void);
#ifdef GLQUAKE
void GLR_MarkQ2Lights (dlight_t *light, int bit, mnode_t *node);
#endif
void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void GLQ3_LightGrid(model_t *mod, const vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
qboolean R_LoadRTLights(void);
qboolean R_ImportRTLights(const char *entlump);

View File

@ -336,7 +336,7 @@ qboolean HLMDL_GetModelEvent(model_t *model, int animation, int eventidx, float
int HLMDL_GetNumBones(model_t *mod, qboolean tagstoo);
int HLMDL_GetBoneParent(model_t *mod, int bonenum);
const char *HLMDL_GetBoneName(model_t *mod, int bonenum);
int HLMDL_GetBoneData(model_t *model, int firstbone, int lastbone, framestate_t *fstate, float *result);
int HLMDL_GetBoneData(model_t *model, int firstbone, int lastbone, const framestate_t *fstate, float *result);
int HLMDL_GetAttachment(model_t *model, int tagnum, float *resultmatrix);
#ifndef SERVERONLY

View File

@ -217,6 +217,7 @@ typedef struct shaderpass_s {
shaderfunc_t rgbgen_func;
enum {
ALPHA_GEN_UNDEFINED,
ALPHA_GEN_ENTITY,
ALPHA_GEN_WAVE,
ALPHA_GEN_PORTAL,
@ -990,9 +991,9 @@ void GLBE_PolyOffsetStencilShadow(qboolean foobar);
void GLBE_PolyOffsetStencilShadow(void);
#endif
//Called from shadowmapping code into backend
void GLBE_BaseEntTextures(qbyte *worldpvs);
void D3D9BE_BaseEntTextures(qbyte *worldpvs);
void D3D11BE_BaseEntTextures(qbyte *worldpvs);
void GLBE_BaseEntTextures(const qbyte *worldpvs, const int *worldareas);
void D3D9BE_BaseEntTextures(const qbyte *worldpvs, const int *worldareas);
void D3D11BE_BaseEntTextures(const qbyte *worldpvs, const int *worldareas);
//prebuilds shadow volumes
void Sh_PreGenerateLights(void);
//Draws lights, called from the backend

View File

@ -852,10 +852,6 @@ void PR_Deinit(void)
World_Destroy(&sv.world);
#ifdef SQL
SQL_KillServers();
#endif
//clear out function pointers (so changing game modes cannot lead to confusions)
memset(&gfuncs, 0, sizeof(gfuncs));
SpectatorConnect = 0;
@ -863,14 +859,6 @@ void PR_Deinit(void)
SpectatorDisconnect = 0;
}
void PR_Shutdown(void)
{
PR_Deinit();
#ifdef SQL
SQL_DeInit();
#endif
}
void PR_LoadGlabalStruct(qboolean muted)
{
static float svphysicsmode = 2;
@ -1989,10 +1977,6 @@ void Q_InitProgs(qboolean cinematic)
Con_Printf(CON_ERROR"Running without gamecode\n");
}
#ifdef SQL
SQL_KillServers(); // TODO: is this the best placement for this?
#endif
if (oldprnum >= 0)
f = PR_FindFunction (svprogfuncs, "AddAddonProgs", oldprnum);
else
@ -3901,7 +3885,7 @@ void PF_newcheckclient (pubprogfuncs_t *prinst, world_t *w)
w->lastcheckpvs = NULL;
else
{
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, checkorg);
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, checkorg, NULL);
w->lastcheckpvs = sv.world.worldmodel->funcs.ClusterPVS (sv.world.worldmodel, cluster, &checkpvsbuffer, PVM_FAST);
}
@ -3956,7 +3940,7 @@ int PF_checkclient_Internal (pubprogfuncs_t *prinst)
if (w->lastcheckpvs)
{
clust = w->worldmodel->funcs.ClusterForPoint(w->worldmodel, view);
clust = w->worldmodel->funcs.ClusterForPoint(w->worldmodel, view, NULL);
if ( (clust<0) || !(w->lastcheckpvs[clust>>3] & (1<<(clust&7)) ) )
{
return 0;
@ -6488,7 +6472,7 @@ void QCBUILTIN PF_sqlconnect (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
if (!driver[0])
driver = sql_driver.string;
G_FLOAT(OFS_RETURN) = SQL_NewServer(driver, paramstr);
G_FLOAT(OFS_RETURN) = SQL_NewServer(prinst, driver, paramstr);
}
void QCBUILTIN PF_sqldisconnect (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -6497,7 +6481,7 @@ void QCBUILTIN PF_sqldisconnect (pubprogfuncs_t *prinst, struct globalvars_s *pr
if (SQL_Available())
{
server = SQL_GetServer(G_FLOAT(OFS_PARM0), false);
server = SQL_GetServer(prinst, G_FLOAT(OFS_PARM0), false);
if (server)
{
SQL_Disconnect(server);
@ -6555,7 +6539,7 @@ void QCBUILTIN PF_sqlopenquery (pubprogfuncs_t *prinst, struct globalvars_s *pr_
if (SQL_Available())
{
server = SQL_GetServer(G_FLOAT(OFS_PARM0), false);
server = SQL_GetServer(prinst, G_FLOAT(OFS_PARM0), false);
if (server)
{
queryrequest_t *qreq;
@ -6597,7 +6581,7 @@ void QCBUILTIN PF_sqlclosequery (pubprogfuncs_t *prinst, struct globalvars_s *pr
if (SQL_Available())
{
server = SQL_GetServer(G_FLOAT(OFS_PARM0), false);
server = SQL_GetServer(prinst, G_FLOAT(OFS_PARM0), false);
if (server)
{
qreq = SQL_GetQueryRequest(server, G_FLOAT(OFS_PARM1));
@ -6621,7 +6605,7 @@ void QCBUILTIN PF_sqlreadfield (pubprogfuncs_t *prinst, struct globalvars_s *pr_
if (SQL_Available())
{
server = SQL_GetServer(G_FLOAT(OFS_PARM0), false);
server = SQL_GetServer(prinst, G_FLOAT(OFS_PARM0), false);
if (server)
{
qres = SQL_GetQueryResult(server, G_FLOAT(OFS_PARM1), G_FLOAT(OFS_PARM2));
@ -6653,7 +6637,7 @@ void QCBUILTIN PF_sqlreadfloat (pubprogfuncs_t *prinst, struct globalvars_s *pr_
if (SQL_Available())
{
server = SQL_GetServer(G_FLOAT(OFS_PARM0), false);
server = SQL_GetServer(prinst, G_FLOAT(OFS_PARM0), false);
if (server)
{
if (G_FLOAT(OFS_PARM2) < 0)
@ -6729,7 +6713,7 @@ void QCBUILTIN PF_sqlreadblob (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
if (SQL_Available())
{
server = SQL_GetServer(serveridx, false);
server = SQL_GetServer(prinst, serveridx, false);
if (server)
{
qres = SQL_GetQueryResult(server, queryidx, row);
@ -6791,7 +6775,7 @@ void QCBUILTIN PF_sqlerror (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
if (SQL_Available())
{
server = SQL_GetServer(G_FLOAT(OFS_PARM0), true);
server = SQL_GetServer(prinst, G_FLOAT(OFS_PARM0), true);
if (server)
{
if (svprogfuncs->callargc == 2)
@ -6825,7 +6809,7 @@ void QCBUILTIN PF_sqlescape (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
if (SQL_Available())
{
server = SQL_GetServer(G_FLOAT(OFS_PARM0), false);
server = SQL_GetServer(prinst, G_FLOAT(OFS_PARM0), false);
if (server)
{
toescape = PR_GetStringOfs(prinst, OFS_PARM1);
@ -6847,7 +6831,7 @@ void QCBUILTIN PF_sqlversion (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
if (SQL_Available())
{
server = SQL_GetServer(G_FLOAT(OFS_PARM0), false);
server = SQL_GetServer(prinst, G_FLOAT(OFS_PARM0), false);
if (server)
{
RETURN_TSTRING(SQL_Info(server));

View File

@ -28,7 +28,6 @@ void SVQ1_CvarChanged(cvar_t *var);
#define NewGetEdictFieldValue GetEdictFieldValue
void Q_SetProgsParms(qboolean forcompiler);
void PR_Deinit(void); //server shutting down
void PR_Shutdown(void); //server quitting
void PR_LoadGlabalStruct(qboolean muted);
void Q_InitProgs(qboolean cinematic);
void PR_SpawnInitialEntities(const char *file);

View File

@ -400,7 +400,9 @@ typedef enum {
BOTLIB_PC_LOAD_SOURCE,
BOTLIB_PC_FREE_SOURCE,
BOTLIB_PC_READ_TOKEN,
BOTLIB_PC_SOURCE_FILE_AND_LINE
BOTLIB_PC_SOURCE_FILE_AND_LINE,
G_DEFAULTCASEWARNINGDISABLE //note: not an allowed index, just exists to prevent clang from warning about the default case.
} q3ggameImport_t;

View File

@ -448,6 +448,23 @@ enum
#define STUFFCMD_BROADCAST ( 1<<2) // everyone sees it.
#define STUFFCMD_UNRELIABLE ( 1<<3) // someone might not see it. oh well.
enum serverprotocols_e
{
SCP_BAD, //don't send (a bot)
SCP_QUAKEWORLD,
SCP_QUAKE2,
SCP_QUAKE3,
//all the below are considered netquake clients.
SCP_NETQUAKE,
//bjp1, bjp2
SCP_BJP3, //16bit angles,model+sound indexes. nothing else (assume raised ent limits too).
SCP_FITZ666,
//dp5
SCP_DARKPLACES6,
SCP_DARKPLACES7 //extra prediction stuff
//note, nq is nq+
};
typedef struct client_s
{
client_conn_state_t state;
@ -660,21 +677,7 @@ typedef struct client_s
unsigned int max_net_clients; /*max number of player slots supported by the client */
unsigned int maxmodels; /*max models supported by whatever the protocol is*/
enum {
SCP_BAD, //don't send (a bot)
SCP_QUAKEWORLD,
SCP_QUAKE2,
SCP_QUAKE3,
//all the below are considered netquake clients.
SCP_NETQUAKE,
//bjp1, bjp2
SCP_BJP3, //16bit angles,model+sound indexes. nothing else (assume raised ent limits too).
SCP_FITZ666,
//dp5
SCP_DARKPLACES6,
SCP_DARKPLACES7 //extra prediction stuff
//note, nq is nq+
} protocol;
enum serverprotocols_e protocol;
unsigned int supportedprotocols;
qboolean proquake_angles_hack; //expect 16bit client->server angles .
@ -1145,7 +1148,29 @@ char *SV_PlayerPublicAddress(client_t *cl);
qboolean SVC_GetChallenge (qboolean respond_dp);
int SV_NewChallenge (void);
client_t *SVC_DirectConnect(void);
void SVC_DirectConnect(int expectedreliablesequence);
typedef struct
{
enum serverprotocols_e protocol; //protocol used to talk to this client.
#ifdef NQPROT
qboolean proquakeanglehack; //specifies that the client will expect proquake angles if we give a proquake CCREP_ACCEPT response.
unsigned int expectedreliablesequence; //required for nq connection cookies (like tcp's syn cookies).
unsigned int supportedprotocols; //1<<SCP_* bitmask
#endif
unsigned int ftepext1;
unsigned int ftepext2;
// unsigned int ezpext1;
int qport; //part of the qw protocol to avoid issues with buggy routers that periodically renumber cl2sv ports.
#ifdef HUFFNETWORK
int huffcrc; //network compression stuff
#endif
int challenge; //the challenge used at connect. remembered to make life harder for proxies.
int mtu; //allowed fragment size (also signifies that it supports fragmented qw packets)
char userinfo[2048]; //random userinfo data. no blobs, obviously.
char guid[128]; //user's guid data
netadr_t adr; //the address the connect request came from (so we can check passwords before accepting)
} svconnectinfo_t;
void SV_DoDirectConnect(svconnectinfo_t *fte_restrict info);
int SV_ModelIndex (const char *name);
@ -1213,13 +1238,15 @@ void MSV_SubServerCommand_f(void);
void MSV_SubServerCommand_f(void);
void MSV_MapCluster_f(void);
void SSV_Send(const char *dest, const char *src, const char *cmd, const char *msg);
qboolean MSV_ClusterLogin(char *guid, char *userinfo, size_t userinfosize);
qboolean MSV_ClusterLogin(svconnectinfo_t *info);
void MSV_PollSlaves(void);
void MSV_Status(void);
void MSV_OpenUserDatabase(void);
#else
#define SSV_UpdateAddresses() ((void)0)
#define MSV_ClusterLogin(guid,info,infosize) false
#define MSV_ClusterLogin(info) false
#define SSV_IsSubServer() false
#define MSV_OpenUserDatabase()
#endif
//

View File

@ -14,6 +14,24 @@
//FIXME: deadlocks when both gw and ss both fill their pipe buffers.
//FIXME: no networking for remote nodes.
//The servers are arranged as a 'tree'.
//There is only one root server, the one that used the 'mapcluster [startmap]' command.
// This is treated as a gateway, that clients connect to and then get redirected to one of the other servers.
// It may be a 'listen' server, with the server component offloaded to another process/thread.
// It may be a dedicated server started with the 'map' command (but not a listen server).
//Additional 'leaf' servers are automatically started on the same host.
// Will be started automatically when a player tries to transfer to a new/unknown map.
// leaf sends a ccmd_serveraddress at init+mapchanges
// root sends a ccmd_acceptserver to tell the new leaf what it should be.
//Transferring a player from one leaf to another:
// ccmd_transferplayer is sent to the root (which includes the player's parms)
// the root finds/creates the target server and sends it the ccmd_takeplayer message.
// destination tries to create a loadzombie and replies with ccmd_tookplayer (to accept or reject), which root forwards to the source
// source tells client to connect to the destination's address
// destination receives connection from client (or times out) and sends a ccmd_saveplayer(0) to the root, root sees the server change and sends ccmd_transferedplayer to the source.
// source knows that the player is no longer present (or aborts the transfer if it was a timeout, reenabling other transfers/retries).
#ifdef SUBSERVERS
#ifdef SQL
@ -22,7 +40,7 @@
extern cvar_t sv_serverip;
void VARGS SV_RejectMessage(int protocol, char *format, ...);
void VARGS SV_RejectMessage(enum serverprotocols_e protocol, char *format, ...);
void MSV_UpdatePlayerStats(unsigned int playerid, unsigned int serverid, int numstats, float *stats);
@ -43,7 +61,7 @@ typedef struct {
static pubsubserver_t *subservers;
static link_t clusterplayers;
qboolean isClusterSlave;
unsigned int nextserverid;
static unsigned int nextserverid;
static clusterplayer_t *MSV_FindPlayerId(unsigned int playerid)
{
@ -104,8 +122,8 @@ pubsubserver_t *MSV_FindSubServer(unsigned int id)
return NULL;
}
vfsfile_t *msv_loop_to_ss;
vfsfile_t *msv_loop_from_ss;
static vfsfile_t *msv_loop_to_ss;
static vfsfile_t *msv_loop_from_ss;
static void MSV_Loop_Instruct(pubsubserver_t *ps, sizebuf_t *cmd)
{
unsigned short size = cmd->cursize;
@ -289,7 +307,7 @@ void MSV_MapCluster_f(void)
};
Con_Printf("Opening database \"%s\"\n", sqlparams[3]);
sv.logindatabase = SQL_NewServer("sqlite", sqlparams);
sv.logindatabase = SQL_NewServer(&sv, "sqlite", sqlparams);
if (sv.logindatabase == -1)
#endif
{
@ -1097,7 +1115,7 @@ void SSV_InitiatePlayerTransfer(client_t *cl, const char *newserver)
#ifdef SQL
#include "sv_sql.h"
int pendinglookups = 0;
static int pendinglookups = 0;
struct logininfo_s
{
netadr_t clientaddr;
@ -1113,11 +1131,11 @@ void MSV_UpdatePlayerStats(unsigned int playerid, unsigned int serverid, int num
{
#ifdef SQL
queryrequest_t *req;
sqlserver_t *srv;
sqlserver_t *srv = SQL_GetServer(&sv, sv.logindatabase, false);
static char hex[16] = "0123456789abcdef";
char sql[2048], *sqle;
union{float *f;qbyte *b;} blob;
if (sv.logindatabase != -1)
if (srv)
{
Q_snprintfz(sql, sizeof(sql), "UPDATE accounts SET stats=x'");
sqle = sql+strlen(sql);
@ -1128,9 +1146,7 @@ void MSV_UpdatePlayerStats(unsigned int playerid, unsigned int serverid, int num
}
Q_snprintfz(sqle, sizeof(sql)-(sqle-sql), "', serverid=%u WHERE playerid = %u;", serverid, playerid);
srv = SQL_GetServer(sv.logindatabase, false);
if (srv)
SQL_NewQuery(srv, SV_IgnoreSQLResult, sql, &req);
SQL_NewQuery(srv, SV_IgnoreSQLResult, sql, &req);
}
#endif
}
@ -1199,81 +1215,121 @@ qboolean MSV_ClusterLoginReply(netadr_t *legacyclientredirect, unsigned int serv
#ifdef SQL
qboolean MSV_ClusterLoginSQLResult(queryrequest_t *req, int firstrow, int numrows, int numcols, qboolean eof)
{
sqlserver_t *sql = SQL_GetServer(req->srvid, true);
sqlserver_t *sql = SQL_GetServer(&sv, req->srvid, true);
queryresult_t *res = SQL_GetQueryResult(sql, req->num, 0);
struct logininfo_s *info = req->user.thread;
svconnectinfo_t *info = req->user.thread;
char *s;
int playerid, serverid;
char *statsblob;
size_t blobsize;
res = SQL_GetQueryResult(sql, req->num, 0);
if (!res)
//we only expect one row. if its a continuation then don't bug out
if (!firstrow)
{
playerid = 0;
statsblob = NULL;
blobsize = 0;
serverid = 0;
res = SQL_GetQueryResult(sql, req->num, 0);
if (!res)
{
playerid = 0;
statsblob = NULL;
blobsize = 0;
serverid = 0;
}
else
{
s = SQL_ReadField(sql, res, 0, 0, true, NULL);
playerid = atoi(s);
statsblob = SQL_ReadField(sql, res, 0, 2, true, &blobsize);
s = SQL_ReadField(sql, res, 0, 1, true, NULL);
serverid = s?atoi(s):0;
}
net_from = info->adr; //okay, that's a bit stupid, rewrite rejectmessage to accept an arg?
if (!playerid)
SV_RejectMessage(info->protocol, "Bad username or password.\n");
else if (sv.state == ss_clustermode)
MSV_ClusterLoginReply(NULL, serverid, playerid, Info_ValueForKey(info->userinfo, "name"), info->guid, &info->adr, statsblob, blobsize);
else
SV_DoDirectConnect(info);
Z_Free(info);
req->user.thread = NULL;
pendinglookups--;
}
else
{
s = SQL_ReadField(sql, res, 0, 0, true, NULL);
playerid = atoi(s);
statsblob = SQL_ReadField(sql, res, 0, 2, true, &blobsize);
s = SQL_ReadField(sql, res, 0, 1, true, NULL);
serverid = s?atoi(s):0;
}
net_from = info->clientaddr; //okay, that's a bit stupid, rewrite rejectmessage to accept an arg?
if (!playerid)
SV_RejectMessage(SCP_QUAKEWORLD, "Bad username or password.\n");
else
MSV_ClusterLoginReply(NULL, serverid, playerid, info->name, info->guid, &info->clientaddr, statsblob, blobsize);
Z_Free(info);
pendinglookups--;
return false;
}
#endif
qboolean MSV_IgnoreSQLResult(queryrequest_t *req, int firstrow, int numrows, int numcols, qboolean eof)
{
return false;
}
void MSV_OpenUserDatabase(void)
{
#if 0
sqlserver_t *sql;
const char *sqlparams[] =
{
"",
"",
"",
"login",
};
Con_Printf("Opening database \"%s\"\n", sqlparams[3]);
sv.logindatabase = SQL_NewServer(&sv, "sqlite", sqlparams);
//create a the accounts table, so we don't end up with unusable databases.
sql = SQL_GetServer(&sv, sv.logindatabase, false);
if (sql)
{
SQL_NewQuery(sql, MSV_IgnoreSQLResult,
"CREATE TABLE IF NOT EXISTS accounts("
"playerid INTEGER PRIMARY KEY,"
"name TEXT NOT NULL UNIQUE,"
"password TEXT,"
"serverid INTEGER,"
"parms BLOB,"
"parmstring TEXT"
");", NULL);
}
#endif
}
//returns true to block entry to this server.
extern int nextuserid;
qboolean MSV_ClusterLogin(char *guid, char *userinfo, size_t userinfosize)
qboolean MSV_ClusterLogin(svconnectinfo_t *info)
{
if (sv.state != ss_clustermode)
return false;
/*if (!*guid)
{
SV_RejectMessage(SCP_QUAKEWORLD, "No guid info, please set cl_sendguid to 1.\n");
return false;
}*/
#ifdef SQL
if (sv.logindatabase != -1)
{
char escname[64], escpasswd[64];
struct logininfo_s *info;
sqlserver_t *sql;
queryrequest_t *req;
if (pendinglookups > 10)
return true;
sql = SQL_GetServer(sv.logindatabase, false);
return true; //don't spam requests if we're getting dos-spammed.
sql = SQL_GetServer(&sv, sv.logindatabase, false);
if (!sql)
return true;
SQL_Escape(sql, Info_ValueForKey(userinfo, "name"), escname, sizeof(escname));
SQL_Escape(sql, Info_ValueForKey(userinfo, "password"), escpasswd, sizeof(escpasswd));
if (SQL_NewQuery(sql, MSV_ClusterLoginSQLResult, va("SELECT playerid,serverid,stats FROM accounts WHERE name='%s' AND password='%s';", escname, escpasswd), &req) != -1)
return true; //connection was killed? o.O
SQL_Escape(sql, Info_ValueForKey(info->userinfo, "name"), escname, sizeof(escname));
SQL_Escape(sql, Info_ValueForKey(info->userinfo, "password"), escpasswd, sizeof(escpasswd));
if (SQL_NewQuery(sql, MSV_ClusterLoginSQLResult, va("SELECT playerid,serverid,parms,parmstring FROM accounts WHERE name='%s' AND password='%s';", escname, escpasswd), &req) != -1)
{
pendinglookups++;
req->user.thread = info = Z_Malloc(sizeof(*info));
Q_strncpyz(info->guid, guid, sizeof(info->guid));
info->clientaddr = net_from;
req->user.thread = Z_Malloc(sizeof(*info));
memcpy(req->user.thread, info, sizeof(*info));
}
}
else
#endif
if (sv.state != ss_clustermode)
return false;
else
/* if (0)
{
char tmpbuf[256];
@ -1286,7 +1342,7 @@ qboolean MSV_ClusterLogin(char *guid, char *userinfo, size_t userinfosize)
return true;
}
else*/
MSV_ClusterLoginReply(NULL, 0, ++nextuserid, Info_ValueForKey(userinfo, "name"), guid, &net_from, NULL, 0);
MSV_ClusterLoginReply(NULL, 0, ++nextuserid, Info_ValueForKey(info->userinfo, "name"), info->guid, &net_from, NULL, 0);
return true;
}
#endif

View File

@ -33,6 +33,7 @@ typedef struct
int numents;
edict_t *ent[SV_PVS_CAMERAS]; //ents in this list are always sent, even if the server thinks that they are invisible.
vec3_t org[SV_PVS_CAMERAS];
int area[1+SV_PVS_CAMERAS];
pvsbuffer_t pvs;
} pvscamera_t;
@ -2695,7 +2696,7 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *
continue;
// ignore if not touching a PV leaf
if (cameras && !sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &ent->pvsinfo, cameras->pvs.buffer))
if (cameras && !sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &ent->pvsinfo, cameras->pvs.buffer, &cameras->numents))
continue;
if (!((int)clent->xv->dimension_see & ((int)ent->xv->dimension_seen | (int)ent->xv->dimension_ghost)))
@ -3690,13 +3691,13 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, pvscamera_t
}
else
{
if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &((wedict_t*)tracecullent)->pvsinfo, cameras->pvs.buffer))
if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &((wedict_t*)tracecullent)->pvsinfo, cameras->pvs.buffer, cameras->area))
continue;
}
}
else
{
if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &((wedict_t*)ent)->pvsinfo, cameras->pvs.buffer))
if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &((wedict_t*)ent)->pvsinfo, cameras->pvs.buffer, cameras->area))
continue;
tracecullent = ent;
}
@ -3710,14 +3711,14 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, pvscamera_t
{
//FIXME: this lookup should be cachable or something.
if (client->edict)
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, client->edict->v->origin);
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, client->edict->v->origin, NULL); //ignore areas, can hear through doors.
else
cluster = -1; //mvd
if (cluster >= 0)
{
mask = phs + cluster * 4*((sv.world.worldmodel->numclusters+31)>>5);
cluster = sv.world.worldmodel->funcs.ClusterForPoint (sv.world.worldmodel, ent->v->origin);
cluster = sv.world.worldmodel->funcs.ClusterForPoint (sv.world.worldmodel, ent->v->origin, NULL);
if (cluster >= 0 && !(mask[cluster>>3] & (1<<(cluster&7)) ) )
{
continue;
@ -3859,6 +3860,7 @@ void SV_AddCameraEntity(pvscamera_t *cameras, edict_t *ent, vec3_t viewofs)
{
int i;
vec3_t org;
int area;
for (i = 0; i < cameras->numents; i++)
{
@ -3871,6 +3873,17 @@ void SV_AddCameraEntity(pvscamera_t *cameras, edict_t *ent, vec3_t viewofs)
else
VectorCopy (ent->v->origin, org);
sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, org, &area);
for (i = 1; ; i++)
{
if (i > cameras->area[0])
{ //reached the end of the known count. add it now.
cameras->area[++cameras->area[0]] = area;
break;
}
if (cameras->area[i] == area)
break; //already have a camera in this area, don't make stuff slow with dupes.
}
sv.world.worldmodel->funcs.FatPVS(sv.world.worldmodel, org, &cameras->pvs, cameras->numents!=0);
if (cameras->numents < SV_PVS_CAMERAS)
{
@ -3882,6 +3895,7 @@ void SV_AddCameraEntity(pvscamera_t *cameras, edict_t *ent, vec3_t viewofs)
void SV_Snapshot_SetupPVS(client_t *client, pvscamera_t *camera)
{
camera->area[0] = 0;
camera->numents = 0;
for (; client; client = client->controlled)
{

View File

@ -20,6 +20,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
#include "pr_common.h"
#ifdef SQL
#include "sv_sql.h"
#endif
#ifndef CLIENTONLY
extern int total_loading_size, current_loading_size, loading_stage;
char *T_GetString(int num);
@ -798,6 +801,9 @@ void SV_WipeServerState(void)
for (i = 0; i < sizeof(sv.strings) / sizeof(sv.strings.ptrs[0]); i++)
Z_Free(ptrs[i]);
}
#ifdef SQL
SQL_KillServers(&sv);
#endif
memset (&sv, 0, sizeof(sv));
sv.logindatabase = -1;
}
@ -1103,6 +1109,8 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
sv.state = ss_loading;
MSV_OpenUserDatabase();
sv.world.max_edicts = pr_maxedicts.value;
if (sv.world.max_edicts > MAX_EDICTS)
sv.world.max_edicts = MAX_EDICTS;

File diff suppressed because it is too large Load Diff

View File

@ -781,7 +781,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
mask = NULL;
else
{
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, origin);
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, origin, NULL);
if (cluster >= 0)
mask = sv.world.worldmodel->phs + cluster*sv.world.worldmodel->pvsbytes;
else
@ -792,7 +792,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
case MULTICAST_PVS_R:
reliable = true; // intentional fallthrough
case MULTICAST_PVS:
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, origin);
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, origin, NULL);
if (cluster >= 0)
mask = sv.world.worldmodel->funcs.ClusterPVS(sv.world.worldmodel, cluster, NULL, PVM_FAST);
else
@ -877,7 +877,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
{
vec3_t pos;
VectorAdd(split->edict->v->origin, split->edict->v->view_ofs, pos);
cluster = sv.world.worldmodel->funcs.ClusterForPoint (sv.world.worldmodel, pos);
cluster = sv.world.worldmodel->funcs.ClusterForPoint (sv.world.worldmodel, pos, NULL);
if (cluster>= 0 && !(mask[cluster>>3] & (1<<(cluster&7)) ) )
{
// Con_Printf ("PVS supressed multicast\n");
@ -1042,7 +1042,7 @@ void SV_MulticastCB(vec3_t origin, multicast_t to, const char *reliableinfokey,
mask = NULL;
else
{
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, origin);
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, origin, NULL);
if (cluster >= 0)
mask = sv.world.worldmodel->phs + cluster * sv.world.worldmodel->pvsbytes;
else
@ -1053,7 +1053,7 @@ void SV_MulticastCB(vec3_t origin, multicast_t to, const char *reliableinfokey,
case MULTICAST_PVS_R:
reliable = true; // intentional fallthrough
case MULTICAST_PVS:
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, origin);
cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, origin, NULL);
if (cluster >= 0)
mask = sv.world.worldmodel->funcs.ClusterPVS(sv.world.worldmodel, cluster, NULL, PVM_FAST);
else
@ -1127,7 +1127,7 @@ void SV_MulticastCB(vec3_t origin, multicast_t to, const char *reliableinfokey,
{
vec3_t pos;
VectorAdd(split->edict->v->origin, split->edict->v->view_ofs, pos);
cluster = sv.world.worldmodel->funcs.ClusterForPoint (sv.world.worldmodel, pos);
cluster = sv.world.worldmodel->funcs.ClusterForPoint (sv.world.worldmodel, pos, NULL);
if (cluster>= 0 && !(mask[cluster>>3] & (1<<(cluster&7)) ) )
{
// Con_Printf ("PVS supressed multicast\n");

View File

@ -166,10 +166,14 @@ queryrequest_t *SQL_PullRequest(sqlserver_t *server, qboolean lock)
return qreq;
}
sqlserver_t **sqlservers;
int sqlservercount;
int sqlavailable;
int sqlinited;
struct
{
void *owner;
sqlserver_t *handle;
} *sqlservers;
static int sqlservercount;
static int sqlavailable;
static int sqlinited;
#ifdef USE_SQLITE
//this is to try to sandbox sqlite so it can only edit the file its originally opened with.
@ -506,15 +510,17 @@ int sql_serverworker(void *sref)
return 0;
}
sqlserver_t *SQL_GetServer (int serveridx, qboolean inactives)
sqlserver_t *SQL_GetServer (void *owner, int serveridx, qboolean inactives)
{
if (serveridx < 0 || serveridx >= sqlservercount)
return NULL;
if (!sqlservers[serveridx])
if (owner && sqlservers[serveridx].owner != owner)
return NULL;
if (!inactives && sqlservers[serveridx]->active == false)
if (!sqlservers[serveridx].handle)
return NULL;
return sqlservers[serveridx];
if (!inactives && sqlservers[serveridx].handle->active == false)
return NULL;
return sqlservers[serveridx].handle;
}
queryrequest_t *SQL_GetQueryRequest (sqlserver_t *server, int queryidx)
@ -801,7 +807,7 @@ void SQL_CleanupServer(sqlserver_t *server)
Z_Free(server);
}
int SQL_NewServer(const char *driver, const char **paramstr)
int SQL_NewServer(void *owner, const char *driver, const char **paramstr)
{
sqlserver_t *server;
int serverref;
@ -851,13 +857,13 @@ int SQL_NewServer(const char *driver, const char **paramstr)
{
serverref = 0;
sqlservercount = 1;
sqlservers = (sqlserver_t **)BZ_Malloc(sizeof(sqlserver_t *));
sqlservers = BZ_Malloc(sizeof(*sqlservers));
}
else
{
serverref = sqlservercount;
sqlservercount++;
sqlservers = (sqlserver_t **)BZ_Realloc(sqlservers, sizeof(sqlserver_t *) * sqlservercount);
sqlservers = BZ_Realloc(sqlservers, sizeof(*sqlservers) * sqlservercount);
}
// assemble server structure
@ -883,7 +889,8 @@ int SQL_NewServer(const char *driver, const char **paramstr)
// string should be null-terminated due to Z_Malloc
}
sqlservers[serverref] = server;
sqlservers[serverref].owner = owner;
sqlservers[serverref].handle = server;
server->driver = (sqldrv_t)drvchoice;
server->querynum = 1;
@ -944,11 +951,13 @@ int SQL_NewQuery(sqlserver_t *server, qboolean (*callback)(queryrequest_t *req,
SQL_PushRequest(server, qreq);
Sys_ConditionSignal(server->requestcondv);
*reqout = qreq;
if (reqout)
*reqout = qreq;
return querynum;
}
*reqout = NULL;
if (reqout)
*reqout = NULL;
return -1;
}
@ -1079,7 +1088,7 @@ void SQL_Status_f(void)
queryrequest_t *qreq;
queryresult_t *qres;
sqlserver_t *server = sqlservers[i];
sqlserver_t *server = sqlservers[i].handle;
if (!server)
continue;
@ -1168,7 +1177,7 @@ void SQL_Kill_f (void)
return;
}
server = SQL_GetServer(atoi(Cmd_Argv(1)), false);
server = SQL_GetServer(NULL, atoi(Cmd_Argv(1)), false);
if (server)
{
server->active = false;
@ -1179,7 +1188,7 @@ void SQL_Kill_f (void)
void SQL_Killall_f (void)
{
SQL_KillServers();
SQL_KillServers(NULL);
}
void SQL_ServerCycle (void)
@ -1188,7 +1197,7 @@ void SQL_ServerCycle (void)
for (i = 0; i < sqlservercount; i++)
{
sqlserver_t *server = sqlservers[i];
sqlserver_t *server = sqlservers[i].handle;
queryresult_t *qres;
queryrequest_t *qreq;
@ -1244,7 +1253,7 @@ void SQL_ServerCycle (void)
if (server->terminated)
{
sqlservers[i] = NULL;
sqlservers[i].handle = NULL;
SQL_CleanupServer(server);
continue;
}
@ -1294,28 +1303,36 @@ void SQL_Init(void)
Cvar_Register(&sql_defaultdb, SQLCVAROPTIONS);
}
void SQL_KillServers(void)
void SQL_KillServers(void *owner)
{
int i;
for (i = 0; i < sqlservercount; i++)
for (i = sqlservercount; i-- > 0; )
{
sqlserver_t *server = sqlservers[i];
sqlservers[i] = NULL;
if (!server)
continue;
SQL_CleanupServer(server);
if (!owner || sqlservers[i].owner == owner)
{
sqlserver_t *server = sqlservers[i].handle;
sqlservers[i].handle = NULL;
sqlservers[i].owner = NULL;
if (server)
SQL_CleanupServer(server);
if (sqlservercount == i+1)
sqlservercount--;
}
}
if (!sqlservercount)
{
if (sqlservers)
Z_Free(sqlservers);
sqlservers = NULL;
}
if (sqlservers)
Z_Free(sqlservers);
sqlservers = NULL;
sqlservercount = 0;
}
void SQL_DeInit(void)
{
sqlavailable = 0;
SQL_KillServers();
SQL_KillServers(NULL);
sqlinited = false;
#ifdef USE_MYSQL

View File

@ -95,10 +95,10 @@ typedef struct sqlserver_s
/* prototypes */
void SQL_Init(void);
void SQL_KillServers(void);
void SQL_KillServers(void *owner);
void SQL_DeInit(void);
sqlserver_t *SQL_GetServer (int serveridx, qboolean inactives);
sqlserver_t *SQL_GetServer (void *owner, int serveridx, qboolean inactives);
queryrequest_t *SQL_GetQueryRequest (sqlserver_t *server, int queryidx);
queryresult_t *SQL_GetQueryResult (sqlserver_t *server, int queryidx, int row);
//void SQL_DeallocResult(sqlserver_t *server, queryresult_t *qres);
@ -107,7 +107,7 @@ void SQL_CloseResult(sqlserver_t *server, queryresult_t *qres);
void SQL_CloseRequest(sqlserver_t *server, queryrequest_t *qres, qboolean force);
void SQL_CloseAllResults(sqlserver_t *server);
char *SQL_ReadField (sqlserver_t *server, queryresult_t *qres, int row, int col, qboolean fields, size_t *resultsize);
int SQL_NewServer(const char *driver, const char **paramstr);
int SQL_NewServer(void *owner, const char *driver, const char **paramstr);
int SQL_NewQuery(sqlserver_t *server, qboolean (*callback)(queryrequest_t *req, int firstrow, int numrows, int numcols, qboolean eof), const char *str, queryrequest_t **reqout); //callback will be called on the main thread once the result is back
void SQL_Disconnect(sqlserver_t *server);
void SQL_Escape(sqlserver_t *server, const char *src, char *dst, int dstlen);

View File

@ -723,14 +723,6 @@ static qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_
maxs1[0] >= mins2[0] && maxs1[1] >= mins2[1] && maxs1[2] >= mins2[2]);
}
typedef struct {
int serverTime;
int angles[3];
int buttons;
qbyte weapon; // weapon
signed char forwardmove, rightmove, upmove;
} q3usercmd_t;
#define CMD_MASK Q3UPDATE_MASK
static qboolean SVQ3_GetUserCmd(int clientnumber, q3usercmd_t *ucmd)
{
usercmd_t *cmd;
@ -768,7 +760,7 @@ void SVQ3_SendServerCommand(client_t *cl, char *str)
}
cl->server_command_sequence++;
Q_strncpyz(cl->server_commands[cl->server_command_sequence & TEXTCMD_MASK], str, sizeof(cl->server_commands[0]));
Q_strncpyz(cl->server_commands[cl->server_command_sequence & Q3TEXTCMD_MASK], str, sizeof(cl->server_commands[0]));
}
void SVQ3_SendConfigString(client_t *dest, int num, char *string)
@ -839,7 +831,7 @@ static int SVQ3_BotGetConsoleMessage( int client, char *buf, int size )
return false;
cl->server_command_ack++;
index = cl->server_command_ack & TEXTCMD_MASK;
index = cl->server_command_ack & Q3TEXTCMD_MASK;
if ( !cl->server_commands[index][0] )
return false;
@ -861,11 +853,55 @@ static void SVQ3_Adjust_Area_Portal_State(q3sharedEntity_t *ge, qboolean open)
CMQ3_SetAreaPortalState(sv.world.worldmodel, se->areanum, se->areanum2, open);
}
static qboolean SV_InPVS(vec3_t p1, vec3_t p2)
{
model_t *worldmodel = sv.world.worldmodel;
if (!worldmodel || worldmodel->loadstate != MLS_LOADED)
return false; //still loading, don't give bad results.
else if (!worldmodel->funcs.FatPVS)
return true; //no pvs info, assume everything is visible
else
{
#if 1
int l1 = CM_PointLeafnum(worldmodel, p1);
int l2 = CM_PointLeafnum(worldmodel, p2);
int c1 = CM_LeafCluster(worldmodel, l1);
int c2 = CM_LeafCluster(worldmodel, l2);
qbyte *pvs;
if (c1 < 0 || c2 < 0)
return (c1<0); //outside can see in, inside cannot (normally) see out.
pvs = CM_ClusterPVS(worldmodel, c1, NULL, PVM_FAST);
if (pvs[c2>>3] & (1<<(c2&7)))
{
int a1 = CM_LeafArea(worldmodel, l1);
int a2 = CM_LeafArea(worldmodel, l2);
if (CM_AreasConnected(worldmodel, a1, a2))
return true;
}
return false;
#else
const qbyte *mask;
int c1 = worldmodel->funcs.ClusterForPoint(worldmodel, p1);
int c2 = worldmodel->funcs.ClusterForPoint(worldmodel, p2);
if (c1 < 0 || c2 < 0)
return true; //one is outside of the world, so can see inside.
mask = worldmodel->funcs.ClusterPVS(worldmodel, c1, NULL, PVM_FAST);
if (mask[c2>>3] & (1<<(c2&7)))
{
//FIXME: check areas/portals too
return true; //visible
}
return false; //nope. :(
#endif
}
}
#define VALIDATEPOINTER(o,l) if ((int)o + l >= mask || VM_POINTER(o) < offset) SV_Error("Call to game trap %u passes invalid pointer\n", (unsigned int)fn); //out of bounds.
static qintptr_t Q3G_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, const qintptr_t *arg)
{
int ret = 0;
switch(fn)
switch((q3ggameImport_t)fn)
{
case G_PRINT: // ( const char *string );
Con_Printf("%s", (char*)VM_POINTER(arg[0]));
@ -946,16 +982,17 @@ static qintptr_t Q3G_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, co
case G_FS_FOPEN_FILE: //fopen
if ((int)arg[1] + 4 >= mask || VM_POINTER(arg[1]) < offset)
break; //out of bounds.
VM_LONG(ret) = VM_fopen(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 0);
ret = VM_fopen(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]), 0);
break;
case G_FS_READ: //fread
if ((int)arg[0] + VM_LONG(arg[1]) >= mask || VM_POINTER(arg[0]) < offset)
break; //out of bounds.
VM_FRead(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), 0);
ret = VM_FRead(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), 0);
break;
case G_FS_WRITE: //fwrite
ret = VM_FWrite(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), 0);
break;
case G_FS_FCLOSE_FILE: //fclose
VM_fclose(VM_LONG(arg[0]), 0);
@ -1081,8 +1118,8 @@ static qintptr_t Q3G_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, co
return !!mapentspointer;
case G_REAL_TIME: // 41
VM_FLOAT(ret) = realtime;
return ret;
VALIDATEPOINTER(arg[0], sizeof(q3time_t));
return Q3VM_GetRealtime(VM_POINTER(arg[0]));
case G_SNAPVECTOR:
{
float *fp = (float *)VM_POINTER( arg[0] );
@ -1566,9 +1603,30 @@ static qintptr_t Q3G_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, co
#endif
case G_IN_PVS:
return SV_InPVS(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
case G_AREAS_CONNECTED: Con_Printf("Q3Game: builtin %s is not implemented\n", "G_AREAS_CONNECTED"); return ret;
case G_DEBUG_POLYGON_CREATE: Con_Printf("Q3Game: builtin %s is not implemented\n", "G_DEBUG_POLYGON_CREATE"); return ret;
case G_DEBUG_POLYGON_DELETE: Con_Printf("Q3Game: builtin %s is not implemented\n", "G_DEBUG_POLYGON_DELETE"); return ret;
case G_IN_PVS_IGNORE_PORTALS: Con_Printf("Q3Game: builtin %s is not implemented\n", "G_IN_PVS_IGNORE_PORTALS"); return ret;
case G_MATRIXMULTIPLY: Con_Printf("Q3Game: builtin %s is not implemented\n", "G_MATRIXMULTIPLY"); return ret;
case G_ANGLEVECTORS:
VALIDATEPOINTER(arg[1], sizeof(vec3_t));
VALIDATEPOINTER(arg[2], sizeof(vec3_t));
VALIDATEPOINTER(arg[3], sizeof(vec3_t));
AngleVectors(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_POINTER(arg[3]));
break;
case G_PERPENDICULARVECTOR: Con_Printf("Q3Game: builtin %s is not implemented\n", "G_PERPENDICULARVECTOR"); return ret;
VALIDATEPOINTER(arg[1], sizeof(vec3_t));
PerpendicularVector(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
break;
case G_FS_SEEK: Con_Printf("Q3Game: builtin %s is not implemented\n", "G_FS_SEEK"); return ret;
return VM_FSeek(arg[0], arg[1], arg[2], 0);
//case G_DEFAULTCASEWARNINGDISABLE: NOT A REAL VALUE
// notimplemented:
default:
Con_Printf("builtin %i is not implemented\n", (int)fn);
Con_Printf("Q3Game: builtin %i is not known\n", (int)fn);
}
return ret;
}
@ -2709,7 +2767,7 @@ static void SVQ3_WriteServerCommandsToClient(client_t *client, sizebuf_t *msg)
{
MSG_WriteBits(msg, svcq3_serverCommand, 8);
MSG_WriteBits(msg, i, 32);
str = client->server_commands[i & TEXTCMD_MASK];
str = client->server_commands[i & Q3TEXTCMD_MASK];
len = strlen(str);
for (j = 0; j <= len; j++)
MSG_WriteBits(msg, str[j], 8);
@ -2905,7 +2963,7 @@ static qboolean SVQ3_Netchan_Process(client_t *client)
// calculate bitmask
bitmask = (serverid ^ lastSequence ^ client->challenge) & 0xff;
string = client->server_commands[lastServerCommandNum & TEXTCMD_MASK];
string = client->server_commands[lastServerCommandNum & Q3TEXTCMD_MASK];
#ifndef Q3_NOENCRYPT
// decrypt the packet
@ -3003,7 +3061,7 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta)
return; // was dropped
// calculate key for usercmd decryption
string = client->server_commands[client->server_command_ack & TEXTCMD_MASK];
string = client->server_commands[client->server_command_ack & Q3TEXTCMD_MASK];
key = client->last_sequence ^ fs_key ^ StringKey(string, 32);
// read delta sequenced usercmds
@ -3219,8 +3277,8 @@ void SVQ3_ParseClientMessage(client_t *client)
// read last server command number client received
client->server_command_ack = MSG_ReadBits(32);
if( client->server_command_ack <= client->server_command_sequence - TEXTCMD_BACKUP )
client->server_command_ack = client->server_command_sequence - TEXTCMD_BACKUP + 1; //too old
if( client->server_command_ack <= client->server_command_sequence - Q3TEXTCMD_BACKUP )
client->server_command_ack = client->server_command_sequence - Q3TEXTCMD_BACKUP + 1; //too old
else if( client->server_command_ack > client->server_command_sequence )
client->server_command_ack = client->server_command_sequence; //client is from the future? o.O make fatal?
@ -3341,8 +3399,11 @@ void SVQ3_NewMapConnects(void)
if (svs.clients[i].state < cs_connected)
continue;
ret = VM_Call(q3gamevm, GAME_CLIENT_CONNECT, i, false, svs.clients[i].protocol == SCP_BAD);
if (ret || (gametype->value == 2 && svs.clients[i].protocol == SCP_BAD))
if (gametype->value == 2 && svs.clients[i].protocol == SCP_BAD)
ret = true;
else
ret = VM_Call(q3gamevm, GAME_CLIENT_CONNECT, i, false, svs.clients[i].protocol == SCP_BAD);
if (ret)
{
SV_DropClient(&svs.clients[i]);
}
@ -3461,6 +3522,7 @@ int SVQ3_AddBot(void)
cl->state = cs_spawned;
memset(&cl->netchan.remote_address, 0, sizeof(cl->netchan.remote_address));
GENTITY_FOR_NUM(cl-svs.clients)->s.number = cl-svs.clients;
return cl - svs.clients;
}

View File

@ -138,7 +138,7 @@ qboolean World_BoxTrace(struct model_s *model, int hulloverride, int frame, vec3
VectorCopy (p2, trace->endpos);
return Q1BSP_RecursiveHullCheck (hull, hull->firstclipnode, p1, p2, against, trace);
}
qboolean World_CapsuleTrace(struct model_s *model, int hulloverride, framestate_t *framestate, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace)
qboolean World_CapsuleTrace(struct model_s *model, int hulloverride, const framestate_t *framestate, const vec3_t axis[3], const vec3_t p1, const vec3_t p2, const vec3_t mins, const vec3_t maxs, qboolean capsule, unsigned int against, struct trace_s *trace)
{
//bbox vs capsule (NYI)
//capsule vs capsule (NYI)
@ -196,7 +196,7 @@ qboolean World_CapsuleTrace(struct model_s *model, int hulloverride, framestate_
}
return false;
}
model_t *World_CapsuleForBox(vec3_t mins, vec3_t maxs)
model_t *World_CapsuleForBox(const vec3_t mins, const vec3_t maxs)
{
VectorCopy(mins, mod_capsule.mins);
VectorCopy(maxs, mod_capsule.maxs);
@ -1068,7 +1068,7 @@ void WorldQ2_Q1BSP_LinkEdict(world_t *w, q2edict_t *ent)
#if defined(Q2BSPS) || defined(Q3BSPS)
void Q23BSP_FindTouchedLeafs(model_t *model, struct pvscache_s *ent, float *mins, float *maxs)
void Q23BSP_FindTouchedLeafs(model_t *model, struct pvscache_s *ent, const float *mins, const float *maxs)
{
#define MAX_TOTAL_ENT_LEAFS 128
int leafs[MAX_TOTAL_ENT_LEAFS];
@ -1536,7 +1536,7 @@ int World_AreaEdicts (world_t *w, vec3_t mins, vec3_t maxs, wedict_t **list, int
#endif
#ifdef Q2SERVER
float *area_mins, *area_maxs;
const float *area_mins, *area_maxs;
q2edict_t **area_q2list;
int area_count, area_maxcount;
int area_type;
@ -1598,7 +1598,7 @@ static void WorldQ2_AreaEdicts_r (areanode_t *node)
WorldQ2_AreaEdicts_r ( node->children[1] );
}
int VARGS WorldQ2_AreaEdicts (world_t *w, vec3_t mins, vec3_t maxs, q2edict_t **list,
int VARGS WorldQ2_AreaEdicts (world_t *w, const vec3_t mins, const vec3_t maxs, q2edict_t **list,
int maxcount, int areatype)
{
area_mins = mins;

View File

@ -5478,7 +5478,7 @@ static void R_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist
d += 0.1; //an epsilon on the far side
VectorMA(point, d, plane.normal, point);
clust = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, point);
clust = cl.worldmodel->funcs.ClusterForPoint(cl.worldmodel, point, NULL);
if (i == batch->firstmesh)
r_refdef.forcedvis = cl.worldmodel->funcs.ClusterPVS(cl.worldmodel, clust, &newvis, PVM_REPLACE);
else
@ -5790,10 +5790,10 @@ void VKBE_SubmitMeshes (batch_t **worldbatches, batch_t **blist, int first, int
#ifdef RTLIGHTS
//FIXME: needs context for threading
void VKBE_BaseEntTextures(qbyte *scenepvs)
void VKBE_BaseEntTextures(const qbyte *scenepvs, const int *sceneareas)
{
batch_t *batches[SHADER_SORT_COUNT];
BE_GenModelBatches(batches, shaderstate.curdlight, shaderstate.mode, scenepvs);
BE_GenModelBatches(batches, shaderstate.curdlight, shaderstate.mode, scenepvs, sceneareas);
VKBE_SubmitMeshes(NULL, batches, SHADER_SORT_PORTAL, SHADER_SORT_SEETHROUGH+1);
VKBE_SelectEntity(&r_worldentity);
}
@ -6245,7 +6245,7 @@ void VKBE_DrawWorld (batch_t **worldbatches)
shaderstate.curdlight = NULL;
//fixme: figure out some way to safely orphan this data so that we can throw the rest to a worker.
BE_GenModelBatches(batches, shaderstate.curdlight, BEM_STANDARD, r_refdef.scenevis);
BE_GenModelBatches(batches, shaderstate.curdlight, BEM_STANDARD, r_refdef.scenevis, r_refdef.sceneareas);
BE_UploadLightmaps(false);
if (r_refdef.scenevis)

View File

@ -465,7 +465,7 @@ void VKBE_VBO_Data(vbobctx_t *ctx, void *data, size_t size, vboarray_t *varray);
void VKBE_VBO_Finish(vbobctx_t *ctx, void *edata, size_t esize, vboarray_t *earray, void **vbomem, void **ebomem);
void VKBE_VBO_Destroy(vboarray_t *vearray, void *mem);
void VKBE_Scissor(srect_t *rect);
void VKBE_BaseEntTextures(qbyte *scenepvs);
void VKBE_BaseEntTextures(const qbyte *scenepvs, const int *sceneareas);
struct vk_shadowbuffer;
struct vk_shadowbuffer *VKBE_GenerateShadowBuffer(vecV_t *verts, int numverts, index_t *indicies, int numindicies, qboolean istemp);