From ba789a5446a3ff0d60023b6ecb48b63df9b00a3e Mon Sep 17 00:00:00 2001 From: Spoike Date: Wed, 4 Jan 2006 00:44:34 +0000 Subject: [PATCH] I've been fixing up client downloading. Hopefully we're a little more robust. requiredownloads 0 can possibly cause problems though, with missing maps and such. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1785 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_main.c | 18 +- engine/client/cl_parse.c | 367 ++++++++++++++++++++------------------ engine/client/cl_screen.c | 4 +- engine/client/client.h | 8 +- engine/client/skin.c | 36 +--- engine/client/wad.c | 3 +- engine/common/fs.c | 27 ++- engine/gl/gl_screen.c | 2 +- 8 files changed, 241 insertions(+), 224 deletions(-) diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 8ea570215..071ecbd18 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -2394,17 +2394,11 @@ void CL_Download_f (void) return; } - cls.downloadtype = dl_singlestuffed; - - CL_CheckOrDownloadFile(url, url, false); + CL_CheckOrEnqueDownloadFile(url, url); return; } - else - { - cls.downloadtype = dl_single; - } - CL_EnqueDownload(url, url, true, false); + CL_EnqueDownload(url, url, true, true); /* strcpy(cls.downloadname, url); @@ -2979,9 +2973,6 @@ void Host_Frame (double time) CL_AllowIndependantSendCmd(false); - if (cls.downloadtype == dl_none && !*cls.downloadname && cl.downloadlist) - CL_RequestNextDownload(); - // fetch results from server CL_ReadPackets (); @@ -3064,10 +3055,7 @@ void Host_Frame (double time) // process console commands Cbuf_Execute (); - if (cls.downloadtype == dl_none && !*cls.downloadname && cl.downloadlist) - { -CL_RequestNextDownload(); - } + CL_RequestNextDownload(); } static void simple_crypt(char *buf, int len) diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 6a4507bc1..23792b2b2 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -354,21 +354,16 @@ void CL_FinishDownload(char *filename, char *tempname) // rename the temp file to it's final name if (tempname) { - char oldn[MAX_OSPATH], newn[MAX_OSPATH]; if (strcmp(tempname, filename)) { if (strncmp(tempname,"skins/",6)) { - sprintf (oldn, "%s/%s", com_gamedir, tempname); - sprintf (newn, "%s/%s", com_gamedir, filename); + FS_Rename(tempname, filename, FS_GAME); } else { - sprintf (oldn, "qw/%s", tempname); - sprintf (newn, "qw/%s", filename); + FS_Rename(tempname+6, filename+6, FS_SKINS); } - if (rename (oldn, newn)) - Con_TPrintf (TL_RENAMEFAILED); } } @@ -386,6 +381,18 @@ void CL_FinishDownload(char *filename, char *tempname) break; } } + for (i = 0; i < MAX_MODELS; i++) //go and load this model now. + { + if (!strcmp(cl.model_name[i], filename)) + { + cl.model_precache[i] = Mod_ForName(cl.model_name[i], false); //throw away result. + if (i == 1) + cl.worldmodel = cl.model_precache[i]; + break; + } + } + + //this'll do the magic for us Skin_FlushSkin(filename); } } @@ -401,14 +408,14 @@ void MapDownload(char *name, qboolean gotornot) */ /* =============== -CL_CheckOrDownloadFile +CL_CheckOrEnqueDownloadFile Returns true if the file exists, otherwise it attempts to start a download from the server. =============== */ -qboolean CL_CheckOrDownloadFile (char *filename, char *localname, int nodelay) -{ +qboolean CL_CheckOrEnqueDownloadFile (char *filename, char *localname) +{ //returns false if we don't have the file yet. if (!localname) localname = filename; if (strstr (localname, "..")) @@ -443,10 +450,8 @@ qboolean CL_CheckOrDownloadFile (char *filename, char *localname, int nodelay) HTTP_CL_Get(va("http://maps.quakeworld.nu/%s/download/", base), filename, MapDownload); } */ - if (CL_EnqueDownload(filename, localname, false, false)) - return !nodelay; - else - return true; + CL_EnqueDownload(filename, localname, false, false); + return false; } qboolean CL_CheckMD2Skins (char *name) @@ -485,14 +490,7 @@ qboolean CL_CheckMD2Skins (char *name) LittleLong(pheader->ofs_skins) + (precache_model_skin - 1)*MD2MAX_SKINNAME; COM_CleanUpPath(str); - if (!CL_CheckOrDownloadFile(str, str, false)) - { - precache_model_skin++; - - BZ_Free(precache_model); - precache_model=NULL; - return true; // started a download - } + CL_CheckOrEnqueDownloadFile(str, str); precache_model_skin++; } if (precache_model) { @@ -516,13 +514,16 @@ void Model_NextDownload (void) int i; extern char gamedirfile[]; - if (cls.downloadnumber == 0) + Con_TPrintf (TLC_CHECKINGMODELS); + +/* if (cls.downloadnumber == 0) { Con_TPrintf (TLC_CHECKINGMODELS); cls.downloadnumber = 1; cl.worldmodel = NULL; } +*/ #ifdef Q2CLIENT if (cls.protocol == CP_QUAKE2) { @@ -533,21 +534,17 @@ void Model_NextDownload (void) if (!*cl.image_name[i]) continue; sprintf(picname, "pics/%s.pcx", cl.image_name[i]); - if (!CL_CheckOrDownloadFile(picname, picname, false)) - return; + CL_CheckOrEnqueDownloadFile(picname, picname); } if (!CLQ2_RegisterTEntModels()) return; } #endif - cls.downloadtype = dl_model; - - for ( - ; cl.model_name[cls.downloadnumber][0] - ; cls.downloadnumber++) + for ( i = 1; cl.model_name[i][0] + ; i++) { - s = cl.model_name[cls.downloadnumber]; + s = cl.model_name[i]; if (s[0] == '*') continue; // inline brush model @@ -559,8 +556,7 @@ void Model_NextDownload (void) continue; #endif - if (!CL_CheckOrDownloadFile(s, s, cls.downloadnumber==1)) //world is required to be loaded. - return; // started a download + CL_CheckOrEnqueDownloadFile(s, s); //world is required to be loaded. if (strstr(s, ".md2")) if (CL_CheckMD2Skins(s)) @@ -569,81 +565,122 @@ void Model_NextDownload (void) CL_AllowIndependantSendCmd(false); //stop it now, the indep stuff *could* require model tracing. + +// if (cl.worldmodel->type != mod_brush && cl.worldmodel->type != mod_heightmap) +// Host_EndGame("Worldmodel must be a bsp of some sort\n"); + + + Hunk_Check (); // make sure nothing is hurt + + cl.sendprespawn = true; +} + +int CL_LoadModels(int stage) +{ + extern model_t *loadmodel; + int i; + +#define atstage() ((cl.contentstage == stage++)?++cl.contentstage:false) + + if (atstage()) + { + if (cls.fteprotocolextensions & PEXT_CSQC) + { + char *s; + s = Info_ValueForKey(cl.serverinfo, "*csprogs"); + if (*s || cls.demoplayback) //only allow csqc if the server says so, and the 'checksum' matches. + { + unsigned int chksum = strtoul(s, NULL, 0); + if (CSQC_Init(chksum)) + CL_SendClientCommand(true, "enablecsqc"); + else + Sbar_Start(); //try and start this before we're actually on the server, + //this'll stop the mod from sending so much stuffed data at us, whilst we're frozen while trying to load. + //hopefully this'll make it more robust. + //csqc is expected to use it's own huds, or to run on decent servers. :p + } + } + return -1; + } + + if (cl.playernum[0] == -1) { //q2 cinematic - don't load the models. cl.worldmodel = cl.model_precache[1] = Mod_ForName ("", false); } - else if (!cl.worldmodel) + else { for (i=1 ; itype == mod_dummy || cl.model_precache[i]->needload))) + if (atstage()) { - Con_TPrintf (TL_FILE_X_MISSING, cl.model_name[i]); - Con_TPrintf (TL_GETACLIENTPACK, gamedirfile); - CL_Disconnect (); - return; + Hunk_Check(); + + cl.model_precache[i] = Mod_ForName (cl.model_name[i], false); + + Hunk_Check(); + + S_ExtraUpdate(); + + return -1; } - - S_ExtraUpdate(); } - - cl.worldmodel = cl.model_precache[1]; - - if (!cl.worldmodel) - Host_EndGame("Worldmodel wasn't sent\n"); } - if (cl.worldmodel->type != mod_brush && cl.worldmodel->type != mod_heightmap) - Host_EndGame("Worldmodel must be a bsp of some sort\n"); - - if (!R_CheckSky()) - return; - if (!Wad_NextDownload()) //world is required to be loaded. - return; // started a download - + if (atstage()) { - extern model_t *loadmodel; - loadmodel = cl.worldmodel; + cl.worldmodel = cl.model_precache[1]; if (!cl.worldmodel) + Host_EndGame("Worldmodel wasn't sent\n"); + + R_CheckSky(); + + return -1; + } + if (atstage()) + { + Wad_NextDownload(); + + return -1; + } + + if (atstage()) + { + loadmodel = cl.worldmodel; + if (!loadmodel) Host_EndGame("No worldmodel was loaded\n"); if (R_PreNewMap) R_PreNewMap(); + return -1; + } + if (atstage()) + { + loadmodel = cl.worldmodel; + if (!loadmodel) + Host_EndGame("No worldmodel was loaded\n"); Mod_NowLoadExternal(); + + return -1; } // all done - R_NewMap (); + if (atstage()) + { + loadmodel = cl.worldmodel; + if (!loadmodel) + Host_EndGame("No worldmodel was loaded\n"); + R_NewMap (); - Hunk_Check (); // make sure nothing is hurt -#ifdef Q2CLIENT - if (cls.protocol == CP_QUAKE2) - { - cls.downloadnumber = 0; - Skin_NextDownload(); - } - else -#endif - { - // done with modellist, request first of static signon messages - if (CL_RemoveClientCommands("prespawn")) - Con_Printf("Multiple prespawns\n"); -// CL_SendClientCommand("prespawn %i 0 %i", cl.servercount, cl.worldmodel->checksum2); - CL_SendClientCommand(true, prespawn_name, cl.servercount, LittleLong(cl.worldmodel->checksum2)); + return -1; } + + return stage; } /* @@ -656,65 +693,37 @@ void Sound_NextDownload (void) char *s; int i; - cls.downloadtype = dl_sound; - if (cls.downloadnumber == 0) - { - Con_TPrintf (TLC_CHECKINGSOUNDS); -#ifdef CSQC_DAT - if (cls.fteprotocolextensions & PEXT_CSQC) - { - s = Info_ValueForKey(cl.serverinfo, "*csprogs"); - if (*s || cls.demoplayback) //only allow csqc if the server says so, and the 'checksum' matches. - { - extern cvar_t allow_download_csprogs; - unsigned int chksum = strtoul(s, NULL, 0); - if (allow_download_csprogs.value) - { - char *str = va("csprogsvers/%x.dat", chksum); - if (!CL_CheckOrDownloadFile("csprogs.dat", str, true)) - { - cls.downloadnumber = 1; - return; - } - } - else - { - Con_Printf("Not downloading csprogs.dat\n"); - } - } - } - cls.downloadnumber = 1; -#endif - } + Con_TPrintf (TLC_CHECKINGSOUNDS); #ifdef CSQC_DAT - if (cls.downloadnumber == 1 && cls.fteprotocolextensions & PEXT_CSQC) + if (cls.fteprotocolextensions & PEXT_CSQC) { s = Info_ValueForKey(cl.serverinfo, "*csprogs"); if (*s || cls.demoplayback) //only allow csqc if the server says so, and the 'checksum' matches. { + extern cvar_t allow_download_csprogs; unsigned int chksum = strtoul(s, NULL, 0); - if (CSQC_Init(chksum)) - CL_SendClientCommand(true, "enablecsqc"); + if (allow_download_csprogs.value) + { + char *str = va("csprogsvers/%x.dat", chksum); + CL_CheckOrEnqueDownloadFile("csprogs.dat", str); + } else - Sbar_Start(); //try and start this before we're actually on the server, - //this'll stop the mod from sending so much stuffed data at us, whilst we're frozen while trying to load. - //hopefully this'll make it more robust. - //csqc is expected to use it's own huds, or to run on decent servers. :p + { + Con_Printf("Not downloading csprogs.dat\n"); + } } } #endif - for ( - ; cl.sound_name[cls.downloadnumber][0] - ; cls.downloadnumber++) + for (i = 1; cl.sound_name[i][0] + ; i++) { - s = cl.sound_name[cls.downloadnumber]; + s = cl.sound_name[i]; if (*s == '*') continue; - if (!CL_CheckOrDownloadFile(va("sound/%s",s), NULL, false)) - return; // started a download + CL_CheckOrEnqueDownloadFile(va("sound/%s",s), NULL); } for (i=1 ; ilocalname)) - CL_SendDownloadRequest(cl.downloadlist->name, cl.downloadlist->localname); - else + if (cls.downloadmethod) + return; + + if (cl.sendprespawn || cls.state == ca_active) + if (cl.downloadlist) { - Con_Printf("Already have %s\n", cl.downloadlist->localname); - CL_DisenqueDownload(cl.downloadlist->name); + if (!COM_FCheckExists (cl.downloadlist->localname)) + CL_SendDownloadRequest(cl.downloadlist->name, cl.downloadlist->localname); + else + { + Con_Printf("Already have %s\n", cl.downloadlist->localname); + CL_DisenqueDownload(cl.downloadlist->name); + } + if (requiredownloads.value || !cl.worldmodel) + return; } - return; - } - if (!requiredownloads.value) - return; - switch (cls.downloadtype) - { - case dl_single: - case dl_singlestuffed: - break; - case dl_skin: - Skin_NextDownload (); - break; - case dl_model: - Model_NextDownload (); - break; - case dl_sound: - Sound_NextDownload (); - break; - case dl_none: - default: - Con_DPrintf("Unknown download type.\n"); + + if (cl.sendprespawn) + { // get next signon phase + + if (CL_LoadModels(0) < 0) + return; //not yet + + cl.sendprespawn = false; + + +#ifdef Q2CLIENT + if (cls.protocol == CP_QUAKE2) + { + Skin_NextDownload(); + } + else +#endif + { + // done with modellist, request first of static signon messages + if (CL_RemoveClientCommands("prespawn")) + Con_Printf("Multiple prespawns\n"); + // CL_SendClientCommand("prespawn %i 0 %i", cl.servercount, cl.worldmodel->checksum2); + CL_SendClientCommand(true, prespawn_name, cl.servercount, LittleLong(cl.worldmodel->checksum2)); + } + } } @@ -923,7 +941,9 @@ void CL_ParseChunkedDownload(void) Host_EndGame("Received second download - \"%s\"\n", svname); if (strcmp(cls.downloadname, svname)) - Host_EndGame("Server sent the wrong download - \"%s\" instead of \"%s\"\n", svname, cls.downloadname); + if (strcmp(cls.downloadname, "csprogs.dat") || strcmp(cls.downloadname, "csprogsvers/")) + Host_EndGame("Server sent the wrong download - \"%s\" instead of \"%s\"\n", svname, cls.downloadname); + //start the new download cls.downloadmethod = DL_QWCHUNKS; @@ -1003,6 +1023,16 @@ void CL_ParseChunkedDownload(void) cls.downloadpercent = receivedbytes/(float)downloadsize*100; } +int CL_CountQueuedDownloads(void) +{ + int count = 0; + downloadlist_t *dl; + for (dl = cl.downloadlist; dl; dl = dl->next) + count++; + + return count; +} + int CL_RequestADownloadChunk(void) { int i; @@ -1033,7 +1063,7 @@ int CL_RequestADownloadChunk(void) VFS_CLOSE(cls.downloadqw); CL_FinishDownload(cls.downloadname, cls.downloadtempname); - Con_Printf("Download took %i seconds\n", (int)(Sys_DoubleTime() - downloadstarttime)); + Con_Printf("Download took %i seconds (%i more)\n", (int)(Sys_DoubleTime() - downloadstarttime), CL_CountQueuedDownloads()); *cls.downloadname = '\0'; cls.downloadqw = NULL; @@ -1109,13 +1139,17 @@ void CL_ParseDownload (void) if (!cls.downloadqw) { if (strncmp(cls.downloadtempname,"skins/",6)) - sprintf (name, "%s/%s", com_gamedir, cls.downloadtempname); + { + sprintf (name, "%s", cls.downloadtempname); + FS_CreatePath (name, FS_GAME); + cls.downloadqw = FS_OpenVFS (name, "wb", FS_GAME); + } else - sprintf (name, "qw/%s", cls.downloadtempname); - - COM_CreatePath (name); - - cls.downloadqw = FS_OpenVFS (name, "wb", FS_GAME); + { + sprintf (name, "%s", cls.downloadtempname+6); + FS_CreatePath (name, FS_SKINS); + cls.downloadqw = FS_OpenVFS (name, "wb", FS_SKINS); + } if (!cls.downloadqw) { msg_readcount += size; @@ -1933,8 +1967,6 @@ void CL_ParseSoundlist (void) return; } - cls.downloadnumber = 0; - cls.downloadtype = dl_sound; Sound_NextDownload (); } @@ -2006,8 +2038,6 @@ void CL_ParseModellist (qboolean lots) return; } - cls.downloadnumber = 0; - cls.downloadtype = dl_model; Model_NextDownload (); } @@ -2183,9 +2213,6 @@ void CLQ2_Precache_f (void) CG_Start(); #endif - cls.downloadnumber = 0; - cls.downloadtype = dl_sound; - CL_RequestNextDownload(); } @@ -3508,7 +3535,7 @@ void CL_ParsePrecache(void) if (i >= 1 && i < MAX_MODELS) { model_t *model; - CL_CheckOrDownloadFile(s, s, true); + CL_CheckOrEnqueDownloadFile(s, s); model = Mod_ForName(s, i == 1); if (!model) Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s); @@ -3524,7 +3551,7 @@ void CL_ParsePrecache(void) if (i >= 1 && i < MAX_SOUNDS) { sfx_t *sfx; - CL_CheckOrDownloadFile(va("sounds/%s", s), NULL, true); + CL_CheckOrEnqueDownloadFile(va("sounds/%s", s), NULL); sfx = S_PrecacheSound (s); if (!sfx) Con_Printf("svc_precache: S_PrecacheSound(\"%s\") failed\n", s); diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index ca3c473a9..4c3135a36 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -619,7 +619,7 @@ void SCR_ShowPic_Create(void) sp->x = MSG_ReadShort(); sp->y = MSG_ReadShort(); - CL_CheckOrDownloadFile(sp->picname, sp->picname, -1); + CL_CheckOrEnqueDownloadFile(sp->picname, sp->picname); } void SCR_ShowPic_Hide(void) @@ -667,7 +667,7 @@ void SCR_ShowPic_Update(void) sp->picname = Z_Malloc(strlen(s)+1); strcpy(sp->picname, s); - CL_CheckOrDownloadFile(sp->picname, sp->picname, false); + CL_CheckOrEnqueDownloadFile(sp->picname, sp->picname); } void SCR_ShowPic_Script_f(void) diff --git a/engine/client/client.h b/engine/client/client.h index 747d409a7..9f931caaa 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -335,9 +335,6 @@ typedef struct int downloadpercent; int downloadchunknum; - int downloadnumber; //file number - dltype_t downloadtype; //of type - // demo loop control int demonum; // -1 = don't play demos char demos[MAX_DEMOS][MAX_DEMONAME]; // when not playing @@ -574,6 +571,9 @@ typedef struct int deathmatch; qboolean teamfortress; //*sigh*. This is used for teamplay stuff. This sucks. + + qboolean sendprespawn; + int contentstage; } client_state_t; extern int cl_teamtopcolor; @@ -743,7 +743,7 @@ void CLNQ_ParseServerMessage (void); void CLQ2_ParseServerMessage (void); #endif void CL_NewTranslation (int slot); -qboolean CL_CheckOrDownloadFile (char *filename, char *localname, int nodelay); +qboolean CL_CheckOrEnqueDownloadFile (char *filename, char *localname); qboolean CL_IsUploading(void); void CL_NextUpload(void); void CL_StartUpload (qbyte *data, int size); diff --git a/engine/client/skin.c b/engine/client/skin.c index 0526e9339..86a4e7f3f 100644 --- a/engine/client/skin.c +++ b/engine/client/skin.c @@ -207,9 +207,6 @@ qbyte *Skin_Cache8 (skin_t *skin) int runLength; int fbremap[256]; - if (cls.downloadtype == dl_skin) - return NULL; // use base until downloaded - if (noskins.value==1) // JACK: So NOSKINS > 1 will show skins, but return NULL; // not download new ones. @@ -390,9 +387,6 @@ qbyte *Skin_Cache32 (skin_t *skin) qbyte *raw; qbyte *out, *pix; - if (cls.downloadtype == dl_skin) - return NULL; // use base until downloaded - if (noskins.value==1) // JACK: So NOSKINS > 1 will show skins, but return NULL; // not download new ones. @@ -473,15 +467,11 @@ void Skin_NextDownload (void) player_info_t *sc; int i; - if (cls.downloadnumber == 0) - Con_Printf ("Checking skins...\n"); - cls.downloadtype = dl_skin; + Con_Printf ("Checking skins...\n"); - for ( - ; cls.downloadnumber != MAX_CLIENTS - ; cls.downloadnumber++) + for (i = 0; i != MAX_CLIENTS; i++) { - sc = &cl.players[cls.downloadnumber]; + sc = &cl.players[i]; if (!sc->name[0]) continue; Skin_Find (sc); @@ -491,12 +481,9 @@ void Skin_NextDownload (void) if (strchr(sc->skin->name, ' ')) //skip over skins using a space continue; - if (!CL_CheckOrDownloadFile(va("skins/%s.pcx", sc->skin->name), NULL, false)) - return; // started a download + CL_CheckOrEnqueDownloadFile(va("skins/%s.pcx", sc->skin->name), NULL); } - cls.downloadtype = dl_none; - // now load them in for real for (i=0 ; iskin = NULL; #endif } - - if (cls.state != ca_active) - { // get next signon phase - CL_SendClientCommand(true, "begin %i", cl.servercount); - Cache_Report (); // print remaining memory - } } //called from a few places when some skin cheat is applied. @@ -549,14 +530,11 @@ void Skin_Skins_f (void) } numskins = 0; - cls.downloadnumber = 0; - cls.downloadtype = dl_skin; Skin_NextDownload (); -#ifdef VM_CG - CG_Stop(); - CG_Start(); -#endif + + CL_SendClientCommand(true, "begin %i", cl.servercount); + Cache_Report (); // print remaining memory } diff --git a/engine/client/wad.c b/engine/client/wad.c index e8c65d999..c20e82829 100644 --- a/engine/client/wad.c +++ b/engine/client/wad.c @@ -568,8 +568,7 @@ qboolean Wad_NextDownload (void) if (wadname[9]) { if (COM_FCheckExists(wadname+9)) //wad is in root dir, so we don't need to try textures. - if (!CL_CheckOrDownloadFile(wadname, wadname, true)) - return false; + CL_CheckOrEnqueDownloadFile(wadname, wadname); } wads[i] = k; diff --git a/engine/common/fs.c b/engine/common/fs.c index 91a819e11..8200b3005 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -1634,7 +1634,32 @@ vfsfile_t *FS_OpenVFS(char *filename, char *mode, int relativeto) void FS_Rename(char *oldf, char *newf, int relativeto) { - rename(oldf, newf); + char fullname[MAX_OSPATH]; + + switch (relativeto) + { + case FS_GAME: + if (*com_homedir) + _snprintf(fullname, sizeof(fullname), "%s/%s/", com_homedir, gamedirfile); + else + _snprintf(fullname, sizeof(fullname), "%s/%s/", com_quakedir, gamedirfile); + break; + case FS_SKINS: + if (*com_homedir) + _snprintf(fullname, sizeof(fullname), "%s/qw/skins/", com_homedir); + else + _snprintf(fullname, sizeof(fullname), "%s/qw/skins/", com_quakedir); + break; + case FS_BASE: + if (*com_homedir) + _snprintf(fullname, sizeof(fullname), "%s/", com_homedir); + else + _snprintf(fullname, sizeof(fullname), "%s/", com_quakedir); + break; + default: + Sys_Error("FS_Rename case not handled\n"); + } + rename(va("%s%s", fullname, oldf), va("%s%s", fullname, newf)); } void FS_Remove(char *fname, int relativeto) { diff --git a/engine/gl/gl_screen.c b/engine/gl/gl_screen.c index 8f2b74c18..1e5f3a8c3 100644 --- a/engine/gl/gl_screen.c +++ b/engine/gl/gl_screen.c @@ -276,7 +276,7 @@ void GLSCR_UpdateScreen (void) else #endif #ifdef CSQC_DAT - if (CSQC_DrawView()) + if (cls.state == ca_active && CSQC_DrawView()) nohud = true; else #endif