diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index ba1d99bc1..0cce16c89 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -3682,13 +3682,15 @@ void Host_DoRunFile(hrf_t *f) int len = VFS_GETLEN(f->srcfile); char *fdata = BZ_Malloc(len+1); VFS_READ(f->srcfile, fdata, len); - VFS_CLOSE(f->srcfile); fdata[len] = 0; man = FS_Manifest_Parse(fdata); if (!man->updateurl) man->updateurl = Z_StrDup(f->fname); BZ_Free(fdata); FS_ChangeGame(man, true); + + f->flags |= HRF_ABORT; + Host_DoRunFile(f); return; } } @@ -4385,11 +4387,10 @@ void CL_ExecInitialConfigs(char *resetcommand) { int qrc, hrc, def; - Cbuf_AddText ("cl_warncmd 0\n", RESTRICT_LOCAL); - - Cmd_ExecuteString("unbindall", RESTRICT_LOCAL); - Cmd_ExecuteString("cvarreset *", RESTRICT_LOCAL); - Cmd_ExecuteString(resetcommand, RESTRICT_LOCAL); + Cbuf_AddText("cl_warncmd 0\n", RESTRICT_LOCAL); + Cbuf_AddText("unbindall", RESTRICT_LOCAL); + Cbuf_AddText("cvarreset *", RESTRICT_LOCAL); + Cbuf_AddText(resetcommand, RESTRICT_LOCAL); //who should we imitate? qrc = COM_FDepthFile("quake.rc", true); //q1 @@ -4418,6 +4419,12 @@ void CL_ExecInitialConfigs(char *resetcommand) com_parseutf8.ival = com_parseutf8.value; + //if the renderer is already up and running, be prepared to reload content to match the new conback/font/etc + if (qrenderer != QR_NONE) + Cbuf_AddText ("vid_reload\n", RESTRICT_LOCAL); + if (key_dest == key_menu) + Cbuf_AddText ("closemenu\ntogglemenu\n", RESTRICT_LOCAL); //make sure the menu has the right content loaded. + Cbuf_Execute (); //if the server initialisation causes a problem, give it a place to abort to diff --git a/engine/client/input.h b/engine/client/input.h index b9f998377..72afaf154 100644 --- a/engine/client/input.h +++ b/engine/client/input.h @@ -36,10 +36,10 @@ extern cvar_t in_xflip; extern float mousecursor_x, mousecursor_y; extern float mousemove_x, mousemove_y; -#ifdef _SDL +//#ifdef _SDL void IN_ActivateMouse(void); void IN_DeactivateMouse(void); -#endif +//#endif int CL_TargettedSplit(qboolean nowrap); diff --git a/engine/client/renderer.c b/engine/client/renderer.c index f6b39a08d..36906df64 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -524,6 +524,7 @@ void R_InitTextures (void) void R_SetRenderer_f (void); +void R_ReloadRenderer_f (void); void Renderer_Init(void) { @@ -540,6 +541,7 @@ void Renderer_Init(void) r_blockvidrestart = true; Cmd_AddCommand("setrenderer", R_SetRenderer_f); Cmd_AddCommand("vid_restart", R_RestartRenderer_f); + Cmd_AddCommand("vid_reload", R_ReloadRenderer_f); #ifdef RTLIGHTS Cmd_AddCommand ("r_editlights_reload", R_ReloadRTLights_f); @@ -1326,35 +1328,9 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n")); #endif } - switch (qrenderer) + if (newr && qrenderer != QR_NONE) { - case QR_NONE: - Con_Printf( "\n" - "-----------------------------\n" - "Dedicated console created\n"); - break; - case QR_SOFTWARE: - Con_Printf( "\n" - "-----------------------------\n" - "Software renderer initialized\n"); - break; - - case QR_OPENGL: - Con_Printf( "\n" - "-----------------------------\n" - "OpenGL renderer initialized\n"); - break; - - case QR_DIRECT3D9: - Con_Printf( "\n" - "-----------------------------\n" - "Direct3d9 renderer initialized\n"); - break; - case QR_DIRECT3D11: - Con_Printf( "\n" - "-----------------------------\n" - "Direct3d11 renderer initialized\n"); - break; + Con_Printf("%s renderer initialized\n", newr->renderer->description); } TRACE(("dbg: R_ApplyRenderer: S_Restart_f\n")); @@ -1368,6 +1344,12 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n")); return true; } +void R_ReloadRenderer_f (void) +{ + //reloads textures without destroying video context. + R_ApplyRenderer_Load(NULL); +} + #define DEFAULT_WIDTH 640 #define DEFAULT_HEIGHT 480 #define DEFAULT_BPP 32 diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 70d98d31f..be390f0f2 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -666,7 +666,6 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un start += len; break; case VOIP_OPUS: -#if 1 len = bytes; if (decodesamps > 0) { @@ -686,25 +685,6 @@ void S_Voip_Decode(unsigned int sender, unsigned int codec, unsigned int gen, un bytes -= len; start += len; -#else - //FIXME: we shouldn't need this crap - bytes--; - len = *start++; - if (bytes < len) - break; - r = qopus_decode(s_voip.decoder[sender], start, len, decodebuf + decodesamps, sizeof(decodebuf)/sizeof(decodebuf[0]) - decodesamps, false); - if (r > 0) - { - decodesamps += r; - s_voip.decseq[sender]++; - seq++; - } - else if (r < 0) - Con_Printf("Opus decoding error %i\n", r); - - bytes -= len; - start += len; -#endif break; } } @@ -1085,7 +1065,6 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf) samps+=len / 2; //number of samplepairs eaten in this packet. for stats. break; case VOIP_OPUS: -#if 1 { //opus rtp only supports/allows a single chunk in each packet. int frames; @@ -1128,26 +1107,6 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf) } } break; -#else - level += S_Voip_Preprocess(start, s_voip.encframesize, micamp); - len = qopus_encode(s_voip.encoder, start, s_voip.encframesize, outbuf+(outpos+1), max(255, sizeof(outbuf) - (outpos+1))); - if (len == 1) //packet does not need to be transmitted if it returns 1, supposedly. crazyness. - len = 0; - else if (len > 0) - { - outbuf[outpos] = len; - outpos += 1+len; - } - else - { - //error! - Con_Printf("Opus encoding error: %i\n", len); - } - s_voip.encsequence++; - samps+=s_voip.encframesize; - encpos += s_voip.encframesize*2; - break; -#endif default: outbuf[outpos] = 0; break; diff --git a/engine/common/common.h b/engine/common/common.h index adf802e3b..2582ac555 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -336,7 +336,6 @@ extern char com_configdir[MAX_OSPATH]; //dir to put cfg_save configs in //extern char *com_basedir; void COM_WriteFile (const char *filename, const void *data, int len); -FTE_DEPRECATED FILE *COM_WriteFileOpen (char *filename); typedef struct { struct searchpath_s *search; @@ -457,6 +456,7 @@ typedef struct struct { char *path; //the 'pure' name + qboolean crcknown; //if the crc was specified unsigned int crc; //the public crc char *mirrors[8]; //a randomized (prioritized) list of http mirrors to use. int mirrornum; //the index we last tried to download from, so we still work even if mirrors are down. diff --git a/engine/common/fs.c b/engine/common/fs.c index e50d52903..109987fce 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -261,7 +261,10 @@ void FS_Manifest_Print(ftemanifest_t *man) { if (man->package[i].path) { - Con_Printf("package \"%s\" 0x%x", man->package[i].path, man->package[i].crc); + if (man->package[i].crcknown) + Con_Printf("package \"%s\" 0x%x", man->package[i].path, man->package[i].crc); + else + Con_Printf("package \"%s\" -", man->package[i].path); for (j = 0; j < sizeof(man->package[i].mirrors) / sizeof(man->package[i].mirrors[0]); j++) if (man->package[i].mirrors[j]) Con_Printf(" \"%s\"", man->package[i].mirrors[j]); @@ -348,11 +351,13 @@ static void FS_Manifest_ParseTokens(ftemanifest_t *man) } else { + qboolean crcknown; int crc; int i, j; if (!stricmp(fname, "package")) Cmd_ShiftArgs(1, false); + crcknown = (strcmp(Cmd_Argv(1), "-") && *Cmd_Argv(1)); crc = strtoul(Cmd_Argv(1), NULL, 0); for (i = 0; i < sizeof(man->package) / sizeof(man->package[0]); i++) @@ -360,6 +365,7 @@ static void FS_Manifest_ParseTokens(ftemanifest_t *man) if (!man->package[i].path) { man->package[i].path = Z_StrDup(Cmd_Argv(0)); + man->package[i].crcknown = crcknown; man->package[i].crc = crc; for (j = 0; j < Cmd_Argc()-2 && j < sizeof(man->package[i].mirrors) / sizeof(man->package[i].mirrors[0]); j++) { @@ -393,6 +399,13 @@ ftemanifest_t *FS_Manifest_Parse(const char *data) data = Cmd_TokenizeString((char*)data, false, false); FS_Manifest_ParseTokens(man); } + if (!man->installation) + { //every manifest should have an internal name specified, so we can use the correct basedir + //if we don't recognise it, then we'll typically prompt (or just use the working directory), but always assuming a default at least ensures things are sane. + //fixme: we should probably fill in the basegame here (and share that logic with the legacy manifest generation code) + data = Cmd_TokenizeString((char*)"game quake", false, false); + FS_Manifest_ParseTokens(man); + } return man; } @@ -576,22 +589,6 @@ void COM_WriteFile (const char *filename, const void *data, int len) com_fschanged=true; } -FILE *COM_WriteFileOpen (char *filename) //like fopen, but based around quake's paths. -{ - FILE *f; - char name[MAX_OSPATH]; - - if (!FS_NativePath(filename, FS_GAMEONLY, name, sizeof(name))) - return NULL; - - COM_CreatePath(name); - - f = fopen (name, "wb"); - - return f; -} - - /* ============ COM_CreatePath @@ -1690,10 +1687,13 @@ static void FS_AddDataFiles(searchpath_t **oldpaths, const char *purepath, const searchpath_t *oldp; char pname[MAX_OSPATH]; char lname[MAX_OSPATH]; - snprintf(lname, sizeof(lname), "%#x", fs_manifest->package[i].crc); + if (fs_manifest->package[i].crcknown) + snprintf(lname, sizeof(lname), "%#x", fs_manifest->package[i].crc); + else + snprintf(lname, sizeof(lname), ""); if (!FS_GenCachedPakName(fs_manifest->package[i].path, lname, pname, sizeof(pname))) continue; - snprintf (lname, sizeof(lname), "%s%s", logicalpath, pname+ptlen+1); + snprintf (lname, sizeof(lname), "%s%s", logicalpaths, pname+ptlen+1); for (oldp = com_searchpaths; oldp; oldp = oldp->next) { @@ -1714,7 +1714,7 @@ static void FS_AddDataFiles(searchpath_t **oldpaths, const char *purepath, const handle = OpenNew (vfs, lname); } } - if (handle) + if (handle && fs_manifest->package[i].crcknown) { int truecrc = handle->GeneratePureCRC(handle, 0, false); if (truecrc != fs_manifest->package[i].crc) @@ -3317,6 +3317,7 @@ static void FS_PackageDownloaded(struct dl_download *dl) } static void FS_BeginNextPackageDownload(void) { + char *crcstr; int j; ftemanifest_t *man = fs_manifest; vfsfile_t *check; @@ -3329,7 +3330,11 @@ static void FS_BeginNextPackageDownload(void) if (!man->package[j].path) continue; - if (!FS_GenCachedPakName(man->package[j].path, va("%#x", man->package[j].crc), buffer, sizeof(buffer))) + if (man->package[j].crcknown) + crcstr = va("%#x", man->package[j].crc); + else + crcstr = ""; + if (!FS_GenCachedPakName(man->package[j].path, crcstr, buffer, sizeof(buffer))) continue; check = FS_OpenVFS(buffer, "rb", FS_ROOT); @@ -3339,7 +3344,7 @@ static void FS_BeginNextPackageDownload(void) continue; } FS_NativePath(buffer, FS_ROOT, fspdl_finalpath, sizeof(fspdl_finalpath)); - if (!FS_GenCachedPakName(va("%s.tmp", man->package[j].path), va("%#x", man->package[j].crc), buffer, sizeof(buffer))) + if (!FS_GenCachedPakName(va("%s.tmp", man->package[j].path), crcstr, buffer, sizeof(buffer))) continue; FS_NativePath(buffer, FS_ROOT, fspdl_temppath, sizeof(fspdl_temppath)); diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 589125dc8..18b0ee207 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -605,7 +605,7 @@ static void SnapVector( vec3_t normal ) normal[i] = 1; break; } - if( fabs( normal[i] - -1 ) < PLANE_NORMAL_EPSILON ) + if( fabs( normal[i] + 1 ) < PLANE_NORMAL_EPSILON ) { VectorClear( normal ); normal[i] = -1; diff --git a/engine/dotnet2005/ftequake.vcproj b/engine/dotnet2005/ftequake.vcproj index eba3a3c99..4682c1009 100644 --- a/engine/dotnet2005/ftequake.vcproj +++ b/engine/dotnet2005/ftequake.vcproj @@ -17406,6 +17406,170 @@ /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index 8843de796..ebc5d1e88 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -453,10 +453,7 @@ void GLDraw_Init (void) int maxtexsize; if (gltextures) - { - Con_Printf("gl_draw didn't shut down cleanly\n"); gltextures = NULL; - } memset(gltexturetablebuckets, 0, sizeof(gltexturetablebuckets)); Hash_InitTable(&gltexturetable, sizeof(gltexturetablebuckets)/sizeof(gltexturetablebuckets[0]), gltexturetablebuckets); @@ -470,12 +467,16 @@ void GLDraw_Init (void) maxtexsize = gl_max_size.value; + if (uploadmemorybuffer) + BZ_Free(uploadmemorybuffer); + if (uploadmemorybufferintermediate) + BZ_Free(uploadmemorybufferintermediate); //required to hold the image after scaling has occured - sizeofuploadmemorybuffer = 1; - sizeofuploadmemorybufferintermediate = 1; + sizeofuploadmemorybuffer = 0; + sizeofuploadmemorybufferintermediate = 0; TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); - uploadmemorybuffer = BZ_Realloc(uploadmemorybuffer, sizeofuploadmemorybuffer); - uploadmemorybufferintermediate = BZ_Realloc(uploadmemorybufferintermediate, sizeofuploadmemorybufferintermediate); + uploadmemorybuffer = NULL; + uploadmemorybufferintermediate = NULL; R2D_Init(); diff --git a/engine/http/httpserver.c b/engine/http/httpserver.c index 7da66840e..6691d3556 100644 --- a/engine/http/httpserver.c +++ b/engine/http/httpserver.c @@ -11,6 +11,115 @@ static qboolean httpserverinitied = false; qboolean httpserverfailed = false; static int httpserversocket; +static int httpserverport; + +#ifdef WEBSVONLY +static int natpmpsocket = INVALID_SOCKET; +static int natpmptime; +#include +static void sendnatpmp(int port) +{ + struct sockaddr_in router; + struct + { + qbyte ver; + qbyte op; + short reserved1; + short privport; short pubport; + int mapping_expectancy; + } pmpreqmsg; + + int curtime = timeGetTime(); + if (natpmpsocket == INVALID_SOCKET) + { + unsigned long _true = true; + natpmpsocket = socket(AF_INET, SOCK_DGRAM, 0); + if (natpmpsocket == INVALID_SOCKET) + return; + ioctlsocket (natpmpsocket, FIONBIO, &_true); + } + else if (curtime - natpmptime < 0) + return; + natpmptime = curtime+60*1000; + + memset(&router, 0, sizeof(router)); + router.sin_family = AF_INET; + router.sin_port = htons(5351); + router.sin_addr.S_un.S_un_b.s_b1 = 192; + router.sin_addr.S_un.S_un_b.s_b2 = 168; + router.sin_addr.S_un.S_un_b.s_b3 = 0; + router.sin_addr.S_un.S_un_b.s_b4 = 1; + + pmpreqmsg.ver = 0; + pmpreqmsg.op = 0; + pmpreqmsg.reserved1 = htons(0); + pmpreqmsg.privport = htons(port); + pmpreqmsg.pubport = htons(port); + pmpreqmsg.mapping_expectancy = htons(60*5); + + sendto(natpmpsocket, (void*)&pmpreqmsg, 2, 0, (struct sockaddr*)&router, sizeof(router)); + + pmpreqmsg.op = 2; + sendto(natpmpsocket, (void*)&pmpreqmsg, sizeof(pmpreqmsg), 0, (struct sockaddr*)&router, sizeof(router)); +} +void checknatpmp(int port) +{ + struct + { + qbyte ver; qbyte op; short resultcode; + int age; + union + { + struct + { + short privport; short pubport; + int mapping_expectancy; + }; + qbyte ipv4[4]; + }; + } pmpreqrep; + struct sockaddr_in from; + int fromlen = sizeof(from); + int len; + static int oldip=-1; + static short oldport; + memset(&pmpreqrep, 0, sizeof(pmpreqrep)); + sendnatpmp(port); + if (natpmpsocket == INVALID_SOCKET) + len = -1; + else + len = recvfrom(natpmpsocket, (void*)&pmpreqrep, sizeof(pmpreqrep), 0, (struct sockaddr*)&from, &fromlen); + if (len == 12 && pmpreqrep.op == 128) + { + if (oldip != *(int*)pmpreqrep.ipv4) + { + oldip = *(int*)pmpreqrep.ipv4; + oldport = 0; + IWebPrintf("Public ip is %i.%i.%i.%i\n", pmpreqrep.ipv4[0], pmpreqrep.ipv4[1], pmpreqrep.ipv4[2], pmpreqrep.ipv4[3]); + } + } + else if (len == 16 && pmpreqrep.op == 129) + { + if (oldport != pmpreqrep.pubport) + { + oldport = pmpreqrep.pubport; + IWebPrintf("Public udp port %i (local %i)\n", ntohs(pmpreqrep.pubport), ntohs(pmpreqrep.privport)); + } + } + else if (len == 16 && pmpreqrep.op == 130) + { + if (oldport != pmpreqrep.pubport) + { + oldport = pmpreqrep.pubport; + IWebPrintf("Public tcp port %i (local %i)\n", ntohs(pmpreqrep.pubport), ntohs(pmpreqrep.privport)); + } + } +} +#else +void checknatpmp(int port) +{ +} +#endif typedef enum {HTTP_WAITINGFORREQUEST,HTTP_SENDING} http_mode_t; @@ -64,6 +173,7 @@ qboolean HTTP_ServerInit(int port) httpserverinitied = true; httpserverfailed = false; + httpserverport = port; IWebPrintf("HTTP server is running\n"); return true; @@ -554,6 +664,8 @@ qboolean HTTP_ServerPoll(qboolean httpserverwanted, int portnum) //loop while tr HTTP_active_connections_t *cl; + if (httpserverport != portnum && httpserverinitied) + HTTP_ServerShutdown(); if (!httpserverinitied) { if (httpserverwanted) @@ -566,6 +678,8 @@ qboolean HTTP_ServerPoll(qboolean httpserverwanted, int portnum) //loop while tr return false; } + checknatpmp(httpserverport); + if (httpconnectioncount>32) return false; diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index 6977877e6..06bc98632 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -1102,7 +1102,10 @@ pubprogfuncs_t deffuncs = { PR_UglyValueString, ED_ParseEval }; -#undef printf +static int PDECL qclib_null_printf(const char *s, ...) +{ + return 0; +} //defs incase following structure is not passed. struct edict_s *safesv_edicts; @@ -1115,7 +1118,7 @@ progexterns_t defexterns = { NULL, //char *(*ReadFile) (char *fname, void *buffer, int len); NULL, //int (*FileSize) (char *fname); //-1 if file does not exist NULL, //bool (*WriteFile) (char *name, void *data, int len); - printf, //void (*printf) (char *, ...); + qclib_null_printf, //void (*printf) (char *, ...); (void*)exit, //void (*Sys_Error) (char *, ...); NULL, //void (*Abort) (char *, ...); sizeof(edictrun_t), //int edictsize; //size of edict_t