Optimised the textures of defaultwall with fast preset.
Fix simpleitems transparency in gles2. Fix a couple of GL errors in gles2 (including some fixed function stuff that could result in segfaults). Dynamically adjust MTU values with legacy qw clients too. Added some small sleeps while waiting for downloads (this fixes insanely slow valgrind startups but might make non-valgrind start a smidge slower). Fix title metadata in the updates system. Clean up some issues for when WEBCLIENT is not defined. HAVE_HTTPSV also disables websocket connections, to completely avoid any http strings anywhere, in the hope that it reduces virus scanner false positives. Fix presets initial option, again. Writing files to FS_GAMEONLY no longer purges the entire fscache, which should give a speedup in certain situations. Added some new cvars to control heightmap lightmap generation. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5461 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
b3050121cf
commit
3c5518afa8
41 changed files with 735 additions and 279 deletions
|
@ -4195,7 +4195,7 @@ void CL_LinkPacketEntities (void)
|
||||||
Q_snprintfz(name, sizeof(name), "textures/bmodels/simple_%s_%i.tga", basename, ent->skinnum);
|
Q_snprintfz(name, sizeof(name), "textures/bmodels/simple_%s_%i.tga", basename, ent->skinnum);
|
||||||
else
|
else
|
||||||
Q_snprintfz(name, sizeof(name), "textures/models/simple_%s_%i.tga", basename, ent->skinnum);
|
Q_snprintfz(name, sizeof(name), "textures/models/simple_%s_%i.tga", basename, ent->skinnum);
|
||||||
model->simpleskin[ent->skinnum] = R_RegisterShader(name, 0, va("{\nnomipmaps\nprogram defaultsprite\nsurfaceparm noshadows\nsurfaceparm nodlight\nsort seethrough\n{\nmap \"%s\"\nalphafunc ge128\n}\n}\n", name));
|
model->simpleskin[ent->skinnum] = R_RegisterShader(name, 0, va("{\nnomipmaps\nprogram defaultsprite#MASK=0.5\nsurfaceparm noshadows\nsurfaceparm nodlight\nsort seethrough\n{\nmap \"%s\"\nalphafunc ge128\n}\n}\n", name));
|
||||||
}
|
}
|
||||||
VectorCopy(le->angles, angles);
|
VectorCopy(le->angles, angles);
|
||||||
|
|
||||||
|
|
|
@ -3493,9 +3493,14 @@ client_connect: //fixme: make function
|
||||||
if (cls.protocol_q2 == PROTOCOL_VERSION_R1Q2 || cls.protocol_q2 == PROTOCOL_VERSION_Q2PRO)
|
if (cls.protocol_q2 == PROTOCOL_VERSION_R1Q2 || cls.protocol_q2 == PROTOCOL_VERSION_Q2PRO)
|
||||||
cls.netchan.qportsize = 1;
|
cls.netchan.qportsize = 1;
|
||||||
}
|
}
|
||||||
cls.netchan.fragmentsize = connectinfo.mtu;
|
cls.netchan.pext_fragmentation = connectinfo.mtu?true:false;
|
||||||
if (connectinfo.mtu >= 64)
|
if (connectinfo.mtu >= 64)
|
||||||
|
{
|
||||||
|
cls.netchan.mtu = connectinfo.mtu;
|
||||||
cls.netchan.message.maxsize = sizeof(cls.netchan.message_buf);
|
cls.netchan.message.maxsize = sizeof(cls.netchan.message_buf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cls.netchan.mtu = MAX_QWMSGLEN;
|
||||||
#ifdef HUFFNETWORK
|
#ifdef HUFFNETWORK
|
||||||
cls.netchan.compresstable = Huff_CompressionCRC(connectinfo.compresscrc);
|
cls.netchan.compresstable = Huff_CompressionCRC(connectinfo.compresscrc);
|
||||||
#else
|
#else
|
||||||
|
@ -6396,7 +6401,12 @@ void Host_FinishLoading(void)
|
||||||
FS_ChangeGame(NULL, true, true);
|
FS_ChangeGame(NULL, true, true);
|
||||||
|
|
||||||
if (waitingformanifest)
|
if (waitingformanifest)
|
||||||
|
{
|
||||||
|
#ifdef MULTITHREAD
|
||||||
|
Sys_Sleep(0.1);
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Con_History_Load();
|
Con_History_Load();
|
||||||
|
|
||||||
|
@ -6437,7 +6447,12 @@ void Host_FinishLoading(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PM_IsApplying(true))
|
if (PM_IsApplying(true))
|
||||||
|
{
|
||||||
|
#ifdef MULTITHREAD
|
||||||
|
Sys_Sleep(0.1);
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//android may find that it has no renderer at various points.
|
//android may find that it has no renderer at various points.
|
||||||
if (r_forceheadless)
|
if (r_forceheadless)
|
||||||
|
|
|
@ -1390,6 +1390,15 @@ static void PM_MarkPackage(package_t *package, unsigned int markflag)
|
||||||
return; //looks like its already picked. marking it again will do no harm.
|
return; //looks like its already picked. marking it again will do no harm.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WEBCLIENT
|
||||||
|
//can't mark for download if we cannot download.
|
||||||
|
if (!(package->flags & DPF_PRESENT))
|
||||||
|
{ //though we can at least unmark it for deletion...
|
||||||
|
package->flags &= ~DPF_PURGE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//any file-conflicts prevent the package from being installable.
|
//any file-conflicts prevent the package from being installable.
|
||||||
//this is mostly for pak1.pak
|
//this is mostly for pak1.pak
|
||||||
for (dep = package->deps; dep; dep = dep->next)
|
for (dep = package->deps; dep; dep = dep->next)
|
||||||
|
@ -1881,7 +1890,7 @@ static void PM_WriteInstalledPackages(void)
|
||||||
if (*p->title && strcmp(p->title, p->name))
|
if (*p->title && strcmp(p->title, p->name))
|
||||||
{
|
{
|
||||||
Q_strncatz(buf, " ", sizeof(buf));
|
Q_strncatz(buf, " ", sizeof(buf));
|
||||||
COM_QuotedConcat(va("title=%s", p->version), buf, sizeof(buf));
|
COM_QuotedConcat(va("title=%s", p->title), buf, sizeof(buf));
|
||||||
}
|
}
|
||||||
if (*p->version)
|
if (*p->version)
|
||||||
{
|
{
|
||||||
|
@ -2745,7 +2754,6 @@ qboolean PM_CanInstall(const char *packagename)
|
||||||
|
|
||||||
void PM_Command_f(void)
|
void PM_Command_f(void)
|
||||||
{
|
{
|
||||||
size_t i;
|
|
||||||
package_t *p;
|
package_t *p;
|
||||||
const char *act = Cmd_Argv(1);
|
const char *act = Cmd_Argv(1);
|
||||||
const char *key;
|
const char *key;
|
||||||
|
@ -2878,6 +2886,7 @@ void PM_Command_f(void)
|
||||||
}
|
}
|
||||||
Con_Printf("<end of list>\n");
|
Con_Printf("<end of list>\n");
|
||||||
}
|
}
|
||||||
|
#ifdef WEBCLIENT
|
||||||
else if (!strcmp(act, "sources") || !strcmp(act, "addsource"))
|
else if (!strcmp(act, "sources") || !strcmp(act, "addsource"))
|
||||||
{
|
{
|
||||||
if (Cmd_Argc() == 2)
|
if (Cmd_Argc() == 2)
|
||||||
|
@ -2890,6 +2899,7 @@ void PM_Command_f(void)
|
||||||
else
|
else
|
||||||
PM_AddSubList(Cmd_Argv(2), "", true, true);
|
PM_AddSubList(Cmd_Argv(2), "", true, true);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if (!strcmp(act, "remsource"))
|
else if (!strcmp(act, "remsource"))
|
||||||
PM_RemSubList(Cmd_Argv(2));
|
PM_RemSubList(Cmd_Argv(2));
|
||||||
else if (!strcmp(act, "apply"))
|
else if (!strcmp(act, "apply"))
|
||||||
|
@ -2908,8 +2918,10 @@ void PM_Command_f(void)
|
||||||
{
|
{
|
||||||
PM_RevertChanges();
|
PM_RevertChanges();
|
||||||
}
|
}
|
||||||
|
#ifdef WEBCLIENT
|
||||||
else if (!strcmp(act, "update"))
|
else if (!strcmp(act, "update"))
|
||||||
{ //flush package cache, make a new request.
|
{ //flush package cache, make a new request.
|
||||||
|
int i;
|
||||||
for (i = 0; i < numdownloadablelists; i++)
|
for (i = 0; i < numdownloadablelists; i++)
|
||||||
downloadablelist[i].received = 0;
|
downloadablelist[i].received = 0;
|
||||||
}
|
}
|
||||||
|
@ -2924,6 +2936,7 @@ void PM_Command_f(void)
|
||||||
else
|
else
|
||||||
Con_Printf("Already using latest versions of all packages\n");
|
Con_Printf("Already using latest versions of all packages\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if (!strcmp(act, "add") || !strcmp(act, "get") || !strcmp(act, "install") || !strcmp(act, "enable"))
|
else if (!strcmp(act, "add") || !strcmp(act, "get") || !strcmp(act, "install") || !strcmp(act, "enable"))
|
||||||
{ //FIXME: make sure this updates.
|
{ //FIXME: make sure this updates.
|
||||||
int arg = 2;
|
int arg = 2;
|
||||||
|
@ -2938,6 +2951,7 @@ void PM_Command_f(void)
|
||||||
}
|
}
|
||||||
PM_PrintChanges();
|
PM_PrintChanges();
|
||||||
}
|
}
|
||||||
|
#ifdef WEBCLIENT
|
||||||
else if (!strcmp(act, "reinstall"))
|
else if (!strcmp(act, "reinstall"))
|
||||||
{ //fixme: favour the current verson.
|
{ //fixme: favour the current verson.
|
||||||
int arg = 2;
|
int arg = 2;
|
||||||
|
@ -2955,6 +2969,7 @@ void PM_Command_f(void)
|
||||||
}
|
}
|
||||||
PM_PrintChanges();
|
PM_PrintChanges();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if (!strcmp(act, "disable") || !strcmp(act, "rem") || !strcmp(act, "remove"))
|
else if (!strcmp(act, "disable") || !strcmp(act, "rem") || !strcmp(act, "remove"))
|
||||||
{
|
{
|
||||||
int arg = 2;
|
int arg = 2;
|
||||||
|
@ -3234,9 +3249,11 @@ static qboolean MD_Key (struct menucustom_s *c, struct menu_s *m, int key, unsig
|
||||||
case DPF_USERMARKED:
|
case DPF_USERMARKED:
|
||||||
case DPF_MARKED:
|
case DPF_MARKED:
|
||||||
p->flags |= DPF_PURGE;
|
p->flags |= DPF_PURGE;
|
||||||
|
#ifdef WEBCLIENT
|
||||||
//now: re-get despite already having it.
|
//now: re-get despite already having it.
|
||||||
if ((p->flags & DPF_CORRUPT) || ((p->flags & DPF_PRESENT) && !PM_PurgeOnDisable(p)))
|
if ((p->flags & DPF_CORRUPT) || ((p->flags & DPF_PRESENT) && !PM_PurgeOnDisable(p)))
|
||||||
break; //only makes sense if we already have a cached copy that we're not going to use.
|
break; //only makes sense if we already have a cached copy that we're not going to use.
|
||||||
|
#endif
|
||||||
//fallthrough
|
//fallthrough
|
||||||
case DPF_USERMARKED|DPF_PURGE:
|
case DPF_USERMARKED|DPF_PURGE:
|
||||||
case DPF_AUTOMARKED|DPF_PURGE:
|
case DPF_AUTOMARKED|DPF_PURGE:
|
||||||
|
@ -3444,10 +3461,13 @@ static void MD_Download_UpdateStatus(struct menu_s *m)
|
||||||
dlmenu_t *info = m->data;
|
dlmenu_t *info = m->data;
|
||||||
int i, y;
|
int i, y;
|
||||||
package_t *p;
|
package_t *p;
|
||||||
unsigned int totalpackages=0, selectedpackages=0, addpackages=0, rempackages=0, downloads=0;
|
unsigned int totalpackages=0, selectedpackages=0, addpackages=0, rempackages=0;
|
||||||
menuoption_t *si;
|
menuoption_t *si;
|
||||||
menubutton_t *b, *d;
|
menubutton_t *b, *d;
|
||||||
|
#ifdef WEBCLIENT
|
||||||
|
unsigned int downloads=0;
|
||||||
menucustom_t *c;
|
menucustom_t *c;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (info->downloadablessequence != downloadablessequence || !info->populated)
|
if (info->downloadablessequence != downloadablessequence || !info->populated)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1062,6 +1062,7 @@ void M_Menu_Preset_f (void)
|
||||||
item = 6; //fast
|
item = 6; //fast
|
||||||
else
|
else
|
||||||
item = 7; //simple
|
item = 7; //simple
|
||||||
|
item++; //the autosave option
|
||||||
item -= bias;
|
item -= bias;
|
||||||
while (item --> 0)
|
while (item --> 0)
|
||||||
menu->selecteditem = menu->selecteditem->common.next;
|
menu->selecteditem = menu->selecteditem->common.next;
|
||||||
|
|
|
@ -306,15 +306,15 @@ static void S_Info(void);
|
||||||
|
|
||||||
static void S_Shutdown_f(void);
|
static void S_Shutdown_f(void);
|
||||||
*/
|
*/
|
||||||
static cvar_t s_al_debug = CVAR("s_al_debug", "0");
|
static cvar_t s_al_debug = CVARD("s_al_debug", "0", "Enables periodic checks for OpenAL errors.");
|
||||||
static cvar_t s_al_use_reverb = CVAR("s_al_use_reverb", "1");
|
static cvar_t s_al_use_reverb = CVARD("s_al_use_reverb", "1", "Controls whether reverb effects will be used. Set to 0 to block them. Reverb requires gamecode to configure the reverb properties, other than underwater.");
|
||||||
static cvar_t s_al_max_distance = CVARFC("s_al_max_distance", "1000",0,OnChangeALSettings);
|
static cvar_t s_al_max_distance = CVARFC("s_al_max_distance", "1000",0,OnChangeALSettings);
|
||||||
static cvar_t s_al_speedofsound = CVARFC("s_al_speedofsound", "343.3",0,OnChangeALSettings);
|
static cvar_t s_al_speedofsound = CVARFCD("s_al_speedofsound", "343.3",0,OnChangeALSettings, "Configures the speed of sound, in game units per second. This affects doppler.");
|
||||||
static cvar_t s_al_dopplerfactor = CVARFC("s_al_dopplerfactor", "1.0",0,OnChangeALSettings);
|
static cvar_t s_al_dopplerfactor = CVARFCD("s_al_dopplerfactor", "1.0",0,OnChangeALSettings, "Multiplies the strength of doppler effects.");
|
||||||
static cvar_t s_al_distancemodel = CVARFC("s_al_distancemodel", "2",0,OnChangeALSettings);
|
static cvar_t s_al_distancemodel = CVARFCD("s_al_distancemodel", legacyval("2","0"),0,OnChangeALSettings, "Controls how sounds fade with distance.\n0: Inverse (most realistic)\n1: Inverse Clamped\n2: Linear (Quake-like)\n3: Linear Clamped\n4: Exponential\n5: Exponential Clamped\n6: None");
|
||||||
static cvar_t s_al_rolloff_factor = CVAR("s_al_rolloff_factor", "1");
|
//static cvar_t s_al_rolloff_factor = CVAR("s_al_rolloff_factor", "1");
|
||||||
static cvar_t s_al_reference_distance = CVAR("s_al_reference_distance", "120");
|
static cvar_t s_al_reference_distance = CVARD("s_al_reference_distance", "120", "This is the distance at which the sound is audiable with standard volume in the inverse distance models. Nearer sounds will be louder than the original sample.");
|
||||||
static cvar_t s_al_velocityscale = CVAR("s_al_velocityscale", "1");
|
static cvar_t s_al_velocityscale = CVARD("s_al_velocityscale", "1", "Rescales velocity values, before doppler can be calculated.");
|
||||||
static cvar_t s_al_static_listener = CVAR("s_al_static_listener", "0"); //cheat
|
static cvar_t s_al_static_listener = CVAR("s_al_static_listener", "0"); //cheat
|
||||||
extern cvar_t snd_doppler;
|
extern cvar_t snd_doppler;
|
||||||
|
|
||||||
|
@ -503,7 +503,7 @@ static void QDECL OpenAL_CvarInit(void)
|
||||||
Cvar_Register(&s_al_dopplerfactor, SOUNDVARS);
|
Cvar_Register(&s_al_dopplerfactor, SOUNDVARS);
|
||||||
Cvar_Register(&s_al_distancemodel, SOUNDVARS);
|
Cvar_Register(&s_al_distancemodel, SOUNDVARS);
|
||||||
Cvar_Register(&s_al_reference_distance, SOUNDVARS);
|
Cvar_Register(&s_al_reference_distance, SOUNDVARS);
|
||||||
Cvar_Register(&s_al_rolloff_factor, SOUNDVARS);
|
// Cvar_Register(&s_al_rolloff_factor, SOUNDVARS);
|
||||||
Cvar_Register(&s_al_velocityscale, SOUNDVARS);
|
Cvar_Register(&s_al_velocityscale, SOUNDVARS);
|
||||||
Cvar_Register(&s_al_static_listener, SOUNDVARS);
|
Cvar_Register(&s_al_static_listener, SOUNDVARS);
|
||||||
Cvar_Register(&s_al_speedofsound, SOUNDVARS);
|
Cvar_Register(&s_al_speedofsound, SOUNDVARS);
|
||||||
|
|
|
@ -802,8 +802,7 @@ static void Friendly_Crash_Handler(int sig, siginfo_t *info, void *vcontext)
|
||||||
|
|
||||||
#if defined(__i386__)
|
#if defined(__i386__)
|
||||||
//x86 signals don't leave the stack in a clean state, so replace the signal handler with the real crash address, and hide this function
|
//x86 signals don't leave the stack in a clean state, so replace the signal handler with the real crash address, and hide this function
|
||||||
ucontext_t *uc = vcontext;
|
array[1] = (void*)((ucontext_t*)vcontext)->uc_mcontext.gregs[REG_EIP];
|
||||||
array[1] = (void*)uc->uc_mcontext.gregs[REG_EIP];
|
|
||||||
firstframe = 1;
|
firstframe = 1;
|
||||||
#elif defined(__amd64__)
|
#elif defined(__amd64__)
|
||||||
//amd64 is sane enough, but this function and the libc signal handler are on the stack, and should be ignored.
|
//amd64 is sane enough, but this function and the libc signal handler are on the stack, and should be ignored.
|
||||||
|
@ -995,7 +994,6 @@ int main (int c, const char **v)
|
||||||
#endif
|
#endif
|
||||||
TL_InitLanguages(parms.binarydir);
|
TL_InitLanguages(parms.binarydir);
|
||||||
|
|
||||||
|
|
||||||
if (!isatty(STDIN_FILENO))
|
if (!isatty(STDIN_FILENO))
|
||||||
noconinput = !isPlugin; //don't read the stdin if its probably screwed (running in qtcreator seems to pipe stdout to stdin in an attempt to screw everything up).
|
noconinput = !isPlugin; //don't read the stdin if its probably screwed (running in qtcreator seems to pipe stdout to stdin in an attempt to screw everything up).
|
||||||
else
|
else
|
||||||
|
|
|
@ -3362,10 +3362,15 @@ static void *Q1MDL_LoadFrameGroup (galiasinfo_t *galias, dmdl_t *pq1inmodel, mod
|
||||||
galias->numanimations++;
|
galias->numanimations++;
|
||||||
|
|
||||||
intervals = (daliasinterval_t *)(ingroup+1);
|
intervals = (daliasinterval_t *)(ingroup+1);
|
||||||
|
if (frame->numposes == 0)
|
||||||
|
frame->rate = 10;
|
||||||
|
else
|
||||||
|
{
|
||||||
sinter = LittleFloat(intervals->interval);
|
sinter = LittleFloat(intervals->interval);
|
||||||
if (sinter <= 0)
|
if (sinter <= 0)
|
||||||
sinter = 0.1;
|
sinter = 0.1;
|
||||||
frame->rate = 1/sinter;
|
frame->rate = 1/sinter;
|
||||||
|
}
|
||||||
|
|
||||||
pinframe = (dtrivertx_t *)(intervals+frame->numposes);
|
pinframe = (dtrivertx_t *)(intervals+frame->numposes);
|
||||||
for (k = 0; k < frame->numposes; k++)
|
for (k = 0; k < frame->numposes; k++)
|
||||||
|
|
|
@ -52,7 +52,8 @@ typedef struct
|
||||||
#endif
|
#endif
|
||||||
qboolean loop;
|
qboolean loop;
|
||||||
int numposes;
|
int numposes;
|
||||||
float rate;
|
//float *poseendtime; //first starts at 0, anim duration is poseendtime[numposes-1]
|
||||||
|
float rate; //average framerate of animation.
|
||||||
#ifdef NONSKELETALMODELS
|
#ifdef NONSKELETALMODELS
|
||||||
galiaspose_t *poseofs;
|
galiaspose_t *poseofs;
|
||||||
#endif
|
#endif
|
||||||
|
@ -219,7 +220,7 @@ typedef struct modplugfuncs_s
|
||||||
void (QDECL *UnRegisterModelFormat)(int idx);
|
void (QDECL *UnRegisterModelFormat)(int idx);
|
||||||
void (QDECL *UnRegisterAllModelFormats)(void);
|
void (QDECL *UnRegisterAllModelFormats)(void);
|
||||||
|
|
||||||
void *(QDECL *ZG_Malloc)(zonegroup_t *ctx, int size); //ctx=&mod->memgroup and the data will be freed when the model is freed.
|
void *(QDECL *ZG_Malloc)(zonegroup_t *ctx, size_t size); //ctx=&mod->memgroup and the data will be freed when the model is freed.
|
||||||
|
|
||||||
void (QDECL *ConcatTransforms) (const float in1[3][4], const float in2[3][4], float out[3][4]);
|
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 *M3x4_Invert) (const float *in1, float *out);
|
||||||
|
|
|
@ -131,6 +131,13 @@ typedef enum {false, true} qboolean;
|
||||||
#define MAX_SERVERINFO_STRING 1024 //standard quake has 512 here.
|
#define MAX_SERVERINFO_STRING 1024 //standard quake has 512 here.
|
||||||
#define MAX_LOCALINFO_STRING 32768
|
#define MAX_LOCALINFO_STRING 32768
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_LEGACY
|
||||||
|
#define legacyval(_legval,_newval) _legval
|
||||||
|
#else
|
||||||
|
#define legacyval(_legval,_newval) _newval
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CLIENT
|
#ifdef HAVE_CLIENT
|
||||||
#define cls_state cls.state
|
#define cls_state cls.state
|
||||||
#else
|
#else
|
||||||
|
@ -448,7 +455,7 @@ struct cache_user_s;
|
||||||
|
|
||||||
extern char com_gamepath[MAX_OSPATH];
|
extern char com_gamepath[MAX_OSPATH];
|
||||||
extern char com_homepath[MAX_OSPATH];
|
extern char com_homepath[MAX_OSPATH];
|
||||||
extern char com_configdir[MAX_OSPATH]; //dir to put cfg_save configs in
|
//extern char com_configdir[MAX_OSPATH]; //dir to put cfg_save configs in
|
||||||
//extern char *com_basedir;
|
//extern char *com_basedir;
|
||||||
|
|
||||||
//qofs_Make is used to 'construct' a variable of qofs_t type. this is so the code can merge two 32bit ints on old systems and use a long long type internally without generating warnings about bit shifts when qofs_t is only 32bit instead.
|
//qofs_Make is used to 'construct' a variable of qofs_t type. this is so the code can merge two 32bit ints on old systems and use a long long type internally without generating warnings about bit shifts when qofs_t is only 32bit instead.
|
||||||
|
|
|
@ -137,6 +137,7 @@
|
||||||
#define HAVE_WINSSPI //on windows
|
#define HAVE_WINSSPI //on windows
|
||||||
#define FTPSERVER //sv_ftp cvar.
|
#define FTPSERVER //sv_ftp cvar.
|
||||||
#define WEBCLIENT //uri_get+any internal downloads etc
|
#define WEBCLIENT //uri_get+any internal downloads etc
|
||||||
|
#define HAVE_HTTPSV //net_enable_http/websocket
|
||||||
#define TCPCONNECT //support for playing over tcp sockets, instead of just udp. compatible with qizmo.
|
#define TCPCONNECT //support for playing over tcp sockets, instead of just udp. compatible with qizmo.
|
||||||
//#define IRCCONNECT //lame support for routing game packets via irc server. not a good idea.
|
//#define IRCCONNECT //lame support for routing game packets via irc server. not a good idea.
|
||||||
#define SUPPORT_ICE //Internet Connectivity Establishment, for use by plugins to establish voice or game connections.
|
#define SUPPORT_ICE //Internet Connectivity Establishment, for use by plugins to establish voice or game connections.
|
||||||
|
|
|
@ -144,7 +144,7 @@ typedef struct cvar_group_s
|
||||||
#define CVAR_WATCHED (1<<22) //report any attempts to change this cvar.
|
#define CVAR_WATCHED (1<<22) //report any attempts to change this cvar.
|
||||||
#define CVAR_VIDEOLATCH (1<<23)
|
#define CVAR_VIDEOLATCH (1<<23)
|
||||||
|
|
||||||
#define CVAR_LASTFLAG CVAR_SHADERSYSTEM
|
#define CVAR_LASTFLAG CVAR_VIDEOLATCH
|
||||||
|
|
||||||
#define CVAR_LATCHMASK (CVAR_LATCH|CVAR_RENDERERLATCH|CVAR_SERVEROVERRIDE|CVAR_CHEAT|CVAR_SEMICHEAT) //you're only allowed one of these.
|
#define CVAR_LATCHMASK (CVAR_LATCH|CVAR_RENDERERLATCH|CVAR_SERVEROVERRIDE|CVAR_CHEAT|CVAR_SEMICHEAT) //you're only allowed one of these.
|
||||||
#define CVAR_NEEDDEFAULT CVAR_CHEAT
|
#define CVAR_NEEDDEFAULT CVAR_CHEAT
|
||||||
|
|
|
@ -172,14 +172,15 @@ char gamedirfile[MAX_OSPATH];
|
||||||
char pubgamedirfile[MAX_OSPATH]; //like gamedirfile, but not set to the fte-only paths
|
char pubgamedirfile[MAX_OSPATH]; //like gamedirfile, but not set to the fte-only paths
|
||||||
|
|
||||||
|
|
||||||
|
searchpath_t *gameonly_homedir;
|
||||||
|
searchpath_t *gameonly_gamedir;
|
||||||
|
|
||||||
char com_gamepath[MAX_OSPATH]; //c:\games\quake
|
char com_gamepath[MAX_OSPATH]; //c:\games\quake
|
||||||
char com_homepath[MAX_OSPATH]; //c:\users\foo\my docs\fte\quake
|
char com_homepath[MAX_OSPATH]; //c:\users\foo\my docs\fte\quake
|
||||||
qboolean com_homepathenabled;
|
qboolean com_homepathenabled;
|
||||||
qboolean com_homepathusable; //com_homepath is safe, even if not enabled.
|
qboolean com_homepathusable; //com_homepath is safe, even if not enabled.
|
||||||
|
|
||||||
char com_configdir[MAX_OSPATH]; //homedir/fte/configs
|
//char com_configdir[MAX_OSPATH]; //homedir/fte/configs
|
||||||
|
|
||||||
int fs_hash_dups;
|
int fs_hash_dups;
|
||||||
int fs_hash_files;
|
int fs_hash_files;
|
||||||
|
@ -737,7 +738,7 @@ static void COM_Path_f (void)
|
||||||
Con_Printf("pubgamedirfile: \"%s\"\n", pubgamedirfile);
|
Con_Printf("pubgamedirfile: \"%s\"\n", pubgamedirfile);
|
||||||
Con_Printf("com_gamepath: \"%s\"\n", com_gamepath);
|
Con_Printf("com_gamepath: \"%s\"\n", com_gamepath);
|
||||||
Con_Printf("com_homepath: \"%s\" (enabled: %s, usable: %s)\n", com_homepath, com_homepathenabled?"yes":"no", com_homepathusable?"yes":"no");
|
Con_Printf("com_homepath: \"%s\" (enabled: %s, usable: %s)\n", com_homepath, com_homepathenabled?"yes":"no", com_homepathusable?"yes":"no");
|
||||||
Con_Printf("com_configdir: \"%s\"\n", com_configdir);
|
// Con_Printf("com_configdir: \"%s\"\n", com_configdir);
|
||||||
if (fs_manifest)
|
if (fs_manifest)
|
||||||
FS_Manifest_Print(fs_manifest);
|
FS_Manifest_Print(fs_manifest);
|
||||||
return;
|
return;
|
||||||
|
@ -1915,6 +1916,9 @@ vfsfile_t *QDECL FS_OpenVFS(const char *filename, const char *mode, enum fs_rela
|
||||||
|
|
||||||
fs_accessed_time = realtime;
|
fs_accessed_time = realtime;
|
||||||
|
|
||||||
|
if (fs_readonly && *mode == 'w')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (relativeto == FS_SYSTEM)
|
if (relativeto == FS_SYSTEM)
|
||||||
return VFSOS_Open(filename, mode);
|
return VFSOS_Open(filename, mode);
|
||||||
|
|
||||||
|
@ -1937,9 +1941,21 @@ vfsfile_t *QDECL FS_OpenVFS(const char *filename, const char *mode, enum fs_rela
|
||||||
//if there can only be one file (eg: write access) find out where it is.
|
//if there can only be one file (eg: write access) find out where it is.
|
||||||
switch (relativeto)
|
switch (relativeto)
|
||||||
{
|
{
|
||||||
case FS_GAMEONLY: //OS access only, no paks
|
case FS_GAMEONLY: //OS access only, no paks. Used for (re)writing files.
|
||||||
vfs = NULL;
|
vfs = NULL;
|
||||||
|
//FIXME: go via a searchpath, because then the fscache can be selectively updated
|
||||||
if (com_homepathenabled)
|
if (com_homepathenabled)
|
||||||
|
{
|
||||||
|
if (gameonly_homedir)
|
||||||
|
{
|
||||||
|
if ((*mode == 'w')
|
||||||
|
? gameonly_homedir->handle->CreateFile(gameonly_homedir->handle, &loc, filename)
|
||||||
|
: gameonly_homedir->handle->FindFile (gameonly_homedir->handle, &loc, filename, NULL))
|
||||||
|
vfs = gameonly_homedir->handle->OpenVFS (gameonly_homedir->handle, &loc, mode);
|
||||||
|
else
|
||||||
|
vfs = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (!try_snprintf(fullname, sizeof(fullname), "%s%s/%s", com_homepath, gamedirfile, filename))
|
if (!try_snprintf(fullname, sizeof(fullname), "%s%s/%s", com_homepath, gamedirfile, filename))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1947,7 +1963,19 @@ vfsfile_t *QDECL FS_OpenVFS(const char *filename, const char *mode, enum fs_rela
|
||||||
COM_CreatePath(fullname);
|
COM_CreatePath(fullname);
|
||||||
vfs = VFSOS_Open(fullname, mode);
|
vfs = VFSOS_Open(fullname, mode);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!vfs && *gamedirfile)
|
if (!vfs && *gamedirfile)
|
||||||
|
{
|
||||||
|
if (gameonly_gamedir)
|
||||||
|
{
|
||||||
|
if ((*mode == 'w')
|
||||||
|
? gameonly_gamedir->handle->CreateFile(gameonly_gamedir->handle, &loc, filename)
|
||||||
|
: gameonly_gamedir->handle->FindFile (gameonly_gamedir->handle, &loc, filename, NULL))
|
||||||
|
vfs = gameonly_gamedir->handle->OpenVFS (gameonly_gamedir->handle, &loc, mode);
|
||||||
|
else
|
||||||
|
vfs = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (!try_snprintf(fullname, sizeof(fullname), "%s%s/%s", com_gamepath, gamedirfile, filename))
|
if (!try_snprintf(fullname, sizeof(fullname), "%s%s/%s", com_gamepath, gamedirfile, filename))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1955,6 +1983,7 @@ vfsfile_t *QDECL FS_OpenVFS(const char *filename, const char *mode, enum fs_rela
|
||||||
COM_CreatePath(fullname);
|
COM_CreatePath(fullname);
|
||||||
vfs = VFSOS_Open(fullname, mode);
|
vfs = VFSOS_Open(fullname, mode);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (vfs || !(*mode == 'w' || *mode == 'a'))
|
if (vfs || !(*mode == 'w' || *mode == 'a'))
|
||||||
return vfs;
|
return vfs;
|
||||||
//fall through
|
//fall through
|
||||||
|
@ -2793,7 +2822,7 @@ Sets com_gamedir, adds the directory to the head of the path,
|
||||||
then loads and adds pak1.pak pak2.pak ...
|
then loads and adds pak1.pak pak2.pak ...
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
static void FS_AddGameDirectory (searchpath_t **oldpaths, const char *puredir, const char *dir, unsigned int loadstuff, unsigned int flags)
|
static searchpath_t *FS_AddSingleGameDirectory (searchpath_t **oldpaths, const char *puredir, const char *dir, unsigned int loadstuff, unsigned int flags)
|
||||||
{
|
{
|
||||||
unsigned int keptflags;
|
unsigned int keptflags;
|
||||||
searchpath_t *search;
|
searchpath_t *search;
|
||||||
|
@ -2808,7 +2837,7 @@ static void FS_AddGameDirectory (searchpath_t **oldpaths, const char *puredir, c
|
||||||
if (!Q_strcasecmp(search->logicalpath, dir))
|
if (!Q_strcasecmp(search->logicalpath, dir))
|
||||||
{
|
{
|
||||||
search->flags |= flags & SPF_WRITABLE;
|
search->flags |= flags & SPF_WRITABLE;
|
||||||
return; //already loaded (base paths?)
|
return search; //already loaded (base paths?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2831,7 +2860,20 @@ static void FS_AddGameDirectory (searchpath_t **oldpaths, const char *puredir, c
|
||||||
if (!handle)
|
if (!handle)
|
||||||
handle = VFSOS_OpenPath(NULL, NULL, dir, dir, "");
|
handle = VFSOS_OpenPath(NULL, NULL, dir, dir, "");
|
||||||
|
|
||||||
FS_AddPathHandle(oldpaths, puredir, dir, handle, "", flags|keptflags, loadstuff);
|
return FS_AddPathHandle(oldpaths, puredir, dir, handle, "", flags|keptflags, loadstuff);
|
||||||
|
}
|
||||||
|
static void FS_AddGameDirectory (searchpath_t **oldpaths, const char *puredir, unsigned int loadstuff, unsigned int flags)
|
||||||
|
{
|
||||||
|
char syspath[MAX_OSPATH];
|
||||||
|
Q_snprintfz(syspath, sizeof(syspath), "%s%s", com_gamepath, puredir);
|
||||||
|
gameonly_gamedir = FS_AddSingleGameDirectory(oldpaths, puredir, syspath, loadstuff, flags&~(com_homepathenabled?SPF_WRITABLE:0u));
|
||||||
|
if (com_homepathenabled)
|
||||||
|
{
|
||||||
|
Q_snprintfz(syspath, sizeof(syspath), "%s%s", com_homepath, puredir);
|
||||||
|
gameonly_homedir = FS_AddSingleGameDirectory(oldpaths, puredir, syspath, loadstuff, flags);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gameonly_homedir = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if syspath, something like c:\quake\baseq2
|
//if syspath, something like c:\quake\baseq2
|
||||||
|
@ -3698,7 +3740,6 @@ static void FS_ReloadPackFilesFlags(unsigned int reloadflags)
|
||||||
searchpath_t *next;
|
searchpath_t *next;
|
||||||
int i;
|
int i;
|
||||||
int orderkey;
|
int orderkey;
|
||||||
char syspath[MAX_OSPATH];
|
|
||||||
|
|
||||||
COM_AssertMainThread("FS_ReloadPackFilesFlags");
|
COM_AssertMainThread("FS_ReloadPackFilesFlags");
|
||||||
COM_WorkerFullSync();
|
COM_WorkerFullSync();
|
||||||
|
@ -3715,6 +3756,7 @@ static void FS_ReloadPackFilesFlags(unsigned int reloadflags)
|
||||||
com_searchpaths = NULL;
|
com_searchpaths = NULL;
|
||||||
com_purepaths = NULL;
|
com_purepaths = NULL;
|
||||||
com_base_searchpaths = NULL;
|
com_base_searchpaths = NULL;
|
||||||
|
gameonly_gamedir = gameonly_homedir = NULL;
|
||||||
|
|
||||||
i = COM_CheckParm ("-basepack");
|
i = COM_CheckParm ("-basepack");
|
||||||
while (i && i < com_argc-1)
|
while (i && i < com_argc-1)
|
||||||
|
@ -3777,23 +3819,11 @@ static void FS_ReloadPackFilesFlags(unsigned int reloadflags)
|
||||||
else if (*dir == '*')
|
else if (*dir == '*')
|
||||||
{
|
{
|
||||||
//paths with a leading * are private, and not announced to clients that ask what the current gamedir is.
|
//paths with a leading * are private, and not announced to clients that ask what the current gamedir is.
|
||||||
Q_snprintfz(syspath, sizeof(syspath), "%s%s", com_gamepath, dir+1);
|
FS_AddGameDirectory(&oldpaths, dir+1, reloadflags, SPF_EXPLICIT|SPF_PRIVATE|SPF_WRITABLE);
|
||||||
FS_AddGameDirectory(&oldpaths, dir+1, syspath, reloadflags, SPF_EXPLICIT|SPF_PRIVATE|(com_homepathenabled?0:SPF_WRITABLE));
|
|
||||||
if (com_homepathenabled)
|
|
||||||
{
|
|
||||||
Q_snprintfz(syspath, sizeof(syspath), "%s%s", com_homepath, dir+1);
|
|
||||||
FS_AddGameDirectory(&oldpaths, dir+1, syspath, reloadflags, SPF_EXPLICIT|SPF_PRIVATE|SPF_WRITABLE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Q_snprintfz(syspath, sizeof(syspath), "%s%s", com_gamepath, dir);
|
FS_AddGameDirectory(&oldpaths, dir, reloadflags, SPF_EXPLICIT|SPF_WRITABLE);
|
||||||
FS_AddGameDirectory(&oldpaths, dir, syspath, reloadflags, SPF_EXPLICIT|(com_homepathenabled?0:SPF_WRITABLE));
|
|
||||||
if (com_homepathenabled)
|
|
||||||
{
|
|
||||||
Q_snprintfz(syspath, sizeof(syspath), "%s%s", com_homepath, dir);
|
|
||||||
FS_AddGameDirectory(&oldpaths, dir, syspath, reloadflags, SPF_EXPLICIT|SPF_WRITABLE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3823,9 +3853,7 @@ static void FS_ReloadPackFilesFlags(unsigned int reloadflags)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FS_AddGameDirectory(&oldpaths, dir, va("%s%s", com_gamepath, dir), reloadflags, SPF_EXPLICIT|(com_homepathenabled?0:SPF_WRITABLE));
|
FS_AddGameDirectory(&oldpaths, dir, reloadflags, SPF_EXPLICIT|SPF_WRITABLE);
|
||||||
if (com_homepathenabled)
|
|
||||||
FS_AddGameDirectory(&oldpaths, dir, va("%s%s", com_homepath, dir), reloadflags, SPF_EXPLICIT|SPF_WRITABLE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6330,7 +6358,6 @@ static void COM_InitHomedir(ftemanifest_t *man)
|
||||||
//but if it doesn't exist then we use $XDG_DATA_HOME/.fte instead
|
//but if it doesn't exist then we use $XDG_DATA_HOME/.fte instead
|
||||||
//we used to use $HOME/.#HOMESUBDIR/ but this is now only used if it actually exists AND the new path doesn't.
|
//we used to use $HOME/.#HOMESUBDIR/ but this is now only used if it actually exists AND the new path doesn't.
|
||||||
//new installs use $XDG_DATA_HOME/#HOMESUBDIR/ instead
|
//new installs use $XDG_DATA_HOME/#HOMESUBDIR/ instead
|
||||||
|
|
||||||
char *ev = getenv("FTEHOME");
|
char *ev = getenv("FTEHOME");
|
||||||
if (ev && *ev)
|
if (ev && *ev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,9 +49,9 @@ struct searchpathfuncs_s
|
||||||
qboolean (QDECL *PollChanges)(searchpathfuncs_t *handle); //returns true if there were changes
|
qboolean (QDECL *PollChanges)(searchpathfuncs_t *handle); //returns true if there were changes
|
||||||
|
|
||||||
qboolean (QDECL *FileStat)(searchpathfuncs_t *handle, flocation_t *loc, time_t *mtime);
|
qboolean (QDECL *FileStat)(searchpathfuncs_t *handle, flocation_t *loc, time_t *mtime);
|
||||||
qboolean (QDECL *RenameFile)(searchpathfuncs_t *handle, const char *oldname, const char *newname); //returns true on success, false if source doesn't exist, or if dest does.
|
qboolean (QDECL *CreateFile)(searchpathfuncs_t *handle, flocation_t *loc, const char *filename); //like FindFile, but returns a usable loc even if the file does not exist yet (may also create requisite directories too)
|
||||||
|
qboolean (QDECL *RenameFile)(searchpathfuncs_t *handle, const char *oldname, const char *newname); //returns true on success, false if source doesn't exist, or if dest does (cached locs may refer to either new or old name).
|
||||||
qboolean (QDECL *RemoveFile)(searchpathfuncs_t *handle, const char *filename); //returns true on success, false if it wasn't found or is readonly.
|
qboolean (QDECL *RemoveFile)(searchpathfuncs_t *handle, const char *filename); //returns true on success, false if it wasn't found or is readonly.
|
||||||
qboolean (QDECL *MkDir)(searchpathfuncs_t *handle, const char *filename); //is this really needed?
|
|
||||||
};
|
};
|
||||||
//searchpathfuncs_t *(QDECL *OpenNew)(vfsfile_t *file, const char *desc); //returns a handle to a new pak/path
|
//searchpathfuncs_t *(QDECL *OpenNew)(vfsfile_t *file, const char *desc); //returns a handle to a new pak/path
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ int FS_EnumerateKnownGames(qboolean (*callback)(void *usr, ftemanifest_t *man),
|
||||||
#define SPF_TEMPORARY 4 //a map-specific path, purged at map change.
|
#define SPF_TEMPORARY 4 //a map-specific path, purged at map change.
|
||||||
#define SPF_EXPLICIT 8 //a root gamedir (bumps depth on gamedir depth checks).
|
#define SPF_EXPLICIT 8 //a root gamedir (bumps depth on gamedir depth checks).
|
||||||
#define SPF_UNTRUSTED 16 //has been downloaded from somewhere. configs inside it should never be execed with local access rights.
|
#define SPF_UNTRUSTED 16 //has been downloaded from somewhere. configs inside it should never be execed with local access rights.
|
||||||
#define SPF_PRIVATE 32 //private to the client. ie: the fte dir.
|
#define SPF_PRIVATE 32 //private to the client. ie: the fte dir. name is not networked.
|
||||||
#define SPF_WRITABLE 64 //safe to write here. lots of weird rules etc.
|
#define SPF_WRITABLE 64 //safe to write here. lots of weird rules etc.
|
||||||
#define SPF_BASEPATH 128 //part of the basegames, and not the mod gamedir(s).
|
#define SPF_BASEPATH 128 //part of the basegames, and not the mod gamedir(s).
|
||||||
qboolean FS_LoadPackageFromFile(vfsfile_t *vfs, char *pname, char *localname, int *crc, unsigned int flags);
|
qboolean FS_LoadPackageFromFile(vfsfile_t *vfs, char *pname, char *localname, int *crc, unsigned int flags);
|
||||||
|
|
|
@ -271,6 +271,30 @@ static void QDECL FSSTDIO_BuildHash(searchpathfuncs_t *handle, int depth, void (
|
||||||
sp->AddFileHash = AddFileHash;
|
sp->AddFileHash = AddFileHash;
|
||||||
Sys_EnumerateFiles(sp->rootpath, "*", FSSTDIO_RebuildFSHash, AddFileHash, handle);
|
Sys_EnumerateFiles(sp->rootpath, "*", FSSTDIO_RebuildFSHash, AddFileHash, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int QDECL FSSTDIO_CreateLoc(searchpathfuncs_t *handle, flocation_t *loc, const char *filename)
|
||||||
|
{
|
||||||
|
stdiopath_t *sp = (void*)handle;
|
||||||
|
char *ofs;
|
||||||
|
|
||||||
|
loc->len = 0;
|
||||||
|
loc->offset = 0;
|
||||||
|
loc->fhandle = handle;
|
||||||
|
if ((unsigned int)snprintf(loc->rawname, sizeof(loc->rawname), "%s/%s", sp->rootpath, filename) > sizeof(loc->rawname)-1)
|
||||||
|
return FF_NOTFOUND; //too long...
|
||||||
|
|
||||||
|
for (ofs = loc->rawname+1 ; *ofs ; ofs++)
|
||||||
|
{
|
||||||
|
if (*ofs == '/')
|
||||||
|
{ // create the directory
|
||||||
|
*ofs = 0;
|
||||||
|
Sys_mkdir (loc->rawname);
|
||||||
|
*ofs = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FF_FOUND;
|
||||||
|
}
|
||||||
static unsigned int QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
|
static unsigned int QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
|
||||||
{
|
{
|
||||||
stdiopath_t *sp = (void*)handle;
|
stdiopath_t *sp = (void*)handle;
|
||||||
|
@ -289,7 +313,8 @@ static unsigned int QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// check a file in the directory tree
|
// check a file in the directory tree
|
||||||
snprintf (netpath, sizeof(netpath)-1, "%s/%s", sp->rootpath, filename);
|
if ((unsigned int)snprintf (netpath, sizeof(netpath), "%s/%s", sp->rootpath, filename) > sizeof(netpath)-1)
|
||||||
|
return FF_NOTFOUND;
|
||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
{
|
{
|
||||||
|
@ -378,6 +403,7 @@ searchpathfuncs_t *QDECL FSSTDIO_OpenPath(vfsfile_t *mustbenull, searchpathfuncs
|
||||||
np->pub.OpenVFS = FSSTDIO_OpenVFS;
|
np->pub.OpenVFS = FSSTDIO_OpenVFS;
|
||||||
np->pub.PollChanges = FSSTDIO_PollChanges;
|
np->pub.PollChanges = FSSTDIO_PollChanges;
|
||||||
np->pub.FileStat = FSSTDIO_FileStat;
|
np->pub.FileStat = FSSTDIO_FileStat;
|
||||||
|
np->pub.CreateFile = FSSTDIO_CreateLoc;
|
||||||
return &np->pub;
|
return &np->pub;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -522,6 +522,30 @@ static void QDECL VFSW32_BuildHash(searchpathfuncs_t *handle, int hashdepth, voi
|
||||||
wp->hashdepth = hashdepth;
|
wp->hashdepth = hashdepth;
|
||||||
Sys_EnumerateFiles(wp->rootpath, "*", VFSW32_RebuildFSHash, AddFileHash, handle);
|
Sys_EnumerateFiles(wp->rootpath, "*", VFSW32_RebuildFSHash, AddFileHash, handle);
|
||||||
}
|
}
|
||||||
|
static unsigned int QDECL VFSW32_CreateLoc(searchpathfuncs_t *handle, flocation_t *loc, const char *filename)
|
||||||
|
{
|
||||||
|
vfsw32path_t *wp = (void*)handle;
|
||||||
|
char *ofs;
|
||||||
|
|
||||||
|
loc->len = 0;
|
||||||
|
loc->offset = 0;
|
||||||
|
loc->fhandle = handle;
|
||||||
|
loc->rawname[sizeof(loc->rawname)-1] = 0;
|
||||||
|
if ((unsigned int)snprintf (loc->rawname, sizeof(loc->rawname), "%s/%s", wp->rootpath, filename) > sizeof(loc->rawname)-1)
|
||||||
|
return FF_NOTFOUND;
|
||||||
|
for (ofs = loc->rawname+1 ; *ofs ; ofs++)
|
||||||
|
{
|
||||||
|
if (*ofs == '/')
|
||||||
|
{ // create the directory
|
||||||
|
*ofs = 0;
|
||||||
|
Sys_mkdir (loc->rawname);
|
||||||
|
*ofs = '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FF_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
static unsigned int QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
|
static unsigned int QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
|
||||||
{
|
{
|
||||||
|
@ -545,7 +569,8 @@ static unsigned int QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// check a file in the directory tree
|
// check a file in the directory tree
|
||||||
snprintf (netpath, sizeof(netpath)-1, "%s/%s", wp->rootpath, filename);
|
if ((unsigned int)snprintf (netpath, sizeof(netpath), "%s/%s", wp->rootpath, filename) > sizeof(loc->rawname)-1)
|
||||||
|
return FF_NOTFOUND;
|
||||||
|
|
||||||
if (!WinNT)
|
if (!WinNT)
|
||||||
{
|
{
|
||||||
|
@ -634,16 +659,6 @@ static qboolean QDECL VFSW32_RemoveFile(searchpathfuncs_t *handle, const char *f
|
||||||
snprintf (syspath, sizeof(syspath)-1, "%s/%s", wp->rootpath, filename);
|
snprintf (syspath, sizeof(syspath)-1, "%s/%s", wp->rootpath, filename);
|
||||||
return Sys_remove(syspath);
|
return Sys_remove(syspath);
|
||||||
}
|
}
|
||||||
static qboolean QDECL VFSW32_MkDir(searchpathfuncs_t *handle, const char *filename)
|
|
||||||
{
|
|
||||||
vfsw32path_t *wp = (vfsw32path_t*)handle;
|
|
||||||
char syspath[MAX_OSPATH];
|
|
||||||
if (fs_readonly)
|
|
||||||
return false;
|
|
||||||
snprintf (syspath, sizeof(syspath)-1, "%s/%s", wp->rootpath, filename);
|
|
||||||
Sys_mkdir(syspath);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
searchpathfuncs_t *QDECL VFSW32_OpenPath(vfsfile_t *mustbenull, searchpathfuncs_t *parent, const char *filename, const char *desc, const char *prefix)
|
searchpathfuncs_t *QDECL VFSW32_OpenPath(vfsfile_t *mustbenull, searchpathfuncs_t *parent, const char *filename, const char *desc, const char *prefix)
|
||||||
{
|
{
|
||||||
|
@ -675,9 +690,10 @@ searchpathfuncs_t *QDECL VFSW32_OpenPath(vfsfile_t *mustbenull, searchpathfuncs_
|
||||||
|
|
||||||
np->pub.FileStat = VFSW32_FileStat;
|
np->pub.FileStat = VFSW32_FileStat;
|
||||||
|
|
||||||
|
#undef CreateFile //stoopid windows.h
|
||||||
|
np->pub.CreateFile = VFSW32_CreateLoc;
|
||||||
np->pub.RenameFile = VFSW32_RenameFile;
|
np->pub.RenameFile = VFSW32_RenameFile;
|
||||||
np->pub.RemoveFile = VFSW32_RemoveFile;
|
np->pub.RemoveFile = VFSW32_RemoveFile;
|
||||||
np->pub.MkDir = VFSW32_MkDir;
|
|
||||||
|
|
||||||
return &np->pub;
|
return &np->pub;
|
||||||
}
|
}
|
||||||
|
|
|
@ -313,7 +313,8 @@ typedef struct
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
int cp[2];
|
unsigned short cp[2];
|
||||||
|
unsigned short fixedres[2];
|
||||||
} patch;
|
} patch;
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -527,7 +528,7 @@ static int Patch_FlatnessTest( float maxflat2, const float *point0, const float
|
||||||
Patch_GetFlatness
|
Patch_GetFlatness
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
static void Patch_GetFlatness( float maxflat, const float *points, int comp, const int *patch_cp, int *flat )
|
static void Patch_GetFlatness( float maxflat, const float *points, int comp, const unsigned short *patch_cp, int *flat )
|
||||||
{
|
{
|
||||||
int i, p, u, v;
|
int i, p, u, v;
|
||||||
float maxflat2 = maxflat * maxflat;
|
float maxflat2 = maxflat * maxflat;
|
||||||
|
@ -579,7 +580,7 @@ static void Patch_Evaluate_QuadricBezier( float t, const vec_t *point0, const ve
|
||||||
Patch_Evaluate
|
Patch_Evaluate
|
||||||
===============
|
===============
|
||||||
*/
|
*/
|
||||||
static void Patch_Evaluate( const vec_t *p, const int *numcp, const int *tess, vec_t *dest, int comp )
|
static void Patch_Evaluate( const vec_t *p, const unsigned short *numcp, const int *tess, vec_t *dest, int comp )
|
||||||
{
|
{
|
||||||
int num_patches[2], num_tess[2];
|
int num_patches[2], num_tess[2];
|
||||||
int index[3], dstpitch, i, u, v, x, y;
|
int index[3], dstpitch, i, u, v, x, y;
|
||||||
|
@ -850,7 +851,7 @@ static int CM_CreateFacetFromPoints(q2cbrush_t *facet, vec3_t *verts, int numver
|
||||||
/*
|
/*
|
||||||
* CM_CreatePatch
|
* CM_CreatePatch
|
||||||
*/
|
*/
|
||||||
static void CM_CreatePatch(model_t *loadmodel, q3cpatch_t *patch, q2mapsurface_t *shaderref, const vec_t *verts, const int *patch_cp )
|
static void CM_CreatePatch(model_t *loadmodel, q3cpatch_t *patch, q2mapsurface_t *shaderref, const vec_t *verts, const unsigned short *patch_cp, const unsigned short *patch_subdiv)
|
||||||
{
|
{
|
||||||
int step[2], size[2], flat[2];
|
int step[2], size[2], flat[2];
|
||||||
int i, j, k ,u, v;
|
int i, j, k ,u, v;
|
||||||
|
@ -1088,7 +1089,7 @@ static qboolean CM_CreatePatchForFace (model_t *loadmodel, cminfo_t *prv, mleaf_
|
||||||
checkout[facenum] = prv->numpatches++;
|
checkout[facenum] = prv->numpatches++;
|
||||||
|
|
||||||
//gcc warns without this cast
|
//gcc warns without this cast
|
||||||
CM_CreatePatch (loadmodel, patch, surf, (const vec_t *)(prv->verts + face->firstvert), face->patch.cp );
|
CM_CreatePatch (loadmodel, patch, surf, (const vec_t *)(prv->verts + face->firstvert), face->patch.cp, face->patch.fixedres );
|
||||||
}
|
}
|
||||||
leaf->contents |= patch->surface->c.value;
|
leaf->contents |= patch->surface->c.value;
|
||||||
leaf->numleafpatches++;
|
leaf->numleafpatches++;
|
||||||
|
@ -2554,8 +2555,12 @@ static qboolean CModRBSP_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l)
|
||||||
|
|
||||||
if (out->facetype == MST_PATCH)
|
if (out->facetype == MST_PATCH)
|
||||||
{
|
{
|
||||||
out->patch.cp[0] = LittleLong ( in->patchwidth );
|
unsigned int w = LittleLong ( in->patchwidth );
|
||||||
out->patch.cp[1] = LittleLong ( in->patchheight );
|
unsigned int h = LittleLong ( in->patchheight );
|
||||||
|
out->patch.cp[0] = w&0xffff;
|
||||||
|
out->patch.cp[1] = h&0xffff;
|
||||||
|
out->patch.fixedres[0]=w>>16;
|
||||||
|
out->patch.fixedres[1]=h>>16;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2658,11 +2663,12 @@ static index_t tempIndexesArray[MAX_ARRAY_VERTS*6];
|
||||||
|
|
||||||
static void GL_SizePatch(mesh_t *mesh, int patchwidth, int patchheight, int numverts, int firstvert, cminfo_t *prv)
|
static void GL_SizePatch(mesh_t *mesh, int patchwidth, int patchheight, int numverts, int firstvert, cminfo_t *prv)
|
||||||
{
|
{
|
||||||
int patch_cp[2], step[2], size[2], flat[2];
|
unsigned short patch_cp[2];
|
||||||
|
int step[2], size[2], flat[2];
|
||||||
float subdivlevel;
|
float subdivlevel;
|
||||||
|
|
||||||
patch_cp[0] = patchwidth;
|
patch_cp[0] = patchwidth&0xffff;
|
||||||
patch_cp[1] = patchheight;
|
patch_cp[1] = patchheight&0xffff;
|
||||||
|
|
||||||
if (patch_cp[0] <= 0 || patch_cp[1] <= 0 )
|
if (patch_cp[0] <= 0 || patch_cp[1] <= 0 )
|
||||||
{
|
{
|
||||||
|
@ -2692,13 +2698,14 @@ static void GL_SizePatch(mesh_t *mesh, int patchwidth, int patchheight, int numv
|
||||||
static void GL_CreateMeshForPatch (model_t *mod, mesh_t *mesh, int patchwidth, int patchheight, int numverts, int firstvert)
|
static void GL_CreateMeshForPatch (model_t *mod, mesh_t *mesh, int patchwidth, int patchheight, int numverts, int firstvert)
|
||||||
{
|
{
|
||||||
cminfo_t *prv = (cminfo_t*)mod->meshinfo;
|
cminfo_t *prv = (cminfo_t*)mod->meshinfo;
|
||||||
int numindexes, patch_cp[2], step[2], size[2], flat[2], i, u, v, p;
|
int numindexes, step[2], size[2], flat[2], i, u, v, p;
|
||||||
|
unsigned short patch_cp[2];
|
||||||
index_t *indexes;
|
index_t *indexes;
|
||||||
float subdivlevel;
|
float subdivlevel;
|
||||||
int sty;
|
int sty;
|
||||||
|
|
||||||
patch_cp[0] = patchwidth;
|
patch_cp[0] = patchwidth&0xffff;
|
||||||
patch_cp[1] = patchheight;
|
patch_cp[1] = patchheight&0xffff;
|
||||||
|
|
||||||
if (patch_cp[0] <= 0 || patch_cp[1] <= 0 )
|
if (patch_cp[0] <= 0 || patch_cp[1] <= 0 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -209,9 +209,10 @@ typedef struct
|
||||||
float nqreliable_resendtime;//force nqreliable_allowed, thereby forcing a resend of anything n
|
float nqreliable_resendtime;//force nqreliable_allowed, thereby forcing a resend of anything n
|
||||||
qbyte nqunreliableonly; //nq can't cope with certain reliables some times. if 2, we have a reliable that result in a block (that should be sent). if 1, we are blocking. if 0, we can send reliables freely. if 3, then we just want to ignore clc_moves
|
qbyte nqunreliableonly; //nq can't cope with certain reliables some times. if 2, we have a reliable that result in a block (that should be sent). if 1, we are blocking. if 0, we can send reliables freely. if 3, then we just want to ignore clc_moves
|
||||||
#endif
|
#endif
|
||||||
|
qboolean pext_fragmentation; //fte's packet fragmentation extension, to avoid issues with low mtus.
|
||||||
struct netprim_s netprim;
|
struct netprim_s netprim;
|
||||||
int fragmentsize;
|
int mtu; //the path mtu, if known
|
||||||
int dupe;
|
int dupe; //how many times to dupe packets
|
||||||
|
|
||||||
float last_received; // for timeouts
|
float last_received; // for timeouts
|
||||||
|
|
||||||
|
|
|
@ -692,7 +692,7 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
||||||
if (chan->message.overflowed)
|
if (chan->message.overflowed)
|
||||||
{
|
{
|
||||||
chan->fatal_error = true;
|
chan->fatal_error = true;
|
||||||
Con_TPrintf ("%s:Outgoing message overflow\n"
|
Con_TPrintf ("%s: Outgoing message overflow\n"
|
||||||
, NET_AdrToString (remote_adr, sizeof(remote_adr), &chan->remote_address));
|
, NET_AdrToString (remote_adr, sizeof(remote_adr), &chan->remote_address));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -716,7 +716,7 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
||||||
|
|
||||||
// write the packet header
|
// write the packet header
|
||||||
send.data = send_buf;
|
send.data = send_buf;
|
||||||
send.maxsize = MAX_QWMSGLEN + PACKET_HEADER;
|
send.maxsize = (chan->mtu?chan->mtu:MAX_QWMSGLEN) + PACKET_HEADER;
|
||||||
send.cursize = 0;
|
send.cursize = 0;
|
||||||
|
|
||||||
w1 = chan->outgoing_sequence | (send_reliable<<31);
|
w1 = chan->outgoing_sequence | (send_reliable<<31);
|
||||||
|
@ -738,9 +738,9 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (chan->fragmentsize)
|
if (chan->pext_fragmentation)
|
||||||
{
|
{
|
||||||
//allow the max size to be bigger
|
//allow the max size to be bigger, sending everything available
|
||||||
send.maxsize = MAX_OVERALLMSGLEN + PACKET_HEADER;
|
send.maxsize = MAX_OVERALLMSGLEN + PACKET_HEADER;
|
||||||
MSG_WriteShort(&send, 0);
|
MSG_WriteShort(&send, 0);
|
||||||
}
|
}
|
||||||
|
@ -748,6 +748,17 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
||||||
// copy the reliable message to the packet first
|
// copy the reliable message to the packet first
|
||||||
if (send_reliable)
|
if (send_reliable)
|
||||||
{
|
{
|
||||||
|
if (send.maxsize - send.cursize < chan->reliable_length)
|
||||||
|
{
|
||||||
|
if (!chan->fatal_error)
|
||||||
|
{
|
||||||
|
chan->fatal_error = true;
|
||||||
|
Con_TPrintf ("%s: Path MTU is lower than %u\n"
|
||||||
|
, NET_AdrToString (remote_adr, sizeof(remote_adr), &chan->remote_address), chan->reliable_length);
|
||||||
|
}
|
||||||
|
chan->outgoing_sequence--;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
SZ_Write (&send, chan->reliable_buf, chan->reliable_length);
|
SZ_Write (&send, chan->reliable_buf, chan->reliable_length);
|
||||||
chan->last_reliable_sequence = chan->outgoing_sequence;
|
chan->last_reliable_sequence = chan->outgoing_sequence;
|
||||||
}
|
}
|
||||||
|
@ -765,7 +776,7 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
||||||
if (chan->compresstable)
|
if (chan->compresstable)
|
||||||
{
|
{
|
||||||
//int oldsize = send.cursize;
|
//int oldsize = send.cursize;
|
||||||
Huff_CompressPacket(chan->compresstable, &send, 8 + ((chan->sock == NS_CLIENT)?2:0) + (chan->fragmentsize?2:0));
|
Huff_CompressPacket(chan->compresstable, &send, 8 + ((chan->sock == NS_CLIENT)?2:0) + (chan->pext_fragmentation?2:0));
|
||||||
// Con_Printf("%i becomes %i\n", oldsize, send.cursize);
|
// Con_Printf("%i becomes %i\n", oldsize, send.cursize);
|
||||||
// Huff_DecompressPacket(&send, (chan->sock == NS_CLIENT)?10:8);
|
// Huff_DecompressPacket(&send, (chan->sock == NS_CLIENT)?10:8);
|
||||||
}
|
}
|
||||||
|
@ -779,20 +790,23 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
||||||
{
|
{
|
||||||
int hsz = 10 + ((chan->sock == NS_CLIENT)?chan->qportsize:0); /*header size, if fragmentation is in use*/
|
int hsz = 10 + ((chan->sock == NS_CLIENT)?chan->qportsize:0); /*header size, if fragmentation is in use*/
|
||||||
|
|
||||||
if ((!chan->fragmentsize))// || send.cursize < ((chan->fragmentsize - hsz)&~7))
|
if ((!chan->pext_fragmentation))// || send.cursize < ((chan->mtu - hsz)&~7))
|
||||||
{
|
{ //vanilla sends
|
||||||
for (i = -1; i < chan->dupe && e == NETERR_SENT; i++)
|
for (i = -1; i < chan->dupe && e == NETERR_SENT; i++)
|
||||||
e = NET_SendPacket (chan->sock, send.cursize, send.data, &chan->remote_address);
|
e = NET_SendPacket (chan->sock, send.cursize, send.data, &chan->remote_address);
|
||||||
send.cursize += send.cursize * i;
|
send.cursize += send.cursize * i;
|
||||||
|
|
||||||
if (e == NETERR_MTU && chan->fragmentsize > 560)
|
//ipv4 'guarentees' mtu sizes of at least 560ish.
|
||||||
|
//our reliable/backbuf messages are limited to 1024 bytes.
|
||||||
|
//this means that large reliables may be unsendable.
|
||||||
|
if (e == NETERR_MTU && chan->mtu > 560)
|
||||||
{
|
{
|
||||||
Con_Printf("Reducing MSS to %i\n", chan->fragmentsize);
|
Con_Printf("Reducing MSS to %i\n", chan->mtu);
|
||||||
chan->fragmentsize -= 10;
|
chan->mtu -= 10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{ //fte's fragmentaton protocol
|
||||||
int offset = 0, no;
|
int offset = 0, no;
|
||||||
qboolean more;
|
qboolean more;
|
||||||
|
|
||||||
|
@ -801,7 +815,7 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
||||||
/*send the additional parts, adding new headers within the previous packet*/
|
/*send the additional parts, adding new headers within the previous packet*/
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
no = offset + chan->fragmentsize - hsz;
|
no = offset + chan->mtu - hsz;
|
||||||
if (no < send.cursize-hsz)
|
if (no < send.cursize-hsz)
|
||||||
{
|
{
|
||||||
no &= ~7;
|
no &= ~7;
|
||||||
|
@ -831,10 +845,10 @@ int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate)
|
||||||
for (i = -1; i < chan->dupe && e == NETERR_SENT; i++)
|
for (i = -1; i < chan->dupe && e == NETERR_SENT; i++)
|
||||||
{
|
{
|
||||||
e = NET_SendPacket (chan->sock, (no - offset) + hsz, send.data + offset, &chan->remote_address);
|
e = NET_SendPacket (chan->sock, (no - offset) + hsz, send.data + offset, &chan->remote_address);
|
||||||
if (e == NETERR_MTU && !offset && chan->fragmentsize > 560)
|
if (e == NETERR_MTU && !offset && chan->mtu > 560)
|
||||||
{
|
{
|
||||||
chan->fragmentsize -= 16;
|
chan->mtu -= 16;
|
||||||
Con_Printf("Reducing MSS to %i\n", chan->fragmentsize);
|
Con_Printf("Reducing MSS to %i\n", chan->mtu);
|
||||||
no = offset;
|
no = offset;
|
||||||
more = true;
|
more = true;
|
||||||
break;
|
break;
|
||||||
|
@ -917,7 +931,7 @@ qboolean Netchan_Process (netchan_t *chan)
|
||||||
MSG_ReadShort ();
|
MSG_ReadShort ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (chan->fragmentsize)
|
if (chan->pext_fragmentation)
|
||||||
offset = (unsigned short)MSG_ReadShort();
|
offset = (unsigned short)MSG_ReadShort();
|
||||||
else
|
else
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
|
|
@ -101,9 +101,9 @@ FTE_ALIGN(4) qbyte net_message_buffer[MAX_OVERALLMSGLEN];
|
||||||
#define HAVE_NATPMP
|
#define HAVE_NATPMP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_SERVER) || defined(MASTERONLY)
|
//#if !defined(HAVE_SERVER) && !defined(MASTERONLY)
|
||||||
#define HAVE_HTTPSV
|
// #undef HAVE_HTTPSV
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
void NET_GetLocalAddress (int socket, netadr_t *out);
|
void NET_GetLocalAddress (int socket, netadr_t *out);
|
||||||
//int TCP_OpenListenSocket (const char *localip, int port);
|
//int TCP_OpenListenSocket (const char *localip, int port);
|
||||||
|
@ -127,6 +127,7 @@ cvar_t net_enable_qtv = CVARD("net_enable_qtv", "1", "Listens for qtv proxie
|
||||||
#if defined(HAVE_SSL)
|
#if defined(HAVE_SSL)
|
||||||
cvar_t net_enable_tls = CVARD("net_enable_tls", "1", "If enabled, binary data sent to a non-tls tcp port will be interpretted as a tls handshake (enabling https or wss over the same tcp port.");
|
cvar_t net_enable_tls = CVARD("net_enable_tls", "1", "If enabled, binary data sent to a non-tls tcp port will be interpretted as a tls handshake (enabling https or wss over the same tcp port.");
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_HTTPSV
|
||||||
#ifdef SV_MASTER
|
#ifdef SV_MASTER
|
||||||
cvar_t net_enable_http = CVARD("net_enable_http", "1", "If enabled, tcp ports will accept http clients, potentially serving large files which could distrupt gameplay.");
|
cvar_t net_enable_http = CVARD("net_enable_http", "1", "If enabled, tcp ports will accept http clients, potentially serving large files which could distrupt gameplay.");
|
||||||
#else
|
#else
|
||||||
|
@ -135,6 +136,7 @@ cvar_t net_enable_http = CVARD("net_enable_http", "0", "If enabled, tcp port
|
||||||
cvar_t net_enable_websockets = CVARD("net_enable_websockets", "1", "If enabled, tcp ports will accept websocket game clients.");
|
cvar_t net_enable_websockets = CVARD("net_enable_websockets", "1", "If enabled, tcp ports will accept websocket game clients.");
|
||||||
cvar_t net_enable_webrtcbroker = CVARD("net_enable_webrtcbroker", "0", "If 1, tcp ports will accept websocket connections from clients trying to broker direct webrtc connections. This should be low traffic, but might involve a lot of mostly-idle connections.");
|
cvar_t net_enable_webrtcbroker = CVARD("net_enable_webrtcbroker", "0", "If 1, tcp ports will accept websocket connections from clients trying to broker direct webrtc connections. This should be low traffic, but might involve a lot of mostly-idle connections.");
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#if defined(HAVE_DTLS) && defined(HAVE_SERVER)
|
#if defined(HAVE_DTLS) && defined(HAVE_SERVER)
|
||||||
static void QDECL NET_Enable_DTLS_Changed(struct cvar_s *var, char *oldvalue)
|
static void QDECL NET_Enable_DTLS_Changed(struct cvar_s *var, char *oldvalue)
|
||||||
{
|
{
|
||||||
|
@ -3693,10 +3695,10 @@ typedef struct ftenet_tcpconnect_stream_s {
|
||||||
{
|
{
|
||||||
TCPC_UNKNOWN, //waiting to see what they send us.
|
TCPC_UNKNOWN, //waiting to see what they send us.
|
||||||
TCPC_QIZMO, //'qizmo\n' handshake, followed by packets prefixed with a 16bit packet length.
|
TCPC_QIZMO, //'qizmo\n' handshake, followed by packets prefixed with a 16bit packet length.
|
||||||
|
#ifdef HAVE_HTTPSV
|
||||||
TCPC_WEBSOCKETU, //utf-8 encoded data.
|
TCPC_WEBSOCKETU, //utf-8 encoded data.
|
||||||
TCPC_WEBSOCKETB, //binary encoded data (subprotocol = 'binary')
|
TCPC_WEBSOCKETB, //binary encoded data (subprotocol = 'binary')
|
||||||
TCPC_WEBSOCKETNQ, //raw nq msg buffers with no encapsulation or handshake
|
TCPC_WEBSOCKETNQ, //raw nq msg buffers with no encapsulation or handshake
|
||||||
#ifdef HAVE_HTTPSV
|
|
||||||
TCPC_HTTPCLIENT, //we're sending a file to this victim.
|
TCPC_HTTPCLIENT, //we're sending a file to this victim.
|
||||||
TCPC_WEBRTC_CLIENT, //for brokering webrtc connections, doesn't carry any actual game data itself.
|
TCPC_WEBRTC_CLIENT, //for brokering webrtc connections, doesn't carry any actual game data itself.
|
||||||
TCPC_WEBRTC_HOST //for brokering webrtc connections, doesn't carry any actual game data itself.
|
TCPC_WEBRTC_HOST //for brokering webrtc connections, doesn't carry any actual game data itself.
|
||||||
|
@ -4718,8 +4720,8 @@ qboolean FTENET_TCP_ParseHTTPRequest(ftenet_tcpconnect_connection_t *con, ftenet
|
||||||
return FTENET_TCPConnect_HTTPResponse(st, arg, acceptsgzip);
|
return FTENET_TCPConnect_HTTPResponse(st, arg, acceptsgzip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#ifdef HAVE_SSL
|
#if defined(HAVE_SSL) && (defined(HAVE_SERVER) || defined(HAVE_HTTPSV))
|
||||||
static int QDECL TLSPromoteRead (struct vfsfile_s *file, void *buffer, int bytestoread)
|
static int QDECL TLSPromoteRead (struct vfsfile_s *file, void *buffer, int bytestoread)
|
||||||
{
|
{
|
||||||
if (bytestoread > net_message.cursize)
|
if (bytestoread > net_message.cursize)
|
||||||
|
@ -4730,7 +4732,6 @@ static int QDECL TLSPromoteRead (struct vfsfile_s *file, void *buffer, int bytes
|
||||||
return bytestoread;
|
return bytestoread;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
void FTENET_TCPConnect_PrintStatus(ftenet_generic_connection_t *gcon)
|
void FTENET_TCPConnect_PrintStatus(ftenet_generic_connection_t *gcon)
|
||||||
{
|
{
|
||||||
ftenet_tcpconnect_connection_t *con = (ftenet_tcpconnect_connection_t*)gcon;
|
ftenet_tcpconnect_connection_t *con = (ftenet_tcpconnect_connection_t*)gcon;
|
||||||
|
@ -4749,12 +4750,12 @@ void FTENET_TCPConnect_PrintStatus(ftenet_generic_connection_t *gcon)
|
||||||
case TCPC_QIZMO:
|
case TCPC_QIZMO:
|
||||||
Con_Printf("qizmo %s\n", adr);
|
Con_Printf("qizmo %s\n", adr);
|
||||||
break;
|
break;
|
||||||
|
#ifdef HAVE_HTTPSV
|
||||||
case TCPC_WEBSOCKETU:
|
case TCPC_WEBSOCKETU:
|
||||||
case TCPC_WEBSOCKETB:
|
case TCPC_WEBSOCKETB:
|
||||||
case TCPC_WEBSOCKETNQ:
|
case TCPC_WEBSOCKETNQ:
|
||||||
Con_Printf("websocket %s\n", adr);
|
Con_Printf("websocket %s\n", adr);
|
||||||
break;
|
break;
|
||||||
#ifdef HAVE_HTTPSV
|
|
||||||
case TCPC_HTTPCLIENT:
|
case TCPC_HTTPCLIENT:
|
||||||
Con_Printf("http %s\n", adr);
|
Con_Printf("http %s\n", adr);
|
||||||
break;
|
break;
|
||||||
|
@ -5011,13 +5012,12 @@ closesvstream:
|
||||||
net_from = st->remoteaddr;
|
net_from = st->remoteaddr;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
#ifdef HAVE_HTTPSV
|
||||||
case TCPC_WEBSOCKETU:
|
case TCPC_WEBSOCKETU:
|
||||||
case TCPC_WEBSOCKETB:
|
case TCPC_WEBSOCKETB:
|
||||||
case TCPC_WEBSOCKETNQ:
|
case TCPC_WEBSOCKETNQ:
|
||||||
#ifdef HAVE_HTTPSV
|
|
||||||
case TCPC_WEBRTC_HOST:
|
case TCPC_WEBRTC_HOST:
|
||||||
case TCPC_WEBRTC_CLIENT:
|
case TCPC_WEBRTC_CLIENT:
|
||||||
#endif
|
|
||||||
while (st->inlen >= 2)
|
while (st->inlen >= 2)
|
||||||
{
|
{
|
||||||
unsigned short ctrl = ((unsigned char*)st->inbuffer)[0]<<8 | ((unsigned char*)st->inbuffer)[1];
|
unsigned short ctrl = ((unsigned char*)st->inbuffer)[0]<<8 | ((unsigned char*)st->inbuffer)[1];
|
||||||
|
@ -5164,7 +5164,6 @@ closesvstream:
|
||||||
Con_TPrintf ("Warning: Oversize packet from %s\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr));
|
Con_TPrintf ("Warning: Oversize packet from %s\n", NET_AdrToString (adr, sizeof(adr), &st->remoteaddr));
|
||||||
goto closesvstream;
|
goto closesvstream;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_HTTPSV
|
|
||||||
#ifdef SUPPORT_RTC_ICE
|
#ifdef SUPPORT_RTC_ICE
|
||||||
if (st->clienttype == TCPC_WEBRTC_CLIENT && !*st->webrtc.resource)
|
if (st->clienttype == TCPC_WEBRTC_CLIENT && !*st->webrtc.resource)
|
||||||
{ //this is a client that's corrected directly to us via webrtc.
|
{ //this is a client that's corrected directly to us via webrtc.
|
||||||
|
@ -5203,7 +5202,6 @@ closesvstream:
|
||||||
net_message.cursize = 0;
|
net_message.cursize = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
if (st->clienttype == TCPC_WEBSOCKETNQ)
|
if (st->clienttype == TCPC_WEBSOCKETNQ)
|
||||||
{ //hack in an 8-byte header
|
{ //hack in an 8-byte header
|
||||||
|
@ -5248,6 +5246,7 @@ closesvstream:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5298,7 +5297,6 @@ closesvstream:
|
||||||
|
|
||||||
neterr_t FTENET_TCPConnect_SendPacket(ftenet_generic_connection_t *gcon, int length, const void *data, netadr_t *to)
|
neterr_t FTENET_TCPConnect_SendPacket(ftenet_generic_connection_t *gcon, int length, const void *data, netadr_t *to)
|
||||||
{
|
{
|
||||||
neterr_t e;
|
|
||||||
ftenet_tcpconnect_connection_t *con = (ftenet_tcpconnect_connection_t*)gcon;
|
ftenet_tcpconnect_connection_t *con = (ftenet_tcpconnect_connection_t*)gcon;
|
||||||
ftenet_tcpconnect_stream_t *st;
|
ftenet_tcpconnect_stream_t *st;
|
||||||
|
|
||||||
|
@ -5333,6 +5331,7 @@ neterr_t FTENET_TCPConnect_SendPacket(ftenet_generic_connection_t *gcon, int len
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifdef HAVE_HTTPSV
|
||||||
case TCPC_WEBSOCKETNQ:
|
case TCPC_WEBSOCKETNQ:
|
||||||
if (length < 8 || ((char*)data)[0] & 0x80)
|
if (length < 8 || ((char*)data)[0] & 0x80)
|
||||||
break;
|
break;
|
||||||
|
@ -5344,10 +5343,13 @@ neterr_t FTENET_TCPConnect_SendPacket(ftenet_generic_connection_t *gcon, int len
|
||||||
//fallthrough
|
//fallthrough
|
||||||
case TCPC_WEBSOCKETU:
|
case TCPC_WEBSOCKETU:
|
||||||
case TCPC_WEBSOCKETB:
|
case TCPC_WEBSOCKETB:
|
||||||
e = FTENET_TCPConnect_WebSocket_Splurge(st, (st->clienttype==TCPC_WEBSOCKETU)?1:2, data, length);
|
{
|
||||||
|
neterr_t e = FTENET_TCPConnect_WebSocket_Splurge(st, (st->clienttype==TCPC_WEBSOCKETU)?1:2, data, length);
|
||||||
if (e != NETERR_SENT)
|
if (e != NETERR_SENT)
|
||||||
return e;
|
return e;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -7877,10 +7879,12 @@ void NET_Init (void)
|
||||||
#if defined(HAVE_SSL)
|
#if defined(HAVE_SSL)
|
||||||
Cvar_Register(&net_enable_tls, "networking");
|
Cvar_Register(&net_enable_tls, "networking");
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_HTTPSV
|
||||||
Cvar_Register(&net_enable_http, "networking");
|
Cvar_Register(&net_enable_http, "networking");
|
||||||
Cvar_Register(&net_enable_websockets, "networking");
|
Cvar_Register(&net_enable_websockets, "networking");
|
||||||
Cvar_Register(&net_enable_webrtcbroker, "networking");
|
Cvar_Register(&net_enable_webrtcbroker, "networking");
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ void Plug_RegisterBuiltin(char *name, Plug_Builtin_t bi, int flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
//got an empty number.
|
//got an empty number.
|
||||||
Con_DPrintf("%s: %i\n", name, newnum);
|
Con_DLPrintf(2, "%s: %i\n", name, newnum);
|
||||||
plugbuiltins[newnum].name = name;
|
plugbuiltins[newnum].name = name;
|
||||||
plugbuiltins[newnum].func = bi;
|
plugbuiltins[newnum].func = bi;
|
||||||
plugbuiltins[newnum].flags = flags;
|
plugbuiltins[newnum].flags = flags;
|
||||||
|
|
|
@ -364,7 +364,9 @@ pubsubserver_t *Sys_ForkServer(void)
|
||||||
//make sure we're fully synced, so that workers can't mess up
|
//make sure we're fully synced, so that workers can't mess up
|
||||||
Cvar_Set(Cvar_FindVar("worker_count"), "0");
|
Cvar_Set(Cvar_FindVar("worker_count"), "0");
|
||||||
COM_WorkerFullSync();
|
COM_WorkerFullSync();
|
||||||
|
#ifdef WEBCLIENT
|
||||||
DL_DeThread();
|
DL_DeThread();
|
||||||
|
#endif
|
||||||
#ifdef SQL
|
#ifdef SQL
|
||||||
SQL_KillServers(); //FIXME: this is bad...
|
SQL_KillServers(); //FIXME: this is bad...
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -52,11 +52,11 @@ qbyte sentinalkey;
|
||||||
|
|
||||||
#define TAGLESS 1
|
#define TAGLESS 1
|
||||||
|
|
||||||
int zmemtotal;
|
size_t zmemtotal;
|
||||||
int zmemdelta;
|
size_t zmemdelta;
|
||||||
|
|
||||||
typedef struct memheader_s {
|
typedef struct memheader_s {
|
||||||
int size;
|
size_t size;
|
||||||
int tag;
|
int tag;
|
||||||
} memheader_t;
|
} memheader_t;
|
||||||
|
|
||||||
|
@ -108,13 +108,13 @@ static void Z_DumpTree(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *VARGS Z_TagMalloc(int size, int tag)
|
void *Z_TagMalloc(size_t size, int tag)
|
||||||
{
|
{
|
||||||
zone_t *zone;
|
zone_t *zone;
|
||||||
|
|
||||||
zone = (zone_t *)malloc(size + sizeof(zone_t));
|
zone = (zone_t *)malloc(size + sizeof(zone_t));
|
||||||
if (!zone)
|
if (!zone)
|
||||||
Sys_Error("Z_Malloc: Failed on allocation of %i bytes", size);
|
Sys_Error("Z_Malloc: Failed on allocation of %"PRIuSIZE" bytes", size);
|
||||||
Q_memset(zone, 0, size + sizeof(zone_t));
|
Q_memset(zone, 0, size + sizeof(zone_t));
|
||||||
zone->mh.tag = tag;
|
zone->mh.tag = tag;
|
||||||
zone->mh.size = size;
|
zone->mh.size = size;
|
||||||
|
@ -184,7 +184,7 @@ void *Z_MallocNamed(int size, char *file, int line)
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void *ZF_Malloc(int size)
|
void *ZF_Malloc(size_t size)
|
||||||
{
|
{
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
void *ret = NULL;
|
void *ret = NULL;
|
||||||
|
@ -202,11 +202,11 @@ void *ZF_Malloc(int size)
|
||||||
return calloc(size, 1);
|
return calloc(size, 1);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void *Z_Malloc(int size)
|
void *Z_Malloc(size_t size)
|
||||||
{
|
{
|
||||||
void *mem = ZF_Malloc(size);
|
void *mem = ZF_Malloc(size);
|
||||||
if (!mem)
|
if (!mem)
|
||||||
Sys_Error("Z_Malloc: Failed on allocation of %i bytes", size);
|
Sys_Error("Z_Malloc: Failed on allocation of %"PRIuSIZE" bytes", size);
|
||||||
|
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
@ -423,7 +423,7 @@ void *BZF_MallocNamed(int size, const char *file, int line) //BZ_MallocNamed but
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void *BZF_Malloc(int size) //BZ_Malloc but allowed to fail - like straight malloc.
|
void *BZF_Malloc(size_t size) //BZ_Malloc but allowed to fail - like straight malloc.
|
||||||
{
|
{
|
||||||
void *mem;
|
void *mem;
|
||||||
mem = malloc(size);
|
mem = malloc(size);
|
||||||
|
@ -446,11 +446,11 @@ void *BZ_MallocNamed(int size, const char *file, int line) //BZ_MallocNamed but
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void *BZ_Malloc(int size) //Doesn't clear. The expectation is a large file, rather than sensitive data structures.
|
void *BZ_Malloc(size_t size) //Doesn't clear. The expectation is a large file, rather than sensitive data structures.
|
||||||
{
|
{
|
||||||
void *mem = BZF_Malloc(size);
|
void *mem = BZF_Malloc(size);
|
||||||
if (!mem)
|
if (!mem)
|
||||||
Sys_Error("BZ_Malloc: Failed on allocation of %i bytes", size);
|
Sys_Error("BZ_Malloc: Failed on allocation of %"PRIuSIZE" bytes", size);
|
||||||
|
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
@ -472,17 +472,17 @@ void *BZ_ReallocNamed(void *data, int newsize, const char *file, int line)
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void *BZF_Realloc(void *data, int newsize)
|
void *BZF_Realloc(void *data, size_t newsize)
|
||||||
{
|
{
|
||||||
return realloc(data, newsize);
|
return realloc(data, newsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *BZ_Realloc(void *data, int newsize)
|
void *BZ_Realloc(void *data, size_t newsize)
|
||||||
{
|
{
|
||||||
void *mem = BZF_Realloc(data, newsize);
|
void *mem = BZF_Realloc(data, newsize);
|
||||||
|
|
||||||
if (!mem)
|
if (!mem)
|
||||||
Sys_Error("BZ_Realloc: Failed on reallocation of %i bytes", newsize);
|
Sys_Error("BZ_Realloc: Failed on reallocation of %"PRIuSIZE" bytes", newsize);
|
||||||
|
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
@ -508,7 +508,7 @@ typedef struct zonegroupblock_s
|
||||||
void *QDECL ZG_Malloc(zonegroup_t *ctx, int size){return ZG_MallocNamed(ctx, size, "ZG_Malloc", size);}
|
void *QDECL ZG_Malloc(zonegroup_t *ctx, int size){return ZG_MallocNamed(ctx, size, "ZG_Malloc", size);}
|
||||||
void *ZG_MallocNamed(zonegroup_t *ctx, int size, char *file, int line)
|
void *ZG_MallocNamed(zonegroup_t *ctx, int size, char *file, int line)
|
||||||
#else
|
#else
|
||||||
void *QDECL ZG_Malloc(zonegroup_t *ctx, int size)
|
void *QDECL ZG_Malloc(zonegroup_t *ctx, size_t size)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
zonegroupblock_t *newm;
|
zonegroupblock_t *newm;
|
||||||
|
@ -590,7 +590,7 @@ void Hunk_TempFree(void)
|
||||||
|
|
||||||
//allocates without clearing previous temp.
|
//allocates without clearing previous temp.
|
||||||
//safer than my hack that fuh moaned about...
|
//safer than my hack that fuh moaned about...
|
||||||
void *Hunk_TempAllocMore (int size)
|
void *Hunk_TempAllocMore (size_t size)
|
||||||
{
|
{
|
||||||
void *buf;
|
void *buf;
|
||||||
|
|
||||||
|
@ -624,7 +624,7 @@ void *Hunk_TempAllocMore (int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void *Hunk_TempAlloc (int size)
|
void *Hunk_TempAlloc (size_t size)
|
||||||
{
|
{
|
||||||
Hunk_TempFree();
|
Hunk_TempFree();
|
||||||
|
|
||||||
|
@ -657,8 +657,8 @@ void Cache_Flush(void)
|
||||||
|
|
||||||
static void Hunk_Print_f (void)
|
static void Hunk_Print_f (void)
|
||||||
{
|
{
|
||||||
Con_Printf("Z Delta: %iKB\n", zmemdelta/1024); zmemdelta = 0;
|
Con_Printf("Z Delta: %"PRIuSIZE"KB\n", zmemdelta/1024); zmemdelta = 0;
|
||||||
Con_Printf("Z Total: %iKB\n", zmemtotal/1024);
|
Con_Printf("Z Total: %"PRIuSIZE"KB\n", zmemtotal/1024);
|
||||||
//note: Zone memory isn't tracked reliably. we don't track the mem that is freed, so it'll just climb and climb
|
//note: Zone memory isn't tracked reliably. we don't track the mem that is freed, so it'll just climb and climb
|
||||||
//we don't track reallocs either.
|
//we don't track reallocs either.
|
||||||
|
|
||||||
|
|
|
@ -87,12 +87,12 @@ void Memory_Init (void);
|
||||||
void Memory_DeInit(void);
|
void Memory_DeInit(void);
|
||||||
|
|
||||||
void VARGS Z_Free (void *ptr);
|
void VARGS Z_Free (void *ptr);
|
||||||
void *Z_Malloc (int size); // returns 0 filled memory
|
void *Z_Malloc (size_t size); // returns 0 filled memory
|
||||||
void *ZF_Malloc (int size); // allowed to fail
|
void *ZF_Malloc (size_t size); // allowed to fail
|
||||||
void *Z_MallocNamed (int size, char *file, int line); // returns 0 filled memory
|
void *Z_MallocNamed (size_t size, char *file, int line); // returns 0 filled memory
|
||||||
void *ZF_MallocNamed (int size, char *file, int line); // allowed to fail
|
void *ZF_MallocNamed (size_t size, char *file, int line); // allowed to fail
|
||||||
//#define Z_Malloc(x) Z_MallocNamed2(x, __FILE__, __LINE__ )
|
//#define Z_Malloc(x) Z_MallocNamed2(x, __FILE__, __LINE__ )
|
||||||
void *VARGS Z_TagMalloc (int size, int tag);
|
void *Z_TagMalloc (size_t size, int tag);
|
||||||
void VARGS Z_TagFree(void *ptr);
|
void VARGS Z_TagFree(void *ptr);
|
||||||
void VARGS Z_FreeTags(int tag);
|
void VARGS Z_FreeTags(int tag);
|
||||||
qboolean ZF_ReallocElements(void **ptr, size_t *elements, size_t newelements, size_t elementsize); //returns false on error
|
qboolean ZF_ReallocElements(void **ptr, size_t *elements, size_t newelements, size_t elementsize); //returns false on error
|
||||||
|
@ -101,14 +101,14 @@ qboolean ZF_ReallocElementsNamed(void **ptr, size_t *elements, size_t newelement
|
||||||
|
|
||||||
//Big Zone: allowed to fail, doesn't clear. The expectation is a large file, rather than sensitive data structures.
|
//Big Zone: allowed to fail, doesn't clear. The expectation is a large file, rather than sensitive data structures.
|
||||||
//(this is a nicer name for malloc)
|
//(this is a nicer name for malloc)
|
||||||
void *BZ_Malloc(int size);
|
void *BZ_Malloc(size_t size);
|
||||||
void *BZF_Malloc(int size);
|
void *BZF_Malloc(size_t size);
|
||||||
void *BZ_MallocNamed (int size, const char *file, int line); // returns 0 filled memory
|
void *BZ_MallocNamed (size_t size, const char *file, int line); // returns 0 filled memory
|
||||||
void *BZF_MallocNamed (int size, const char *file, int line); // allowed to fail
|
void *BZF_MallocNamed (size_t size, const char *file, int line); // allowed to fail
|
||||||
void *BZ_Realloc(void *ptr, int size);
|
void *BZ_Realloc(void *ptr, size_t size);
|
||||||
void *BZ_ReallocNamed(void *data, int newsize, const char *file, int line);
|
void *BZ_ReallocNamed(void *data, size_t newsize, const char *file, int line);
|
||||||
void *BZF_Realloc(void *data, int newsize);
|
void *BZF_Realloc(void *data, size_t newsize);
|
||||||
void *BZF_ReallocNamed(void *data, int newsize, const char *file, int line);
|
void *BZF_ReallocNamed(void *data, size_t newsize, const char *file, int line);
|
||||||
void BZ_Free(void *ptr);
|
void BZ_Free(void *ptr);
|
||||||
|
|
||||||
//ctx should start off as void*ctx=NULL
|
//ctx should start off as void*ctx=NULL
|
||||||
|
@ -117,8 +117,8 @@ typedef struct zonegroup_s
|
||||||
void *first;
|
void *first;
|
||||||
int bytes;
|
int bytes;
|
||||||
} zonegroup_t;
|
} zonegroup_t;
|
||||||
void *QDECL ZG_Malloc(zonegroup_t *ctx, int size);
|
void *QDECL ZG_Malloc(zonegroup_t *ctx, size_t size);
|
||||||
void *ZG_MallocNamed(zonegroup_t *ctx, int size, char *file, int line);
|
void *ZG_MallocNamed(zonegroup_t *ctx, size_t size, char *file, int line);
|
||||||
void ZG_FreeGroup(zonegroup_t *ctx);
|
void ZG_FreeGroup(zonegroup_t *ctx);
|
||||||
|
|
||||||
#ifdef USE_MSVCRT_DEBUG
|
#ifdef USE_MSVCRT_DEBUG
|
||||||
|
@ -141,8 +141,8 @@ void *Hunk_Alloc (int size); // returns 0 filled memory
|
||||||
void *Hunk_AllocName (int size, char *name);
|
void *Hunk_AllocName (int size, char *name);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void *Hunk_TempAlloc (int size);
|
void *Hunk_TempAlloc (size_t size);
|
||||||
void *Hunk_TempAllocMore (int size); //Don't clear old temp
|
void *Hunk_TempAllocMore (size_t size); //Don't clear old temp
|
||||||
|
|
||||||
/*
|
/*
|
||||||
typedef struct cache_user_s
|
typedef struct cache_user_s
|
||||||
|
|
|
@ -15,4 +15,5 @@ vid_conwidth "0" //make something up based upon aspect ratio
|
||||||
vid_conheight "300" //not using autoscale as it can make the menu unusable.
|
vid_conheight "300" //not using autoscale as it can make the menu unusable.
|
||||||
vid_conautoscale "0" // Text/Menu size. 2 is the default. 4 is bigger
|
vid_conautoscale "0" // Text/Menu size. 2 is the default. 4 is bigger
|
||||||
|
|
||||||
|
scr_consize 0.4 //android's onscreen keyboard can take up over half the screen (and we don't know exactly where it is).
|
||||||
exec touch.cfg
|
exec touch.cfg
|
||||||
|
|
|
@ -4725,6 +4725,20 @@ static void DrawMeshes(void)
|
||||||
p = &shaderstate.curshader->passes[passno];
|
p = &shaderstate.curshader->passes[passno];
|
||||||
passno += p->numMergedPasses;
|
passno += p->numMergedPasses;
|
||||||
|
|
||||||
|
if (p->prog)
|
||||||
|
{
|
||||||
|
shaderstate.pendingcolourvbo = shaderstate.sourcevbo->colours[0].gl.vbo;
|
||||||
|
shaderstate.pendingcolourpointer = shaderstate.sourcevbo->colours[0].gl.addr;
|
||||||
|
shaderstate.colourarraytype = shaderstate.sourcevbo->colours_bytes?GL_UNSIGNED_BYTE:GL_FLOAT;
|
||||||
|
|
||||||
|
shaderstate.pendingtexcoordparts[0] = 2;
|
||||||
|
shaderstate.pendingtexcoordvbo[0] = shaderstate.sourcevbo->texcoord.gl.vbo;
|
||||||
|
shaderstate.pendingtexcoordpointer[0] = shaderstate.sourcevbo->texcoord.gl.addr;
|
||||||
|
|
||||||
|
BE_RenderMeshProgram(shaderstate.curshader, p, p->prog);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
emumode = 0;
|
emumode = 0;
|
||||||
emumode = (p->shaderbits & SBITS_ATEST_BITS) >> SBITS_ATEST_SHIFT;
|
emumode = (p->shaderbits & SBITS_ATEST_BITS) >> SBITS_ATEST_SHIFT;
|
||||||
|
|
||||||
|
|
|
@ -135,11 +135,11 @@ void GL_SetupFormats(void)
|
||||||
if (gl_config_gles)
|
if (gl_config_gles)
|
||||||
{
|
{
|
||||||
//pre-3 gles doesn't support sized formats, and only a limited number of them too
|
//pre-3 gles doesn't support sized formats, and only a limited number of them too
|
||||||
glfmtc(PTI_RGB8, GL_RGB, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, tc_rgb);
|
glfmtc(PTI_RGB8, 0, GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, tc_rgb);
|
||||||
glfmtc(PTI_RGBA8, GL_RGBA, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tc_rgba8);
|
glfmtc(PTI_RGBA8, 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, tc_rgba8);
|
||||||
glfmt(PTI_L8A8, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
|
glfmt(PTI_L8A8, 0, GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
|
||||||
glfmt(PTI_L8, GL_LUMINANCE, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE);
|
glfmt(PTI_L8, 0, GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE);
|
||||||
// glfmt(PTI_RGBA8, GL_ALPHA, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);
|
// glfmt(PTI_A8, 0, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE);
|
||||||
|
|
||||||
if (!gl_config.webgl_ie)
|
if (!gl_config.webgl_ie)
|
||||||
{ //these should work on all gles2+webgl1 devices, but microsoft doesn't give a shit.
|
{ //these should work on all gles2+webgl1 devices, but microsoft doesn't give a shit.
|
||||||
|
@ -754,7 +754,6 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
|
||||||
{
|
{
|
||||||
qglTexParameteri(targ, GL_TEXTURE_BASE_LEVEL, 0);
|
qglTexParameteri(targ, GL_TEXTURE_BASE_LEVEL, 0);
|
||||||
qglTexParameteri(targ, GL_TEXTURE_MAX_LEVEL, nummips-1);
|
qglTexParameteri(targ, GL_TEXTURE_MAX_LEVEL, nummips-1);
|
||||||
qglTexParameteri(targ, GL_TEXTURE_LOD_BIAS, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,10 @@ struct patchvert_s
|
||||||
cvar_t mod_terrain_networked = CVARD("mod_terrain_networked", "0", "Terrain edits are networked. Clients will download sections on demand, and servers will notify clients of changes.");
|
cvar_t mod_terrain_networked = CVARD("mod_terrain_networked", "0", "Terrain edits are networked. Clients will download sections on demand, and servers will notify clients of changes.");
|
||||||
cvar_t mod_terrain_defaulttexture = CVARD("mod_terrain_defaulttexture", "", "Newly created terrain tiles will use this texture. This should generally be updated by the terrain editor.");
|
cvar_t mod_terrain_defaulttexture = CVARD("mod_terrain_defaulttexture", "", "Newly created terrain tiles will use this texture. This should generally be updated by the terrain editor.");
|
||||||
cvar_t mod_terrain_savever = CVARD("mod_terrain_savever", "", "Which terrain section version to write if terrain was edited.");
|
cvar_t mod_terrain_savever = CVARD("mod_terrain_savever", "", "Which terrain section version to write if terrain was edited.");
|
||||||
|
cvar_t mod_terrain_sundir = CVARD("mod_terrain_sundir", "0.4 0.7 2", "The direction of the sun (vector will be normalised).");
|
||||||
|
cvar_t mod_terrain_ambient = CVARD("mod_terrain_ambient", "0.5", "Proportion of ambient light.");
|
||||||
|
cvar_t mod_terrain_shadows = CVARD("mod_terrain_shadows", "0", "Cast rays to determine whether parts of the terrain should be in shadow.");
|
||||||
|
cvar_t mod_terrain_shadow_dist = CVARD("mod_terrain_shadow_dist", "2048", "How far rays should be cast in order to look for occlusing geometry.");
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -81,7 +85,7 @@ void validatelinks2(link_t *firstnode, link_t *panic)
|
||||||
|
|
||||||
|
|
||||||
#ifndef SERVERONLY
|
#ifndef SERVERONLY
|
||||||
static void ted_dorelight(heightmap_t *hm);
|
static void ted_dorelight(model_t *m, heightmap_t *hm);
|
||||||
static void Terr_WorkerLoadedSectionLightmap(void *ctx, void *data, size_t a, size_t b);
|
static void Terr_WorkerLoadedSectionLightmap(void *ctx, void *data, size_t a, size_t b);
|
||||||
static qboolean Terr_Collect(heightmap_t *hm);
|
static qboolean Terr_Collect(heightmap_t *hm);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1933,6 +1937,18 @@ void Terr_DestroySection(heightmap_t *hm, hmsection_t *s, qboolean lightmapreusa
|
||||||
if (!s || s->loadstate < TSLS_LOADING2)
|
if (!s || s->loadstate < TSLS_LOADING2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
{
|
||||||
|
int cx = s->sx/MAXSECTIONS;
|
||||||
|
int cy = s->sy/MAXSECTIONS;
|
||||||
|
hmcluster_t *c = hm->cluster[cx + cy*MAXCLUSTERS];
|
||||||
|
int sx = s->sx & (MAXSECTIONS-1);
|
||||||
|
int sy = s->sy & (MAXSECTIONS-1);
|
||||||
|
|
||||||
|
if (c->section[sx+sy*MAXSECTIONS] != s)
|
||||||
|
Sys_Error("Section %i,%i already destroyed...\n", s->sx, s->sy);
|
||||||
|
c->section[sx+sy*MAXSECTIONS] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
validatelinks(&hm->recycle);
|
validatelinks(&hm->recycle);
|
||||||
|
|
||||||
RemoveLink(&s->recycle);
|
RemoveLink(&s->recycle);
|
||||||
|
@ -1965,13 +1981,19 @@ void Terr_DestroySection(heightmap_t *hm, hmsection_t *s, qboolean lightmapreusa
|
||||||
if (qrenderer == QR_OPENGL)
|
if (qrenderer == QR_OPENGL)
|
||||||
{
|
{
|
||||||
if (qglDeleteBuffersARB)
|
if (qglDeleteBuffersARB)
|
||||||
|
{
|
||||||
|
if (s->vbo.coord.gl.vbo)
|
||||||
{
|
{
|
||||||
qglDeleteBuffersARB(1, &s->vbo.coord.gl.vbo);
|
qglDeleteBuffersARB(1, &s->vbo.coord.gl.vbo);
|
||||||
s->vbo.coord.gl.vbo = 0;
|
s->vbo.coord.gl.vbo = 0;
|
||||||
|
}
|
||||||
|
if (s->vbo.indicies.gl.vbo)
|
||||||
|
{
|
||||||
qglDeleteBuffersARB(1, &s->vbo.indicies.gl.vbo);
|
qglDeleteBuffersARB(1, &s->vbo.indicies.gl.vbo);
|
||||||
s->vbo.indicies.gl.vbo = 0;
|
s->vbo.indicies.gl.vbo = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
@ -2123,8 +2145,6 @@ validatelinks(&hm->recycle);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c->section[sx+sy*MAXSECTIONS] = NULL;
|
|
||||||
|
|
||||||
validatelinks(&hm->recycle);
|
validatelinks(&hm->recycle);
|
||||||
Terr_DestroySection(hm, s, lightmapreusable);
|
Terr_DestroySection(hm, s, lightmapreusable);
|
||||||
validatelinks(&hm->recycle);
|
validatelinks(&hm->recycle);
|
||||||
|
@ -2999,7 +3019,7 @@ void Terr_DrawTerrainModel (batch_t **batches, entity_t *e)
|
||||||
|
|
||||||
// hm->beinglazy = false;
|
// hm->beinglazy = false;
|
||||||
if (hm->relight)
|
if (hm->relight)
|
||||||
ted_dorelight(hm);
|
ted_dorelight(m, hm);
|
||||||
|
|
||||||
if (e->model == cl.worldmodel && hm->skyshader)
|
if (e->model == cl.worldmodel && hm->skyshader)
|
||||||
{
|
{
|
||||||
|
@ -3310,9 +3330,10 @@ unsigned int Heightmap_NativeBoxContents(model_t *model, int hulloverride, frame
|
||||||
return Heightmap_PointContentsHM(hm, mins[2], org);
|
return Heightmap_PointContentsHM(hm, mins[2], org);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Heightmap_Normal(heightmap_t *hm, vec3_t org, vec3_t norm)
|
float Heightmap_Normal(heightmap_t *hm, vec2_t org, vec3_t norm) //returns the z
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
|
float z = 0;
|
||||||
norm[0] = 0;
|
norm[0] = 0;
|
||||||
norm[1] = 0;
|
norm[1] = 0;
|
||||||
norm[2] = 1;
|
norm[2] = 1;
|
||||||
|
@ -3322,6 +3343,7 @@ void Heightmap_Normal(heightmap_t *hm, vec3_t org, vec3_t norm)
|
||||||
vec3_t d1, d2;
|
vec3_t d1, d2;
|
||||||
const float wbias = CHUNKBIAS * hm->sectionsize;
|
const float wbias = CHUNKBIAS * hm->sectionsize;
|
||||||
hmsection_t *s;
|
hmsection_t *s;
|
||||||
|
float z;
|
||||||
|
|
||||||
norm[0] = 0;
|
norm[0] = 0;
|
||||||
norm[1] = 0;
|
norm[1] = 0;
|
||||||
|
@ -3330,12 +3352,12 @@ void Heightmap_Normal(heightmap_t *hm, vec3_t org, vec3_t norm)
|
||||||
sx = (org[0]+wbias)/hm->sectionsize;
|
sx = (org[0]+wbias)/hm->sectionsize;
|
||||||
sy = (org[1]+wbias)/hm->sectionsize;
|
sy = (org[1]+wbias)/hm->sectionsize;
|
||||||
if (sx < hm->firstsegx || sy < hm->firstsegy)
|
if (sx < hm->firstsegx || sy < hm->firstsegy)
|
||||||
return;
|
return hm->defaultgroundheight;
|
||||||
if (sx >= hm->maxsegx || sy >= hm->maxsegy)
|
if (sx >= hm->maxsegx || sy >= hm->maxsegy)
|
||||||
return;
|
return hm->defaultgroundheight;
|
||||||
s = Terr_GetSection(hm, sx, sy, TGS_TRYLOAD);
|
s = Terr_GetSection(hm, sx, sy, TGS_TRYLOAD);
|
||||||
if (!s)
|
if (!s)
|
||||||
return;
|
return hm->defaultgroundheight;
|
||||||
|
|
||||||
x = (org[0]+wbias - (sx*hm->sectionsize))*(SECTHEIGHTSIZE-1)/hm->sectionsize;
|
x = (org[0]+wbias - (sx*hm->sectionsize))*(SECTHEIGHTSIZE-1)/hm->sectionsize;
|
||||||
y = (org[1]+wbias - (sy*hm->sectionsize))*(SECTHEIGHTSIZE-1)/hm->sectionsize;
|
y = (org[1]+wbias - (sy*hm->sectionsize))*(SECTHEIGHTSIZE-1)/hm->sectionsize;
|
||||||
|
@ -3354,6 +3376,10 @@ void Heightmap_Normal(heightmap_t *hm, vec3_t org, vec3_t norm)
|
||||||
d2[0] = 0;
|
d2[0] = 0;
|
||||||
d2[1] = (hm->sectionsize / SECTHEIGHTSIZE);
|
d2[1] = (hm->sectionsize / SECTHEIGHTSIZE);
|
||||||
d2[2] = (s->heights[(sx+1)+(sy+1)*SECTHEIGHTSIZE] - s->heights[(sx+1)+(sy+0)*SECTHEIGHTSIZE]);
|
d2[2] = (s->heights[(sx+1)+(sy+1)*SECTHEIGHTSIZE] - s->heights[(sx+1)+(sy+0)*SECTHEIGHTSIZE]);
|
||||||
|
|
||||||
|
z = (s->heights[(sx+0)+(sy+1)*SECTHEIGHTSIZE]*(1-y) +
|
||||||
|
s->heights[(sx+1)+(sy+1)*SECTHEIGHTSIZE]*(x+y-1) +
|
||||||
|
s->heights[(sx+1)+(sy+0)*SECTHEIGHTSIZE]*(1-x));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //the 0,0 triangle
|
{ //the 0,0 triangle
|
||||||
|
@ -3366,13 +3392,19 @@ void Heightmap_Normal(heightmap_t *hm, vec3_t org, vec3_t norm)
|
||||||
d2[0] = 0;
|
d2[0] = 0;
|
||||||
d2[1] = (hm->sectionsize / SECTHEIGHTSIZE);
|
d2[1] = (hm->sectionsize / SECTHEIGHTSIZE);
|
||||||
d2[2] = (s->heights[(sx+0)+(sy+1)*SECTHEIGHTSIZE] - s->heights[(sx+0)+(sy+0)*SECTHEIGHTSIZE]);
|
d2[2] = (s->heights[(sx+0)+(sy+1)*SECTHEIGHTSIZE] - s->heights[(sx+0)+(sy+0)*SECTHEIGHTSIZE]);
|
||||||
|
|
||||||
|
z = (s->heights[(sx+0)+(sy+1)*SECTHEIGHTSIZE]*(y) +
|
||||||
|
s->heights[(sx+1)+(sy+0)*SECTHEIGHTSIZE]*(x) +
|
||||||
|
s->heights[(sx+0)+(sy+0)*SECTHEIGHTSIZE]*(1-y-x));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VectorNormalize(d1);
|
VectorNormalize(d1);
|
||||||
VectorNormalize(d2);
|
VectorNormalize(d2);
|
||||||
CrossProduct(d1, d2, norm);
|
CrossProduct(d1, d2, norm);
|
||||||
VectorNormalize(norm);
|
VectorNormalize(norm);
|
||||||
#endif
|
#endif
|
||||||
|
return z;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -4244,11 +4276,11 @@ qboolean Heightmap_Trace_Test(struct model_s *model, int hulloverride, framestat
|
||||||
qboolean ret = Heightmap_Trace(model, hulloverride, framestate, mataxis, start, end, mins, maxs, capsule, against, trace);
|
qboolean ret = Heightmap_Trace(model, hulloverride, framestate, mataxis, start, end, mins, maxs, capsule, against, trace);
|
||||||
|
|
||||||
if (!trace->startsolid)
|
if (!trace->startsolid)
|
||||||
{
|
{ //FIXME: this code should not be needed.
|
||||||
trace_t testtrace;
|
trace_t testtrace;
|
||||||
Heightmap_Trace(model, hulloverride, framestate, mataxis, trace->endpos, trace->endpos, mins, maxs, capsule, against, &testtrace);
|
Heightmap_Trace(model, hulloverride, framestate, mataxis, trace->endpos, trace->endpos, mins, maxs, capsule, against, &testtrace);
|
||||||
if (testtrace.startsolid)
|
if (testtrace.startsolid)
|
||||||
{
|
{ //yup, we're bugged.
|
||||||
Con_DPrintf("Trace became solid\n");
|
Con_DPrintf("Trace became solid\n");
|
||||||
trace->fraction = 0;
|
trace->fraction = 0;
|
||||||
VectorCopy(start, trace->endpos);
|
VectorCopy(start, trace->endpos);
|
||||||
|
@ -4370,32 +4402,37 @@ static unsigned char *QDECL Terr_GetLightmap(hmsection_t *s, int idx, qboolean e
|
||||||
}
|
}
|
||||||
return lightmap[s->lightmap]->lightmaps + ((s->lmy+y) * HMLMSTRIDE + (s->lmx+x)) * lightmap[s->lightmap]->pixbytes;
|
return lightmap[s->lightmap]->lightmaps + ((s->lmy+y) * HMLMSTRIDE + (s->lmx+x)) * lightmap[s->lightmap]->pixbytes;
|
||||||
}
|
}
|
||||||
static void ted_dorelight(heightmap_t *hm)
|
static void ted_dorelight(model_t *m, heightmap_t *hm)
|
||||||
{
|
{
|
||||||
unsigned char *lm = Terr_GetLightmap(hm->relight, 0, true);
|
unsigned char *lm = Terr_GetLightmap(hm->relight, 0, true);
|
||||||
int x, y;
|
int x, y, k;
|
||||||
#define EXPAND 2
|
#define EXPAND 2
|
||||||
vec3_t surfnorms[(SECTTEXSIZE+EXPAND*2)*(SECTTEXSIZE+EXPAND*2)];
|
vec3_t surfnorms[(SECTTEXSIZE+EXPAND*2)*(SECTTEXSIZE+EXPAND*2)];
|
||||||
|
vec3_t surfpoint[(SECTTEXSIZE+EXPAND*2)*(SECTTEXSIZE+EXPAND*2)];
|
||||||
// float scaletab[EXPAND*2*EXPAND*2];
|
// float scaletab[EXPAND*2*EXPAND*2];
|
||||||
vec3_t ldir = {0.4, 0.7, 2};
|
vec3_t ldir;
|
||||||
hmsection_t *s = hm->relight;
|
hmsection_t *s = hm->relight;
|
||||||
|
float ambient, diffuse;
|
||||||
|
trace_t trace;
|
||||||
s->flags &= ~TSF_RELIGHT;
|
s->flags &= ~TSF_RELIGHT;
|
||||||
hm->relight = NULL;
|
hm->relight = NULL;
|
||||||
|
|
||||||
if (s->lightmap < 0)
|
if (s->lightmap < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
ambient = 255*mod_terrain_ambient.value;
|
||||||
|
diffuse = 255-ambient;
|
||||||
|
|
||||||
for (y = -EXPAND; y < SECTTEXSIZE+EXPAND; y++)
|
for (y = -EXPAND; y < SECTTEXSIZE+EXPAND; y++)
|
||||||
for (x = -EXPAND; x < SECTTEXSIZE+EXPAND; x++)
|
for (x = -EXPAND; x < SECTTEXSIZE+EXPAND; x++)
|
||||||
{
|
{
|
||||||
vec3_t pos;
|
k = x+EXPAND + (y+EXPAND)*(SECTTEXSIZE+EXPAND*2);
|
||||||
pos[0] = hm->relightmin[0] + (x*hm->sectionsize/(SECTTEXSIZE-1));
|
surfpoint[k][0] = hm->relightmin[0] + (x*hm->sectionsize/(SECTTEXSIZE-1));
|
||||||
pos[1] = hm->relightmin[1] + (y*hm->sectionsize/(SECTTEXSIZE-1));
|
surfpoint[k][1] = hm->relightmin[1] + (y*hm->sectionsize/(SECTTEXSIZE-1));
|
||||||
pos[2] = 0;
|
surfpoint[k][2] = Heightmap_Normal(s->hmmod, surfpoint[k], surfnorms[k])+0.1;
|
||||||
Heightmap_Normal(s->hmmod, pos, surfnorms[x+EXPAND + (y+EXPAND)*(SECTTEXSIZE+EXPAND*2)]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorNormalize(ldir);
|
VectorNormalize2(mod_terrain_sundir.vec4, ldir);
|
||||||
|
|
||||||
for (y = 0; y < SECTTEXSIZE; y++, lm += (HMLMSTRIDE-SECTTEXSIZE)*4)
|
for (y = 0; y < SECTTEXSIZE; y++, lm += (HMLMSTRIDE-SECTTEXSIZE)*4)
|
||||||
for (x = 0; x < SECTTEXSIZE; x++, lm += 4)
|
for (x = 0; x < SECTTEXSIZE; x++, lm += 4)
|
||||||
|
@ -4415,10 +4452,18 @@ static void ted_dorelight(heightmap_t *hm)
|
||||||
d = DotProduct(ldir, norm);
|
d = DotProduct(ldir, norm);
|
||||||
if (d < 0)
|
if (d < 0)
|
||||||
d = 0;
|
d = 0;
|
||||||
|
else if (mod_terrain_shadows.ival)
|
||||||
|
{
|
||||||
|
float *point = surfpoint[x+EXPAND + (y+EXPAND)*(SECTTEXSIZE+EXPAND*2)];
|
||||||
|
vec3_t sun;
|
||||||
|
VectorMA(point, mod_terrain_shadow_dist.value, ldir, sun);
|
||||||
|
if (m->funcs.NativeTrace(m, 0, NULL, NULL, point, sun, vec3_origin, vec3_origin, false, FTECONTENTS_SOLID|FTECONTENTS_BODY, &trace))
|
||||||
|
d = 0;
|
||||||
|
}
|
||||||
// lm[0] = norm[0]*127 + 128;
|
// lm[0] = norm[0]*127 + 128;
|
||||||
// lm[1] = norm[1]*127 + 128;
|
// lm[1] = norm[1]*127 + 128;
|
||||||
// lm[2] = norm[2]*127 + 128;
|
// lm[2] = norm[2]*127 + 128;
|
||||||
lm[3] = 127 + d*128;
|
lm[3] = ambient + d*diffuse;
|
||||||
}
|
}
|
||||||
|
|
||||||
lightmap[s->lightmap]->modified = true;
|
lightmap[s->lightmap]->modified = true;
|
||||||
|
@ -7102,11 +7147,11 @@ void Terr_WriteBrushInfo(vfsfile_t *file, brushes_t *br)
|
||||||
}
|
}
|
||||||
hasrgba = (y < br->patch->ypoints*br->patch->xpoints);
|
hasrgba = (y < br->patch->ypoints*br->patch->xpoints);
|
||||||
|
|
||||||
VFS_PRINTF(file, "\n\tpatchDef%s\n\t{\n\t\t\"%s\"\n\t\t( %.9g %.9g %.9g %.9g %.9g )\n\t\t(\n",
|
VFS_PRINTF(file, "\n\tpatchDef%s\n\t{\n\t\t\"%s\"\n\t\t( %u %u %.9g %.9g %.9g )\n\t\t(\n",
|
||||||
hasrgba?"WS":"2",
|
hasrgba?"WS":"2",
|
||||||
br->patch->tex?br->patch->tex->shadername:"",
|
br->patch->tex?br->patch->tex->shadername:"",
|
||||||
0.0/*xoffset*/,
|
br->patch->xpoints/*width*/,
|
||||||
0.0/*yoffset*/,
|
br->patch->ypoints/*height*/,
|
||||||
0.0/*rotation*/,
|
0.0/*rotation*/,
|
||||||
1.0/*xscale*/,
|
1.0/*xscale*/,
|
||||||
1.0/*yscale*/);
|
1.0/*yscale*/);
|
||||||
|
@ -7480,9 +7525,10 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (inbrush && (!strcmp(token, "patchDef2") || !strcmp(token, "patchDefWS")))
|
else if (inbrush && (!strcmp(token, "patchDef2") || !strcmp(token, "patchDef3") || !strcmp(token, "patchDefWS")))
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
|
qboolean patchdef3 = !strcmp(token, "patchDef3"); //fancy alternative with rgba colours per control point
|
||||||
qboolean parsergba = !strcmp(token, "patchDefWS"); //fancy alternative with rgba colours per control point
|
qboolean parsergba = !strcmp(token, "patchDefWS"); //fancy alternative with rgba colours per control point
|
||||||
if (numplanes || patch_tex)
|
if (numplanes || patch_tex)
|
||||||
{
|
{
|
||||||
|
@ -7498,10 +7544,17 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
|
||||||
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
||||||
if (strcmp(token, "(")) {Con_Printf(CON_ERROR "%s: invalid patch\n", mod->name);return false;}
|
if (strcmp(token, "(")) {Con_Printf(CON_ERROR "%s: invalid patch\n", mod->name);return false;}
|
||||||
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
||||||
/*xoffset = atof(token);*/
|
/*patch_w = atof(token);*/
|
||||||
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
||||||
/*yoffset = atof(token);*/
|
/*patch_h = atof(token);*/
|
||||||
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
||||||
|
if (patchdef3)
|
||||||
|
{
|
||||||
|
/*xsubdiv = atof(token);*/
|
||||||
|
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
||||||
|
/*ysubdiv = atof(token);*/
|
||||||
|
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
||||||
|
}
|
||||||
/*rotation = atof(token);*/
|
/*rotation = atof(token);*/
|
||||||
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
||||||
/*xscale = atof(token);*/
|
/*xscale = atof(token);*/
|
||||||
|
@ -7532,7 +7585,12 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
|
||||||
patch_v[y][x].tc[1] = atof(token);
|
patch_v[y][x].tc[1] = atof(token);
|
||||||
|
|
||||||
if (parsergba)
|
if (parsergba)
|
||||||
{
|
{ //the following four lines are stupid.
|
||||||
|
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
||||||
|
if (strcmp(token, ")")) {Con_Printf(CON_ERROR "%s: invalid patch\n", mod->name);return false;}
|
||||||
|
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
||||||
|
if (strcmp(token, "(")) {Con_Printf(CON_ERROR "%s: invalid patch\n", mod->name);return false;}
|
||||||
|
|
||||||
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
||||||
patch_v[y][x].rgba[0] = atof(token);
|
patch_v[y][x].rgba[0] = atof(token);
|
||||||
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
|
||||||
|
@ -7981,31 +8039,33 @@ void *Mod_LoadTerrainInfo(model_t *mod, char *loadname, qboolean force)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SERVERONLY
|
#ifndef SERVERONLY
|
||||||
|
#if 0 //not yet ready
|
||||||
struct ted_import_s
|
struct ted_import_s
|
||||||
{
|
{
|
||||||
int x, y;
|
size_t x, y;
|
||||||
int width;
|
size_t width;
|
||||||
int height;
|
size_t height;
|
||||||
unsigned short *data;
|
unsigned short *data;
|
||||||
};
|
};
|
||||||
//static void ted_itterate(heightmap_t *hm, int distribution, float *pos, float radius, float strength, int steps,
|
//static void ted_itterate(heightmap_t *hm, int distribution, float *pos, float radius, float strength, int steps,
|
||||||
void ted_import_heights(void *vctx, hmsection_t *s, int idx, float wx, float wy, float strength)
|
static void ted_import_heights_r16(void *vctx, hmsection_t *s, int idx, float wx, float wy, float strength)
|
||||||
{
|
{
|
||||||
struct ted_import_s *ctx = vctx;
|
struct ted_import_s *ctx = vctx;
|
||||||
unsigned int y = idx/SECTHEIGHTSIZE;
|
unsigned int y = idx/SECTHEIGHTSIZE;
|
||||||
unsigned int x = idx%SECTHEIGHTSIZE;
|
unsigned int x = idx%SECTHEIGHTSIZE;
|
||||||
x += s->sx*(SECTHEIGHTSIZE-1) - ctx->x;
|
x += s->sx*(SECTHEIGHTSIZE-1) - ctx->x;
|
||||||
y += s->sy*(SECTHEIGHTSIZE-1) - ctx->y;
|
y += s->sy*(SECTHEIGHTSIZE-1) - ctx->y;
|
||||||
if (x < 0 || x >= ctx->width || y < 0 || y >= ctx->height)
|
if (x >= ctx->width || y >= ctx->height)
|
||||||
return;
|
return;
|
||||||
s->flags |= TSF_NOTIFY|TSF_EDITED|TSF_DIRTY|TSF_RELIGHT;
|
s->flags |= TSF_NOTIFY|TSF_EDITED|TSF_DIRTY|TSF_RELIGHT;
|
||||||
s->heights[idx] = ctx->data[x + y*ctx->width] * (8192.0/(1<<16));
|
s->heights[idx] = ctx->data[x + y*ctx->width] * (8192.0/(1<<16));
|
||||||
}
|
}
|
||||||
void Mod_Terrain_Import_f(void)
|
static void Mod_Terrain_Import_f(void)
|
||||||
{
|
{
|
||||||
model_t *mod;
|
model_t *mod;
|
||||||
struct ted_import_s ctx;
|
struct ted_import_s ctx;
|
||||||
const char *mapname = Cmd_Argv(1);
|
const char *mapname = Cmd_Argv(1);
|
||||||
|
const char *filename;
|
||||||
size_t fsize;
|
size_t fsize;
|
||||||
heightmap_t *hm;
|
heightmap_t *hm;
|
||||||
vec3_t pos = {0};
|
vec3_t pos = {0};
|
||||||
|
@ -8025,16 +8085,142 @@ void Mod_Terrain_Import_f(void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fsize = 0;
|
fsize = 0;
|
||||||
ctx.data = (void*)FS_LoadMallocFile("quake8km/height8km.r16", &fsize);
|
filename = va("maps/%s.r16", mapname);
|
||||||
|
ctx.data = (void*)FS_LoadMallocFile(filename, &fsize);
|
||||||
|
if (!ctx.data)
|
||||||
|
{
|
||||||
|
Con_Printf("Unable to read %s\n", filename);
|
||||||
|
return;
|
||||||
|
}
|
||||||
ctx.width = ctx.height = sqrt(fsize/2);
|
ctx.width = ctx.height = sqrt(fsize/2);
|
||||||
ctx.x = 0;
|
ctx.x = 0;
|
||||||
ctx.y = 0;
|
ctx.y = 0;
|
||||||
pos[0] += hm->sectionsize * CHUNKBIAS;
|
pos[0] += hm->sectionsize * CHUNKBIAS;
|
||||||
pos[1] += hm->sectionsize * CHUNKBIAS;
|
pos[1] += hm->sectionsize * CHUNKBIAS;
|
||||||
if (fsize == ctx.width*ctx.height*2)
|
if (fsize == ctx.width*ctx.height*2)
|
||||||
ted_itterate(hm, tid_flat, pos, max(ctx.width, ctx.height), 1, SECTHEIGHTSIZE, ted_import_heights, &ctx);
|
ted_itterate(hm, tid_flat, pos, max(ctx.width, ctx.height), 1, SECTHEIGHTSIZE, ted_import_heights_r16, &ctx);
|
||||||
FS_FreeFile(ctx.data);
|
FS_FreeFile(ctx.data);
|
||||||
}
|
}
|
||||||
|
static void Mod_Terrain_Export_f(void)
|
||||||
|
{
|
||||||
|
model_t *mod;
|
||||||
|
struct ted_import_s ctx;
|
||||||
|
char mapname[MAX_QPATH];
|
||||||
|
const char *filename;
|
||||||
|
heightmap_t *hm;
|
||||||
|
size_t w, h;
|
||||||
|
size_t tx, ty;
|
||||||
|
size_t sx, sy;
|
||||||
|
unsigned int outtilex=0,outtiley=0;
|
||||||
|
qboolean populated;
|
||||||
|
if (Cmd_IsInsecure())
|
||||||
|
{
|
||||||
|
Con_Printf("Please use this command via the console\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (*Cmd_Argv(1))
|
||||||
|
mod = NULL;//Mod_FindName(va("maps/%s", mapname));
|
||||||
|
else
|
||||||
|
mod = cl.worldmodel;
|
||||||
|
if (!mod || mod->type == mod_dummy)
|
||||||
|
return;
|
||||||
|
hm = mod->terrain;
|
||||||
|
if (!hm)
|
||||||
|
return;
|
||||||
|
|
||||||
|
COM_StripExtension(mod->name, mapname, sizeof(mapname));
|
||||||
|
|
||||||
|
ctx.x = hm->firstsegx * (SECTHEIGHTSIZE-1);
|
||||||
|
w = (hm->maxsegx-hm->firstsegx) * (SECTHEIGHTSIZE-1) + 1;
|
||||||
|
while(w)
|
||||||
|
{
|
||||||
|
ctx.width = w;
|
||||||
|
if (ctx.width > 2048+1)
|
||||||
|
ctx.width = 2048;
|
||||||
|
|
||||||
|
outtiley = 0;
|
||||||
|
ctx.y = hm->firstsegy * (SECTHEIGHTSIZE-1);
|
||||||
|
h = (hm->maxsegy-hm->firstsegy) * (SECTHEIGHTSIZE-1) + 1;
|
||||||
|
while(h)
|
||||||
|
{
|
||||||
|
ctx.height = h;
|
||||||
|
if (ctx.height > 2048+1)
|
||||||
|
ctx.height = 2048;
|
||||||
|
|
||||||
|
populated = false;
|
||||||
|
ctx.data = Z_Malloc(ctx.width*ctx.height*2);
|
||||||
|
for (sy = ctx.y/(SECTHEIGHTSIZE-1); sy < (ctx.y+ctx.height + SECTHEIGHTSIZE-3)/(SECTHEIGHTSIZE-1); sy++)
|
||||||
|
for (sx = ctx.x/(SECTHEIGHTSIZE-1); sx < (ctx.x+ctx.width + SECTHEIGHTSIZE-3)/(SECTHEIGHTSIZE-1); sx++)
|
||||||
|
{
|
||||||
|
hmsection_t *s = Terr_GetSection(hm, sx, sy, TGS_WAITLOAD|TGS_ANYSTATE);
|
||||||
|
if (s->loadstate == TSLS_FAILED)
|
||||||
|
{ //we're doing this weirdly so we can destroy sections as we go.
|
||||||
|
Terr_DestroySection(hm, s, true);
|
||||||
|
s = NULL;
|
||||||
|
}
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
populated = true;
|
||||||
|
for (ty = 0; ty < SECTHEIGHTSIZE; ty++)
|
||||||
|
{
|
||||||
|
size_t y = sy*(SECTHEIGHTSIZE-1)+ty - ctx.y;
|
||||||
|
if (y >= ctx.height)
|
||||||
|
continue;
|
||||||
|
for (tx = 0; tx < SECTHEIGHTSIZE; tx++)
|
||||||
|
{
|
||||||
|
size_t x = sx*(SECTHEIGHTSIZE-1)+tx - ctx.x;
|
||||||
|
if (x >= ctx.width)
|
||||||
|
continue;
|
||||||
|
ctx.data[x + y*ctx.width] = s->heights[tx+y*SECTHEIGHTSIZE] / (8192.0/(1<<16));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!(s->flags & TSF_EDITED))
|
||||||
|
Terr_DestroySection(hm, s, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (ty = 0; ty < SECTHEIGHTSIZE; ty++)
|
||||||
|
{
|
||||||
|
size_t y = sy*(SECTHEIGHTSIZE-1)+ty - ctx.y;
|
||||||
|
if (y >= ctx.height)
|
||||||
|
continue;
|
||||||
|
for (tx = 0; tx < SECTHEIGHTSIZE; tx++)
|
||||||
|
{
|
||||||
|
size_t x = sx*(SECTHEIGHTSIZE-1)+tx - ctx.x;
|
||||||
|
if (x >= ctx.width)
|
||||||
|
continue;
|
||||||
|
ctx.data[x + y*ctx.width] = hm->defaultgroundheight / (8192.0/(1<<16));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = va("%s/x%u_y%u.r16", mapname, outtilex, outtiley);
|
||||||
|
if (populated)
|
||||||
|
{
|
||||||
|
if (FS_WriteFile(filename, ctx.data, ctx.width*ctx.height*2, FS_GAMEONLY))
|
||||||
|
{
|
||||||
|
char sysname[1024];
|
||||||
|
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
|
||||||
|
Con_Printf("Wrote %s\n", sysname);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Con_Printf("Unable to write %s\n", filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Con_Printf("Skipping unpopulated %s\n", filename);
|
||||||
|
Z_Free(ctx.data);
|
||||||
|
|
||||||
|
outtiley++;
|
||||||
|
ctx.y += ctx.height;
|
||||||
|
h -= ctx.height;
|
||||||
|
}
|
||||||
|
outtilex++;
|
||||||
|
ctx.x += ctx.width;
|
||||||
|
w -= ctx.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void Mod_Terrain_Create_f(void)
|
void Mod_Terrain_Create_f(void)
|
||||||
{
|
{
|
||||||
|
@ -8279,9 +8465,15 @@ void Terr_Init(void)
|
||||||
Cmd_AddCommand("mod_terrain_save", Mod_Terrain_Save_f);
|
Cmd_AddCommand("mod_terrain_save", Mod_Terrain_Save_f);
|
||||||
Cmd_AddCommand("mod_terrain_reload", Mod_Terrain_Reload_f);
|
Cmd_AddCommand("mod_terrain_reload", Mod_Terrain_Reload_f);
|
||||||
#ifndef SERVERONLY
|
#ifndef SERVERONLY
|
||||||
Cmd_AddCommandD("mod_terrain_import", Mod_Terrain_Import_f, "Import a raw heightmap");
|
// Cmd_AddCommandD("mod_terrain_export", Mod_Terrain_Export_f, "Export a raw heightmap");
|
||||||
|
// Cmd_AddCommandD("mod_terrain_import", Mod_Terrain_Import_f, "Import a raw heightmap");
|
||||||
Cmd_AddCommand("mod_terrain_create", Mod_Terrain_Create_f);
|
Cmd_AddCommand("mod_terrain_create", Mod_Terrain_Create_f);
|
||||||
Cmd_AddCommandD("mod_terrain_convert", Mod_Terrain_Convert_f, "mod_terrain_convert [mapname] [texkill]\nConvert a terrain to the current format. If texkill is specified, only tiles with the named texture will be converted, and tiles with that texture will be stripped. This is a slow operation.");
|
Cmd_AddCommandD("mod_terrain_convert", Mod_Terrain_Convert_f, "mod_terrain_convert [mapname] [texkill]\nConvert a terrain to the current format. If texkill is specified, only tiles with the named texture will be converted, and tiles with that texture will be stripped. This is a slow operation.");
|
||||||
|
|
||||||
|
Cvar_Register(&mod_terrain_sundir, "Terrain");
|
||||||
|
Cvar_Register(&mod_terrain_ambient, "Terrain");
|
||||||
|
Cvar_Register(&mod_terrain_shadows, "Terrain");
|
||||||
|
Cvar_Register(&mod_terrain_shadow_dist, "Terrain");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Mod_RegisterModelFormatText(NULL, "FTE Heightmap Map (hmp)", "terrain", Terr_LoadTerrainModel);
|
Mod_RegisterModelFormatText(NULL, "FTE Heightmap Map (hmp)", "terrain", Terr_LoadTerrainModel);
|
||||||
|
|
|
@ -1256,6 +1256,7 @@ struct programpermu_s *Shader_LoadPermutation(program_t *prog, unsigned int p)
|
||||||
size_t n, pn = 0;
|
size_t n, pn = 0;
|
||||||
char defines[8192];
|
char defines[8192];
|
||||||
size_t offset;
|
size_t offset;
|
||||||
|
qboolean fail = false;
|
||||||
|
|
||||||
extern cvar_t gl_specular, gl_specular_power;
|
extern cvar_t gl_specular, gl_specular_power;
|
||||||
|
|
||||||
|
@ -1294,14 +1295,14 @@ struct programpermu_s *Shader_LoadPermutation(program_t *prog, unsigned int p)
|
||||||
permutationdefines[pn++] = NULL;
|
permutationdefines[pn++] = NULL;
|
||||||
|
|
||||||
if (!sh_config.pCreateProgram(prog, pp, prog->shaderver, permutationdefines, prog->shadertext, prog->tess?prog->shadertext:NULL, prog->tess?prog->shadertext:NULL, prog->geom?prog->shadertext:NULL, prog->shadertext, prog->warned, NULL))
|
if (!sh_config.pCreateProgram(prog, pp, prog->shaderver, permutationdefines, prog->shadertext, prog->tess?prog->shadertext:NULL, prog->tess?prog->shadertext:NULL, prog->geom?prog->shadertext:NULL, prog->shadertext, prog->warned, NULL))
|
||||||
prog->warned = true;
|
prog->warned = fail = true;
|
||||||
|
|
||||||
//extra loop to validate the programs actually linked properly.
|
//extra loop to validate the programs actually linked properly.
|
||||||
//delaying it like this gives certain threaded drivers a chance to compile them all while we're messing around with other junk
|
//delaying it like this gives certain threaded drivers a chance to compile them all while we're messing around with other junk
|
||||||
if (sh_config.pValidateProgram && !sh_config.pValidateProgram(prog, pp, prog->warned, NULL))
|
if (!fail && sh_config.pValidateProgram && !sh_config.pValidateProgram(prog, pp, prog->warned, NULL))
|
||||||
prog->warned = true;
|
prog->warned = fail = true;
|
||||||
|
|
||||||
if (sh_config.pProgAutoFields)
|
if (!fail && sh_config.pProgAutoFields)
|
||||||
{
|
{
|
||||||
cvar_t *cvarrefs[64];
|
cvar_t *cvarrefs[64];
|
||||||
char *cvarnames[64+1];
|
char *cvarnames[64+1];
|
||||||
|
@ -1320,9 +1321,52 @@ struct programpermu_s *Shader_LoadPermutation(program_t *prog, unsigned int p)
|
||||||
cvarnames[i] = NULL; //no more
|
cvarnames[i] = NULL; //no more
|
||||||
sh_config.pProgAutoFields(prog, pp, cvarrefs, cvarnames, cvartypes);
|
sh_config.pProgAutoFields(prog, pp, cvarrefs, cvarnames, cvartypes);
|
||||||
}
|
}
|
||||||
|
if (fail)
|
||||||
|
{
|
||||||
|
Z_Free(pp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return pp;
|
return pp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qboolean Shader_PermutationEnabled(unsigned int bit)
|
||||||
|
{
|
||||||
|
if (bit == PERMUTATION_REFLECTCUBEMASK)
|
||||||
|
return gl_load24bit.ival;
|
||||||
|
if (bit == PERMUTATION_BUMPMAP)
|
||||||
|
return r_loadbumpmapping;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
qboolean Com_PermuOrFloatArgument(const char *shadername, char *arg, size_t arglen, float def)
|
||||||
|
{
|
||||||
|
extern cvar_t gl_specular;
|
||||||
|
size_t p;
|
||||||
|
//load-time-only permutations...
|
||||||
|
if (arglen == 8 && !strncmp("SPECULAR", arg, arglen) && gl_specular.value)
|
||||||
|
return true;
|
||||||
|
if ((arglen==5||arglen==6) && !strncmp("DELUXE", arg, arglen) && r_deluxemapping && Shader_PermutationEnabled(PERMUTATION_BUMPMAP))
|
||||||
|
return true;
|
||||||
|
if (arglen == 13 && !strncmp("OFFSETMAPPING", arg, arglen) && r_glsl_offsetmapping.ival)
|
||||||
|
return true;
|
||||||
|
if (arglen == 13 && !strncmp("RELIEFMAPPING", arg, arglen) && r_glsl_offsetmapping.ival && r_glsl_offsetmapping_reliefmapping.ival)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
//real permutations
|
||||||
|
if (arglen == 5 && (!strncmp("UPPER", arg, arglen)||!strncmp("LOWER", arg, arglen)) && Shader_PermutationEnabled(PERMUTATION_BIT_UPPERLOWER))
|
||||||
|
return true;
|
||||||
|
for (p = 0; p < countof(permutations); p++)
|
||||||
|
{
|
||||||
|
if (arglen == strlen(permutations[p].name) && !strncmp(permutations[p].name, arg, arglen))
|
||||||
|
{
|
||||||
|
if (Shader_PermutationEnabled(permutations[p].bitmask))
|
||||||
|
return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Com_FloatArgument(shadername, arg, arglen, def) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *script, int qrtype, int ver, char *blobfilename)
|
static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *script, int qrtype, int ver, char *blobfilename)
|
||||||
{
|
{
|
||||||
#if defined(GLQUAKE) || defined(D3DQUAKE)
|
#if defined(GLQUAKE) || defined(D3DQUAKE)
|
||||||
|
@ -1412,15 +1456,16 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
|
||||||
if (*token == '=' || *token == '!')
|
if (*token == '=' || *token == '!')
|
||||||
{
|
{
|
||||||
len = strlen(token);
|
len = strlen(token);
|
||||||
if (*token == (Com_FloatArgument(name, token+1, len-1, 0)?'!':'='))
|
if (*token == (Com_PermuOrFloatArgument(name, token+1, len-1, 0)?'!':'='))
|
||||||
ignore = true;
|
ignore = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ignore)
|
else if (ignore)
|
||||||
continue;
|
continue;
|
||||||
#ifdef HAVE_LEGACY
|
#if 1//def HAVE_LEGACY
|
||||||
else if (!strncmp(token, "deluxmap", 8))
|
else if (!strncmp(token, "deluxmap", 8))
|
||||||
{ //FIXME: remove this some time.
|
{ //FIXME: remove this some time.
|
||||||
|
Con_DPrintf("Outdated texture name \"%s\" in program \"%s\"\n", token, name);
|
||||||
token = va("deluxemap%s",token+8);
|
token = va("deluxemap%s",token+8);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1470,7 +1515,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
|
||||||
prog->numsamplers = i;
|
prog->numsamplers = i;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Con_Printf("Unknown texture name in %s\n", name);
|
Con_Printf("Unknown texture name \"%s\" in program \"%s\"\n", token, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1667,6 +1712,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
|
||||||
{
|
{
|
||||||
if (!strncmp(permutations[p].name, script, end - script) && permutations[p].name[end-script] == '\0')
|
if (!strncmp(permutations[p].name, script, end - script) && permutations[p].name[end-script] == '\0')
|
||||||
{
|
{
|
||||||
|
if (Shader_PermutationEnabled(permutations[p].bitmask))
|
||||||
nopermutation &= ~permutations[p].bitmask;
|
nopermutation &= ~permutations[p].bitmask;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1738,10 +1784,10 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
|
||||||
nopermutation |= PERMUTATION_SKELETAL;
|
nopermutation |= PERMUTATION_SKELETAL;
|
||||||
|
|
||||||
//multiple lightmaps is kinda hacky. if any are set, all must be.
|
//multiple lightmaps is kinda hacky. if any are set, all must be.
|
||||||
#define ALTLIGHTMAPSAMP 13
|
#define ALTLIGHTMAPSAMP 14
|
||||||
if (prog->defaulttextures & ((1u<<(ALTLIGHTMAPSAMP+0)) | (1u<<(ALTLIGHTMAPSAMP+1)) | (1u<<(ALTLIGHTMAPSAMP+2))))
|
if (prog->defaulttextures & ((1u<<(ALTLIGHTMAPSAMP+0)) | (1u<<(ALTLIGHTMAPSAMP+1)) | (1u<<(ALTLIGHTMAPSAMP+2))))
|
||||||
prog->defaulttextures |=((1u<<(ALTLIGHTMAPSAMP+0)) | (1u<<(ALTLIGHTMAPSAMP+1)) | (1u<<(ALTLIGHTMAPSAMP+2)));
|
prog->defaulttextures |=((1u<<(ALTLIGHTMAPSAMP+0)) | (1u<<(ALTLIGHTMAPSAMP+1)) | (1u<<(ALTLIGHTMAPSAMP+2)));
|
||||||
#define ALTDELUXMAPSAMP 16
|
#define ALTDELUXMAPSAMP 17
|
||||||
if (prog->defaulttextures & ((1u<<(ALTDELUXMAPSAMP+0)) | (1u<<(ALTDELUXMAPSAMP+1)) | (1u<<(ALTDELUXMAPSAMP+2))))
|
if (prog->defaulttextures & ((1u<<(ALTDELUXMAPSAMP+0)) | (1u<<(ALTDELUXMAPSAMP+1)) | (1u<<(ALTDELUXMAPSAMP+2))))
|
||||||
prog->defaulttextures |=((1u<<(ALTDELUXMAPSAMP+0)) | (1u<<(ALTDELUXMAPSAMP+1)) | (1u<<(ALTDELUXMAPSAMP+2)));
|
prog->defaulttextures |=((1u<<(ALTDELUXMAPSAMP+0)) | (1u<<(ALTDELUXMAPSAMP+1)) | (1u<<(ALTDELUXMAPSAMP+2)));
|
||||||
|
|
||||||
|
|
|
@ -420,7 +420,7 @@ qboolean GL_CheckExtension(char *extname)
|
||||||
for (i = 0; i < gl_num_extensions; i++)
|
for (i = 0; i < gl_num_extensions; i++)
|
||||||
if (!strcmp(qglGetStringi(GL_EXTENSIONS, i), extname))
|
if (!strcmp(qglGetStringi(GL_EXTENSIONS, i), extname))
|
||||||
{
|
{
|
||||||
Con_DPrintf("Detected GL extension %s\n", extname);
|
Con_DPrintf("GL: Found %s\n", extname);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2280,6 +2280,9 @@ static GLhandleARB GLSlang_CreateShader (program_t *prog, const char *name, int
|
||||||
"#ifndef USE_ARB_SHADOW\n" //fall back on regular samplers if we must
|
"#ifndef USE_ARB_SHADOW\n" //fall back on regular samplers if we must
|
||||||
"#define sampler2DShadow sampler2D\n"
|
"#define sampler2DShadow sampler2D\n"
|
||||||
"#elif defined(GL_ES)\n"
|
"#elif defined(GL_ES)\n"
|
||||||
|
"#if __VERSION__ < 300\n"
|
||||||
|
"#extension GL_EXT_shadow_samplers : require\n"
|
||||||
|
"#endif\n"
|
||||||
"precision lowp sampler2DShadow;\n" //gah
|
"precision lowp sampler2DShadow;\n" //gah
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2975,7 +2975,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
|
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
|
||||||
//the vertex shader is responsible for calculating lighting values.
|
//the vertex shader is responsible for calculating lighting values.
|
||||||
|
|
||||||
"#if gl_affinemodels==1 && __VERSION__ >= 130\n"
|
"#if gl_affinemodels==1 && __VERSION__ >= 130 && !defined(GL_ES)\n"
|
||||||
"#define affine noperspective\n"
|
"#define affine noperspective\n"
|
||||||
"#else\n"
|
"#else\n"
|
||||||
"#define affine\n"
|
"#define affine\n"
|
||||||
|
@ -5599,11 +5599,17 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
"!!permu REFLECTCUBEMASK\n"
|
"!!permu REFLECTCUBEMASK\n"
|
||||||
"!!cvarf r_glsl_offsetmapping_scale\n"
|
"!!cvarf r_glsl_offsetmapping_scale\n"
|
||||||
"!!cvardf r_tessellation_level=5\n"
|
"!!cvardf r_tessellation_level=5\n"
|
||||||
"!!samps !EIGHTBIT diffuse specular normalmap fullbright reflectmask reflectcube\n"
|
"!!samps diffuse\n"
|
||||||
|
"!!samps !EIGHTBIT =FULLBRIGHT fullbright\n"
|
||||||
|
"!!samps !EIGHTBIT =BUMP normalmap\n"
|
||||||
|
"!!samps !EIGHTBIT =REFLECTCUBEMASK reflectmask reflectcube\n"
|
||||||
//diffuse gives us alpha, and prevents dlight from bugging out when there's no diffuse.
|
//diffuse gives us alpha, and prevents dlight from bugging out when there's no diffuse.
|
||||||
"!!samps =EIGHTBIT paletted 1 specular diffuse\n"
|
"!!samps =EIGHTBIT paletted 1\n"
|
||||||
"!!samps lightmap deluxemap\n"
|
"!!samps =SPECULAR specular\n"
|
||||||
"!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3 deluxemap deluxemap1 deluxemap2 deluxemap3\n"
|
"!!samps lightmap\n"
|
||||||
|
"!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3\n"
|
||||||
|
"!!samps =DELUXE deluxmap\n"
|
||||||
|
"!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3\n"
|
||||||
|
|
||||||
"#if defined(ORM) || defined(SG)\n"
|
"#if defined(ORM) || defined(SG)\n"
|
||||||
"#define PBR\n"
|
"#define PBR\n"
|
||||||
|
@ -5960,7 +5966,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
"#else\n"
|
"#else\n"
|
||||||
//now we have our diffuse+specular terms, modulate by lightmap values.
|
//now we have our diffuse+specular terms, modulate by lightmap values.
|
||||||
"col.rgb *= lightmaps.rgb;\n"
|
"col.rgb *= lightmaps.rgb;\n"
|
||||||
|
|
||||||
//add on the fullbright
|
//add on the fullbright
|
||||||
"#ifdef FULLBRIGHT\n"
|
"#ifdef FULLBRIGHT\n"
|
||||||
"col.rgb += texture2D(s_fullbright, tc).rgb;\n"
|
"col.rgb += texture2D(s_fullbright, tc).rgb;\n"
|
||||||
|
@ -10603,10 +10608,11 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
#endif
|
#endif
|
||||||
#ifdef GLQUAKE
|
#ifdef GLQUAKE
|
||||||
{QR_OPENGL, 110, "terrain",
|
{QR_OPENGL, 110, "terrain",
|
||||||
|
"!!ver 100 300\n"
|
||||||
"!!permu FOG\n"
|
"!!permu FOG\n"
|
||||||
//t0-t3 are the diffusemaps, t4 is the blend factors
|
//RTLIGHT (+PCF,CUBE,SPOT,etc)
|
||||||
"!!samps 4\n"
|
"!!samps tr=0 tg=1 tb=2 tx=3 //the four texturemaps\n"
|
||||||
"!!samps mix=4\n"
|
"!!samps mix=4 //how the ground is blended\n"
|
||||||
"!!samps =PCF shadowmap\n"
|
"!!samps =PCF shadowmap\n"
|
||||||
"!!samps =CUBE projectionmap\n"
|
"!!samps =CUBE projectionmap\n"
|
||||||
|
|
||||||
|
@ -10703,10 +10709,12 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
||||||
"vec4 r;\n"
|
"vec4 r;\n"
|
||||||
"vec4 m = texture2D(s_mix, lm);\n"
|
"vec4 m = texture2D(s_mix, lm);\n"
|
||||||
|
|
||||||
"r = texture2D(s_t0, tc)*m.r;\n"
|
"r = texture2D(s_tr, tc)*m.r;\n"
|
||||||
"r += texture2D(s_t1, tc)*m.g;\n"
|
"r += texture2D(s_tg, tc)*m.g;\n"
|
||||||
"r += texture2D(s_t2, tc)*m.b;\n"
|
"r += texture2D(s_tb, tc)*m.b;\n"
|
||||||
"r += texture2D(s_t3, tc)*(1.0 - (m.r + m.g + m.b));\n"
|
"r += texture2D(s_tx, tc)*(1.0 - (m.r + m.g + m.b));\n"
|
||||||
|
|
||||||
|
"r.rgb *= 1.0/r.a; //fancy maths, so low alpha values give other textures a greater focus\n"
|
||||||
|
|
||||||
//vertex colours provide a scaler that applies even through rtlights.
|
//vertex colours provide a scaler that applies even through rtlights.
|
||||||
"r *= vc;\n"
|
"r *= vc;\n"
|
||||||
|
|
|
@ -23,7 +23,7 @@ void *PRHunkAlloc(progfuncs_t *progfuncs, int ammount, const char *name)
|
||||||
|
|
||||||
return ((char *)mem)+sizeof(prmemb_t);
|
return ((char *)mem)+sizeof(prmemb_t);
|
||||||
}
|
}
|
||||||
void *PDECL QC_HunkAlloc(pubprogfuncs_t *ppf, int ammount, char *name)
|
static void *PDECL QC_HunkAlloc(pubprogfuncs_t *ppf, int ammount, char *name)
|
||||||
{
|
{
|
||||||
return PRHunkAlloc((progfuncs_t*)ppf, ammount, name);
|
return PRHunkAlloc((progfuncs_t*)ppf, ammount, name);
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ void PRHunkFree(progfuncs_t *progfuncs, int mark)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if we ran out of memory, the vm can allocate a new block, but doing so requires fixing up all sorts of pointers*/
|
/*if we ran out of memory, the vm can allocate a new block, but doing so requires fixing up all sorts of pointers*/
|
||||||
void PRAddressableRelocate(progfuncs_t *progfuncs, char *oldb, char *newb, int oldlen)
|
static void PRAddressableRelocate(progfuncs_t *progfuncs, char *oldb, char *newb, int oldlen)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
edictrun_t *e;
|
edictrun_t *e;
|
||||||
|
@ -583,7 +583,7 @@ static void PDECL PR_Configure (pubprogfuncs_t *ppf, size_t addressable_size, in
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct globalvars_s *PDECL PR_globals (pubprogfuncs_t *ppf, progsnum_t pnum)
|
static struct globalvars_s *PDECL PR_globals (pubprogfuncs_t *ppf, progsnum_t pnum)
|
||||||
{
|
{
|
||||||
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
||||||
if (pnum < 0)
|
if (pnum < 0)
|
||||||
|
@ -598,7 +598,7 @@ struct globalvars_s *PDECL PR_globals (pubprogfuncs_t *ppf, progsnum_t pnum)
|
||||||
return (struct globalvars_s *)pr_progstate[pnum].globals;
|
return (struct globalvars_s *)pr_progstate[pnum].globals;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct entvars_s *PDECL PR_entvars (pubprogfuncs_t *ppf, struct edict_s *ed)
|
static struct entvars_s *PDECL PR_entvars (pubprogfuncs_t *ppf, struct edict_s *ed)
|
||||||
{
|
{
|
||||||
// progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
// progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
||||||
if (((edictrun_t *)ed)->ereftype != ER_ENTITY)
|
if (((edictrun_t *)ed)->ereftype != ER_ENTITY)
|
||||||
|
@ -607,7 +607,7 @@ struct entvars_s *PDECL PR_entvars (pubprogfuncs_t *ppf, struct edict_s *ed)
|
||||||
return (struct entvars_s *)edvars(ed);
|
return (struct entvars_s *)edvars(ed);
|
||||||
}
|
}
|
||||||
|
|
||||||
pbool PDECL PR_GetFunctionInfo(pubprogfuncs_t *ppf, func_t func, int *args, int *builtinnum, char *funcname, size_t funcnamesize)
|
static pbool PDECL PR_GetFunctionInfo(pubprogfuncs_t *ppf, func_t func, int *args, int *builtinnum, char *funcname, size_t funcnamesize)
|
||||||
{
|
{
|
||||||
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
||||||
|
|
||||||
|
@ -697,7 +697,7 @@ func_t PDECL PR_FindFunc(pubprogfuncs_t *ppf, const char *funcname, progsnum_t p
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDECL QC_FindPrefixedGlobals(pubprogfuncs_t *ppf, int pnum, char *prefix, void (PDECL *found) (pubprogfuncs_t *progfuncs, char *name, union eval_s *val, etype_t type, void *ctx), void *ctx)
|
static void PDECL QC_FindPrefixedGlobals(pubprogfuncs_t *ppf, int pnum, char *prefix, void (PDECL *found) (pubprogfuncs_t *progfuncs, char *name, union eval_s *val, etype_t type, void *ctx), void *ctx)
|
||||||
{
|
{
|
||||||
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
@ -795,7 +795,7 @@ eval_t *PDECL PR_FindGlobal(pubprogfuncs_t *ppf, const char *globname, progsnum_
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *PDECL PR_VarString (pubprogfuncs_t *ppf, int first)
|
static char *PDECL PR_VarString (pubprogfuncs_t *ppf, int first)
|
||||||
{
|
{
|
||||||
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
||||||
int i;
|
int i;
|
||||||
|
@ -816,7 +816,7 @@ char *PDECL PR_VarString (pubprogfuncs_t *ppf, int first)
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PDECL PR_QueryField (pubprogfuncs_t *ppf, unsigned int fieldoffset, etype_t *type, char const**name, evalc_t *fieldcache)
|
static int PDECL PR_QueryField (pubprogfuncs_t *ppf, unsigned int fieldoffset, etype_t *type, char const**name, evalc_t *fieldcache)
|
||||||
{
|
{
|
||||||
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
||||||
fdef_t *var;
|
fdef_t *var;
|
||||||
|
@ -868,7 +868,7 @@ eval_t *PDECL QC_GetEdictFieldValue(pubprogfuncs_t *ppf, struct edict_s *ed, con
|
||||||
return (eval_t *) &(((int*)(((edictrun_t*)ed)->fields))[cache->ofs32->ofs]);
|
return (eval_t *) &(((int*)(((edictrun_t*)ed)->fields))[cache->ofs32->ofs]);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct edict_s *PDECL ProgsToEdict (pubprogfuncs_t *ppf, int progs)
|
static struct edict_s *PDECL ProgsToEdict (pubprogfuncs_t *ppf, int progs)
|
||||||
{
|
{
|
||||||
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
||||||
if ((unsigned)progs >= (unsigned)prinst.maxedicts)
|
if ((unsigned)progs >= (unsigned)prinst.maxedicts)
|
||||||
|
@ -883,7 +883,7 @@ struct edict_s *PDECL ProgsToEdict (pubprogfuncs_t *ppf, int progs)
|
||||||
}
|
}
|
||||||
return (struct edict_s *)PROG_TO_EDICT_PB(progfuncs.inst, progs);
|
return (struct edict_s *)PROG_TO_EDICT_PB(progfuncs.inst, progs);
|
||||||
}
|
}
|
||||||
int PDECL EdictToProgs (pubprogfuncs_t *ppf, struct edict_s *ed)
|
static int PDECL EdictToProgs (pubprogfuncs_t *ppf, struct edict_s *ed)
|
||||||
{
|
{
|
||||||
// progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
// progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
||||||
return EDICT_TO_PROG(progfuncs, ed);
|
return EDICT_TO_PROG(progfuncs, ed);
|
||||||
|
@ -935,7 +935,7 @@ string_t PDECL PR_StringToProgs (pubprogfuncs_t *ppf, const char *str)
|
||||||
return (string_t)((unsigned int)i | STRING_STATIC);
|
return (string_t)((unsigned int)i | STRING_STATIC);
|
||||||
}
|
}
|
||||||
//if ed is null, fld points to a global. if str_is_static, then s doesn't need its own memory allocated.
|
//if ed is null, fld points to a global. if str_is_static, then s doesn't need its own memory allocated.
|
||||||
void PDECL PR_SetStringField(pubprogfuncs_t *progfuncs, struct edict_s *ed, string_t *fld, const char *str, pbool str_is_static)
|
static void PDECL PR_SetStringField(pubprogfuncs_t *progfuncs, struct edict_s *ed, string_t *fld, const char *str, pbool str_is_static)
|
||||||
{
|
{
|
||||||
if (!str)
|
if (!str)
|
||||||
*fld = 0;
|
*fld = 0;
|
||||||
|
@ -951,7 +951,7 @@ void PDECL PR_SetStringField(pubprogfuncs_t *progfuncs, struct edict_s *ed, stri
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *PDECL PR_RemoveProgsString (pubprogfuncs_t *ppf, string_t str)
|
static char *PDECL PR_RemoveProgsString (pubprogfuncs_t *ppf, string_t str)
|
||||||
{
|
{
|
||||||
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
||||||
char *ret;
|
char *ret;
|
||||||
|
@ -1110,7 +1110,7 @@ void QCBUILTIN PF_memsetval (pubprogfuncs_t *inst, struct globalvars_s *globals)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string_t PDECL PR_AllocTempStringLen (pubprogfuncs_t *ppf, char **str, unsigned int len)
|
static string_t PDECL PR_AllocTempStringLen (pubprogfuncs_t *ppf, char **str, unsigned int len)
|
||||||
{
|
{
|
||||||
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
||||||
tempstr_t **ntable;
|
tempstr_t **ntable;
|
||||||
|
@ -1319,7 +1319,7 @@ static void PR_FreeAllTemps (progfuncs_t *progfuncs)
|
||||||
prinst.numtempstrings = 0;
|
prinst.numtempstrings = 0;
|
||||||
prinst.nexttempstring = 0;
|
prinst.nexttempstring = 0;
|
||||||
}
|
}
|
||||||
pbool PDECL PR_DumpProfiles (pubprogfuncs_t *ppf, pbool resetprofiles)
|
static pbool PDECL PR_DumpProfiles (pubprogfuncs_t *ppf, pbool resetprofiles)
|
||||||
{
|
{
|
||||||
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
|
||||||
struct progstate_s *ps;
|
struct progstate_s *ps;
|
||||||
|
@ -1391,7 +1391,7 @@ static void PDECL PR_CloseProgs(pubprogfuncs_t *ppf);
|
||||||
|
|
||||||
static void PDECL RegisterBuiltin(pubprogfuncs_t *progfncs, const char *name, builtin_t func);
|
static void PDECL RegisterBuiltin(pubprogfuncs_t *progfncs, const char *name, builtin_t func);
|
||||||
|
|
||||||
pubprogfuncs_t deffuncs = {
|
static pubprogfuncs_t deffuncs = {
|
||||||
PROGSTRUCT_VERSION,
|
PROGSTRUCT_VERSION,
|
||||||
PR_CloseProgs,
|
PR_CloseProgs,
|
||||||
PR_Configure,
|
PR_Configure,
|
||||||
|
@ -1510,11 +1510,11 @@ static void PDECL qclib_free(void *ptr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//defs incase following structure is not passed.
|
//defs incase following structure is not passed.
|
||||||
struct edict_s *safesv_edicts;
|
static struct edict_s *safesv_edicts;
|
||||||
int safesv_num_edicts;
|
static int safesv_num_edicts;
|
||||||
double safetime=0;
|
static double safetime=0;
|
||||||
|
|
||||||
progexterns_t defexterns = {
|
static progexterns_t defexterns = {
|
||||||
PROGSTRUCT_VERSION,
|
PROGSTRUCT_VERSION,
|
||||||
|
|
||||||
NULL, //char *(*ReadFile) (char *fname, void *buffer, int len);
|
NULL, //char *(*ReadFile) (char *fname, void *buffer, int len);
|
||||||
|
|
|
@ -10451,9 +10451,14 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
||||||
{"bprint", PF_bprint, 0, 23, 0, 0, D("void(float msglvl, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7)", "QW: Concatenates all string arguments, and prints the messsage on the console of only all clients who's 'msg' infokey is set lower or equal to the supplied 'msglvl' argument.")},
|
{"bprint", PF_bprint, 0, 23, 0, 0, D("void(float msglvl, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7)", "QW: Concatenates all string arguments, and prints the messsage on the console of only all clients who's 'msg' infokey is set lower or equal to the supplied 'msglvl' argument.")},
|
||||||
{"sprint", PF_sprint, 24, 0, 24, 0, D("void(entity client, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7)", "NQ: Concatenates all string arguments, and prints the messsage on the named client's console")},
|
{"sprint", PF_sprint, 24, 0, 24, 0, D("void(entity client, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7)", "NQ: Concatenates all string arguments, and prints the messsage on the named client's console")},
|
||||||
{"sprint", PF_sprint, 0, 24, 0, 0, D("void(entity client, float msglvl, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6)", "QW: Concatenates all string arguments, and prints the messsage on the named client's console, but only if that client's 'msg' infokey is set lower or equal to the supplied 'msglvl' argument.")},
|
{"sprint", PF_sprint, 0, 24, 0, 0, D("void(entity client, float msglvl, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6)", "QW: Concatenates all string arguments, and prints the messsage on the named client's console, but only if that client's 'msg' infokey is set lower or equal to the supplied 'msglvl' argument.")},
|
||||||
|
#ifdef HAVE_LEGACY
|
||||||
//these have subtly different behaviour, and are implemented using different internal builtins, which is a bit weird in the extensions file. documentation is documentation.
|
//these have subtly different behaviour, and are implemented using different internal builtins, which is a bit weird in the extensions file. documentation is documentation.
|
||||||
{"dprint", PF_dprint, 25, 0, 25, 0, D("void(string s, ...)", "NQ: Prints the given message on the server's console, but only if the developer cvar is set. Arguments will be concatenated into a single message.")},
|
{"dprint", PF_dprint, 25, 0, 25, 0, D("void(string s, ...)", "NQ: Prints the given message on the server's console, but only if the developer cvar is set. Arguments will be concatenated into a single message.")},
|
||||||
{"dprint", PF_print, 0, 25, 0, 0, D("void(string s, ...)", "QW: Unconditionally prints the given message on the server's console. Arguments will be concatenated into a single message.")},
|
{"dprint", PF_print, 0, 25, 0, 0, D("void(string s, ...)", "QW: Unconditionally prints the given message on the server's console. Arguments will be concatenated into a single message.")},
|
||||||
|
#else
|
||||||
|
//going forward, we have print and dprint
|
||||||
|
{"dprint", PF_dprint, 25, 25, 25, 0, D("void(string s, ...)", "NQ: Prints the given message on the server's console, but only if the developer cvar is set. Arguments will be concatenated into a single message.")},
|
||||||
|
#endif
|
||||||
{"ftos", PF_ftos, 26, 26, 26, 0, D("string(float val)", "Returns a tempstring containing a representation of the given float. Precision depends upon engine.")},
|
{"ftos", PF_ftos, 26, 26, 26, 0, D("string(float val)", "Returns a tempstring containing a representation of the given float. Precision depends upon engine.")},
|
||||||
{"vtos", PF_vtos, 27, 27, 27, 0, D("string(vector val)", "Returns a tempstring containing a representation of the given vector. Precision depends upon engine.")},
|
{"vtos", PF_vtos, 27, 27, 27, 0, D("string(vector val)", "Returns a tempstring containing a representation of the given vector. Precision depends upon engine.")},
|
||||||
{"coredump", PF_coredump, 28, 28, 28, 0, D("void()", "Writes out a coredump. This contains stack, globals, and field info for all ents. This can be handy for debugging.")},
|
{"coredump", PF_coredump, 28, 28, 28, 0, D("void()", "Writes out a coredump. This contains stack, globals, and field info for all ents. This can be handy for debugging.")},
|
||||||
|
|
|
@ -565,7 +565,10 @@ void SV_Map_f (void)
|
||||||
#ifdef Q3SERVER
|
#ifdef Q3SERVER
|
||||||
q3singleplayer = !strcmp(Cmd_Argv(0), "spmap");
|
q3singleplayer = !strcmp(Cmd_Argv(0), "spmap");
|
||||||
#endif
|
#endif
|
||||||
flushparms = !strcmp(Cmd_Argv(0), "map") || !strcmp(Cmd_Argv(0), "spmap");
|
if ((svs.gametype == GT_PROGS || svs.gametype == GT_Q1QVM) && progstype == PROG_QW)
|
||||||
|
flushparms = !strcmp(Cmd_Argv(0), "spmap"); //quakeworld's map command preserves spawnparms.
|
||||||
|
else
|
||||||
|
flushparms = !strcmp(Cmd_Argv(0), "map") || !strcmp(Cmd_Argv(0), "spmap"); //[sp]map flushes in nq+h2+q2+etc
|
||||||
#ifdef SAVEDGAMES
|
#ifdef SAVEDGAMES
|
||||||
newunit = flushparms || (!strcmp(Cmd_Argv(0), "changelevel") && !startspot);
|
newunit = flushparms || (!strcmp(Cmd_Argv(0), "changelevel") && !startspot);
|
||||||
q2savetos0 = !strcmp(Cmd_Argv(0), "gamemap") && !isDedicated; //q2
|
q2savetos0 = !strcmp(Cmd_Argv(0), "gamemap") && !isDedicated; //q2
|
||||||
|
@ -1910,7 +1913,10 @@ static void SV_Status_f (void)
|
||||||
#if defined(HAVE_SSL)
|
#if defined(HAVE_SSL)
|
||||||
extern cvar_t net_enable_tls;
|
extern cvar_t net_enable_tls;
|
||||||
#endif
|
#endif
|
||||||
extern cvar_t net_enable_http, net_enable_webrtcbroker, net_enable_websockets, net_enable_qizmo, net_enable_qtv;
|
#ifdef HAVE_HTTPSV
|
||||||
|
extern cvar_t net_enable_http, net_enable_webrtcbroker, net_enable_websockets;
|
||||||
|
#endif
|
||||||
|
extern cvar_t net_enable_qizmo, net_enable_qtv;
|
||||||
#endif
|
#endif
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
extern cvar_t sv_listen_nq, sv_listen_dp;
|
extern cvar_t sv_listen_nq, sv_listen_dp;
|
||||||
|
@ -1990,12 +1996,14 @@ static void SV_Status_f (void)
|
||||||
if (net_enable_tls.ival)
|
if (net_enable_tls.ival)
|
||||||
Con_Printf(" TLS");
|
Con_Printf(" TLS");
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_HTTPSV
|
||||||
if (net_enable_http.ival)
|
if (net_enable_http.ival)
|
||||||
Con_Printf(" HTTP");
|
Con_Printf(" HTTP");
|
||||||
if (net_enable_webrtcbroker.ival)
|
if (net_enable_webrtcbroker.ival)
|
||||||
Con_Printf(" WebRTC");
|
Con_Printf(" WebRTC");
|
||||||
if (net_enable_websockets.ival)
|
if (net_enable_websockets.ival)
|
||||||
Con_Printf(" WS");
|
Con_Printf(" WS");
|
||||||
|
#endif
|
||||||
if (net_enable_qizmo.ival)
|
if (net_enable_qizmo.ival)
|
||||||
Con_Printf(" QZ");
|
Con_Printf(" QZ");
|
||||||
if (net_enable_qtv.ival)
|
if (net_enable_qtv.ival)
|
||||||
|
|
|
@ -3140,13 +3140,27 @@ client_t *SVC_DirectConnect(void)
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
newcl->netchan.compresstable = NULL;
|
newcl->netchan.compresstable = NULL;
|
||||||
|
newcl->netchan.pext_fragmentation = mtu?true:false;
|
||||||
|
//this is the upper bound of the mtu, if its too high we'll get EMSGSIZE and we'll reduce it.
|
||||||
|
//however, if it drops below newcl->netchan.message.maxsize then we'll start to see undeliverable reliables, which means dropped clients.
|
||||||
|
newcl->netchan.mtu = MAX_DATAGRAM; //vanilla qw clients are assumed to have an mtu of this size.
|
||||||
if (mtu >= 64)
|
if (mtu >= 64)
|
||||||
{ //if we support application fragmenting, then we can send massive reliables without too much issue
|
{ //if we support application fragmenting, then we can send massive reliables without too much issue
|
||||||
newcl->netchan.fragmentsize = mtu;
|
newcl->netchan.mtu = mtu;
|
||||||
newcl->netchan.message.maxsize = sizeof(newcl->netchan.message_buf);
|
newcl->netchan.message.maxsize = sizeof(newcl->netchan.message_buf);
|
||||||
}
|
}
|
||||||
else //otherwise we can't fragment the packets, and the only way to honour the mtu is to send less data. yay for more round-trips.
|
else //otherwise we can't fragment the packets, and the only way to honour the mtu is to send less data. yay for more round-trips.
|
||||||
newcl->netchan.message.maxsize = min(newcl->netchan.message.maxsize, max(net_mtu.ival, 512));
|
{
|
||||||
|
mtu = atoi(Info_ValueForKey (userinfo[0], "mtu"));
|
||||||
|
if (mtu)
|
||||||
|
newcl->netchan.mtu = mtu; //locked mtu size, because not everyone has a working connection (we need icmp would-fragment responses for mtu detection)
|
||||||
|
else //if its not set then use some 'safe' fallback.
|
||||||
|
mtu = MAX_BACKBUFLEN; //MAX_BACKBUFLEN of 1200 is < ipv6 required segment size so should always work for reliables.
|
||||||
|
//enforce some boundaries
|
||||||
|
mtu = bound(512-8, mtu, sizeof(newcl->netchan.message_buf));
|
||||||
|
newcl->netchan.message.maxsize = mtu;
|
||||||
|
}
|
||||||
|
Con_DLPrintf(2, "MTU size: %i - %i\n", newcl->netchan.message.maxsize, newcl->netchan.mtu);
|
||||||
|
|
||||||
newcl->protocol = protocol;
|
newcl->protocol = protocol;
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
|
|
|
@ -35,7 +35,7 @@ void ClientReliableCheckBlock(client_t *cl, int maxsize)
|
||||||
memset(&cl->backbuf, 0, sizeof(cl->backbuf));
|
memset(&cl->backbuf, 0, sizeof(cl->backbuf));
|
||||||
cl->backbuf.allowoverflow = true;
|
cl->backbuf.allowoverflow = true;
|
||||||
cl->backbuf.data = cl->backbuf_data[0];
|
cl->backbuf.data = cl->backbuf_data[0];
|
||||||
cl->backbuf.maxsize = sizeof(cl->backbuf_data[0]);
|
cl->backbuf.maxsize = min(cl->netchan.message.maxsize, sizeof(cl->backbuf_data[0]));
|
||||||
cl->backbuf_size[0] = 0;
|
cl->backbuf_size[0] = 0;
|
||||||
cl->num_backbuf++;
|
cl->num_backbuf++;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ void ClientReliableCheckBlock(client_t *cl, int maxsize)
|
||||||
memset(&cl->backbuf, 0, sizeof(cl->backbuf));
|
memset(&cl->backbuf, 0, sizeof(cl->backbuf));
|
||||||
cl->backbuf.allowoverflow = true;
|
cl->backbuf.allowoverflow = true;
|
||||||
cl->backbuf.data = cl->backbuf_data[cl->num_backbuf];
|
cl->backbuf.data = cl->backbuf_data[cl->num_backbuf];
|
||||||
cl->backbuf.maxsize = sizeof(cl->backbuf_data[cl->num_backbuf]);
|
cl->backbuf.maxsize = min(cl->netchan.message.maxsize, sizeof(cl->backbuf_data[cl->num_backbuf]));
|
||||||
cl->backbuf_size[cl->num_backbuf] = 0;
|
cl->backbuf_size[cl->num_backbuf] = 0;
|
||||||
cl->num_backbuf++;
|
cl->num_backbuf++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2573,13 +2573,15 @@ qboolean SV_SendClientDatagram (client_t *client)
|
||||||
client->edict->v->goalentity = 0;
|
client->edict->v->goalentity = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client->netchan.fragmentsize)
|
if (client->netchan.pext_fragmentation)
|
||||||
{
|
{
|
||||||
if (client->netchan.remote_address.type == NA_LOOPBACK)
|
if (client->netchan.remote_address.type == NA_LOOPBACK)
|
||||||
clientlimit = countof(buf); //biiiig...
|
clientlimit = countof(buf); //biiiig...
|
||||||
else
|
else
|
||||||
clientlimit = client->netchan.fragmentsize; //try not to overflow
|
clientlimit = client->netchan.mtu; //try not to overflow
|
||||||
}
|
}
|
||||||
|
else if (client->netchan.mtu)
|
||||||
|
clientlimit = client->netchan.mtu;
|
||||||
else if (client->protocol == SCP_NETQUAKE)
|
else if (client->protocol == SCP_NETQUAKE)
|
||||||
clientlimit = MAX_NQDATAGRAM; //vanilla client is limited.
|
clientlimit = MAX_NQDATAGRAM; //vanilla client is limited.
|
||||||
else
|
else
|
||||||
|
@ -3411,7 +3413,7 @@ void SV_SendClientMessages (void)
|
||||||
memset(&c->backbuf, 0, sizeof(c->backbuf));
|
memset(&c->backbuf, 0, sizeof(c->backbuf));
|
||||||
c->backbuf.data = c->backbuf_data[c->num_backbuf - 1];
|
c->backbuf.data = c->backbuf_data[c->num_backbuf - 1];
|
||||||
c->backbuf.cursize = c->backbuf_size[c->num_backbuf - 1];
|
c->backbuf.cursize = c->backbuf_size[c->num_backbuf - 1];
|
||||||
c->backbuf.maxsize = sizeof(c->backbuf_data[c->num_backbuf - 1]);
|
c->backbuf.maxsize = min(c->netchan.message.maxsize, sizeof(c->backbuf_data[c->num_backbuf-1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3526,6 +3528,9 @@ void SV_SendClientMessages (void)
|
||||||
c->datagram.cursize = 0;
|
c->datagram.cursize = 0;
|
||||||
}
|
}
|
||||||
c->lastoutgoingphysicstime = sv.world.physicstime;
|
c->lastoutgoingphysicstime = sv.world.physicstime;
|
||||||
|
|
||||||
|
if (c->netchan.fatal_error)
|
||||||
|
c->drop = true;
|
||||||
}
|
}
|
||||||
#ifdef MVD_RECORDING
|
#ifdef MVD_RECORDING
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
|
|
|
@ -987,12 +987,12 @@ void SV_SendClientPrespawnInfo(client_t *client)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//just because we CAN generate huge messages doesn't meant that we should.
|
//just because we CAN generate huge messages doesn't mean that we should.
|
||||||
//try to keep packets within reasonable sizes so that we don't trigger insane burst+packetloss on map changes.
|
//try to keep packets within reasonable sizes so that we don't trigger insane burst+packetloss on map changes.
|
||||||
maxsize = client->netchan.message.maxsize/2;
|
maxsize = client->netchan.message.maxsize/2;
|
||||||
if (client->netchan.fragmentsize && maxsize > client->netchan.fragmentsize-200)
|
if (client->netchan.mtu && maxsize > client->netchan.mtu-200)
|
||||||
{
|
{
|
||||||
maxsize = client->netchan.fragmentsize-200;
|
maxsize = client->netchan.mtu-200;
|
||||||
if (maxsize < 500)
|
if (maxsize < 500)
|
||||||
maxsize = 500;
|
maxsize = 500;
|
||||||
}
|
}
|
||||||
|
@ -1933,7 +1933,6 @@ void SVQW_Spawn_f (void)
|
||||||
// when that is completed, a begin command will be issued
|
// when that is completed, a begin command will be issued
|
||||||
ClientReliableWrite_Begin (host_client, svc_stufftext, 8);
|
ClientReliableWrite_Begin (host_client, svc_stufftext, 8);
|
||||||
ClientReliableWrite_String (host_client, "skins\n" );
|
ClientReliableWrite_String (host_client, "skins\n" );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -7733,6 +7732,8 @@ void SV_ReadQCRequest(void)
|
||||||
done:
|
done:
|
||||||
args[i] = 0;
|
args[i] = 0;
|
||||||
rname = MSG_ReadString();
|
rname = MSG_ReadString();
|
||||||
|
//We used to use Cmd_foo_args, but that conflicts with a zquake extension and would cause [e]zquake mods that use it to be remotely exploitable (mostly crashes from uninitialised args though).
|
||||||
|
//Instead, we've switched to some more weird prefix that's much less likly to conflict.
|
||||||
if (i)
|
if (i)
|
||||||
fname = va("CSEv_%s_%s", rname, args);
|
fname = va("CSEv_%s_%s", rname, args);
|
||||||
else if (strchr(rname, '_')) //this is awkward, as not forcing an underscore would allow people to mis-call things with lingering data (the alternative is to block underscores entirely).
|
else if (strchr(rname, '_')) //this is awkward, as not forcing an underscore would allow people to mis-call things with lingering data (the alternative is to block underscores entirely).
|
||||||
|
@ -7749,7 +7750,10 @@ done:
|
||||||
rname = va("Cmd_%s", rname);
|
rname = va("Cmd_%s", rname);
|
||||||
f = PR_FindFunction(svprogfuncs, rname, PR_ANY);
|
f = PR_FindFunction(svprogfuncs, rname, PR_ANY);
|
||||||
if (f)
|
if (f)
|
||||||
SV_ClientPrintf(host_client, PRINT_HIGH, "the name \"%s\" is deprecated\n", rname);
|
{
|
||||||
|
SV_ClientPrintf(host_client, PRINT_HIGH, "\"%s\" is no longer supported.\n", rname);
|
||||||
|
f = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (host_client->drop)
|
if (host_client->drop)
|
||||||
|
|
|
@ -809,6 +809,10 @@ static void QDECL PFQ2_SetAreaPortalState(unsigned int p, qboolean s)
|
||||||
CMQ2_SetAreaPortalState(sv.world.worldmodel, p, s);
|
CMQ2_SetAreaPortalState(sv.world.worldmodel, p, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *VARGS ZQ2_TagMalloc(int size, int tag)
|
||||||
|
{
|
||||||
|
return Z_TagMalloc(size, tag);
|
||||||
|
}
|
||||||
qboolean SVQ2_InitGameProgs(void)
|
qboolean SVQ2_InitGameProgs(void)
|
||||||
{
|
{
|
||||||
extern cvar_t maxclients;
|
extern cvar_t maxclients;
|
||||||
|
@ -862,7 +866,7 @@ qboolean SVQ2_InitGameProgs(void)
|
||||||
import.WriteDir = PFQ2_WriteDir;
|
import.WriteDir = PFQ2_WriteDir;
|
||||||
import.WriteAngle = PFQ2_WriteAngle;
|
import.WriteAngle = PFQ2_WriteAngle;
|
||||||
|
|
||||||
import.TagMalloc = Z_TagMalloc;
|
import.TagMalloc = ZQ2_TagMalloc;
|
||||||
import.TagFree = Z_TagFree;
|
import.TagFree = Z_TagFree;
|
||||||
import.FreeTags = Z_FreeTags;
|
import.FreeTags = Z_FreeTags;
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
|
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
|
||||||
//the vertex shader is responsible for calculating lighting values.
|
//the vertex shader is responsible for calculating lighting values.
|
||||||
|
|
||||||
#if gl_affinemodels==1 && __VERSION__ >= 130
|
#if gl_affinemodels==1 && __VERSION__ >= 130 && !defined(GL_ES)
|
||||||
#define affine noperspective
|
#define affine noperspective
|
||||||
#else
|
#else
|
||||||
#define affine
|
#define affine
|
||||||
|
|
|
@ -9,11 +9,17 @@
|
||||||
!!permu REFLECTCUBEMASK
|
!!permu REFLECTCUBEMASK
|
||||||
!!cvarf r_glsl_offsetmapping_scale
|
!!cvarf r_glsl_offsetmapping_scale
|
||||||
!!cvardf r_tessellation_level=5
|
!!cvardf r_tessellation_level=5
|
||||||
!!samps !EIGHTBIT diffuse specular normalmap fullbright reflectmask reflectcube
|
!!samps diffuse
|
||||||
|
!!samps !EIGHTBIT =FULLBRIGHT fullbright
|
||||||
|
!!samps !EIGHTBIT =BUMP normalmap
|
||||||
|
!!samps !EIGHTBIT =REFLECTCUBEMASK reflectmask reflectcube
|
||||||
//diffuse gives us alpha, and prevents dlight from bugging out when there's no diffuse.
|
//diffuse gives us alpha, and prevents dlight from bugging out when there's no diffuse.
|
||||||
!!samps =EIGHTBIT paletted 1 specular diffuse
|
!!samps =EIGHTBIT paletted 1
|
||||||
!!samps lightmap deluxemap
|
!!samps =SPECULAR specular
|
||||||
!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3 deluxemap deluxemap1 deluxemap2 deluxemap3
|
!!samps lightmap
|
||||||
|
!!samps =LIGHTSTYLED lightmap1 lightmap2 lightmap3
|
||||||
|
!!samps =DELUXE deluxmap
|
||||||
|
!!samps =LIGHTSTYLED =DELUXE deluxemap1 deluxemap2 deluxemap3
|
||||||
|
|
||||||
#if defined(ORM) || defined(SG)
|
#if defined(ORM) || defined(SG)
|
||||||
#define PBR
|
#define PBR
|
||||||
|
@ -299,7 +305,7 @@ void main ()
|
||||||
vec3 deluxe = (texture2D(s_deluxemap, lm0).rgb-0.5);
|
vec3 deluxe = (texture2D(s_deluxemap, lm0).rgb-0.5);
|
||||||
#ifdef BUMPMODELSPACE
|
#ifdef BUMPMODELSPACE
|
||||||
deluxe = normalize(deluxe*invsurface);
|
deluxe = normalize(deluxe*invsurface);
|
||||||
#else
|
#else
|
||||||
deluxe = normalize(deluxe);
|
deluxe = normalize(deluxe);
|
||||||
lightmaps *= 2.0 / max(0.25, deluxe.z); //counter the darkening from deluxemaps
|
lightmaps *= 2.0 / max(0.25, deluxe.z); //counter the darkening from deluxemaps
|
||||||
#endif
|
#endif
|
||||||
|
@ -370,7 +376,6 @@ void main ()
|
||||||
#else
|
#else
|
||||||
//now we have our diffuse+specular terms, modulate by lightmap values.
|
//now we have our diffuse+specular terms, modulate by lightmap values.
|
||||||
col.rgb *= lightmaps.rgb;
|
col.rgb *= lightmaps.rgb;
|
||||||
|
|
||||||
//add on the fullbright
|
//add on the fullbright
|
||||||
#ifdef FULLBRIGHT
|
#ifdef FULLBRIGHT
|
||||||
col.rgb += texture2D(s_fullbright, tc).rgb;
|
col.rgb += texture2D(s_fullbright, tc).rgb;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
!!ver 100 300
|
||||||
!!permu FOG
|
!!permu FOG
|
||||||
//t0-t3 are the diffusemaps, t4 is the blend factors
|
//RTLIGHT (+PCF,CUBE,SPOT,etc)
|
||||||
!!samps 4
|
!!samps tr=0 tg=1 tb=2 tx=3 //the four texturemaps
|
||||||
!!samps mix=4
|
!!samps mix=4 //how the ground is blended
|
||||||
!!samps =PCF shadowmap
|
!!samps =PCF shadowmap
|
||||||
!!samps =CUBE projectionmap
|
!!samps =CUBE projectionmap
|
||||||
|
|
||||||
|
@ -98,10 +99,12 @@ void main (void)
|
||||||
vec4 r;
|
vec4 r;
|
||||||
vec4 m = texture2D(s_mix, lm);
|
vec4 m = texture2D(s_mix, lm);
|
||||||
|
|
||||||
r = texture2D(s_t0, tc)*m.r;
|
r = texture2D(s_tr, tc)*m.r;
|
||||||
r += texture2D(s_t1, tc)*m.g;
|
r += texture2D(s_tg, tc)*m.g;
|
||||||
r += texture2D(s_t2, tc)*m.b;
|
r += texture2D(s_tb, tc)*m.b;
|
||||||
r += texture2D(s_t3, tc)*(1.0 - (m.r + m.g + m.b));
|
r += texture2D(s_tx, tc)*(1.0 - (m.r + m.g + m.b));
|
||||||
|
|
||||||
|
r.rgb *= 1.0/r.a; //fancy maths, so low alpha values give other textures a greater focus
|
||||||
|
|
||||||
//vertex colours provide a scaler that applies even through rtlights.
|
//vertex colours provide a scaler that applies even through rtlights.
|
||||||
r *= vc;
|
r *= vc;
|
||||||
|
|
Loading…
Reference in a new issue