From 80474cc3be71f4c3950f04f37d249db14c3d1097 Mon Sep 17 00:00:00 2001 From: Spoike Date: Sat, 16 May 2020 13:12:58 +0000 Subject: [PATCH] Fix web+android targets. Fix some relatively recent quake2 bugs. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5695 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/m_download.c | 51 ++++++---- engine/client/merged.h | 2 +- engine/client/vr.h | 17 +--- engine/common/fs.c | 19 ++++ engine/gl/gl_rmain.c | 131 +++++++++++++------------ engine/gl/gl_viddroid.c | 2 +- engine/gl/r_bishaders.h | 2 + engine/server/sv_user.c | 50 +++++----- engine/server/svq2_game.c | 2 +- engine/shaders/glsl/defaultskybox.glsl | 10 +- 10 files changed, 162 insertions(+), 124 deletions(-) diff --git a/engine/client/m_download.c b/engine/client/m_download.c index 1c42d07a..d5f864c4 100644 --- a/engine/client/m_download.c +++ b/engine/client/m_download.c @@ -3468,6 +3468,17 @@ static void PM_PromptApplyChanges(void) } } #endif +#ifdef HAVE_CLIENT +static void PM_AddSubList_Callback(void *ctx, promptbutton_t opt) +{ + if (opt == PROMPT_YES) + { + PM_AddSubList(ctx, "", true, true); + PM_WriteInstalledPackages(); + } + Z_Free(ctx); +} +#endif //names packages that were listed from the manifest. //if 'mark' is true, then this is an initial install. @@ -3537,27 +3548,31 @@ void PM_Command_f(void) if (!strcmp(act, "sources") || !strcmp(act, "addsource")) { -#ifdef WEBCLIENT - if (Cmd_Argc() == 2) - { - int i; - for (i = 0; i < numdownloadablelists; i++) - Con_Printf("%s %s\n", downloadablelist[i].url, downloadablelist[i].save?"(explicit)":"(implicit)"); - Con_Printf("<%i sources>\n", numdownloadablelists); - } - else - { - PM_AddSubList(Cmd_Argv(2), "", true, true); - PM_WriteInstalledPackages(); - } -#endif + #ifdef WEBCLIENT + if (Cmd_Argc() == 2) + { + int i; + for (i = 0; i < numdownloadablelists; i++) + Con_Printf("%s %s\n", downloadablelist[i].url, downloadablelist[i].save?"(explicit)":"(implicit)"); + Con_Printf("<%i sources>\n", numdownloadablelists); + } + else + { + #ifdef HAVE_CLIENT + Menu_Prompt(PM_AddSubList_Callback, Z_StrDup(Cmd_Argv(2)), va("Add updates source?\n%s", Cmd_Argv(2)), "Confirm", NULL, "Cancel"); + #else + PM_AddSubList(Cmd_Argv(2), "", true, true); + PM_WriteInstalledPackages(); + #endif + } + #endif } else if (!strcmp(act, "remsource")) { -#ifdef WEBCLIENT - PM_RemSubList(Cmd_Argv(2)); - PM_WriteInstalledPackages(); -#endif + #ifdef WEBCLIENT + PM_RemSubList(Cmd_Argv(2)); + PM_WriteInstalledPackages(); + #endif } else { diff --git a/engine/client/merged.h b/engine/client/merged.h index 34573a5e..6c0bd97e 100644 --- a/engine/client/merged.h +++ b/engine/client/merged.h @@ -4,7 +4,7 @@ #ifdef VKQUAKE //we need some types available elsewhere, but don't really want to have to include the entire vulkan api everywhere. //unfortunately, vulkan's handle types are not well defined. -#if defined(__LP64__) || defined(_WIN64) +#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__) #define VulkanAPIRandomness void* #elif defined(_MSC_VER) && _MSC_VER < 1300 #define VulkanAPIRandomness __int64 diff --git a/engine/client/vr.h b/engine/client/vr.h index 8f804ead..30f7af5d 100644 --- a/engine/client/vr.h +++ b/engine/client/vr.h @@ -57,19 +57,10 @@ typedef struct vrsetup_s } d3d; struct - { //sometimes pointers, sometimes ints. nasty datatypes that suck. this is hideous. -#ifndef VulkanAPIRandomness - #if defined(__LP64__) || defined(_WIN64) - #define VulkanAPIRandomness void* - #elif defined(_MSC_VER) && _MSC_VER < 1300 - #define VulkanAPIRandomness __int64 - #else - #define VulkanAPIRandomness long long - #endif -#endif - VulkanAPIRandomness instance; - VulkanAPIRandomness physicaldevice; - VulkanAPIRandomness device; + { //these are ALWAYS pointers in vulkan (annoyingly unlike many of its typedefs). + void *instance; + void *physicaldevice; + void *device; unsigned int queuefamily; unsigned int queueindex; } vk; diff --git a/engine/common/fs.c b/engine/common/fs.c index d436444b..e9aabe3f 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -702,6 +702,25 @@ static qboolean FS_Manifest_ParseTokens(ftemanifest_t *man) { int i; char *newdir = Cmd_Argv(1); + qboolean basegame = !Q_strcasecmp(cmd, "basegame"); + + for (i = 0; i < sizeof(man->gamepath) / sizeof(man->gamepath[0]); i++) + { + if (man->gamepath[i].path) + { + if (!Q_strcasecmp(man->gamepath[i].path, newdir)) + { + if (basegame && !(man->gamepath[i].flags & GAMEDIR_BASEGAME)) + { + Z_Free(man->gamepath[i].path); + man->gamepath[i].path = NULL; //if we're adding a basegame when there's a mod game with the same name then drop the redundant mod name + man->gamepath[i].flags = 0; + } + else + return true; //already in there, don't add a conflicting one. + } + } + } for (i = 0; i < sizeof(man->gamepath) / sizeof(man->gamepath[0]); i++) { diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 40e6498b..90abc08a 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -435,7 +435,7 @@ void R_RotateForEntity (float *m, float *modelview, const entity_t *e, const mod R_SetupGL ============= */ -static void R_SetupGL (vec3_t axisorigin[4], vec4_t fovoverrides, texid_t fbo) +static void R_SetupGL (vec3_t axisorigin[4], vec4_t fovoverrides, float projmatrix[16]/*for webvr*/, texid_t fbo) { int x, x2, y2, y, w, h; vec3_t newa; @@ -559,67 +559,56 @@ static void R_SetupGL (vec3_t axisorigin[4], vec4_t fovoverrides, texid_t fbo) r_refdef.pxrect.maxheight = vid.fbpheight; } - if (fovoverrides) + if (projmatrix) { - fov_l = fovoverrides[0]; - fov_r = fovoverrides[1]; - fov_d = fovoverrides[2]; - fov_u = fovoverrides[3]; - - fov_x = fov_r-fov_l; - fov_y = fov_u-fov_d; - - fovv_x = fov_x; - fovv_y = fov_y; - r_refdef.flipcull = ((fov_u < fov_d)^(fov_r < fov_l))?SHADER_CULL_FLIP:0; + memcpy(r_refdef.m_projection_std, projmatrix, sizeof(r_refdef.m_projection_std)); + memcpy(r_refdef.m_projection_view, projmatrix, sizeof(r_refdef.m_projection_view)); + r_refdef.flipcull = 0; } else { - fov_x = r_refdef.fov_x; - fov_y = r_refdef.fov_y; - fovv_x = r_refdef.fovv_x; - fovv_y = r_refdef.fovv_y; - - if ((*r_refdef.rt_destcolour[0].texname || *r_refdef.rt_depth.texname) && strcmp(r_refdef.rt_destcolour[0].texname, "megascreeny")) + if (fovoverrides) { - r_refdef.pxrect.y = r_refdef.pxrect.maxheight - (r_refdef.pxrect.height+r_refdef.pxrect.y); - fov_y *= -1; - fovv_y *= -1; - r_refdef.flipcull ^= SHADER_CULL_FLIP; + fov_l = fovoverrides[0]; + fov_r = fovoverrides[1]; + fov_d = fovoverrides[2]; + fov_u = fovoverrides[3]; + + fov_x = fov_r-fov_l; + fov_y = fov_u-fov_d; + + fovv_x = fov_x; + fovv_y = fov_y; + r_refdef.flipcull = ((fov_u < fov_d)^(fov_r < fov_l))?SHADER_CULL_FLIP:0; } - else if ((r_refdef.flags & RDF_UNDERWATER) && !(r_refdef.flags & RDF_WATERWARP)) + else { - fov_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value); - fov_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value); + fov_x = r_refdef.fov_x; + fov_y = r_refdef.fov_y; + fovv_x = r_refdef.fovv_x; + fovv_y = r_refdef.fovv_y; - fovv_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value); - fovv_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value); + if ((*r_refdef.rt_destcolour[0].texname || *r_refdef.rt_depth.texname) && strcmp(r_refdef.rt_destcolour[0].texname, "megascreeny")) + { + r_refdef.pxrect.y = r_refdef.pxrect.maxheight - (r_refdef.pxrect.height+r_refdef.pxrect.y); + fov_y *= -1; + fovv_y *= -1; + r_refdef.flipcull ^= SHADER_CULL_FLIP; + } + else if ((r_refdef.flags & RDF_UNDERWATER) && !(r_refdef.flags & RDF_WATERWARP)) + { + fov_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value); + fov_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value); + + fovv_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value); + fovv_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value); + } + fov_l = -fov_x / 2; + fov_r = fov_x / 2; + fov_d = -fov_y / 2; + fov_u = fov_y / 2; } - fov_l = -fov_x / 2; - fov_r = fov_x / 2; - fov_d = -fov_y / 2; - fov_u = fov_y / 2; - } - GL_ViewportUpdate(); - -#ifdef FTE_TARGET_WEB - if (r_refdef.stereomethod == STEREO_WEBVR) - { - float vm[16], em[16]; - emscriptenfte_getvreyedata(i, r_refdef.m_projection_std, em); - memcpy(r_refdef.m_projection_view, r_refdef.m_projection_std, sizeof(r_refdef.m_projection_view)); - Matrix4x4_Identity(em); - - Matrix4x4_CM_ModelViewMatrixFromAxis(vm, vpn, vright, vup, r_origin); - Matrix4_Multiply(vm, em, r_refdef.m_view); - //fixme: read the axis+org back out... - -// Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, vpn, vright, vup, r_origin); - } - else -#endif - { if (r_refdef.useperspective) { int stencilshadows = Sh_StencilShadowsActive(); @@ -652,14 +641,16 @@ static void R_SetupGL (vec3_t axisorigin[4], vec4_t fovoverrides, texid_t fbo) } Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, vpn, vright, vup, r_origin); - - r_refdef.m_projection_view[2+4*0] *= 0.333; - r_refdef.m_projection_view[2+4*1] *= 0.333; - r_refdef.m_projection_view[2+4*2] *= 0.333; - r_refdef.m_projection_view[2+4*3] *= 0.333; - r_refdef.m_projection_view[14] -= 0.666; - //FIXME: bias, so that we use -1 to -.333 range instead of -.333 to 0.333 } + + //bias the viewmodel depth range to a third: -1 through -0.333 (instead of -1 to 1) + r_refdef.m_projection_view[2+4*0] *= 0.333; + r_refdef.m_projection_view[2+4*1] *= 0.333; + r_refdef.m_projection_view[2+4*2] *= 0.333; + r_refdef.m_projection_view[2+4*3] *= 0.333; + r_refdef.m_projection_view[14] -= 0.666; + + GL_ViewportUpdate(); } if (qglLoadMatrixf) @@ -754,7 +745,7 @@ static void R_RenderEyeScene (texid_t rendertarget, vec4_t fovoverride, vec3_t a vid.fbpheight = rendertarget->height; } - R_SetupGL (axisorigin, fovoverride, rendertarget); + R_SetupGL (axisorigin, fovoverride, NULL, rendertarget); R_RenderScene_Internal(); if (rendertarget) @@ -811,9 +802,25 @@ static void R_RenderScene (void) qglClear (GL_DEPTH_BUFFER_BIT); r_framecount++; - R_SetupGL (NULL, NULL, NULL); + R_SetupGL (NULL, NULL, NULL, NULL); R_RenderScene_Internal(); } +#ifdef FTE_TARGET_WEB + else if (r_refdef.stereomethod == STEREO_WEBVR) + { + float projmatrix[16], eyematrix[16]; + GL_ForceDepthWritable(); + qglClear (GL_DEPTH_BUFFER_BIT); + r_framecount++; + + for (i = 0; i < stereoframes; i++) + { + emscriptenfte_getvreyedata(i, projmatrix, eyematrix); + R_SetupGL (eyematrix, NULL, projmatrix, NULL); + R_RenderScene_Internal(); + } + } +#endif else for (i = 0; i < stereoframes; i++) { switch (stereomode) @@ -880,7 +887,7 @@ static void R_RenderScene (void) axisorg[3][0] = 0; axisorg[3][1] = stereooffset[i]; axisorg[3][2] = 0; - R_SetupGL (axisorg, NULL, NULL); + R_SetupGL (axisorg, NULL, NULL, NULL); R_RenderScene_Internal (); } diff --git a/engine/gl/gl_viddroid.c b/engine/gl/gl_viddroid.c index db0485e3..ebc057b0 100644 --- a/engine/gl/gl_viddroid.c +++ b/engine/gl/gl_viddroid.c @@ -311,7 +311,7 @@ void VID_Register(void) gles1rendererinfo.description = "OpenGL ES 1"; memset(&gles1rendererinfo.name, 0, sizeof(gles1rendererinfo.name)); //make sure there's no 'gl' etc names. gles1rendererinfo.name[0] = "gles1"; - R_RegisterRenderer(&gles1rendererinfo); + R_RegisterRenderer(NULL, &gles1rendererinfo); } diff --git a/engine/gl/r_bishaders.h b/engine/gl/r_bishaders.h index cd3684f7..ae2ef9ec 100644 --- a/engine/gl/r_bishaders.h +++ b/engine/gl/r_bishaders.h @@ -4652,11 +4652,13 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "vec4 skybox = textureCube(s_reflectcube, pos);\n" //Fun question: should sky be fogged as if infinite, or as if an actual surface? +"#ifdef FOG\n" "#if 1\n" "skybox.rgb = mix(skybox.rgb, w_fogcolour_ float(r_skyfog)*w_fogalpha); //flat fog ignoring actual geometry\n" "#else\n" "skybox.rgb = mix(skybox.rgb, fog3(skybox.rgb), float(r_skyfog)); //fog in terms of actual geometry distance\n" "#endif\n" +"#endif\n" "gl_FragColor = skybox;\n" "}\n" "#endif\n" diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index c4ce2c74..8fbc153b 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -2066,21 +2066,24 @@ void SV_Begin_Core(client_t *split) if (split->spawned) { - //NEH_RESTOREGAME - //officially RestoreGame tells the mod when the game has been loaded. - //this allows mods to send any stuffcmds the client will have forgotten. - //the original intention would not have been client-specific (and indeed nehahra only saves in singleplayer) - //doing it elsewhere unfortunately results in race conditions. - func_t f = PR_FindFunction(svprogfuncs, "RestoreGame", PR_ANY); - if (f) + if (svprogfuncs) { - pr_global_struct->time = sv.world.physicstime; - pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict); - PR_ExecuteProgram (svprogfuncs, f); - } + //NEH_RESTOREGAME + //officially RestoreGame tells the mod when the game has been loaded. + //this allows mods to send any stuffcmds the client will have forgotten. + //the original intention would not have been client-specific (and indeed nehahra only saves in singleplayer) + //doing it elsewhere unfortunately results in race conditions. + func_t f = PR_FindFunction(svprogfuncs, "RestoreGame", PR_ANY); + if (f) + { + pr_global_struct->time = sv.world.physicstime; + pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict); + PR_ExecuteProgram (svprogfuncs, f); + } - SV_SendFixAngle(split, NULL, FIXANGLE_FIXED, false); - split->edict->v->fixangle = FIXANGLE_NO; //no point doing it again + SV_SendFixAngle(split, NULL, FIXANGLE_FIXED, false); + split->edict->v->fixangle = FIXANGLE_NO; //no point doing it again + } return; } split->spawned = true; @@ -2248,20 +2251,19 @@ void SV_Begin_Core(client_t *split) } } } - } + SV_SendFixAngle(split, NULL, FIXANGLE_FIXED, false); + split->edict->v->fixangle = FIXANGLE_NO; //no point doing it again #ifdef HAVE_LEGACY - split->dp_ping = NULL; - split->dp_pl = NULL; - if (progstype == PROG_NQ) - { - split->dp_ping = (float*)sv.world.progs->GetEdictFieldValue(sv.world.progs, split->edict, "ping", ev_float, NULL); - split->dp_pl = (float*)sv.world.progs->GetEdictFieldValue(sv.world.progs, split->edict, "ping_packetloss", ev_float, NULL); - } + split->dp_ping = NULL; + split->dp_pl = NULL; + if (progstype == PROG_NQ) + { + split->dp_ping = (float*)sv.world.progs->GetEdictFieldValue(sv.world.progs, split->edict, "ping", ev_float, NULL); + split->dp_pl = (float*)sv.world.progs->GetEdictFieldValue(sv.world.progs, split->edict, "ping_packetloss", ev_float, NULL); + } #endif - - SV_SendFixAngle(split, NULL, FIXANGLE_FIXED, false); - split->edict->v->fixangle = FIXANGLE_NO; //no point doing it again + } } /* diff --git a/engine/server/svq2_game.c b/engine/server/svq2_game.c index 3e45e296..6738d082 100644 --- a/engine/server/svq2_game.c +++ b/engine/server/svq2_game.c @@ -343,7 +343,7 @@ static int SVQ2_FindIndex (const char *name, int start, int max, int overflowtyp case 1: overflowstrings = sv.strings.q2_extramodels; max = countof(sv.strings.q2_extramodels); - i++; //do not allow 255 to be allocated, ever. just live with the gap. + i++; //do not allow 255 to be allocated, ever. just live with the gap (255 means special things). start = 0x8000; break; case 2: diff --git a/engine/shaders/glsl/defaultskybox.glsl b/engine/shaders/glsl/defaultskybox.glsl index dfe236f2..a15a5d34 100644 --- a/engine/shaders/glsl/defaultskybox.glsl +++ b/engine/shaders/glsl/defaultskybox.glsl @@ -37,10 +37,12 @@ void main () vec4 skybox = textureCube(s_reflectcube, pos); //Fun question: should sky be fogged as if infinite, or as if an actual surface? -#if 1 - skybox.rgb = mix(skybox.rgb, w_fogcolour_ float(r_skyfog)*w_fogalpha); //flat fog ignoring actual geometry -#else - skybox.rgb = mix(skybox.rgb, fog3(skybox.rgb), float(r_skyfog)); //fog in terms of actual geometry distance +#ifdef FOG + #if 1 + skybox.rgb = mix(skybox.rgb, w_fogcolour_ float(r_skyfog)*w_fogalpha); //flat fog ignoring actual geometry + #else + skybox.rgb = mix(skybox.rgb, fog3(skybox.rgb), float(r_skyfog)); //fog in terms of actual geometry distance + #endif #endif gl_FragColor = skybox; }