diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 5b2a6622d..2ccaa33dd 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -1535,18 +1535,6 @@ void CL_ReRecord_f (void) CL_BeginServerReconnect(); } -#ifdef WEBCLIENT -void CL_PlayDownloadedDemo(char *name, qboolean success) -{ - if (success == false) - Con_Printf("Failed to download %s\n", name); - else - { - Cbuf_AddText(va("playdemo %s\n", name), RESTRICT_LOCAL); - } -} -#endif - /* ==================== CL_PlayDemo_f @@ -1554,6 +1542,7 @@ CL_PlayDemo_f play [demoname] ==================== */ +void CL_PlayDownloadedDemo(struct dl_download *dl); void CL_PlayDemo_f (void) { char *demoname; @@ -1567,10 +1556,7 @@ void CL_PlayDemo_f (void) cls.state = ca_disconnected; #ifdef WEBCLIENT -#ifdef warningmsg -#pragma warningmsg("playdemo http://blah is broken right now") -#endif -#if 0 +#if 1 if (!strncmp(Cmd_Argv(1), "ftp://", 6) || !strncmp(Cmd_Argv(1), "http://", 7)) { if (Cmd_ExecLevel == RESTRICT_LOCAL) @@ -1682,10 +1668,92 @@ vfsfile_t *CL_OpenFileInZipOrSys(char *name) else return CL_OpenFileInPackage(NULL, name); } +//tries to determine the demo type +void CL_PlayDemoFile(vfsfile_t *f, char *demoname) +{ + qofs_t start; + + if (!VFS_GETLEN (f)) + { + VFS_CLOSE(f); + Con_Printf ("demo \"%s\" is empty.\n", demoname); + return; + } + + //figure out where we started + start = VFS_TELL(f); + +#ifdef Q2CLIENT + { + int len; + char type; + int protocol; + //check if its a quake2 demo. + VFS_READ(f, &len, sizeof(len)); + VFS_READ(f, &type, sizeof(type)); + VFS_READ(f, &protocol, sizeof(protocol)); + VFS_SEEK(f, start); + if (len > 5 && type == svcq2_serverdata && protocol == PROTOCOL_VERSION_Q2) + { + CL_PlayDemoStream(f, NULL, demoname, DPB_QUAKE2, 0); + return; + } + } +#endif + +#ifdef NQPROT + { + int ft = 0, neg = false; + char chr; + //not quake2, check if its NQ + //work out if the first line is a int for the track number. + while ((VFS_READ(f, &chr, 1)==1) && (chr != '\n')) + { + if (chr == ' ') + ; + else if (chr == '-') + neg = true; + else if (chr < '0' || chr > '9') + break; + else + ft = ft * 10 + ((int)chr - '0'); + } + if (neg) + ft *= -1; + if (chr == '\n') + { + CL_PlayDemoStream(f, NULL, demoname, DPB_NETQUAKE, 0); + return; + } + VFS_SEEK(f, start); + } +#endif + + //its not NQ then. must be QuakeWorld, either .qwd or .mvd + //could also be .qwz or .dmz or whatever that nq extension is. we don't support either. + + //mvd and qwd have no identifying markers, other than the extension. + if (!Q_strcasecmp(demoname + strlen(demoname) - 3, "mvd") || + !Q_strcasecmp(demoname + strlen(demoname) - 6, "mvd.gz")) + CL_PlayDemoStream(f, NULL, demoname, DPB_MVD, 0); + else + CL_PlayDemoStream(f, NULL, demoname, DPB_QUAKEWORLD, 0); +} +#ifdef WEBCLIENT +void CL_PlayDownloadedDemo(struct dl_download *dl) +{ + if (dl->status != DL_FINISHED || !dl->file) + Con_Printf("Failed to download %s\n", dl->url); + else + { + CL_PlayDemoFile(dl->file, dl->url); + dl->file = NULL; + } +} +#endif void CL_PlayDemo(char *demoname) { char name[256]; - qofs_t start; vfsfile_t *f; // @@ -1720,71 +1788,7 @@ void CL_PlayDemo(char *demoname) } Q_strncpyz (lastdemoname, demoname, sizeof(lastdemoname)); - if (!VFS_GETLEN (f)) - { - VFS_CLOSE(f); - Con_Printf ("demo \"%s\" is empty.\n", demoname); - return; - } - - //figure out where we started - start = VFS_TELL(f); - -#ifdef Q2CLIENT - { - int len; - char type; - int protocol; - //check if its a quake2 demo. - VFS_READ(f, &len, sizeof(len)); - VFS_READ(f, &type, sizeof(type)); - VFS_READ(f, &protocol, sizeof(protocol)); - VFS_SEEK(f, start); - if (len > 5 && type == svcq2_serverdata && protocol == PROTOCOL_VERSION_Q2) - { - CL_PlayDemoStream(f, NULL, name, DPB_QUAKE2, 0); - return; - } - } -#endif - -#ifdef NQPROT - { - int ft = 0, neg = false; - char chr; - //not quake2, check if its NQ - //work out if the first line is a int for the track number. - while ((VFS_READ(f, &chr, 1)==1) && (chr != '\n')) - { - if (chr == ' ') - ; - else if (chr == '-') - neg = true; - else if (chr < '0' || chr > '9') - break; - else - ft = ft * 10 + ((int)chr - '0'); - } - if (neg) - ft *= -1; - if (chr == '\n') - { - CL_PlayDemoStream(f, NULL, name, DPB_NETQUAKE, 0); - return; - } - VFS_SEEK(f, start); - } -#endif - - //its not NQ then. must be QuakeWorld, either .qwd or .mvd - //could also be .qwz or .dmz or whatever that nq extension is. we don't support either. - - //mvd and qwd have no identifying markers, other than the extension. - if (!Q_strcasecmp(name + strlen(name) - 3, "mvd") || - !Q_strcasecmp(name + strlen(name) - 6, "mvd.gz")) - CL_PlayDemoStream(f, NULL, name, DPB_MVD, 0); - else - CL_PlayDemoStream(f, NULL, name, DPB_QUAKEWORLD, 0); + CL_PlayDemoFile(f, name); } /*used with qtv*/ @@ -1914,7 +1918,7 @@ void CL_QTVPoll (void) colon = ""; if (!strcmp(s, "PERROR")) - { //printable error + { //permanent printable error Con_Printf("QTV Error:\n%s\n", colon); } else if (!strcmp(s, "PRINT")) @@ -1922,7 +1926,7 @@ void CL_QTVPoll (void) Con_Printf("QTV:\n%s\n", colon); } else if (!strcmp(s, "TERROR")) - { //printable error + { //temporary printable error Con_Printf("QTV Error:\n%s\n", colon); } else if (!strcmp(s, "ADEMO")) diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index f17b12906..085524291 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -1543,6 +1543,10 @@ void SCR_DrawLoading (qboolean opaque) char *s; int qdepth; int h2depth; + + if (CSQC_UseGamecodeLoadingScreen()) + return; + //int mtype = M_GameType(); //unused variable y = vid.height/2; diff --git a/engine/client/client.h b/engine/client/client.h index 6b01888bb..3457d94c0 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -1213,6 +1213,7 @@ qboolean CSQC_ConsoleLink(char *text, char *info); void CSQC_RegisterCvarsAndThings(void); qboolean CSQC_SetupToRenderPortal(int entnum); qboolean CSQC_DrawView(void); +qboolean CSQC_UseGamecodeLoadingScreen(void); void CSQC_Shutdown(void); qboolean CSQC_StuffCmd(int lplayernum, char *cmd, char *cmdend); qboolean CSQC_LoadResource(char *resname, char *restype); @@ -1241,6 +1242,7 @@ void CSQC_CvarChanged(cvar_t *var); #else #define CSQC_UnconnectedOkay(inprinciple) false #define CSQC_UnconnectedInit() false +#define CSQC_UseGamecodeLoadingScreen() false #endif // diff --git a/engine/client/image.c b/engine/client/image.c index f03542ab0..d2d365bd7 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -3569,6 +3569,10 @@ static qboolean Image_GenMip0(struct pendingtextureinfo *mips, unsigned int flag case PTI_BGRA8: mips->encoding = PTI_RGBX8; break; + case PTI_RGBA16F: + case PTI_RGBA32F: + case PTI_ARGB4444: + case PTI_ARGB1555: case PTI_RGBA4444: case PTI_RGBA5551: break; //erk diff --git a/engine/client/m_items.c b/engine/client/m_items.c index 3ac1bfa31..142c8670e 100644 --- a/engine/client/m_items.c +++ b/engine/client/m_items.c @@ -124,10 +124,11 @@ void Draw_Hexen2BigFontString(int x, int y, const char *text) { unsigned int w = ((unsigned int*)file)[0]; unsigned int h = ((unsigned int*)file)[1]; - p->defaulttextures.base = R_LoadReplacementTexture("gfx/menu/bigfont.lmp", NULL, IF_NOPCX|IF_PREMULTIPLYALPHA|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP, (qbyte*)file+8, w, h, TF_H2_TRANS8_0); + if (8+w*h==fsize) + p->defaulttextures.base = R_LoadReplacementTexture("gfx/menu/bigfont.lmp", NULL, IF_NOPCX|IF_PREMULTIPLYALPHA|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP, (qbyte*)file+8, w, h, TF_H2_TRANS8_0); FS_FreeFile(file); //got image data } - else + if (!p->defaulttextures.base) p->defaulttextures.base = R_LoadHiResTexture("gfx/menu/bigfont.lmp", NULL, IF_PREMULTIPLYALPHA|IF_UIPIC|IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP); } diff --git a/engine/client/m_single.c b/engine/client/m_single.c index 9c727b94e..693dc2b21 100644 --- a/engine/client/m_single.c +++ b/engine/client/m_single.c @@ -714,7 +714,10 @@ static void ShowDemoMenu (menu_t *menu, const char *path) } if (info->fsroot == FS_SYSTEM) { - Q_snprintfz(match, sizeof(match), *info->path?"%s*":"/*", info->path); + if (info->path) + Q_snprintfz(match, sizeof(match), "%s*", info->path); + else + Q_snprintfz(match, sizeof(match), "/*"); Sys_EnumerateFiles("", match, DemoAddItem, info, NULL); } else diff --git a/engine/client/menu.c b/engine/client/menu.c index c25b1bd3f..12f03b0e0 100644 --- a/engine/client/menu.c +++ b/engine/client/menu.c @@ -1334,6 +1334,7 @@ void M_Draw (int uimenu) switch (m_state) { + default: case m_none: break; @@ -1371,6 +1372,7 @@ void M_Keydown (int key, int unicode) { switch (m_state) { + default: case m_none: Key_Dest_Remove(kdm_menu); return; diff --git a/engine/client/p_script.c b/engine/client/p_script.c index 76b7ad62f..ecbb5a43b 100644 --- a/engine/client/p_script.c +++ b/engine/client/p_script.c @@ -2023,9 +2023,19 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen) Q_strncatz(outstr, va("spawnorg %g %g\n", ptype->areaspread, ptype->areaspreadvert), outstrlen); if (ptype->veladd || ptype->randomveladd) - Q_strncatz(outstr, va(ptype->randomveladd?"veladd %g %g\n":"veladd %g\n", ptype->veladd, ptype->veladd+ptype->randomveladd), outstrlen); + { + if (ptype->randomveladd) + Q_strncatz(outstr, va("veladd %g %g\n", ptype->veladd, ptype->veladd+ptype->randomveladd), outstrlen); + else + Q_strncatz(outstr, va("veladd %g\n", ptype->veladd), outstrlen); + } if (ptype->orgadd || ptype->randomorgadd) - Q_strncatz(outstr, va(ptype->randomorgadd?"orgadd %g %g\n":"orgadd %g\n", ptype->orgadd, ptype->orgadd+ptype->randomorgadd), outstrlen); + { + if (ptype->randomorgadd) + Q_strncatz(outstr, va("orgadd %g %g\n", ptype->orgadd, ptype->orgadd+ptype->randomorgadd), outstrlen); + else + Q_strncatz(outstr, va("orgadd %g\n", ptype->orgadd), outstrlen); + } if (ptype->randomvel || ptype->randomvelvert || ptype->randomvelvertbias) Q_strncatz(outstr, va("randomvel %g %g %g\n", ptype->randomvel, ptype->randomvelvertbias - ptype->randomvelvert, ptype->randomvelvertbias + ptype->randomvelvert), outstrlen); diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index a26dd2941..0a8d947a6 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -101,7 +101,8 @@ extern sfx_t *cl_sfx_r_exp3; globalfunction(init_function, "CSQC_Init"); \ globalfunction(worldloaded, "CSQC_WorldLoaded"); \ globalfunction(shutdown_function, "CSQC_Shutdown"); \ - globalfunction(draw_function, "CSQC_UpdateView"); \ + globalfunction(f_updateview, "CSQC_UpdateView"); \ + globalfunction(f_updateviewloading, "CSQC_UpdateViewLoading"); \ globalfunction(parse_stuffcmd, "CSQC_Parse_StuffCmd"); \ globalfunction(parse_centerprint, "CSQC_Parse_CenterPrint"); \ globalfunction(parse_print, "CSQC_Parse_Print"); \ @@ -2791,6 +2792,8 @@ static void QCBUILTIN PF_cs_serverkey (pubprogfuncs_t *prinst, struct globalvars else ret = NET_AdrToString(adr, sizeof(adr), &cls.netchan.remote_address); } + else if (!strcmp(keyname, "servername")) + ret = cls.servername; else if (!strcmp(keyname, "constate")) { if (cls.state == ca_disconnected @@ -2804,6 +2807,36 @@ static void QCBUILTIN PF_cs_serverkey (pubprogfuncs_t *prinst, struct globalvars else ret = "connecting"; } + else if (!strcmp(keyname, "loadstate")) + { + extern int total_loading_size, current_loading_size, loading_stage; + extern char levelshotname[MAX_QPATH]; + ret = va("%i %u %u \"%s\"", loading_stage, current_loading_size, total_loading_size, levelshotname); + } + else if (!strcmp(keyname, "transferring")) + { + ret = CL_TryingToConnect(); + if (!ret) + ret = ""; + } + else if (!strcmp(keyname, "dlstate")) + { + if (!cl.downloadlist && !cls.download) + ret = ""; //nothing being downloaded right now + else + { + unsigned int fcount; + qofs_t tsize; + qboolean sizeextra; + CL_GetDownloadSizes(&fcount, &tsize, &sizeextra); + if (cls.download) //downloading something + ret = va("%u %g %u \"%s\" \"%s\" %g %i %g %g", fcount, (float)tsize, sizeextra?1u:0u, cls.download->localname, cls.download->remotename, cls.download->percent, cls.download->rate, (float)cls.download->completedbytes, (float)cls.download->size); + else //not downloading anything right now + ret = va("%u %g %u", fcount, (float)tsize, sizeextra?1u:0u); + } + } + else if (!strcmp(keyname, "pausestate")) + ret = cl.paused?"1":"0"; else if (!strcmp(keyname, "protocol")) { //using this is pretty acedemic, really. Not particuarly portable. switch (cls.protocol) @@ -5520,8 +5553,10 @@ qbyte *PDECL CSQC_PRLoadFile (const char *path, void *buffer, int bufsize, size_ return NULL; //not valid } +#ifndef FTE_TARGET_WEB //back it up COM_WriteFile(newname, file, *sz); +#endif } } @@ -6145,6 +6180,11 @@ void CSQC_CvarChanged(cvar_t *var) } } +qboolean CSQC_UseGamecodeLoadingScreen(void) +{ + return csqcprogs && csqcg.f_updateviewloading; +} + //evil evil function. calling qc from inside the renderer is BAD. qboolean CSQC_SetupToRenderPortal(int entkeynum) { @@ -6195,7 +6235,7 @@ qboolean CSQC_DrawView(void) csqc_resortfrags = true; csqctime = Sys_DoubleTime(); - if (!csqcg.draw_function || !csqcprogs) + if (!csqcg.f_updateview || !csqcprogs) return false; if (cls.state < ca_active && !CSQC_UnconnectedOkay(false)) @@ -6301,7 +6341,10 @@ qboolean CSQC_DrawView(void) G_FLOAT(OFS_PARM2) = !m_state; } //end EXT_CSQC_1 - PR_ExecuteProgram(csqcprogs, csqcg.draw_function); + if (csqcg.f_updateviewloading && cls.state && cls.state < ca_active) + PR_ExecuteProgram(csqcprogs, csqcg.f_updateviewloading); + else + PR_ExecuteProgram(csqcprogs, csqcg.f_updateview); return true; } diff --git a/engine/client/pr_skelobj.c b/engine/client/pr_skelobj.c index e7fd93465..85b29d566 100644 --- a/engine/client/pr_skelobj.c +++ b/engine/client/pr_skelobj.c @@ -834,7 +834,7 @@ void skel_generateragdoll_f(void) { char *modname = Cmd_Argv(1); char *outname; - model_t *mod = Mod_ForName(modname, false); + model_t *mod = Mod_ForName(modname, MLV_SILENT); galiasbone_t *bones; vfsfile_t *f; int i; diff --git a/engine/common/bspfile.h b/engine/common/bspfile.h index 37e708e64..81ec85a0b 100644 --- a/engine/common/bspfile.h +++ b/engine/common/bspfile.h @@ -413,15 +413,19 @@ typedef struct q2miptex_s // leaffaces, leafbrushes, planes, and verts are still bounded by // 16 bit short limits #define SANITY_MAX_Q2MAP_MODELS 1024 -#define MAX_Q2MAP_ENTITIES 2048 +//#define MAX_Q2MAP_ENTITIES 2048 #define SANITY_MAX_MAP_BRUSHES 0x10000 #define MAX_Q2MAP_AREAS 256 #define MAX_Q2MAP_AREAPORTALS 1024 -#define MAX_Q2MAP_VERTS MAX_MAP_VERTS -#define MAX_Q2MAP_FACES MAX_MAP_FACES +//#define MAX_Q2MAP_VERTS MAX_MAP_VERTS +//#define MAX_Q2MAP_FACES MAX_MAP_FACES #define SANITY_MAX_MAP_LEAFFACES 262144 //sanity only +#ifdef FTE_TARGET_WEB +#define MAX_Q2MAP_LEAFBRUSHES (32768) //used in an array +#else #define MAX_Q2MAP_LEAFBRUSHES (65536*2) //used in an array +#endif //#define MAX_Q2MAP_PORTALS 65536 //unused //#define MAX_Q2MAP_EDGES 128000 //unused //#define MAX_Q2MAP_SURFEDGES 256000 //unused diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index a75a4ea07..530cb2961 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -12,10 +12,14 @@ #define MAX_Q3MAP_INDICES 0x8000000 //just a sanity limit #define MAX_Q3MAP_VERTEXES 0x800000 //just a sanity limit -#define MAX_CM_PATCH_VERTS (4096) -#define MAX_CM_FACES (MAX_Q2MAP_FACES) -#define MAX_CM_PATCHES (0x10000) -#define MAX_CM_LEAFFACES (MAX_Q2MAP_LEAFFACES) +//#define MAX_CM_PATCH_VERTS (4096) +//#define MAX_CM_FACES (MAX_Q2MAP_FACES) +#ifdef FTE_TARGET_WEB +#define MAX_CM_PATCHES (0x1000) //fixme +#else +#define MAX_CM_PATCHES (0x10000) //fixme +#endif +//#define MAX_CM_LEAFFACES (MAX_Q2MAP_LEAFFACES) #define MAX_CM_AREAS MAX_Q2MAP_AREAS //#define Q3SURF_NODAMAGE 0x00000001 @@ -6296,9 +6300,9 @@ CM_WritePortalState Writes the portal state to a savegame file =================== */ -void CM_WritePortalState (FILE *f) +void CM_WritePortalState (vfsfile_t *f) { - fwrite (portalopen, sizeof(portalopen), 1, f); + VFS_WRITE(f, portalopen, sizeof(portalopen)); } /* @@ -6309,11 +6313,11 @@ Reads the portal state from a savegame file and recalculates the area connections =================== */ -void CM_ReadPortalState (FILE *f) +void CM_ReadPortalState (vfsfile_t *f) { size_t result; - result = fread (portalopen, 1, sizeof(portalopen), f); // do something with result + result = VFS_READ(f, portalopen, sizeof(portalopen)); // do something with result if (result != sizeof(portalopen)) Con_Printf("CM_ReadPortalState() fread: expected %lu, result was %u\n",(long unsigned int)sizeof(portalopen),(unsigned int)result); diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index a48199772..924720b4b 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -1605,11 +1605,11 @@ void QCBUILTIN PF_fopen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals break; case FRIK_FILE_READ: //read case FRIK_FILE_READNL: //read whole file - fsize = FS_LoadFile(pf_fopen_files[i].name, &pf_fopen_files[i].data); + fsize = FS_LoadFile(pf_fopen_files[i].name, (void**)&pf_fopen_files[i].data); if (!pf_fopen_files[i].data && fallbackread) { Q_strncpyz(pf_fopen_files[i].name, fallbackread, sizeof(pf_fopen_files[i].name)); - fsize = FS_LoadFile(pf_fopen_files[i].name, &pf_fopen_files[i].data); + fsize = FS_LoadFile(pf_fopen_files[i].name, (void**)&pf_fopen_files[i].data); } if (pf_fopen_files[i].data) @@ -3473,12 +3473,12 @@ void QCBUILTIN PF_buf_writefile (pubprogfuncs_t *prinst, struct globalvars_s *p G_FLOAT(OFS_RETURN) = 0; - if ((unsigned int)bufno >= NUMSTRINGBUFS) + if ((unsigned int)bufno >= (unsigned int)NUMSTRINGBUFS) return; if (strbuflist[bufno].prinst != prinst) return; - if (fnum < 0 || fnum >= MAX_QC_FILES) + if ((unsigned int)fnum >= (unsigned int)MAX_QC_FILES) return; if (pf_fopen_files[fnum].prinst != prinst) return; diff --git a/engine/gl/gl_shadow.c b/engine/gl/gl_shadow.c index 24488b130..d47087598 100644 --- a/engine/gl/gl_shadow.c +++ b/engine/gl/gl_shadow.c @@ -55,11 +55,7 @@ cvar_t r_shadow_scissor = CVAR("r_shadow_scissor", "1"); cvar_t r_shadow_realtime_world = CVARF ("r_shadow_realtime_world", "0", CVAR_ARCHIVE); cvar_t r_shadow_realtime_world_shadows = CVARF ("r_shadow_realtime_world_shadows", "1", CVAR_ARCHIVE); cvar_t r_shadow_realtime_world_lightmaps = CVARF ("r_shadow_realtime_world_lightmaps", "0", 0); -#ifdef FTE_TARGET_WEB -cvar_t r_shadow_realtime_dlight = CVARF ("r_shadow_realtime_dlight", "0", CVAR_ARCHIVE); -#else cvar_t r_shadow_realtime_dlight = CVARF ("r_shadow_realtime_dlight", "1", CVAR_ARCHIVE); -#endif cvar_t r_shadow_realtime_dlight_shadows = CVARF ("r_shadow_realtime_dlight_shadows", "1", CVAR_ARCHIVE); cvar_t r_shadow_realtime_dlight_ambient = CVAR ("r_shadow_realtime_dlight_ambient", "0"); cvar_t r_shadow_realtime_dlight_diffuse = CVAR ("r_shadow_realtime_dlight_diffuse", "1"); diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index fd32d8ff7..e9918af35 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -1218,6 +1218,7 @@ static void PDECL qclib_free(void *ptr) free(ptr); } #ifdef FTE_TARGET_WEB +#undef printf #define printf NULL //should be some null wrapper instead #endif diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 8c2b1247f..782104124 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -10496,6 +10496,7 @@ void PR_DumpPlatform_f(void) {"CSQC_WorldLoaded", "noref void()", CS, "Called after model+sound precaches have been executed. Gives a chance for the qc to read the entity lump from the bsp."}, {"CSQC_Shutdown", "noref void()", CS, "Specifies that the csqc is going down. Save your persistant settings here."}, {"CSQC_UpdateView", "noref void(float vwidth, float vheight, float notmenu)", CS, "Called every single video frame. The CSQC is responsible for rendering the entire screen."}, + {"CSQC_UpdateViewLoading", "noref void(float vwidth, float vheight, float notmenu)", CS, "Alternative to CSQC_UpdateView, called when the engine thinks there should be a loading screen. If present, will inhibit the engine's normal loading screen, deferring to qc to draw it."}, {"CSQC_Parse_StuffCmd", "noref void(string msg)", CS, "Gives the CSQC a chance to intercept stuffcmds. Use the tokenize builtin to parse the message. Unrecognised commands would normally be localcmded, but its probably better to drop unrecognised stuffcmds completely."}, {"CSQC_Parse_CenterPrint", "noref float(string msg)", CS, "Gives the CSQC a chance to intercept centerprints. Return true if you wish the engine to otherwise ignore the centerprint."}, {"CSQC_Parse_Print", "noref void(string printmsg, float printlvl)", CS, "Gives the CSQC a chance to intercept sprint/bprint builtin calls. CSQC should filter by the client's current msg setting and then pass the message on to the print command, or handle them itself."}, @@ -10683,6 +10684,15 @@ void PR_DumpPlatform_f(void) {"INFOKEY_P_VOIPSPEAKING","const string", CS, "Boolean value that says whether the given player is currently sending voice information.", 0, "\"voipspeaking\""}, {"INFOKEY_P_VOIPLOUDNESS","const string", CS, "Only valid for the local player. Gives a value between 0 and 1 to indicate to the user how loud their mic is.", 0, "\"voiploudness\""}, + {"SERVERKEY_IP", "const string", CS,"The address of the server we connected to.", 0, "\"ip\""}, + {"SERVERKEY_SERVERNAME","const string", CS,"The hostname that was last passed to the connect command.", 0, "\"servername\""}, + {"SERVERKEY_CONSTATE", "const string", CS,"The current connection state. Will be set to one of: disconnected (menu-only mode), active (gamestate received and loaded), connecting(connecting, downloading, or precaching content, aka: loading screen).", 0, "\"constate\""}, + {"SERVERKEY_TRANSFERRING","const string",CS,"Set to the hostname of the server that we are attempting to connect or transfer to.", 0, "\"transferring\""}, + {"SERVERKEY_LOADSTATE", "const string", CS, "loadstage, loading image name, current step, max steps\nStages are: 1=connecting, 2=serverside, 3=clientside\nKey will be empty if we are not loading.", 0, "\"loadstate\""}, + {"SERVERKEY_PAUSESTATE","const string", CS, "1 if the server claimed to be paused. 0 otherwise", 0, "\"pausestate\""}, + {"SERVERKEY_DLSTATE", "const string", CS, "The progress of any current downloads. Empty string if no download is active, otherwise a tokenizable string containing this info:\nfiles-remaining, total-size, unknown-sizes-flag, file-localname, file-remotename, file-percent, file-rate, file-received-bytes, file-total-bytes\nIf the current file info is omitted, then we are waiting for a download to start.", 0, "\"dlstate\""}, + {"SERVERKEY_PROTOCOL", "const string", CS, "The protocol we are connected to the server with.", 0, "\"protocol\""}, + // edict.flags {"FL_FLY", "const float", QW|NQ|CS, NULL, FL_FLY}, {"FL_SWIM", "const float", QW|NQ|CS, NULL, FL_SWIM}, diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 0721bd24e..c2bf7a759 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -922,13 +922,13 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us #if defined(Q2BSPS) if (usecinematic) { - qboolean QDECL Mod_LoadQ2BrushModel (model_t *mod, void *buffer); + qboolean QDECL Mod_LoadQ2BrushModel (model_t *mod, void *buffer, size_t fsize); Q_strncpyz (sv.name, server, sizeof(sv.name)); Q_strncpyz (sv.modelname, "", sizeof(sv.modelname)); sv.world.worldmodel = Mod_FindName (sv.modelname); - if (Mod_LoadQ2BrushModel (sv.world.worldmodel, NULL)) + if (Mod_LoadQ2BrushModel (sv.world.worldmodel, NULL, 0)) sv.world.worldmodel->loadstate = MLS_LOADED; else sv.world.worldmodel->loadstate = MLS_FAILED; diff --git a/engine/web/ftejslib.h b/engine/web/ftejslib.h index ce9611cf4..c41ebc952 100644 --- a/engine/web/ftejslib.h +++ b/engine/web/ftejslib.h @@ -40,6 +40,7 @@ int emscriptenfte_setupcanvas( int(*Keyboard)(int devid, int down, int keycode, int unicode), void(*LoadFile)(char *newhash, int filehandle), void(*buttonevent)(int joydev, int button, int ispressed), - void(*axisevent)(int joydev, int axis, float value) + void(*axisevent)(int joydev, int axis, float value), + int (*ShouldSwitchToFullscreen)(void) ); diff --git a/engine/web/ftejslib.js b/engine/web/ftejslib.js index 7cabd3555..84e4a038e 100644 --- a/engine/web/ftejslib.js +++ b/engine/web/ftejslib.js @@ -66,7 +66,12 @@ mergeInto(LibraryManager.library, evcb: { resize:0, mouse:0, - key:0 + button:0, + key:0, + loadfile:0, + jbutton:0, + jaxis:0, + wantfullscreen:0 }, loadurl : function(url, arraybuf) @@ -114,6 +119,8 @@ mergeInto(LibraryManager.library, break; case 'mousedown': if (Browser.isFullScreen == 0) + if (FTEC.evcb.wantfullscreen != 0) + if (Runtime.dynCall('i', FTEC.evcb.wantfullscreen, [])) { Browser.requestFullScreen(true, true); Module['canvas'].requestPointerLock(); @@ -143,8 +150,10 @@ mergeInto(LibraryManager.library, case 'keypress': if (FTEC.evcb.key != 0) { - Runtime.dynCall('viiii', FTEC.evcb.key, [0, 1, 0, event.charCode]); - Runtime.dynCall('viiii', FTEC.evcb.key, [0, 0, 0, event.charCode]); + if (event.charCode >= 122 && event.charCode <= 123) //no f11/f12 + break; + Runtime.dynCall('iiiii', FTEC.evcb.key, [0, 1, 0, event.charCode]); + Runtime.dynCall('iiiii', FTEC.evcb.key, [0, 0, 0, event.charCode]); event.preventDefault(); } break; @@ -264,7 +273,7 @@ mergeInto(LibraryManager.library, } }, emscriptenfte_setupcanvas__deps: ['$FTEC', '$Browser', 'emscriptenfte_buf_createfromarraybuf'], - emscriptenfte_setupcanvas : function(nw,nh,evresize,evmouse,evmbutton,evkey,evfile,evjbutton,evjaxis) + emscriptenfte_setupcanvas : function(nw,nh,evresize,evmouse,evmbutton,evkey,evfile,evjbutton,evjaxis,evwantfullscreen) { FTEC.evcb.resize = evresize; FTEC.evcb.mouse = evmouse; @@ -273,6 +282,7 @@ mergeInto(LibraryManager.library, FTEC.evcb.loadfile = evfile; FTEC.evcb.jbutton = evjbutton; FTEC.evcb.jaxis = evjaxis; + FTEC.evcb.wantfullscreen = evwantfullscreen; if ('GamepadEvent' in window) FTEH.gamepads = []; //don't bother ever trying to poll if we can use gamepad events. this will hopefully avoid weirdness. @@ -327,6 +337,11 @@ mergeInto(LibraryManager.library, }; window.onresize(); + if (evmouse) + Module.canvas.style.cursor = "none"; //hide the cursor, we'll do a soft-cursor when one is needed. + else + Module.canvas.style.cursor = "default"; //restore the cursor + if (FTEC.evcb.hashchange) { window.onhashchange = function() diff --git a/engine/web/gl_vidweb.c b/engine/web/gl_vidweb.c index 226553d7a..dfbc7940d 100644 --- a/engine/web/gl_vidweb.c +++ b/engine/web/gl_vidweb.c @@ -172,6 +172,11 @@ void DOM_LoadFile(char *loc, int handle) VFS_CLOSE(file); } } +int VID_ShouldSwitchToFullscreen(void) +{ //if false, mouse grabs won't work and we'll be forced to touchscreen mode. + extern cvar_t vid_fullscreen; + return !!vid_fullscreen.value; +} qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) { vid_isfullscreen = true; @@ -185,7 +190,8 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) DOM_KeyEvent, DOM_LoadFile, IN_JoystickButtonEvent, - IN_JoystickAxisEvent + IN_JoystickAxisEvent, + VID_ShouldSwitchToFullscreen )) { Con_Printf("Couldn't set up canvas\n"); @@ -209,7 +215,7 @@ void GLVID_DeInit (void) { ActiveApp = false; - emscriptenfte_setupcanvas(-1, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + emscriptenfte_setupcanvas(-1, -1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } diff --git a/engine/web/sys_web.c b/engine/web/sys_web.c index a1cfc49d5..6e32a627f 100644 --- a/engine/web/sys_web.c +++ b/engine/web/sys_web.c @@ -100,9 +100,17 @@ qboolean Sys_Rename (char *oldfname, char *newfname) } //someone used the 'quit' command +#include "glquake.h" void Sys_Quit (void) { - Host_Shutdown(); + if (host_initialized) + { + qglClearColor(0,0,0,1); + qglClear(GL_COLOR_BUFFER_BIT); + Draw_FunString (0, 0, "Reload the page to restart"); + + Host_Shutdown(); + } exit (0); } @@ -110,7 +118,7 @@ void Sys_Quit (void) int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, qofs_t, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath) { Con_DPrintf("Warning: Sys_EnumerateFiles not implemented\n"); - return false; + return true; } //blink window if possible (it's not) @@ -136,6 +144,12 @@ void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname) void Sys_Init(void) { + extern cvar_t vid_width, vid_height, vid_fullscreen; + //vid_fullscreen takes effect only on mouse clicks, any suggestion to do a vid_restart is pointless. + vid_fullscreen.flags &= CVAR_RENDERERLATCH; + //these are not really supported. so silence any spam that suggests we do something about something not even supported. + vid_width.flags &= CVAR_RENDERERLATCH; + vid_height.flags &= CVAR_RENDERERLATCH; } void Sys_Shutdown(void) {