1
0
Fork 0
forked from fte/fteqw

Filename security paranoia. Added a glsl extension to the shader system. using serverinfo, you can enable shaders without cheats now.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2079 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2006-03-11 03:12:10 +00:00
parent 05ace9bdcb
commit aeea639fc2
36 changed files with 647 additions and 298 deletions

View file

@ -770,7 +770,7 @@ void CL_Record_f (void)
f = FS_OpenVFS (name, "rb", FS_GAME); f = FS_OpenVFS (name, "rb", FS_GAME);
if (f) if (f)
{ {
COM_StripExtension(name, name); COM_StripExtension(name, name, sizeof(name));
p = name + strlen(name); p = name + strlen(name);
strcat(p, "_XX.qwd"); strcat(p, "_XX.qwd");
p++; p++;
@ -1106,7 +1106,7 @@ void CL_ReRecord_f (void)
// //
// open the demo file // open the demo file
// //
COM_DefaultExtension (name, ".qwd"); COM_DefaultExtension (name, ".qwd", sizeof(name));
cls.demofile = FS_OpenVFS (name, "wb", FS_GAME); cls.demofile = FS_OpenVFS (name, "wb", FS_GAME);
if (!cls.demofile) if (!cls.demofile)
@ -1181,18 +1181,18 @@ void CL_PlayDemo(char *demoname)
// open the demo file // open the demo file
// //
Q_strncpyz (name, demoname, sizeof(name)); Q_strncpyz (name, demoname, sizeof(name));
COM_DefaultExtension (name, ".qwd"); COM_DefaultExtension (name, ".qwd", sizeof(name));
cls.demofile = FS_OpenVFS(name, "rb", FS_GAME); cls.demofile = FS_OpenVFS(name, "rb", FS_GAME);
if (!cls.demofile) if (!cls.demofile)
{ {
Q_strncpyz (name, demoname, sizeof(name)); Q_strncpyz (name, demoname, sizeof(name));
COM_DefaultExtension (name, ".dem"); COM_DefaultExtension (name, ".dem", sizeof(name));
cls.demofile = FS_OpenVFS(name, "rb", FS_GAME); cls.demofile = FS_OpenVFS(name, "rb", FS_GAME);
} }
if (!cls.demofile) if (!cls.demofile)
{ {
Q_strncpyz (name, demoname, sizeof(name)); Q_strncpyz (name, demoname, sizeof(name));
COM_DefaultExtension (name, ".mvd"); COM_DefaultExtension (name, ".mvd", sizeof(name));
cls.demofile = FS_OpenVFS(name, "rb", FS_GAME); cls.demofile = FS_OpenVFS(name, "rb", FS_GAME);
} }
if (!cls.demofile) if (!cls.demofile)

View file

@ -1293,6 +1293,9 @@ void CL_CheckServerInfo(void)
char *s; char *s;
unsigned int allowed; unsigned int allowed;
int oldstate; int oldstate;
qboolean oldallowshaders;
oldallowshaders = cls.allow_shaders;
cl.teamplay = atoi(Info_ValueForKey(cl.serverinfo, "teamplay")); cl.teamplay = atoi(Info_ValueForKey(cl.serverinfo, "teamplay"));
cl.deathmatch = atoi(Info_ValueForKey(cl.serverinfo, "deathmatch")); cl.deathmatch = atoi(Info_ValueForKey(cl.serverinfo, "deathmatch"));
@ -1357,6 +1360,11 @@ void CL_CheckServerInfo(void)
cls.allow_cheats = false; cls.allow_cheats = false;
} }
cls.allow_shaders = cls.allow_cheats;
if (cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "allow_shaders")))
cls.allow_shaders=true;
cls.maxfps = atof(Info_ValueForKey(cl.serverinfo, "maxfps")); cls.maxfps = atof(Info_ValueForKey(cl.serverinfo, "maxfps"));
if (cls.maxfps < 20) if (cls.maxfps < 20)
@ -1425,6 +1433,9 @@ void CL_CheckServerInfo(void)
Cvar_ForceCheatVars(cls.allow_semicheats, cls.allow_cheats); Cvar_ForceCheatVars(cls.allow_semicheats, cls.allow_cheats);
if (oldallowshaders != cls.allow_shaders)
Cache_Flush(); //this will cause all models to be reloaded.
} }
/* /*
================== ==================

View file

@ -328,7 +328,7 @@ void CL_SendDownloadRequest(char *filename, char *localname)
// download to a temp name, and only rename // download to a temp name, and only rename
// to the real name when done, so if interrupted // to the real name when done, so if interrupted
// a runt file wont be left // a runt file wont be left
COM_StripExtension (localname, cls.downloadtempname); COM_StripExtension (localname, cls.downloadtempname, sizeof(cls.downloadtempname)-5);
strcat (cls.downloadtempname, ".tmp"); strcat (cls.downloadtempname, ".tmp");
CL_SendClientCommand(true, "download %s", filename); CL_SendClientCommand(true, "download %s", filename);
@ -2640,7 +2640,7 @@ void CL_NewTranslation (int slot)
player = &cl.players[slot]; player = &cl.players[slot];
s = Skin_FindName (player); s = Skin_FindName (player);
COM_StripExtension(s, s); COM_StripExtension(s, s, MAX_QPATH);
if (player->skin && !stricmp(s, player->skin->name)) if (player->skin && !stricmp(s, player->skin->name))
player->skin = NULL; player->skin = NULL;

View file

@ -1407,7 +1407,7 @@ void SCR_EndLoadingPlaque (void)
void SCR_ImageName (char *mapname) void SCR_ImageName (char *mapname)
{ {
strcpy(levelshotname, "levelshots/"); strcpy(levelshotname, "levelshots/");
COM_FileBase(mapname, levelshotname + strlen(levelshotname)); COM_FileBase(mapname, levelshotname + strlen(levelshotname), sizeof(levelshotname)-strlen(levelshotname));
#ifdef RGLQUAKE #ifdef RGLQUAKE
if (qrenderer == QR_OPENGL) if (qrenderer == QR_OPENGL)
@ -1709,7 +1709,7 @@ void SCR_ScreenShot_f (void)
Con_Printf("Screenshot name refused\n"); Con_Printf("Screenshot name refused\n");
return; return;
} }
COM_DefaultExtension (pcxname, scr_sshot_type.string); COM_DefaultExtension (pcxname, scr_sshot_type.string, sizeof(pcxname));
} }
else else
{ {

View file

@ -307,7 +307,7 @@ static void Stats_LoadFragFile(char *name)
Stats_Clear(); Stats_Clear();
strcpy(filename, name); strcpy(filename, name);
COM_DefaultExtension(filename, ".dat"); COM_DefaultExtension(filename, ".dat", sizeof(filename));
file = COM_LoadTempFile(filename); file = COM_LoadTempFile(filename);
if (!file || !*file) if (!file || !*file)

View file

@ -1912,7 +1912,7 @@ int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean al
int i, e; int i, e;
COM_StripExtension(name, nicename); COM_StripExtension(name, nicename, sizeof(nicename));
while((data = strchr(nicename, '*'))) while((data = strchr(nicename, '*')))
{ {
@ -2036,7 +2036,7 @@ int Mod_LoadBumpmapTexture(char *name, char *subpath)
TRACE(("dbg: Mod_LoadBumpmapTexture: texture %s\n", name)); TRACE(("dbg: Mod_LoadBumpmapTexture: texture %s\n", name));
COM_StripExtension(name, nicename); COM_StripExtension(name, nicename, sizeof(nicename));
if ((len = GL_FindTexture(name))!=-1) //don't bother if it already exists. if ((len = GL_FindTexture(name))!=-1) //don't bother if it already exists.
return len; return len;
@ -2062,7 +2062,7 @@ int Mod_LoadBumpmapTexture(char *name, char *subpath)
Q_strncpyz(map, sv.name, sizeof(map)); Q_strncpyz(map, sv.name, sizeof(map));
else else
#endif #endif
COM_FileBase(cl.model_name[1], map); COM_FileBase(cl.model_name[1], map, sizeof(map));
snprintf(fname, sizeof(fname)-1, path[i], map, nicename, extensions[e]); snprintf(fname, sizeof(fname)-1, path[i], map, nicename, extensions[e]);
} }
else else

View file

@ -238,7 +238,7 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu)
{ {
char selname[MAX_QPATH]; char selname[MAX_QPATH];
Q_strncpyz(selname, option->picture.picturename, sizeof(selname)); Q_strncpyz(selname, option->picture.picturename, sizeof(selname));
COM_StripExtension(selname, selname); COM_StripExtension(selname, selname, sizeof(selname));
p = Draw_SafeCachePic(va("%s_sel", selname)); p = Draw_SafeCachePic(va("%s_sel", selname));
} }

View file

@ -859,6 +859,7 @@ struct cin_s {
float filmstarttime; float filmstarttime;
float nextframetime; float nextframetime;
float filmlasttime;
int currentframe; //last frame in buffer int currentframe; //last frame in buffer
qbyte *framedata; //Z_Malloced buffer qbyte *framedata; //Z_Malloced buffer
@ -1132,14 +1133,19 @@ cin_t *Media_StartCin(char *name)
return NULL; return NULL;
} }
qboolean Media_DecodeFrame(cin_t *cin) qboolean Media_DecodeFrame(cin_t *cin, qboolean nosound)
{ {
float curtime = Sys_DoubleTime(); float curtime = Sys_DoubleTime();
switch (cin->filmtype) switch (cin->filmtype)
{ {
case MFT_ROQ: case MFT_ROQ:
if (curtime<cin->nextframetime || roq_read_frame(cin->roq.roqfilm)==1) //0 if end, -1 if error, 1 if success if ((int)(cin->filmlasttime*30) == (int)((float)realtime*30))
{
cin->outunchanged = !!cin->outtype;
return true;
}
else if (curtime<cin->nextframetime || roq_read_frame(cin->roq.roqfilm)==1) //0 if end, -1 if error, 1 if success
{ {
//#define LIMIT(x) ((x)<0xFFFF)?(x)>>16:0xFF; //#define LIMIT(x) ((x)<0xFFFF)?(x)>>16:0xFF;
#define LIMIT(x) ((((x) > 0xffffff) ? 0xff0000 : (((x) <= 0xffff) ? 0 : (x) & 0xff0000)) >> 16) #define LIMIT(x) ((((x) > 0xffffff) ? 0xff0000 : (((x) <= 0xffff) ? 0 : (x) & 0xff0000)) >> 16)
@ -1153,6 +1159,9 @@ qboolean Media_DecodeFrame(cin_t *cin)
int x; int x;
qbyte *framedata; qbyte *framedata;
cin->filmlasttime = (float)realtime;
if (!(curtime<cin->nextframetime)) //roq file was read properly if (!(curtime<cin->nextframetime)) //roq file was read properly
{ {
cin->nextframetime += 1/30.0; //add a little bit of extra speed so we cover up a little bit of glitchy sound... :o) cin->nextframetime += 1/30.0; //add a little bit of extra speed so we cover up a little bit of glitchy sound... :o)
@ -1197,11 +1206,6 @@ qboolean Media_DecodeFrame(cin_t *cin)
if(y & 0x01) { pb += num_columns; pc += num_columns; } if(y & 0x01) { pb += num_columns; pc += num_columns; }
} }
} }
else if (vid.numpages == 1) //previous frame is still in page.
{
cin->outunchanged = true;
return true;
}
cin->outunchanged = false; cin->outunchanged = false;
cin->outtype = 1; cin->outtype = 1;
@ -1209,6 +1213,7 @@ qboolean Media_DecodeFrame(cin_t *cin)
cin->outheight = cin->roq.roqfilm->height; cin->outheight = cin->roq.roqfilm->height;
cin->outdata = cin->framedata; cin->outdata = cin->framedata;
if (!nosound)
if (cin->roq.roqfilm->audio_channels && sndcardinfo && cin->roq.roqfilm->aud_pos < cin->roq.roqfilm->vid_pos) if (cin->roq.roqfilm->audio_channels && sndcardinfo && cin->roq.roqfilm->aud_pos < cin->roq.roqfilm->vid_pos)
if (roq_read_audio(cin->roq.roqfilm)>0) if (roq_read_audio(cin->roq.roqfilm)>0)
{ {
@ -1349,7 +1354,7 @@ qboolean Media_ShowFilm(void)
{ {
if (!fullscreenvid) if (!fullscreenvid)
return false; return false;
if (!Media_DecodeFrame(fullscreenvid)) if (!Media_DecodeFrame(fullscreenvid, false))
{ {
Media_ShutdownCin(fullscreenvid); Media_ShutdownCin(fullscreenvid);
fullscreenvid = NULL; fullscreenvid = NULL;
@ -1377,27 +1382,30 @@ int Media_UpdateForShader(int texnum, cin_t *cin)
{ {
if (!cin) if (!cin)
return 0; return 0;
if (!Media_DecodeFrame(cin)) if (!Media_DecodeFrame(cin, true))
{ {
return 0; return 0;
} }
GL_Bind(100); if (!cin->outunchanged)
switch(cin->outtype)
{ {
case 1: GL_Bind(texnum);
GL_Upload32("cin", (unsigned int*)cin->outdata, cin->outwidth, cin->outheight, false, false); switch(cin->outtype)
break; {
case 2: case 1:
GL_Upload8("cin", cin->outdata, cin->outwidth, cin->outheight, false, false); GL_Upload32("cin", (unsigned int*)cin->outdata, cin->outwidth, cin->outheight, false, false);
break; break;
case 3: case 2:
GL_Upload24BGR_Flip ("cin", cin->outdata, cin->outwidth, cin->outheight, false, false); GL_Upload8("cin", cin->outdata, cin->outwidth, cin->outheight, false, false);
break; break;
case 3:
GL_Upload24BGR_Flip ("cin", cin->outdata, cin->outwidth, cin->outheight, false, false);
break;
}
} }
return 100; return texnum;
} }
#endif #endif
@ -1691,8 +1699,8 @@ void Media_RecordFilm_f (void)
if (capturetype == CT_AVI) if (capturetype == CT_AVI)
{ {
snprintf(filename, 192, "%s%s", com_gamedir, Cmd_Argv(1)); snprintf(filename, 192, "%s%s", com_gamedir, Cmd_Argv(1));
COM_StripExtension(filename, filename); COM_StripExtension(filename, filename, sizeof(filename));
COM_DefaultExtension (filename, ".avi"); COM_DefaultExtension (filename, ".avi", sizeof(filename));
//wipe it. //wipe it.
f = fopen(filename, "rb"); f = fopen(filename, "rb");

View file

@ -34,7 +34,7 @@ extern void (*Draw_ConsoleBackground) (int lines);
extern void (*Draw_EditorBackground) (int lines); extern void (*Draw_EditorBackground) (int lines);
extern void (*Draw_TileClear) (int x, int y, int w, int h); extern void (*Draw_TileClear) (int x, int y, int w, int h);
extern void (*Draw_Fill) (int x, int y, int w, int h, int c); extern void (*Draw_Fill) (int x, int y, int w, int h, int c);
extern void (*Draw_FillRGB) (int x, int y, int w, int h, float r, float g, float b); extern void (*Draw_FillRGB) (int x, int y, int w, int h, float r, float g, float b);
extern void (*Draw_FadeScreen) (void); extern void (*Draw_FadeScreen) (void);
extern void (*Draw_BeginDisc) (void); extern void (*Draw_BeginDisc) (void);
extern void (*Draw_EndDisc) (void); extern void (*Draw_EndDisc) (void);

View file

@ -1596,7 +1596,7 @@ void P_ReadPointFile_f (void)
char line[1024]; char line[1024];
char *s; char *s;
COM_StripExtension(cl.worldmodel->name, name); COM_StripExtension(cl.worldmodel->name, name, sizeof(name));
strcat(name, ".pts"); strcat(name, ".pts");
f = FS_OpenVFS(name, "rb", FS_GAME); f = FS_OpenVFS(name, "rb", FS_GAME);

View file

@ -180,7 +180,7 @@ cvar_t scr_chatmodecvar = SCVAR("scr_chatmode", "0");
cvar_t gl_shadeq3 = SCVARF("gl_shadeq3", "1", CVAR_SEMICHEAT); //use if you want. cvar_t gl_shadeq3 = SCVARF("gl_shadeq3", "1", CVAR_SEMICHEAT); //use if you want.
cvar_t gl_shadeq2 = SCVARF("gl_shadeq2", "0", CVAR_SEMICHEAT); //use if you want. cvar_t gl_shadeq2 = SCVARF("gl_shadeq2", "0", CVAR_SEMICHEAT); //use if you want.
extern cvar_t r_vertexlight; extern cvar_t r_vertexlight;
cvar_t gl_shadeq1 = SCVARF("gl_shadeq1", "0", CVAR_CHEAT); //FIXME: :( cvar_t gl_shadeq1 = SCVARF("gl_shadeq1", "0", CVAR_SEMICHEAT);
cvar_t gl_shadeq1_name = SCVAR("gl_shadeq1_name", "*"); cvar_t gl_shadeq1_name = SCVAR("gl_shadeq1_name", "*");
#endif #endif

View file

@ -138,12 +138,13 @@ void Skin_Find (player_info_t *sc)
if (*mn) if (*mn)
{ {
mn = va("%s/%s", mn, s); mn = va("%s/%s", mn, s);
COM_StripExtension (mn, name); COM_StripExtension (mn, name, sizeof(name));
} }
else else
{
s = Skin_FindName(sc); s = Skin_FindName(sc);
COM_StripExtension (s, name); COM_StripExtension (s, name, sizeof(name));
}
s = strchr(name, '/'); s = strchr(name, '/');
if (s) if (s)

View file

@ -1599,7 +1599,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
spare = s->sfxcache->length; spare = s->sfxcache->length;
if (spare > snd_speed) if (spare > snd_speed)
{ {
Con_Printf("Sacrificed raw sound stream\n"); Con_DPrintf("Sacrificed raw sound stream\n");
spare = 0; //too far out. sacrifice it all spare = 0; //too far out. sacrifice it all
} }
} }
@ -1611,7 +1611,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
if (s->sfxcache->length > snd_speed*2) // more than 2 seconds of sound if (s->sfxcache->length > snd_speed*2) // more than 2 seconds of sound
{ {
Con_Printf("Sacrificed raw sound stream\n"); Con_DPrintf("Sacrificed raw sound stream\n");
spare = 0; //too far out. sacrifice it all spare = 0; //too far out. sacrifice it all
} }
} }

View file

@ -478,13 +478,18 @@ void Sys_ServerActivity(void)
char *Sys_GetClipboard(void)
{ #define SYS_CLIPBOARD_SIZE 256
return NULL; static char clipboard_buffer[SYS_CLIPBOARD_SIZE] = {0};
char *Sys_GetClipboard(void) {
return clipboard_buffer;
} }
void Sys_CloseClipboard(char *bf) void Sys_CloseClipboard(char *bf)
{ {
} }
void Sys_SaveClipboard(char *text)
{ void Sys_SaveClipboard(char *text) {
Q_strncpyz(clipboard_buffer, text, SYS_CLIPBOARD_SIZE);
} }

View file

@ -1438,7 +1438,7 @@ static void TP_LoadLocFile (char *filename, qbool quiet)
return; return;
Q_snprintfz (fullpath, sizeof(fullpath) - 4, "locs/%s", filename); Q_snprintfz (fullpath, sizeof(fullpath) - 4, "locs/%s", filename);
COM_DefaultExtension (fullpath, ".loc"); COM_DefaultExtension (fullpath, ".loc", sizeof(fullpath));
buf = (char *) COM_LoadTempFile (fullpath); buf = (char *) COM_LoadTempFile (fullpath);
if (!buf) { if (!buf) {
@ -3005,7 +3005,7 @@ qbool TP_CheckSoundTrigger (char *str)
if (!snd_initialized) if (!snd_initialized)
return false; return false;
COM_DefaultExtension (soundname, ".wav"); COM_DefaultExtension (soundname, ".wav", sizeof(soundname));
// make sure we have it on disk (FIXME) // make sure we have it on disk (FIXME)
if (!FS_FLocateFile (va("sound/%s", soundname), FSLFRT_IFFOUND, NULL)) if (!FS_FLocateFile (va("sound/%s", soundname), FSLFRT_IFFOUND, NULL))

View file

@ -499,7 +499,7 @@ void Cmd_Exec_f (void)
if (!*f) if (!*f)
f = "fte"; f = "fte";
snprintf(name, sizeof(name)-5, "configs/%s", f); snprintf(name, sizeof(name)-5, "configs/%s", f);
COM_DefaultExtension(name, ".cfg"); COM_DefaultExtension(name, ".cfg", sizeof(name));
} }
else else
Q_strncpyz(name, Cmd_Argv(1), sizeof(name)); Q_strncpyz(name, Cmd_Argv(1), sizeof(name));
@ -2719,6 +2719,7 @@ void Cmd_WriteConfig_f(void)
{ {
vfsfile_t *f; vfsfile_t *f;
char *filename; char *filename;
char fname[MAX_OSPATH];
filename = Cmd_Argv(1); filename = Cmd_Argv(1);
if (!*filename) if (!*filename)
@ -2733,7 +2734,8 @@ void Cmd_WriteConfig_f(void)
filename = va("configs/%s.cfg",filename); filename = va("configs/%s.cfg",filename);
} }
COM_DefaultExtension(filename, ".cfg"); Q_strncpyz(fname, filename, sizeof(fname));
COM_DefaultExtension(fname, ".cfg", sizeof(fname));
FS_CreatePath(filename, FS_CONFIGONLY); FS_CreatePath(filename, FS_CONFIGONLY);
f = FS_OpenVFS(filename, "wb", FS_CONFIGONLY); f = FS_OpenVFS(filename, "wb", FS_CONFIGONLY);
if (!f) if (!f)
@ -2786,7 +2788,7 @@ void Cmd_Condump_f(void)
filename = "condump"; filename = "condump";
filename = va("%s", filename); filename = va("%s", filename);
COM_DefaultExtension(filename, ".txt"); COM_DefaultExtension(filename, ".txt", MAX_QPATH);
f = FS_OpenVFS (filename, "wb", FS_GAME); f = FS_OpenVFS (filename, "wb", FS_GAME);
if (!f) if (!f)

View file

@ -1371,11 +1371,12 @@ char *COM_SkipPath (char *pathname)
COM_StripExtension COM_StripExtension
============ ============
*/ */
void COM_StripExtension (char *in, char *out) void COM_StripExtension (char *in, char *out, int outlen)
{ {
char *s; char *s;
strcpy(out, in); if (out != in)
Q_strncpyz(out, in, outlen);
s = out+strlen(out); s = out+strlen(out);
@ -1467,7 +1468,7 @@ void COM_CleanUpPath(char *str)
COM_FileBase COM_FileBase
============ ============
*/ */
void COM_FileBase (char *in, char *out) void COM_FileBase (char *in, char *out, int outlen)
{ {
char *s, *s2; char *s, *s2;
@ -1487,8 +1488,11 @@ void COM_FileBase (char *in, char *out)
else else
{ {
s--; s--;
Q_strncpyS (out,s2+1, s-s2); outlen--;
out[s-s2] = 0; if (outlen > s-s2)
outlen = s-s2;
Q_strncpyS (out,s2+1, outlen);
out[outlen] = 0;
} }
} }
@ -1498,7 +1502,7 @@ void COM_FileBase (char *in, char *out)
COM_DefaultExtension COM_DefaultExtension
================== ==================
*/ */
void COM_DefaultExtension (char *path, char *extension) void COM_DefaultExtension (char *path, char *extension, int maxlen)
{ {
char *src; char *src;
// //
@ -1514,7 +1518,7 @@ void COM_DefaultExtension (char *path, char *extension)
src--; src--;
} }
strcat (path, extension); Q_strncatz (path, extension, maxlen);
} }
//============================================================================ //============================================================================

View file

@ -249,9 +249,9 @@ void COM_InitArgv (int argc, char **argv);
void COM_ParsePlusSets (void); void COM_ParsePlusSets (void);
char *COM_SkipPath (char *pathname); char *COM_SkipPath (char *pathname);
void COM_StripExtension (char *in, char *out); void COM_StripExtension (char *in, char *out, int outlen);
void COM_FileBase (char *in, char *out); void COM_FileBase (char *in, char *out, int outlen);
void COM_DefaultExtension (char *path, char *extension); void COM_DefaultExtension (char *path, char *extension, int maxlen);
char *COM_FileExtension (char *in); char *COM_FileExtension (char *in);
void COM_CleanUpPath(char *str); void COM_CleanUpPath(char *str);

View file

@ -1252,29 +1252,18 @@ The filename will be prefixed by the current game directory
*/ */
void COM_WriteFile (char *filename, void *data, int len) void COM_WriteFile (char *filename, void *data, int len)
{ {
FILE *f; vfsfile_t *vfs;
char name[MAX_OSPATH];
sprintf (name, "%s/%s", com_gamedir, filename); Sys_Printf ("COM_WriteFile: %s\n", filename);
COM_CreatePath(name); FS_CreatePath(filename, FS_GAMEONLY);
vfs = FS_OpenVFS(filename, "wb", FS_GAMEONLY);
f = fopen (name, "wb"); if (vfs)
if (!f)
{ {
Sys_mkdir(com_gamedir); VFS_WRITE(vfs, data, len);
f = fopen (name, "wb"); VFS_CLOSE(vfs);
if (!f)
{
Con_Printf("Error opening %s for writing\n", filename);
return;
}
} }
Sys_Printf ("COM_WriteFile: %s\n", name);
fwrite (data, 1, len, f);
fclose (f);
com_fschanged=true; com_fschanged=true;
} }
@ -1997,7 +1986,7 @@ void FS_CreatePath(char *pname, int relativeto)
{ {
case FS_GAMEONLY: case FS_GAMEONLY:
case FS_GAME: case FS_GAME:
snprintf(fullname, sizeof(fullname), "%s%s", com_gamedir, pname); snprintf(fullname, sizeof(fullname), "%s/%s", com_gamedir, pname);
break; break;
case FS_BASE: case FS_BASE:
if (*com_homedir) if (*com_homedir)
@ -2069,7 +2058,7 @@ qbyte *COM_LoadFile (char *path, int usehunk)
com_filesize = len = VFS_GETLEN(f); com_filesize = len = VFS_GETLEN(f);
// extract the filename base name for hunk tag // extract the filename base name for hunk tag
COM_FileBase (path, base); COM_FileBase (path, base, sizeof(base));
if (usehunk == 0) if (usehunk == 0)
buf = (qbyte*)Z_Malloc (len+1); buf = (qbyte*)Z_Malloc (len+1);

View file

@ -992,7 +992,7 @@ void *Mod_LoadWall(char *name)
int width, height; int width, height;
char ln[32]; char ln[32];
COM_FileBase(name, ln); COM_FileBase(name, ln, sizeof(ln));
wal = (void *)COM_LoadMallocFile (name); wal = (void *)COM_LoadMallocFile (name);
if (!wal) if (!wal)

View file

@ -2826,7 +2826,7 @@ int GL_BuildSkinFileList(char *modelname)
} }
skinfilecount=0; skinfilecount=0;
COM_StripExtension(modelname, skinfilename); COM_StripExtension(modelname, skinfilename, sizeof(skinfilename));
//try and add numbered skins, and then try fixed names. //try and add numbered skins, and then try fixed names.
for (i = 0; ; i++) for (i = 0; ; i++)
@ -3205,12 +3205,15 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha)
outskin->texnums=1; outskin->texnums=1;
outskin->ofstexnums = (char *)texnums - (char *)outskin; outskin->ofstexnums = (char *)texnums - (char *)outskin;
/*
#ifdef Q3SHADERS #ifdef Q3SHADERS
sprintf(skinname, "%s_%i", loadname, i); if (cls.allow_shaders)
texnums->shader = R_RegisterSkin(skinname); {
sprintf(skinname, "%s_%i", loadname, i);
texnums->shader = R_RegisterCustom (skinname, NULL);
}
#endif #endif
*/
texnums->base = texture; texnums->base = texture;
texnums->fullbright = fbtexture; texnums->fullbright = fbtexture;
@ -3290,12 +3293,15 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha)
if (t != 0) //only keep the first. if (t != 0) //only keep the first.
BZ_Free(saved); BZ_Free(saved);
} }
/*
#ifdef Q3SHADERS #ifdef Q3SHADERS
sprintf(skinname, "%s_%i_%i", loadname, i, t); if (cls.allow_shaders)
texnums->shader = R_RegisterSkin(skinname); {
sprintf(skinname, "%s_%i_%i", loadname, i, t);
texnums->shader = R_RegisterCustom (skinname, NULL);
}
#endif #endif
*/
texnums->base = texture; texnums->base = texture;
texnums->fullbright = fbtexture; texnums->fullbright = fbtexture;
} }
@ -3471,13 +3477,13 @@ int Mod_ReadFlagsFromMD1(char *name, int md3version)
{ {
dmdl_t *pinmodel; dmdl_t *pinmodel;
char fname[MAX_QPATH]; char fname[MAX_QPATH];
COM_StripExtension(name, fname); COM_StripExtension(name, fname, sizeof(fname));
COM_DefaultExtension(fname, ".mdl"); COM_DefaultExtension(fname, ".mdl", sizeof(fname));
if (strcmp(name, fname)) //md3 renamed as mdl if (strcmp(name, fname)) //md3 renamed as mdl
{ {
COM_StripExtension(name, fname); //seeing as the md3 is named over the mdl, COM_StripExtension(name, fname, sizeof(fname)); //seeing as the md3 is named over the mdl,
COM_DefaultExtension(fname, ".md1");//read from a file with md1 (one, not an ell) COM_DefaultExtension(fname, ".md1", sizeof(fname));//read from a file with md1 (one, not an ell)
return 0; return 0;
} }

View file

@ -276,6 +276,97 @@ int r_backendStart;
int r_dlighttexture; int r_dlighttexture;
extern qbyte *host_basepal;
extern qboolean gammaworks;
extern qbyte gammatable[256];
void R_FetchTopColour(int *retred, int *retgreen, int *retblue)
{
int i;
if (currententity->scoreboard)
{
i = currententity->scoreboard->topcolor;
//colour forcing
if (cl.splitclients<2 && !(cl.fpd & FPD_NO_FORCE_COLOR)) //no colour/skin forcing in splitscreen.
{
if (cl.teamplay && !strcmp(currententity->scoreboard->team, cl.players[cl.playernum[0]].team))
{
if (cl_teamtopcolor>=0)
i = cl_teamtopcolor;
}
else
{
if (cl_enemytopcolor>=0)
i = cl_enemytopcolor;
}
}
}
else
i = TOP_RANGE>>4;
if (i > 8)
{
i<<=4;
}
else
{
i<<=4;
i+=15;
}
i*=3;
*retred = host_basepal[i+0];
*retgreen = host_basepal[i+1];
*retblue = host_basepal[i+2];
if (!gammaworks)
{
*retred = gammatable[*retred];
*retgreen = gammatable[*retgreen];
*retblue = gammatable[*retblue];
}
}
void R_FetchBottomColour(int *retred, int *retgreen, int *retblue)
{
int i;
if (currententity->scoreboard)
{
i = currententity->scoreboard->bottomcolor;
//colour forcing
if (cl.splitclients<2 && !(cl.fpd & FPD_NO_FORCE_COLOR)) //no colour/skin forcing in splitscreen.
{
if (cl.teamplay && !strcmp(currententity->scoreboard->team, cl.players[cl.playernum[0]].team))
{
if (cl_teambottomcolor>=0)
i = cl_teambottomcolor;
}
else
{
if (cl_enemybottomcolor>=0)
i = cl_enemybottomcolor;
}
}
}
else
i = BOTTOM_RANGE>>4;
if (i > 8)
{
i<<=4;
}
else
{
i<<=4;
i+=15;
}
i*=3;
*retred = host_basepal[i+0];
*retgreen = host_basepal[i+1];
*retblue = host_basepal[i+2];
if (!gammaworks)
{
*retred = gammatable[*retred];
*retgreen = gammatable[*retgreen];
*retblue = gammatable[*retblue];
}
}
void R_InitDynamicLightTexture (void) void R_InitDynamicLightTexture (void)
{ {
int x, y; int x, y;
@ -1335,10 +1426,7 @@ R_ModifyColor
*/ */
void R_ModifyColor ( meshbuffer_t *mb, shaderpass_t *pass ) void R_ModifyColor ( meshbuffer_t *mb, shaderpass_t *pass )
{ {
extern qbyte *host_basepal;
extern qboolean gammaworks;
extern qbyte gammatable[256];
int i, b; int i, b;
float *table, c, a; float *table, c, a;
vec3_t t, v; vec3_t t, v;
@ -1420,45 +1508,7 @@ void R_ModifyColor ( meshbuffer_t *mb, shaderpass_t *pass )
case RGB_GEN_TOPCOLOR: //multiply vertex by topcolor (for player models) case RGB_GEN_TOPCOLOR: //multiply vertex by topcolor (for player models)
{ {
int rc, gc, bc; int rc, gc, bc;
if (currententity->scoreboard) R_FetchTopColour(&rc, &gc, &bc);
{
i = currententity->scoreboard->topcolor;
//colour forcing
if (cl.splitclients<2 && !(cl.fpd & FPD_NO_FORCE_COLOR)) //no colour/skin forcing in splitscreen.
{
if (cl.teamplay && !strcmp(currententity->scoreboard->team, cl.players[cl.playernum[0]].team))
{
if (cl_teamtopcolor>=0)
i = cl_teamtopcolor;
}
else
{
if (cl_enemytopcolor>=0)
i = cl_enemytopcolor;
}
}
}
else
i = TOP_RANGE>>4;
if (i > 8)
{
i<<=4;
}
else
{
i<<=4;
i+=15;
}
i*=3;
rc = host_basepal[i+0];
gc = host_basepal[i+1];
bc = host_basepal[i+2];
if (!gammaworks)
{
rc = gammatable[rc];
gc = gammatable[gc];
bc = gammatable[bc];
}
for ( i = 0; i < numColors; i++, bArray += 4, vArray += 4 ) { for ( i = 0; i < numColors; i++, bArray += 4, vArray += 4 ) {
bArray[0] = (vArray[0]*rc)>>8; bArray[0] = (vArray[0]*rc)>>8;
bArray[1] = (vArray[1]*gc)>>8; bArray[1] = (vArray[1]*gc)>>8;
@ -1470,45 +1520,7 @@ void R_ModifyColor ( meshbuffer_t *mb, shaderpass_t *pass )
case RGB_GEN_BOTTOMCOLOR: //multiply vertex by bottomcolor (for player models) case RGB_GEN_BOTTOMCOLOR: //multiply vertex by bottomcolor (for player models)
{ {
int rc, gc, bc; int rc, gc, bc;
if (currententity->scoreboard) R_FetchBottomColour(&rc, &gc, &bc);
{
i = currententity->scoreboard->bottomcolor;
//colour forcing
if (cl.splitclients<2 && !(cl.fpd & FPD_NO_FORCE_COLOR)) //no colour/skin forcing in splitscreen.
{
if (cl.teamplay && !strcmp(currententity->scoreboard->team, cl.players[cl.playernum[0]].team))
{
if (cl_teambottomcolor>=0)
i = cl_teambottomcolor;
}
else
{
if (cl_enemybottomcolor>=0)
i = cl_enemybottomcolor;
}
}
}
else
i = BOTTOM_RANGE>>4;
if (i > 8)
{
i<<=4;
}
else
{
i<<=4;
i+=15;
}
i*=3;
rc = host_basepal[i+0];
gc = host_basepal[i+1];
bc = host_basepal[i+2];
if (!gammaworks)
{
rc = gammatable[rc];
gc = gammatable[gc];
bc = gammatable[bc];
}
for ( i = 0; i < numColors; i++, bArray += 4, vArray += 4 ) { for ( i = 0; i < numColors; i++, bArray += 4, vArray += 4 ) {
bArray[0] = (vArray[0]*rc)>>8; bArray[0] = (vArray[0]*rc)>>8;
bArray[1] = (vArray[1]*gc)>>8; bArray[1] = (vArray[1]*gc)>>8;
@ -2055,6 +2067,69 @@ void R_RenderMeshCombined ( meshbuffer_t *mb, shaderpass_t *pass )
R_FlushArraysMtex (); R_FlushArraysMtex ();
} }
void R_RenderMeshProgram ( meshbuffer_t *mb, shaderpass_t *pass )
{
shader_t *s;
int i;
vec3_t param3;
int r, g, b;
r_numUnits = pass->numMergedPasses;
R_SetShaderpassState ( pass, true );
R_ModifyColor ( mb, pass );
GL_SelectTexture( mtexid0 );
if ( pass->blendmode == GL_REPLACE )
GL_TexEnv( GL_REPLACE );
else
GL_TexEnv( GL_MODULATE );
R_ModifyTextureCoords ( pass, 0 );
for ( i = 1, pass++; i < r_numUnits; i++, pass++ )
{
GL_SelectTexture( mtexid0 + i );
R_ModifyTextureCoords ( pass, i );
}
s = mb->shader;
GLSlang_UseProgram(s->programhandle);
for (i = 0; i < s->numprogparams; i++)
{
switch(s->progparm[i].type)
{
case SP_TIME:
qglUniform1fARB(s->progparm[i].handle, r_localShaderTime);
break;
case SP_ENTCOLOURS:
qglUniform4fvARB(s->progparm[i].handle, 1, currententity->shaderRGBAf);
break;
case SP_TOPCOLOURS:
R_FetchTopColour(&r, &g, &b);
param3[0] = r/255;
param3[1] = g/255;
param3[2] = b/255;
qglUniform3fvARB(s->progparm[i].handle, 1, param3);
break;
case SP_BOTTOMCOLOURS:
R_FetchBottomColour(&r, &g, &b);
param3[0] = r/255;
param3[1] = g/255;
param3[2] = b/255;
qglUniform3fvARB(s->progparm[i].handle, 1, param3);
break;
default:
Host_EndGame("Bad shader program parameter type (%i)", s->progparm[i].type);
break;
}
}
R_FlushArraysMtex ();
GLSlang_UseProgram(0);
}
/* /*
================ ================
R_RenderMeshBuffer R_RenderMeshBuffer
@ -2398,7 +2473,11 @@ void R_FinishMeshBuffer ( meshbuffer_t *mb )
qboolean dlight; qboolean dlight;
shader = mb->shader; shader = mb->shader;
dlight = (mb->dlightbits != 0) && !(shader->flags & SHADER_FLARE); if ((mb->dlightbits != 0) && !(shader->flags & SHADER_FLARE))
dlight = (currententity->model->type == mod_brush && currententity->model->fromgame == fg_quake3);
else
dlight = false;
fogged = mb->fog && ((shader->sort < SHADER_SORT_UNDERWATER && fogged = mb->fog && ((shader->sort < SHADER_SORT_UNDERWATER &&
(shader->flags & (SHADER_DEPTHWRITE|SHADER_SKY))) || shader->fog_dist); (shader->flags & (SHADER_DEPTHWRITE|SHADER_SKY))) || shader->fog_dist);
@ -2410,7 +2489,7 @@ void R_FinishMeshBuffer ( meshbuffer_t *mb )
qglDisable ( GL_ALPHA_TEST ); qglDisable ( GL_ALPHA_TEST );
qglDepthMask ( GL_FALSE ); qglDepthMask ( GL_FALSE );
if (dlight && (currententity->model->type == mod_brush && currententity->model->fromgame == fg_quake3)) //HACK: the extra check is because we play with the lightmaps in q1/q2 if (dlight) //HACK: the extra check is because we play with the lightmaps in q1/q2
{ {
R_AddDynamicLights ( mb ); R_AddDynamicLights ( mb );
} }
@ -2419,6 +2498,8 @@ void R_FinishMeshBuffer ( meshbuffer_t *mb )
{ {
R_RenderFogOnMesh ( shader, mb->fog ); R_RenderFogOnMesh ( shader, mb->fog );
} }
qglDepthMask ( GL_TRUE );
} }
if ( r_showtris.value || r_shownormals.value ) { if ( r_showtris.value || r_shownormals.value ) {

View file

@ -336,15 +336,15 @@ void GLMod_Think (void)
if (lightmodel->deluxdata) if (lightmodel->deluxdata)
{ {
COM_StripExtension(lightmodel->name, filename); COM_StripExtension(lightmodel->name, filename, sizeof(filename));
COM_DefaultExtension(filename, ".lux"); COM_DefaultExtension(filename, ".lux", sizeof(filename));
FS_WriteFile(filename, lightmodel->deluxdata-8, numlightdata*3+8, FS_GAME); FS_WriteFile(filename, lightmodel->deluxdata-8, numlightdata*3+8, FS_GAME);
} }
if (writelitfile) //the user might already have a lit file (don't overwrite it). if (writelitfile) //the user might already have a lit file (don't overwrite it).
{ {
COM_StripExtension(lightmodel->name, filename); COM_StripExtension(lightmodel->name, filename, sizeof(filename));
COM_DefaultExtension(filename, ".lit"); COM_DefaultExtension(filename, ".lit", sizeof(filename));
FS_WriteFile(filename, lightmodel->lightdata-8, numlightdata*3+8, FS_GAME); FS_WriteFile(filename, lightmodel->lightdata-8, numlightdata*3+8, FS_GAME);
} }
} }
@ -459,7 +459,7 @@ model_t *GLMod_LoadModel (model_t *mod, qboolean crash)
if (Q_strcasecmp(ext, "spr") && Q_strcasecmp(ext, "sp2")) if (Q_strcasecmp(ext, "spr") && Q_strcasecmp(ext, "sp2"))
{ {
char mdlbase[MAX_QPATH]; char mdlbase[MAX_QPATH];
COM_StripExtension(mod->name, mdlbase); COM_StripExtension(mod->name, mdlbase, sizeof(mdlbase));
#ifdef MD3MODELS #ifdef MD3MODELS
if (!buf) if (!buf)
buf = (unsigned *)COM_LoadStackFile (va("%s.md3", mdlbase), stackbuf, sizeof(stackbuf)); buf = (unsigned *)COM_LoadStackFile (va("%s.md3", mdlbase), stackbuf, sizeof(stackbuf));
@ -507,7 +507,7 @@ couldntload:
// //
// allocate a new model // allocate a new model
// //
COM_FileBase (mod->name, loadname); COM_FileBase (mod->name, loadname, sizeof(loadname));
Validation_IncludeFile(mod->name, (char *)buf, com_filesize); Validation_IncludeFile(mod->name, (char *)buf, com_filesize);
// //
@ -1009,21 +1009,21 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n"));
} }
} }
#ifdef Q3SHADERS //load q3 syntax shader last, after the textures inside the bsp have been loaded and stuff. #ifdef Q3SHADERS //load q3 syntax shader last, after the textures inside the bsp have been loaded and stuff.
if (gl_shadeq1.value && *gl_shadeq1_name.string) if (cls.allow_shaders && gl_shadeq1.value && *gl_shadeq1_name.string)
{ {
char *star; char *star;
//find the * //find the *
if (!strcmp(gl_shadeq1_name.string, "*")) if (!strcmp(gl_shadeq1_name.string, "*"))
tx->shader = R_RegisterShader(mt->name); //just load the regular name. tx->shader = R_RegisterCustom(mt->name, NULL); //just load the regular name.
else if (!(star = strchr(gl_shadeq1_name.string, '*')) || (strlen(gl_shadeq1_name.string)+strlen(mt->name)+1>=sizeof(altname))) //it's got to fit. else if (!(star = strchr(gl_shadeq1_name.string, '*')) || (strlen(gl_shadeq1_name.string)+strlen(mt->name)+1>=sizeof(altname))) //it's got to fit.
tx->shader = R_RegisterShader(gl_shadeq1_name.string); tx->shader = R_RegisterCustom(gl_shadeq1_name.string, NULL);
else else
{ {
strncpy(altname, gl_shadeq1_name.string, star-gl_shadeq1_name.string); //copy the left strncpy(altname, gl_shadeq1_name.string, star-gl_shadeq1_name.string); //copy the left
altname[star-gl_shadeq1_name.string] = '\0'; altname[star-gl_shadeq1_name.string] = '\0';
strcat(altname, mt->name); //insert the * strcat(altname, mt->name); //insert the *
strcat(altname, star+1); //add any final text. strcat(altname, star+1); //add any final text.
tx->shader = R_RegisterShader(altname); tx->shader = R_RegisterCustom(altname, NULL);
} }
} }
#endif #endif
@ -1247,19 +1247,19 @@ void GLMod_LoadLighting (lump_t *l)
if (!luxdata) if (!luxdata)
{ {
strcpy(luxname, loadmodel->name); strcpy(luxname, loadmodel->name);
COM_StripExtension(loadmodel->name, luxname); COM_StripExtension(loadmodel->name, luxname, sizeof(luxname));
COM_DefaultExtension(luxname, ".lux"); COM_DefaultExtension(luxname, ".lux", sizeof(luxname));
luxdata = COM_LoadHunkFile(luxname); luxdata = COM_LoadHunkFile(luxname);
} }
if (!luxdata) if (!luxdata)
{ {
strcpy(luxname, "luxs/"); strcpy(luxname, "luxs/");
COM_StripExtension(COM_SkipPath(loadmodel->name), luxname+5); COM_StripExtension(COM_SkipPath(loadmodel->name), luxname+5, sizeof(luxname)-5);
strcat(luxname, ".lux"); strcat(luxname, ".lux");
luxdata = COM_LoadHunkFile(luxname); luxdata = COM_LoadHunkFile(luxname);
} }
COM_StripExtension(COM_SkipPath(loadmodel->name), luxname+5); COM_StripExtension(COM_SkipPath(loadmodel->name), luxname+5, sizeof(luxname)-5);
strcat(luxname, ".lux"); strcat(luxname, ".lux");
if (luxdata) if (luxdata)
{ {
@ -1300,13 +1300,13 @@ void GLMod_LoadLighting (lump_t *l)
{ {
strcpy(litnamemaps, loadmodel->name); strcpy(litnamemaps, loadmodel->name);
COM_StripExtension(loadmodel->name, litnamemaps); COM_StripExtension(loadmodel->name, litnamemaps, sizeof(litnamemaps));
COM_DefaultExtension(litnamemaps, ".lit"); COM_DefaultExtension(litnamemaps, ".lit", sizeof(litnamemaps));
depthmaps = COM_FDepthFile(litnamemaps, false); depthmaps = COM_FDepthFile(litnamemaps, false);
} }
{ {
strcpy(litnamelits, "lits/"); strcpy(litnamelits, "lits/");
COM_StripExtension(COM_SkipPath(loadmodel->name), litnamelits+5); COM_StripExtension(COM_SkipPath(loadmodel->name), litnamelits+5, sizeof(litnamelits) - 5);
strcat(litnamelits, ".lit"); strcat(litnamelits, ".lit");
depthlits = COM_FDepthFile(litnamelits, false); depthlits = COM_FDepthFile(litnamelits, false);
} }
@ -1319,7 +1319,7 @@ void GLMod_LoadLighting (lump_t *l)
} }
litdata = COM_LoadHunkFile(litname); litdata = COM_LoadHunkFile(litname);
COM_StripExtension(COM_SkipPath(loadmodel->name), litname+5); COM_StripExtension(COM_SkipPath(loadmodel->name), litname+5, sizeof(litname)-5);
strcat(litname, ".lit"); strcat(litname, ".lit");
if (litdata && (litdata[0] == 'Q' && litdata[1] == 'L' && litdata[2] == 'I' && litdata[3] == 'T')) if (litdata && (litdata[0] == 'Q' && litdata[1] == 'L' && litdata[2] == 'I' && litdata[3] == 'T'))
{ {
@ -1994,8 +1994,8 @@ void GLMod_LoadCrouchHull(void)
//find a name for a ccn and try to load it. //find a name for a ccn and try to load it.
strcpy(crouchhullname, loadmodel->name); strcpy(crouchhullname, loadmodel->name);
COM_StripExtension(loadmodel->name, crouchhullname); COM_StripExtension(loadmodel->name, crouchhullname, sizeof(crouchhullname));
COM_DefaultExtension(crouchhullname, ".crh"); //crouch hull COM_DefaultExtension(crouchhullname, ".crh",sizeof(crouchhullname)); //crouch hull
crouchhullfile = COM_LoadMallocFile(crouchhullname); //or otherwise temporary storage. load on hunk if you want, but that would be a waste. crouchhullfile = COM_LoadMallocFile(crouchhullname); //or otherwise temporary storage. load on hunk if you want, but that would be a waste.
if (!crouchhullfile) if (!crouchhullfile)
@ -2781,13 +2781,13 @@ void * GLMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum
} }
if (!pspriteframe->gl_texturenum) if (!pspriteframe->gl_texturenum)
{ //the older fte way. { //the older fte way.
COM_StripExtension(loadmodel->name, name); COM_StripExtension(loadmodel->name, name, sizeof(name));
strcat(name, va("_%i", framenum)); strcat(name, va("_%i", framenum));
pspriteframe->gl_texturenum = Mod_LoadReplacementTexture(name, "sprites", true, true, true); pspriteframe->gl_texturenum = Mod_LoadReplacementTexture(name, "sprites", true, true, true);
} }
if (!pspriteframe->gl_texturenum) if (!pspriteframe->gl_texturenum)
{ //the fuhquake way { //the fuhquake way
COM_StripExtension(COM_SkipPath(loadmodel->name), name); COM_StripExtension(COM_SkipPath(loadmodel->name), name, sizeof(name));
strcat(name, va("_%i", framenum)); strcat(name, va("_%i", framenum));
pspriteframe->gl_texturenum = Mod_LoadReplacementTexture(name, "sprites", true, true, true); pspriteframe->gl_texturenum = Mod_LoadReplacementTexture(name, "sprites", true, true, true);
} }

View file

@ -1528,11 +1528,18 @@ static void PPL_BaseTextureChain(msurface_t *first)
if (mb.mesh) if (mb.mesh)
R_RenderMeshBuffer ( &mb, false ); R_RenderMeshBuffer ( &mb, false );
return; return;
} }
#endif #endif
qglEnable(GL_TEXTURE_2D); qglEnable(GL_TEXTURE_2D);
t = GLR_TextureAnimation (first->texinfo->texture); t = GLR_TextureAnimation (first->texinfo->texture);
if (first->flags & SURF_DRAWTURB) if (first->flags & SURF_DRAWTURB)
@ -4753,6 +4760,8 @@ qboolean PPL_AddLight(dlight_t *dl)
qglStencilFunc( GL_ALWAYS, 0, ~0 ); qglStencilFunc( GL_ALWAYS, 0, ~0 );
qglDisable(GL_SCISSOR_TEST); qglDisable(GL_SCISSOR_TEST);
qglDisable(GL_BLEND);
GL_TexEnv(GL_REPLACE);
return true; return true;
} }

View file

@ -905,7 +905,7 @@ void R_LoadRTLights(void)
cl_dlights[i].radius = 0; cl_dlights[i].radius = 0;
} }
COM_StripExtension(cl.worldmodel->name, fname); COM_StripExtension(cl.worldmodel->name, fname, sizeof(fname));
strncat(fname, ".rtlights", MAX_QPATH-1); strncat(fname, ".rtlights", MAX_QPATH-1);
file = COM_LoadTempFile(fname); file = COM_LoadTempFile(fname);
@ -992,7 +992,7 @@ void GLR_NewMap (void)
r_worldentity.model = cl.worldmodel; r_worldentity.model = cl.worldmodel;
COM_StripExtension(COM_SkipPath(cl.worldmodel->name), namebuf); COM_StripExtension(COM_SkipPath(cl.worldmodel->name), namebuf, sizeof(namebuf));
Cvar_Set(&host_mapname, namebuf); Cvar_Set(&host_mapname, namebuf);
// clear out efrags in case the level hasn't been reloaded // clear out efrags in case the level hasn't been reloaded

View file

@ -539,6 +539,111 @@ static void Shader_EntityMergable ( shader_t *shader, shaderpass_t *pass, char *
shader->flags |= SHADER_ENTITY_MERGABLE; shader->flags |= SHADER_ENTITY_MERGABLE;
} }
static void Shader_ProgramName ( shader_t *shader, shaderpass_t *pass, char **ptr )
{
char *vert, *frag;
char *token;
if (shader->programhandle)
{ //this allows fallbacks
token = Shader_ParseString ( ptr );
token = Shader_ParseString ( ptr );
return;
}
token = Shader_ParseString ( ptr );
FS_LoadFile(token, &vert);
token = Shader_ParseString ( ptr );
FS_LoadFile(token, &frag);
if (vert && frag)
shader->programhandle = GLSlang_CreateProgram("", vert, frag);
if (vert)
FS_FreeFile(vert);
if (frag)
FS_FreeFile(frag);
}
static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **ptr )
{
cvar_t *cv;
int specialint = 0;
float specialfloat = 0;
enum shaderprogparmtype_e parmtype = SP_BAD;
char *token;
unsigned int uniformloc;
token = Shader_ParseString ( ptr );
if (!Q_stricmp(token, "texture"))
{
token = Shader_ParseString ( ptr );
specialint = atoi(token);
parmtype = SP_TEXTURE;
}
else if (!Q_stricmp(token, "cvari"))
{
token = Shader_ParseString ( ptr );
cv = Cvar_Get(token, "", 0, "GLSL Shader parameters");
if (cv)
{ //Cvar_Get returns null if the cvar is the name of a command
specialint = atoi(cv->string);
specialfloat = cv->value;
}
parmtype = SP_CVARI;
}
else if (!Q_stricmp(token, "cvarf"))
{
token = Shader_ParseString ( ptr );
cv = Cvar_Get(token, "", 0, "GLSL Shader parameters");
if (cv)
{ //Cvar_Get returns null if the cvar is the name of a command
specialint = atoi(cv->string);
specialfloat = cv->value;
}
parmtype = SP_CVARF;
}
else if (!Q_stricmp(token, "time"))
{
parmtype = SP_TIME;
}
if (!shader->programhandle)
{
Con_Printf("shader %s: param without program set\n", shader->name);
token = Shader_ParseString ( ptr );
}
else
{
GLSlang_UseProgram(shader->programhandle);
token = Shader_ParseString ( ptr );
uniformloc = GLSlang_GetUniformLocation(shader->programhandle, token);
if (uniformloc == -1)
{
Con_Printf("shader %s: param without uniform \"%s\"\n", shader->name, token);
return;
}
else
{
switch(parmtype)
{
case SP_TEXTURE:
case SP_CVARI:
GLSlang_SetUniform1i(uniformloc, specialint);
break;
case SP_CVARF:
GLSlang_SetUniform1f(uniformloc, specialfloat);
break;
default:
shader->progparm[shader->numprogparams].type = parmtype;
shader->progparm[shader->numprogparams].handle = uniformloc;
shader->numprogparams++;
break;
}
}
GLSlang_UseProgram(0);
}
}
static shaderkey_t shaderkeys[] = static shaderkey_t shaderkeys[] =
{ {
{"cull", Shader_Cull }, {"cull", Shader_Cull },
@ -552,6 +657,10 @@ static shaderkey_t shaderkeys[] =
{"deformvertexes", Shader_DeformVertexes }, {"deformvertexes", Shader_DeformVertexes },
{"portal", Shader_Portal }, {"portal", Shader_Portal },
{"entitymergable", Shader_EntityMergable }, {"entitymergable", Shader_EntityMergable },
{"program", Shader_ProgramName }, //glsl
{"param", Shader_ProgramParam },
{NULL, NULL} {NULL, NULL}
}; };
@ -1367,6 +1476,57 @@ static qboolean Shader_Parsetok (shader_t *shader, shaderpass_t *pass, shaderkey
} }
} }
if (!Q_stricmp(token, "if"))
{
int indent = 0;
cvar_t *cv;
qboolean conditiontrue = true;
token = COM_ParseExt ( ptr, false );
if (*token == '!')
{
conditiontrue = false;
token++;
}
cv = Cvar_Get(token, "", 0, "Shader Conditions");
if (cv)
conditiontrue = conditiontrue == !!cv->value;
if (conditiontrue)
{
while ( ptr )
{
token = COM_ParseExt (ptr, true);
if ( !token[0] )
continue;
else if (token[0] == ']' || token[0] == '}')
indent--;
else if (token[0] == '[')
indent++;
else
Shader_Parsetok (shader, pass, keys, token, ptr);
if (!indent)
break;
}
}
else
{
while ( ptr )
{
token = COM_ParseExt (ptr, true);
if (!token[0])
continue;
else if (token[0] == ']' || token[0] == '}')
indent--;
else if (token[0] == '[')
indent++;
if (!indent)
break;
}
}
return ( ptr && *ptr && **ptr == '}' );
}
// Next Line // Next Line
while (ptr) while (ptr)
{ {
@ -1553,7 +1713,7 @@ void Shader_Finish ( shader_t *s )
s->sort = SHADER_SORT_ADDITIVE - 1; s->sort = SHADER_SORT_ADDITIVE - 1;
} }
if ( r_vertexlight.value ) if ( r_vertexlight.value && !s->programhandle)
{ {
// do we have a lightmap pass? // do we have a lightmap pass?
pass = s->passes; pass = s->passes;
@ -1718,6 +1878,14 @@ done:;
s->flags &= ~SHADER_DEPTHWRITE; s->flags &= ~SHADER_DEPTHWRITE;
} }
if (s->programhandle)
{
if (!s->numpasses)
s->numpasses = 1;
s->passes->numMergedPasses = s->numpasses;
s->passes->flush = R_RenderMeshProgram;
}
Shader_SetFeatures ( s ); Shader_SetFeatures ( s );
} }
/* /*
@ -1849,7 +2017,7 @@ void Shader_DefaultBSP(char *shortname, shader_t *s)
int bumptex; int bumptex;
extern cvar_t gl_bump; extern cvar_t gl_bump;
if (0)//this isn't working right yet gl_config.arb_texture_env_dot3) if (gl_config.arb_texture_env_dot3)
{ {
if (gl_bump.value) if (gl_bump.value)
bumptex = Mod_LoadHiResTexture(va("normalmaps/%s", shortname), NULL, true, false, false);//GL_FindImage (shortname, 0); bumptex = Mod_LoadHiResTexture(va("normalmaps/%s", shortname), NULL, true, false, false);//GL_FindImage (shortname, 0);
@ -2201,15 +2369,83 @@ void Shader_Default2D(char *shortname, shader_t *s)
s->registration_sequence = 1;//fizme: registration_sequence; s->registration_sequence = 1;//fizme: registration_sequence;
} }
qboolean Shader_ParseShader(char *shortname, char *usename, shader_t *s)
{
unsigned int offset = 0, length;
char path[MAX_QPATH];
char *buf = NULL, *ts = NULL;
Shader_GetPathAndOffset( shortname, &ts, &offset );
if ( ts )
{
Com_sprintf ( path, sizeof(path), "%s", ts );
length = FS_LoadFile ( path, (void **)&buf );
}
else
length = 0;
// the shader is in the shader scripts
if ( ts && buf && (offset < length) )
{
char *file, *token;
file = buf + offset;
token = COM_ParseExt (&file, true);
if ( !file || token[0] != '{' )
{
FS_FreeFile(buf);
return false;
}
memset ( s, 0, sizeof( shader_t ) );
Com_sprintf ( s->name, MAX_QPATH, usename );
// set defaults
s->flags = SHADER_CULL_FRONT;
s->registration_sequence = 1;//fizme: registration_sequence;
// if (!strcmp(COM_FileExtension(ts), "rscript"))
// {
// Shader_DefaultBSP(shortname, s);
// }
while ( file )
{
token = COM_ParseExt (&file, true);
if ( !token[0] )
continue;
else if ( token[0] == '}' )
break;
else if ( token[0] == '{' )
Shader_Readpass ( s, &file );
else if ( Shader_Parsetok (s, NULL, shaderkeys, token, &file ) )
break;
}
Shader_Finish ( s );
FS_FreeFile(buf);
return true;
}
if (buf)
FS_FreeFile(buf);
return false;
}
int R_LoadShader ( char *name, void(*defaultgen)(char *name, shader_t*)) int R_LoadShader ( char *name, void(*defaultgen)(char *name, shader_t*))
{ {
int i, f = -1; int i, f = -1;
unsigned int offset = 0, length = 0; char shortname[MAX_QPATH];
char shortname[MAX_QPATH], path[MAX_QPATH];
char *buf = NULL, *ts = NULL;
shader_t *s; shader_t *s;
COM_StripExtension ( name, shortname ); COM_StripExtension ( name, shortname, sizeof(shortname));
COM_CleanUpPath(shortname); COM_CleanUpPath(shortname);
@ -2237,65 +2473,26 @@ int R_LoadShader ( char *name, void(*defaultgen)(char *name, shader_t*))
} }
s = &r_shaders[f]; s = &r_shaders[f];
memset ( s, 0, sizeof( shader_t ) );
Com_sprintf ( s->name, MAX_QPATH, shortname ); if (gl_config.arb_shader_objects)
Shader_GetPathAndOffset( shortname, &ts, &offset );
if ( ts ) {
Com_sprintf ( path, sizeof(path), "%s", ts );
length = FS_LoadFile ( path, (void **)&buf );
}
// the shader is in the shader scripts
if ( ts && buf && (offset < length) )
{ {
char *ptr, *token; if (Shader_ParseShader(va("%s_glsl", shortname), shortname, s))
return f;
// set defaults
s->flags = SHADER_CULL_FRONT;
s->registration_sequence = 1;//fizme: registration_sequence;
// if (!strcmp(COM_FileExtension(ts), "rscript"))
// {
// Shader_DefaultBSP(shortname, s);
// }
ptr = buf + offset;
token = COM_ParseExt (&ptr, true);
if ( !ptr || token[0] != '{' ) {
return -1;
}
while ( ptr )
{
token = COM_ParseExt (&ptr, true);
if ( !token[0] ) {
continue;
} else if ( token[0] == '}' ) {
break;
} else if ( token[0] == '{' ) {
Shader_Readpass ( s, &ptr );
} else if ( Shader_Parsetok (s, NULL, shaderkeys, token, &ptr ) ) {
break;
}
}
Shader_Finish ( s );
FS_FreeFile ( buf );
} }
else // make a default shader if (Shader_ParseShader(shortname, shortname, s))
return f;
// make a default shader
if (defaultgen)
{ {
if (defaultgen) memset ( s, 0, sizeof( shader_t ) );
defaultgen(shortname, s); Com_sprintf ( s->name, MAX_QPATH, shortname );
else defaultgen(shortname, s);
return -1;
}
return f; return f;
}
return -1;
} }
shader_t *R_RegisterPic (char *name) shader_t *R_RegisterPic (char *name)

View file

@ -112,6 +112,7 @@ PFNGLGETINFOLOGARBPROC qglGetInfoLogARB;
PFNGLLINKPROGRAMARBPROC qglLinkProgramARB; PFNGLLINKPROGRAMARBPROC qglLinkProgramARB;
PFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB; PFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB;
PFNGLUNIFORM4FARBPROC qglUniform4fARB; PFNGLUNIFORM4FARBPROC qglUniform4fARB;
PFNGLUNIFORM4FVARBPROC qglUniform4fvARB;
PFNGLUNIFORM3FARBPROC qglUniform3fARB; PFNGLUNIFORM3FARBPROC qglUniform3fARB;
PFNGLUNIFORM3FVARBPROC qglUniform3fvARB; PFNGLUNIFORM3FVARBPROC qglUniform3fvARB;
PFNGLUNIFORM1IARBPROC qglUniform1iARB; PFNGLUNIFORM1IARBPROC qglUniform1iARB;
@ -369,6 +370,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
qglLinkProgramARB = (void *)getglext("glLinkProgramARB"); qglLinkProgramARB = (void *)getglext("glLinkProgramARB");
qglGetUniformLocationARB = (void *)getglext("glGetUniformLocationARB"); qglGetUniformLocationARB = (void *)getglext("glGetUniformLocationARB");
qglUniform4fARB = (void *)getglext("glUniform4fARB"); qglUniform4fARB = (void *)getglext("glUniform4fARB");
qglUniform4fvARB = (void *)getglext("glUniform4fvARB");
qglUniform3fARB = (void *)getglext("glUniform3fARB"); qglUniform3fARB = (void *)getglext("glUniform3fARB");
qglUniform3fvARB = (void *)getglext("glUniform3fvARB"); qglUniform3fvARB = (void *)getglext("glUniform3fvARB");
qglUniform1iARB = (void *)getglext("glUniform1iARB"); qglUniform1iARB = (void *)getglext("glUniform1iARB");

View file

@ -765,6 +765,7 @@ extern PFNGLGETINFOLOGARBPROC qglGetInfoLogARB;
extern PFNGLLINKPROGRAMARBPROC qglLinkProgramARB; extern PFNGLLINKPROGRAMARBPROC qglLinkProgramARB;
extern PFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB; extern PFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB;
extern PFNGLUNIFORM4FARBPROC qglUniform4fARB; extern PFNGLUNIFORM4FARBPROC qglUniform4fARB;
extern PFNGLUNIFORM4FVARBPROC qglUniform4fvARB;
extern PFNGLUNIFORM3FARBPROC qglUniform3fARB; extern PFNGLUNIFORM3FARBPROC qglUniform3fARB;
extern PFNGLUNIFORM3FVARBPROC qglUniform3fvARB; extern PFNGLUNIFORM3FVARBPROC qglUniform3fvARB;
extern PFNGLUNIFORM1IARBPROC qglUniform1iARB; extern PFNGLUNIFORM1IARBPROC qglUniform1iARB;

View file

@ -5,6 +5,8 @@
#define SHADER_MAX_ANIMFRAMES 8 #define SHADER_MAX_ANIMFRAMES 8
#define SHADER_ANIM_FRAMES_MAX 16 #define SHADER_ANIM_FRAMES_MAX 16
#define SHADER_PROGPARMS_MAX 16
typedef enum { typedef enum {
SHADER_BSP, SHADER_BSP,
SHADER_BSP_VERTEX, SHADER_BSP_VERTEX,
@ -175,8 +177,7 @@ typedef struct shaderpass_s {
SHADER_PASS_LIGHTMAP = 1 << 5, SHADER_PASS_LIGHTMAP = 1 << 5,
SHADER_PASS_DELUXMAP = 1 << 6, SHADER_PASS_DELUXMAP = 1 << 6,
SHADER_PASS_NOCOLORARRAY = 1<< 7, SHADER_PASS_NOCOLORARRAY = 1<< 7,
SHADER_PASS_ANIMMAP = 1 << 8, SHADER_PASS_ANIMMAP = 1 << 8
SHADER_PASS_GPUPROGRAM = 1 << 9
} flags; } flags;
} shaderpass_t; } shaderpass_t;
@ -188,6 +189,23 @@ typedef struct
int nearbox_textures[6]; int nearbox_textures[6];
} skydome_t; } skydome_t;
typedef struct {
enum shaderprogparmtype_e {
SP_BAD,
SP_ENTCOLOURS,
SP_TOPCOLOURS,
SP_BOTTOMCOLOURS,
SP_TIME,
//things that are set immediatly
SP_FIRSTIMMEDIATE, //never set
SP_CVARI,
SP_CVARF,
SP_TEXTURE
} type;
unsigned int handle;
} shaderprogparm_t;
typedef struct shader_s { typedef struct shader_s {
int numpasses; //careful... 0 means it's not loaded... and not actually a proper shader. int numpasses; //careful... 0 means it's not loaded... and not actually a proper shader.
struct shader_s *next; struct shader_s *next;
@ -215,10 +233,13 @@ typedef struct shader_s {
SHADER_DEPTHWRITE = 1 << 11, SHADER_DEPTHWRITE = 1 << 11,
SHADER_AGEN_PORTAL = 1 << 12, SHADER_AGEN_PORTAL = 1 << 12,
SHADER_BLEND = 1 << 13, //blend or alphatest (not 100% opaque). SHADER_BLEND = 1 << 13, //blend or alphatest (not 100% opaque).
SHADER_NODRAW = 1 << 14, //parsed only to pee off developers when they forget it on no-pass shaders. SHADER_NODRAW = 1 << 14 //parsed only to pee off developers when they forget it on no-pass shaders.
SHADER_PROGRAM = 1 << 15 //run a script
} flags; } flags;
unsigned int programhandle;
int numprogparams;
shaderprogparm_t progparm[SHADER_PROGPARMS_MAX];
shaderpass_t passes[SHADER_PASS_MAX]; shaderpass_t passes[SHADER_PASS_MAX];
shadersort_t sort; shadersort_t sort;
@ -238,6 +259,7 @@ extern shader_t r_shaders[];
void R_RenderMeshGeneric ( meshbuffer_t *mb, shaderpass_t *pass ); void R_RenderMeshGeneric ( meshbuffer_t *mb, shaderpass_t *pass );
void R_RenderMeshCombined ( meshbuffer_t *mb, shaderpass_t *pass ); void R_RenderMeshCombined ( meshbuffer_t *mb, shaderpass_t *pass );
void R_RenderMeshMultitextured ( meshbuffer_t *mb, shaderpass_t *pass ); void R_RenderMeshMultitextured ( meshbuffer_t *mb, shaderpass_t *pass );
void R_RenderMeshProgram ( meshbuffer_t *mb, shaderpass_t *pass );
shader_t *R_RegisterPic (char *name); shader_t *R_RegisterPic (char *name);
shader_t *R_RegisterShader (char *name); shader_t *R_RegisterShader (char *name);

View file

@ -435,10 +435,11 @@ usepasv:
else if (ret == 125) //begining transfer else if (ret == 125) //begining transfer
{ {
if (con->type == ftp_getting) if (con->type == ftp_getting)
{ {
COM_StripExtension(con->localfile, msg); char tempname[MAX_OSPATH];
strcat(msg, ".tmp"); COM_StripExtension(con->localfile, tempname, MAX_OSPATH);
con->f = FS_OpenVFS (msg, "wb", FS_GAME); strcat(tempname, ".tmp");
con->f = FS_OpenVFS (tempname, "wb", FS_GAME);
if (!con->f) if (!con->f)
{ {
msg = va("ABOR\r\nQUIT\r\n"); //bummer. we couldn't open this file to output to. msg = va("ABOR\r\nQUIT\r\n"); //bummer. we couldn't open this file to output to.

View file

@ -6,7 +6,7 @@
#the Makefile explicitally tests for config.h, and will pass the right precompiler to gcc so that this file is actually used. #the Makefile explicitally tests for config.h, and will pass the right precompiler to gcc so that this file is actually used.
#And so we don't break in the absence of this file. #And so we don't break in the absence of this file.
if [ $1 = y ]; then if [ "$1" = "y" ]; then
defaulttoyes=true defaulttoyes=true
echo "Checking installed libraries" echo "Checking installed libraries"
else else
@ -26,13 +26,13 @@ echo "" >> config.h
query() query()
{ {
if [ $defaulttoyes = true ]; then if [ "$defaulttoyes" = "true" ]; then
ans=y ans=y
else else
read -n 1 -p "$1 " ans read -n 1 -p "$1 " ans
echo "" echo ""
fi fi
if [ $ans = y -o $ans = Y ]; then if [ "$ans" = "y" -o "$ans" = "Y" ]; then
echo "#define $2" >> config.h echo "#define $2" >> config.h
else else
echo "//#define $2" >> config.h echo "//#define $2" >> config.h
@ -48,6 +48,7 @@ querylibrary()
query "$1" "$2" query "$1" "$2"
return return
fi fi
#they don't have it, force no.
echo "$1 n" echo "$1 n"
echo "//#define $2" >> config.h echo "//#define $2" >> config.h
} }
@ -84,7 +85,7 @@ query "Do you want to enable fish-eye views (only in software) ?" FISH
query "Do you want to enable the built in http/ftp server ?" WEBSERVER query "Do you want to enable the built in http/ftp server ?" WEBSERVER
query "Do you want to enable the built in http/ftp clients ?" WEBCLIENT query "Do you want to enable the built in http/ftp clients ?" WEBCLIENT
query "Do you want to enable the deluxemap generation routine ?" RUNTIMELIGHTING query "Do you want to enable the deluxemap generation routine ?" RUNTIMELIGHTING
query "Do you want to enable the 'qterm' (this is a major security risk) ?" QTERM #query "Do you want to enable the 'qterm' (this is a major security risk) ?" QTERM
query "Do you want to enable the server browser ?" CL_MASTER query "Do you want to enable the server browser ?" CL_MASTER
query "Do you want to enable the serial-mouse support (used in splitscreen) ?" SERIALMOUSE query "Do you want to enable the serial-mouse support (used in splitscreen) ?" SERIALMOUSE
query "Do you want to enable the per-pixel lighting routines ?" PPL query "Do you want to enable the per-pixel lighting routines ?" PPL

View file

@ -1012,7 +1012,7 @@ void Q_InitProgs(void)
if (*progs.string && strlen(progs.string)<64 && *progs.string != '*') //a * is a special case to not load a q2 dll. if (*progs.string && strlen(progs.string)<64 && *progs.string != '*') //a * is a special case to not load a q2 dll.
{ {
Q_strncpyz(addons, progs.string, MAX_QPATH); Q_strncpyz(addons, progs.string, MAX_QPATH);
COM_DefaultExtension(addons, ".dat"); COM_DefaultExtension(addons, ".dat", sizeof(addons));
} }
oldprnum= AddProgs(addons); oldprnum= AddProgs(addons);

View file

@ -535,7 +535,7 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers)
gametype = cache->gametype; gametype = cache->gametype;
sprintf (name, "saves/%s", level); sprintf (name, "saves/%s", level);
COM_DefaultExtension (name, ".lvc"); COM_DefaultExtension (name, ".lvc", sizeof(name));
// Con_TPrintf (STL_LOADGAMEFROM, name); // Con_TPrintf (STL_LOADGAMEFROM, name);
@ -763,7 +763,7 @@ void SV_SaveLevelCache(qboolean dontharmgame)
sprintf (name, "%s/saves/%s", com_gamedir, cache->mapname); sprintf (name, "%s/saves/%s", com_gamedir, cache->mapname);
COM_DefaultExtension (name, ".lvc"); COM_DefaultExtension (name, ".lvc", sizeof(name));
COM_CreatePath(name); COM_CreatePath(name);

View file

@ -482,7 +482,7 @@ void SV_Map_f (void)
if (!strcmp(level, ".")) //restart current if (!strcmp(level, ".")) //restart current
{ {
COM_StripExtension(COM_SkipPath(sv.modelname), level); COM_StripExtension(COM_SkipPath(sv.modelname), level, sizeof(level));
issamelevel = true; issamelevel = true;
Q_strncpyz(spot, Info_ValueForKey(svs.info, "*startspot"), sizeof(spot)); Q_strncpyz(spot, Info_ValueForKey(svs.info, "*startspot"), sizeof(spot));

View file

@ -732,6 +732,26 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
COM_FlushTempoaryPacks(); COM_FlushTempoaryPacks();
//This fixes a bug where the server advertises cheats, the internal client connects, and doesn't think cheats are allowed.
//this applies to a few other things too, but cheats is the only special one (because of the *)
if (sv_cheats.value)
{
sv_allow_cheats = true;
Info_SetValueForStarKey(svs.info, "*cheats", "ON", MAX_SERVERINFO_STRING);
}
else
{
sv_allow_cheats = false;
Info_SetValueForStarKey(svs.info, "*cheats", "", MAX_SERVERINFO_STRING);
}
#ifndef CLIENTONLY
Q_strncpyz(cl.serverinfo, svs.info, sizeof(cl.serverinfo));
CL_CheckServerInfo();
#endif
if (usecinematic) if (usecinematic)
{ {
strcpy (sv.name, server); strcpy (sv.name, server);
@ -781,17 +801,6 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
// //
SV_ClearWorld (); SV_ClearWorld ();
if (sv_cheats.value)
{
sv_allow_cheats = true;
Info_SetValueForStarKey(svs.info, "*cheats", "ON", MAX_SERVERINFO_STRING);
}
else
{
sv_allow_cheats = false;
Info_SetValueForStarKey(svs.info, "*cheats", "", MAX_SERVERINFO_STRING);
}
//do we allow csprogs? //do we allow csprogs?
#ifdef PEXT_CSQC #ifdef PEXT_CSQC
file = COM_LoadTempFile("csprogs.dat"); file = COM_LoadTempFile("csprogs.dat");

View file

@ -1582,8 +1582,8 @@ void SV_MVD_Record_f (void)
snprintf (name, MAX_OSPATH+MAX_MVD_NAME, "%s/%s/%s", com_gamedir, sv_demoDir.string, newname); snprintf (name, MAX_OSPATH+MAX_MVD_NAME, "%s/%s/%s", com_gamedir, sv_demoDir.string, newname);
COM_StripExtension(name, name); COM_StripExtension(name, name, sizeof(name));
COM_DefaultExtension(name, ".mvd"); COM_DefaultExtension(name, ".mvd", sizeof(name));
COM_CreatePath(name); COM_CreatePath(name);
// //
@ -2093,7 +2093,7 @@ void SV_MVDRemove_f (void)
} }
Q_strncpyz(name, Cmd_Argv(1), MAX_MVD_NAME); Q_strncpyz(name, Cmd_Argv(1), MAX_MVD_NAME);
COM_DefaultExtension(name, ".mvd"); COM_DefaultExtension(name, ".mvd", sizeof(name));
snprintf(path, MAX_OSPATH, "%s/%s/%s", com_gamedir, sv_demoDir.string, name); snprintf(path, MAX_OSPATH, "%s/%s/%s", com_gamedir, sv_demoDir.string, name);