From 904a7012817a4e9c0c5b3ba6f8d584aeb13c5478 Mon Sep 17 00:00:00 2001 From: Spoike Date: Tue, 4 Jul 2017 05:07:51 +0000 Subject: [PATCH] command argument completion for a few commands. fix off-by-one pvs bug. add another settings preset. fix classic particles colour issue. fix d3d9 renderer's scissoring (including splitscreen huds) git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5125 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_demo.c | 16 + engine/client/cl_main.c | 10 +- engine/client/cl_screen.c | 7 +- engine/client/client.h | 1 + engine/client/in_generic.c | 6 +- engine/client/keys.c | 116 +- engine/client/m_options.c | 44 +- engine/client/r_surf.c | 11 +- engine/client/renderer.c | 8 +- engine/client/sbar.c | 23 +- engine/client/view.c | 4 +- engine/common/cmd.c | 118 +- engine/common/cmd.h | 7 + engine/common/q1bsp.c | 3 +- engine/common/world.h | 1 + engine/d3d/d3d_backend.c | 5 +- engine/dotnet2005/ftequake.vcproj | 1380 ++++++++++++------------ engine/gl/gl_backend.c | 15 +- engine/gl/gl_model.c | 7 +- engine/gl/gl_shader.c | 3 +- engine/gl/r_bishaders.h | 4 +- engine/server/pr_cmds.c | 34 +- engine/server/savegame.c | 32 + engine/server/server.h | 2 + engine/server/sv_ccmds.c | 39 +- engine/server/sv_init.c | 5 +- engine/server/sv_main.c | 15 +- engine/server/sv_user.c | 5 +- engine/shaders/glsl/defaultsprite.glsl | 4 +- engine/vk/vk_backend.c | 2 +- engine/vk/vk_init.c | 2 +- 31 files changed, 1087 insertions(+), 842 deletions(-) diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 4c2780188..cb866285d 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -1975,6 +1975,22 @@ void CL_Record_f (void) } } +static int QDECL CompleteDemoList (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath) +{ + struct xcommandargcompletioncb_s *ctx = parm; + ctx->cb(name, ctx); + return true; +} +void CL_DemoList_c(int argn, char *partial, struct xcommandargcompletioncb_s *ctx) +{ + if (argn == 1) + { + COM_EnumerateFiles(va("%s*.qwd", partial), CompleteDemoList, ctx); + COM_EnumerateFiles(va("%s*.dem", partial), CompleteDemoList, ctx); + COM_EnumerateFiles(va("%s*.mvd", partial), CompleteDemoList, ctx); + COM_EnumerateFiles(va("%s*.mvd.gz", partial), CompleteDemoList, ctx); + } +} /* ==================== CL_ReRecord_f diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index ba62287da..8d275ebe5 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -4254,15 +4254,15 @@ void CL_Init (void) Cmd_AddCommandD ("changing", CL_Changing_f, "Part of network protocols. This command should not be used manually."); Cmd_AddCommand ("disconnect", CL_Disconnect_f); - Cmd_AddCommand ("record", CL_Record_f); - Cmd_AddCommand ("rerecord", CL_ReRecord_f); - Cmd_AddCommand ("stop", CL_Stop_f); - Cmd_AddCommand ("playdemo", CL_PlayDemo_f); + Cmd_AddCommandAD ("record", CL_Record_f, CL_DemoList_c, NULL); + Cmd_AddCommandAD ("rerecord", CL_ReRecord_f, CL_DemoList_c, "Reconnects to the previous/current server, but starts recording a clean demo."); + Cmd_AddCommandD ("stop", CL_Stop_f, "Stop demo recording."); + Cmd_AddCommandAD ("playdemo", CL_PlayDemo_f, CL_DemoList_c, NULL); Cmd_AddCommand ("qtvplay", CL_QTVPlay_f); Cmd_AddCommand ("qtvlist", CL_QTVList_f); Cmd_AddCommand ("qtvdemos", CL_QTVDemos_f); Cmd_AddCommandD ("demo_jump", CL_DemoJump_f, "Jump to a specified time in a demo. Prefix with a + or - for a relative offset. Seeking backwards will restart the demo and the fast forward, which can take some time in long demos."); - Cmd_AddCommand ("timedemo", CL_TimeDemo_f); + Cmd_AddCommandAD ("timedemo", CL_TimeDemo_f, CL_DemoList_c, NULL); Cmd_AddCommand ("crashme_endgame", CL_CrashMeEndgame_f); Cmd_AddCommandD ("showpic", SCR_ShowPic_Script_f, "showpic [width] [height] [touchcommand]\nDisplays an image onscreen, that potentially has a key binding attached to it when clicked/touched.\nzone should be one of: TL, TR, BL, BR, MM, TM, BM, ML, MR. This serves as an extra offset to move the image around the screen without any foreknowledge of the screen resolution."); diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index f717d77fc..f9d6d2426 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -1945,9 +1945,12 @@ void SCR_ImageName (const char *mapname) if (!scr_disabled_for_loading) { - Sbar_Changed (); scr_drawloading = true; - SCR_UpdateScreen (); + if (qrenderer != QR_NONE) + { + Sbar_Changed (); + SCR_UpdateScreen (); + } scr_drawloading = false; scr_disabled_for_loading = true; } diff --git a/engine/client/client.h b/engine/client/client.h index 13c149997..a4eca133e 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -1195,6 +1195,7 @@ void CL_WriteRecordQ2DemoMessage(sizebuf_t *msg); void CL_Stop_f (void); void CL_Record_f (void); void CL_ReRecord_f (void); +void CL_DemoList_c(int argn, char *partial, struct xcommandargcompletioncb_s *ctx); void CL_PlayDemo_f (void); void CL_QTVPlay_f (void); void CL_QTVPoll (void); diff --git a/engine/client/in_generic.c b/engine/client/in_generic.c index 081659160..09e1e48bd 100644 --- a/engine/client/in_generic.c +++ b/engine/client/in_generic.c @@ -759,10 +759,10 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame } #ifdef QUAKESTATS - if (cl.playerview[pnum].stats[STAT_VIEWZOOM]) + if (cl.playerview[pnum].statsf[STAT_VIEWZOOM]) { - mouse_x *= cl.playerview[pnum].stats[STAT_VIEWZOOM]/255.0f; - mouse_y *= cl.playerview[pnum].stats[STAT_VIEWZOOM]/255.0f; + mouse_x *= cl.playerview[pnum].statsf[STAT_VIEWZOOM]/255.0f; + mouse_y *= cl.playerview[pnum].statsf[STAT_VIEWZOOM]/255.0f; } #endif diff --git a/engine/client/keys.c b/engine/client/keys.c index 7b76b134a..5bd8a3182 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -345,66 +345,63 @@ void CompleteCommand (qboolean force) const char *desc; s = key_lines[edit_line]; + if (*s == ' ' || *s == '\t') + s++; if (*s == '\\' || *s == '/') s++; + if (*s == ' ' || *s == '\t') + s++; - for (cmd = s; *cmd; cmd++) + //check for singular matches and complete if found + cmd = force?NULL:Cmd_CompleteCommand (s, true, true, 2, NULL); + if (!cmd) { - if (*cmd == ' ' || *cmd == '\t') - break; - } - if (*cmd) - cmd = s; - else - { - //check for singular matches and complete if found - cmd = force?NULL:Cmd_CompleteCommand (s, true, true, 2, NULL); - if (!cmd) - { - if (!force) - cmd = Cmd_CompleteCommand (s, false, true, 1, &desc); - else - cmd = Cmd_CompleteCommand (s, true, true, con_commandmatch, &desc); - if (cmd) - { - //complete to that (maybe partial) cmd. - Key_ClearTyping(); - Key_ConsoleInsert("/"); - Key_ConsoleInsert(cmd); - s = key_lines[edit_line]+1; - - //if its the only match, add a space ready for arguments. - cmd = Cmd_CompleteCommand (s, true, true, 0, NULL); - if (cmd && !strcmp(s, cmd)) - { - Key_ConsoleInsert(" "); - } - - if (!con_commandmatch) - con_commandmatch = 1; - - if (desc) - Con_Footerf(NULL, false, "%s: %s", cmd, desc); - else - Con_Footerf(NULL, false, ""); - return; - } - } - //complete to a partial match. - cmd = Cmd_CompleteCommand (s, false, true, 0, &desc); + if (!force) + cmd = Cmd_CompleteCommand (s, false, true, 1, &desc); + else + cmd = Cmd_CompleteCommand (s, true, true, con_commandmatch, &desc); if (cmd) { - int i = key_lines[edit_line][0] == '/'?1:0; - if (i != 1 || strcmp(key_lines[edit_line]+i, cmd)) - { //if successful, use that instead. - Key_ClearTyping(); - Key_ConsoleInsert("/"); - Key_ConsoleInsert(cmd); + if (strlen(cmd) < strlen(s)) + return; - s = key_lines[edit_line]; //readjust to cope with the insertion of a / - if (*s == '\\' || *s == '/') - s++; + //complete to that (maybe partial) cmd. + Key_ClearTyping(); + Key_ConsoleInsert("/"); + Key_ConsoleInsert(cmd); + s = key_lines[edit_line]+1; + + //if its the only match, add a space ready for arguments. + cmd = Cmd_CompleteCommand (s, true, true, 0, NULL); + if (cmd && !strcmp(s, cmd)) + { + Key_ConsoleInsert(" "); } + + if (!con_commandmatch) + con_commandmatch = 1; + + if (desc) + Con_Footerf(NULL, false, "%s: %s", cmd, desc); + else + Con_Footerf(NULL, false, ""); + return; + } + } + //complete to a partial match. + cmd = Cmd_CompleteCommand (s, false, true, 0, &desc); + if (cmd) + { + int i = key_lines[edit_line][0] == '/'?1:0; + if (i != 1 || strcmp(key_lines[edit_line]+i, cmd)) + { //if successful, use that instead. + Key_ClearTyping(); + Key_ConsoleInsert("/"); + Key_ConsoleInsert(cmd); + + s = key_lines[edit_line]; //readjust to cope with the insertion of a / + if (*s == '\\' || *s == '/') + s++; } } con_commandmatch++; @@ -1991,6 +1988,17 @@ void Key_AliasEdit_f (void) Con_Printf("Not an alias\n"); } +void Key_Bind_c(int argn, char *partial, struct xcommandargcompletioncb_s *ctx) +{ + keyname_t *kn; + size_t len = strlen(partial); + //FIXME: shift, ctrl, alt prefixes (+combos) + for (kn=keynames ; kn->name ; kn++) + { + if (!Q_strncasecmp(partial,kn->name, len)) + ctx->cb(kn->name, ctx); + } +} /* =================== Key_Bind_f @@ -2287,10 +2295,10 @@ void Key_Init (void) // // register our functions // - Cmd_AddCommand ("bind",Key_Bind_f); + Cmd_AddCommandAD ("bind",Key_Bind_f, Key_Bind_c, NULL); Cmd_AddCommand ("in_bind",Key_Bind_f); Cmd_AddCommand ("bindlevel",Key_BindLevel_f); - Cmd_AddCommand ("unbind",Key_Unbind_f); + Cmd_AddCommandAD ("unbind",Key_Unbind_f, Key_Bind_c, NULL); Cmd_AddCommand ("unbindall",Key_Unbindall_f); Cmd_AddCommand ("aliasedit",Key_AliasEdit_f); diff --git a/engine/client/m_options.c b/engine/client/m_options.c index 7f8e66c63..728ba37a7 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -713,6 +713,7 @@ const char *presetname[] = { "286", //everything turned off to make it as fast as possible, even if you're crippled without it "Fast", //typical deathmatch settings. + "Spasm", //faithful NQ aesthetics (fairly strict, but not all out). "Vanilla", //vanilla effects enabled, no content replacement. "Normal", //content replacement enabled "Nice", //potentially expensive, but not painful @@ -739,6 +740,7 @@ const char *presetexec[] = "seta r_drawflat 1;" "seta r_lightmap 0;" "seta r_nolerp 1;" + "seta r_noframegrouplerp 1;" "seta r_nolightdir 1;" "seta r_dynamic 0;" "seta r_bloom 0;" @@ -797,12 +799,13 @@ const char *presetexec[] = "r_nolightdir 0;" "seta gl_simpleitems 0;" - , //vanilla options. + , //quakespasm-esque options. "r_part_density 1;" "gl_polyblend 1;" - "r_dynamic 1;" + "r_dynamic 2;" "gl_flashblend 0;" "cl_nolerp 0;" //projectiles lerped at least. + "r_noframegrouplerp 1;" //flames won't lerp "r_waterwarp 1;" "r_drawflame 1;" "v_gunkick 1;" @@ -810,24 +813,27 @@ const char *presetexec[] = "cl_bob 0.02;" //these things are perhaps a little extreme "r_loadlit 0;" - "r_nolerp 1;" - "seta vid_hardwaregamma 1;" - "r_softwarebanding 1;" //ugly software banding. + "vid_hardwaregamma 1;" "d_mipcap 0 2;" //gl without anisotropic filtering favours too-distant mips too often, so lets just pretend it doesn't exist. should probably mess with lod instead or something - "gl_affinemodels 1;" - "gl_texturemode nnl;" //yup, we went there. - "gl_texturemode2d n.l;" //yeah, 2d too. - "r_part_classic_square 1;" //blocky baby! "r_part_classic_expgrav 1;" //vanillaery "r_part_classic_opaque 1;" // "r_particlesystem script;" //q2 or hexen2 particle effects need to be loadable - "cl_sbar 1;" //its a style thing - "sv_nqplayerphysics 1;" //gb wanted this + "cl_sbar 2;" //its a style thing + "sv_nqplayerphysics 1;" //gb wanted this, should give nq physics to people who want nq settings. note that this disables prediction. "cl_demoreel 1;" //yup, arcadey //"d_mipcap \"0 3\";" //logically correct, but will fuck up on ATI drivers if increased mid-map, because ATI will just ignore any levels that are not currently enabled. - "seta cl_gibfilter 0;" + "cl_gibfilter 0;" "seta cl_deadbodyfilter 0;" + , //vanilla-esque options. + "gl_texturemode nnl;" //yup, we went there. + "gl_texturemode2d n.l;" //yeah, 2d too. + "r_nolerp 1;" + "cl_sbar 1;" + "gl_affinemodels 1;" + "r_softwarebanding 1;" //ugly software banding. + "r_part_classic_square 1;" //blocky baby! + , // normal (faithful) options, but with content replacement thrown in //#ifdef MINIMAL // "r_particlesystem classic;" @@ -841,6 +847,7 @@ const char *presetexec[] = "gl_load24bit 1;" "r_replacemodels \"md3 md2\";" "r_coronas 1;" + "r_dynamic 1;" "r_softwarebanding 0;" "d_mipcap 0 1000;" "gl_affinemodels 0;" @@ -852,6 +859,7 @@ const char *presetexec[] = "cl_demoreel 0;" "r_loadlit 1;" "r_nolerp 0;" + "r_noframegrouplerp 0;" , // nice options // "r_stains 0.75;" @@ -865,6 +873,7 @@ const char *presetexec[] = "r_waterstyle 2;" "gl_blendsprites 1;" // "r_fastsky -1;" + "r_dynamic 0;" "r_shadow_realtime_dlight 1;" // "gl_detail 1;" "r_lightstylesmooth 1;" @@ -910,8 +919,9 @@ void M_Menu_Preset_f (void) MB_TEXT("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082", true), MB_CONSOLECMD("simple (untextured)", "fps_preset 286;menupop\n", "Lacks textures, particles, pretty much everything."), MB_CONSOLECMD("fast (deathmatch)", "fps_preset fast;menupop\n", "Fullscreen effects off to give consistant framerates"), + MB_CONSOLECMD("spasm (nq compat)", "fps_preset spasm;menupop\n", "Aims for visual compatibility with common NQ engines. Also affects mods slightly."), MB_CONSOLECMD("vanilla (softwarey)", "fps_preset vanilla;menupop\n", "This is for purists! Party like its 1995! No sanity spared!"), - MB_CONSOLECMD("normal (faithful)", "fps_preset normal;menupop\n", "An updated but still faithful appearance, using content replacements where applicable"), + MB_CONSOLECMD("normal (qw faithful)", "fps_preset normal;menupop\n", "An updated but still faithful appearance, using content replacements where applicable"), MB_CONSOLECMD("nice (dynamic)", "fps_preset nice;menupop\n", "For people who like nice things, but still want to actually play"), #ifdef RTLIGHTS MB_CONSOLECMD("realtime (all on)", "fps_preset realtime;menupop\n", "For people who value pretty over fast/smooth. Not viable for deathmatch."), @@ -937,11 +947,13 @@ void M_Menu_Preset_f (void) else if (gl_load24bit.ival) item = 3; //normal else if (r_softwarebanding_cvar.ival) - item = 4; + item = 4; //vanilla + else if (cl_sbar.ival == 2) + item = 5; //spasm else if (!r_drawflat.ival) - item = 5; + item = 6; //fast else - item = 6; + item = 7; //simple item -= bias; while (item --> 0) menu->selecteditem = menu->selecteditem->common.next; diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 0ae3de24c..83a3c1a6a 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -516,9 +516,14 @@ static void Surf_AddDynamicLightsColours (msurface_t *surf) local[0] -= surf->texturemins[0]; local[1] -= surf->texturemins[1]; - r = cl_dlights[lnum].color[0]*128; - g = cl_dlights[lnum].color[1]*128; - b = cl_dlights[lnum].color[2]*128; + if (r_dynamic.ival == 2) + r = g = b = 128; + else + { + r = cl_dlights[lnum].color[0]*128; + g = cl_dlights[lnum].color[1]*128; + b = cl_dlights[lnum].color[2]*128; + } /* if (cl_dlights[lnum].type == 1) //a wierd effect. { diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 7a3881e89..29c5b2e88 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -106,8 +106,8 @@ cvar_t r_refractreflect_scale = CVARD ("r_refractreflect_scale", "0.5", "Use cvar_t gl_miptexLevel = CVAR ("gl_miptexLevel", "0"); cvar_t r_drawviewmodel = CVARF ("r_drawviewmodel", "1", CVAR_ARCHIVE); cvar_t r_drawviewmodelinvis = CVAR ("r_drawviewmodelinvis", "0"); -cvar_t r_dynamic = CVARF ("r_dynamic", IFMINIMAL("0","1"), - CVAR_ARCHIVE); +cvar_t r_dynamic = CVARFD ("r_dynamic", IFMINIMAL("0","1"), + CVAR_ARCHIVE, "-1: the engine will bypass dlights completely, allowing for better batching.\n0: no standard dlights at all.\n1: coloured dlights will be used, they may show through walls. These are not realtime things.\n2: The dlights will be forced to monochrome (this does not affect coronas/flashblends/rtlights attached to the same light)."); cvar_t r_fastturb = CVARF ("r_fastturb", "0", CVAR_SHADERSYSTEM); cvar_t r_fastsky = CVARF ("r_fastsky", "0", @@ -1280,6 +1280,10 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr) vid.dpi_x = 0; vid.dpi_y = 0; +#ifndef CLIENTONLY + sv.world.lastcheckpvs = NULL; +#endif + if (qrenderer != QR_NONE) //graphics stuff only when not dedicated { size_t sz; diff --git a/engine/client/sbar.c b/engine/client/sbar.c index 4bcd4576d..ce6f23b3a 100644 --- a/engine/client/sbar.c +++ b/engine/client/sbar.c @@ -40,6 +40,8 @@ cvar_t scr_scoreboard_teamsort = CVARD("scr_scoreboard_teamsort", "0", "On the s cvar_t scr_scoreboard_titleseperator = CVAR("scr_scoreboard_titleseperator", "1"); cvar_t sbar_teamstatus = CVARD("sbar_teamstatus", "1", "Display the last team say from each of your team members just above the sbar area."); +cvar_t cl_sbaralpha = CVARAD("cl_sbaralpha", "0.75", "scr_sbaralpha", "Specifies the transparency of the status bar. Only Takes effect when cl_sbar is set to 2."); //with premultiplied alpha, this needs to affect the RGB values too. + //=========================================== //rogue changed and added defines #define RIT_SHELLS (1u<<7) @@ -1112,6 +1114,7 @@ void Sbar_Init (void) Cvar_Register(&scr_scoreboard_titleseperator, "Scoreboard settings"); Cvar_Register(&sbar_teamstatus, "Status bar settings"); + Cvar_Register(&cl_sbaralpha, "Status bar settings"); Cmd_AddCommand ("+showscores", Sbar_ShowScores); Cmd_AddCommand ("-showscores", Sbar_DontShowScores); @@ -1675,7 +1678,7 @@ void Sbar_DrawInventory (playerview_t *pv) float wleft, wtop; apic_t *ibar; - headsup = !(cl_sbar.value || (scr_viewsize.value<100&&cl.splitclients==1)); + headsup = !(cl_sbar.value || (scr_viewsize.value<100)); hudswap = cl_hudswap.value; // Get that nasty float out :) //coord for the left of the weapons, with hud @@ -1695,7 +1698,12 @@ void Sbar_DrawInventory (playerview_t *pv) ibar = sb_ibar; if (!headsup) + { + if (cl_sbar.ival != 1 && scr_viewsize.value >= 100) + R2D_ImageColours (cl_sbaralpha.value, cl_sbaralpha.value, cl_sbaralpha.value, cl_sbaralpha.value); Sbar_DrawPic (0, -24, 320, 24, ibar); + R2D_ImageColours (1, 1, 1, 1); + } // weapons for (i=0 ; i<7 ; i++) @@ -1921,7 +1929,7 @@ int Sbar_TranslateHudClick(void) float vx = mousecursor_x - sbar_rect.x; float vy = mousecursor_y - (sbar_rect.y + (sbar_rect.height-SBAR_HEIGHT)); - qboolean headsup = !(cl_sbar.value || (scr_viewsize.value<100&&cl.splitclients==1)); + qboolean headsup = !(cl_sbar.value || (scr_viewsize.value<100)); qboolean hudswap = cl_hudswap.value; // Get that nasty float out :) //inventory. clicks do specific-weapon impulses. @@ -2082,8 +2090,13 @@ Sbar_DrawNormal */ void Sbar_DrawNormal (playerview_t *pv) { - if (cl_sbar.value || (scr_viewsize.value<100&&cl.splitclients==1)) + if (cl_sbar.value || (scr_viewsize.value<100)) + { + if (cl_sbar.ival != 1 && scr_viewsize.value >= 100) + R2D_ImageColours (cl_sbaralpha.value, cl_sbaralpha.value, cl_sbaralpha.value, cl_sbaralpha.value); Sbar_DrawPic (0, 0, 320, 24, sb_sbar); + R2D_ImageColours (1, 1, 1, 1); + } //hipnotic's keys appear to the right of health. if (sbar_hipnotic) @@ -2189,7 +2202,7 @@ qboolean Sbar_ShouldDraw (playerview_t *pv) return false; #endif - headsup = !(cl_sbar.value || (scr_viewsize.value<100&&cl.splitclients==1)); + headsup = !(cl_sbar.value || (scr_viewsize.value<100)); if ((sb_updates >= vid.numpages) && !headsup) return false; @@ -2755,7 +2768,7 @@ void Sbar_Draw (playerview_t *pv) qboolean minidmoverlay; extern cvar_t scr_centersbar; - headsup = !(cl_sbar.value || (scr_viewsize.value<100&&cl.splitclients==1)); + headsup = !(cl_sbar.value || (scr_viewsize.value<100)); if ((sb_updates >= vid.numpages) && !headsup) return; diff --git a/engine/client/view.c b/engine/client/view.c index ef0711591..d67a5a170 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -1172,8 +1172,8 @@ void V_ApplyAFov(playerview_t *pv) if (!afov) //make sure its sensible. afov = scr_fov.value; #ifdef QUAKESTATS - if (pv && pv->stats[STAT_VIEWZOOM]) - afov *= pv->stats[STAT_VIEWZOOM]/255.0f; + if (pv && pv->statsf[STAT_VIEWZOOM]) + afov *= pv->statsf[STAT_VIEWZOOM]/255.0f; #endif afov = bound(0.001, afov, 170); diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 1c1d06af5..cca4e013e 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -727,6 +727,21 @@ void Cmd_Exec_f (void) BZ_Free(f); } +static int QDECL CompleteExecList (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath) +{ + struct xcommandargcompletioncb_s *ctx = parm; + ctx->cb(name, ctx); + return true; +} +void Cmd_Exec_c(int argn, char *partial, struct xcommandargcompletioncb_s *ctx) +{ + if (argn == 1) + { + COM_EnumerateFiles(va("configs/%s*.cfg", partial), CompleteExecList, ctx); + COM_EnumerateFiles(va("%s*.cfg", partial), CompleteExecList, ctx); + COM_EnumerateFiles(va("%s*.rc", partial), CompleteExecList, ctx); + } +} /* =============== @@ -1198,6 +1213,7 @@ typedef struct cmd_function_s char *name; char *description; xcommand_t function; + xcommandargcompletion_t argcompletion; qbyte restriction; //restriction of admin level } cmd_function_t; @@ -1667,7 +1683,7 @@ Cmd_AddCommand ============ */ -qboolean Cmd_AddCommandD (char *cmd_name, xcommand_t function, char *desc) +qboolean Cmd_AddCommandAD (char *cmd_name, xcommand_t function, xcommandargcompletion_t argcompletion, char *desc) { cmd_function_t *cmd; @@ -1696,6 +1712,7 @@ qboolean Cmd_AddCommandD (char *cmd_name, xcommand_t function, char *desc) cmd = (cmd_function_t*)Z_Malloc (sizeof(cmd_function_t)+strlen(cmd_name)+1); cmd->name = (char*)(cmd+1); + cmd->argcompletion = argcompletion; cmd->description = desc; strcpy(cmd->name, cmd_name); cmd->function = function; @@ -1706,9 +1723,13 @@ qboolean Cmd_AddCommandD (char *cmd_name, xcommand_t function, char *desc) return true; } +qboolean Cmd_AddCommandD (char *cmd_name, xcommand_t function, char *desc) +{ + return Cmd_AddCommandAD(cmd_name, function, NULL, desc); +} qboolean Cmd_AddCommand (char *cmd_name, xcommand_t function) { - return Cmd_AddCommandD(cmd_name, function, NULL); + return Cmd_AddCommandAD(cmd_name, function, NULL, NULL); } void Cmd_RemoveCommand (char *cmd_name) @@ -1942,7 +1963,7 @@ typedef struct { char result[256]; const char *desc; } match_t; -void Cmd_CompleteCheck(char *check, match_t *match, const char *desc) //compare cumulative strings and join the result +void Cmd_CompleteCheck(const char *check, match_t *match, const char *desc) //compare cumulative strings and join the result { if (*match->result) { @@ -1971,6 +1992,59 @@ void Cmd_CompleteCheck(char *check, match_t *match, const char *desc) //compare match->desc = desc; } } +struct cmdargcompletionctx_s +{ + struct xcommandargcompletioncb_s cb; + cmd_function_t *cmd; + char *prefix; + size_t prefixlen; + match_t *match; + const char *desc; +}; +void Cmd_CompleteCheckArg(const char *value, void *vctx) //compare cumulative strings and join the result +{ + struct cmdargcompletionctx_s *ctx = vctx; + match_t *match = ctx->match; + const char *desc = ctx->desc; + + if (ctx->prefixlen >= countof(match->result)-1) + return; //don't allow overflows. + + if (*match->result) + { + char *r; + const char *check; + if (match->allowcutdown) + { + for(r = match->result, check=ctx->prefix; check < ctx->prefix+ctx->prefixlen && *r == *check && *r; r++, check++) + ; + if (check == ctx->prefix+ctx->prefixlen) + { + for(check=value; *r == *check && *r; r++, check++) + ; + } + *r = '\0'; + match->cutdown = true; + if (match->matchnum > 0) + match->matchnum--; + } + else if (match->matchnum > 0) + { + memcpy(match->result, ctx->prefix, ctx->prefixlen); + Q_strncpyz(match->result+ctx->prefixlen, value, sizeof(match->result)-ctx->prefixlen); + match->desc = desc; + match->matchnum--; + } + } + else + { + if (match->matchnum > 0) + match->matchnum--; + memcpy(match->result, ctx->prefix, ctx->prefixlen); + Q_strncpyz(match->result+ctx->prefixlen, value, sizeof(match->result)-ctx->prefixlen); + match->desc = desc; + } +} char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens, int matchnum, const char **descptr) { extern cvar_group_t *cvar_groups; @@ -1984,11 +2058,19 @@ char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens cvar_t *cvar; char *sp; - sp = strchr(partial, ' '); - if (sp) - len = sp - partial; + for (sp = partial; *sp; sp++) + { + if (*sp == ' ' || *sp == '\t') + break; + } + len = sp - partial; + if (*sp) + { + while (*sp == ' ' || *sp == '\t') + sp++; + } else - len = Q_strlen(partial); + sp = NULL; if (descptr) *descptr = NULL; @@ -2014,7 +2096,21 @@ char *Cmd_CompleteCommand (char *partial, qboolean fullonly, qboolean caseinsens { for (cmd=cmd_functions ; cmd ; cmd=cmd->next) if (!Q_strncasecmp (partial,cmd->name, len) && (matchnum == -1 || !partial[len] || strlen(cmd->name) == len)) - Cmd_CompleteCheck(cmd->name, &match, cmd->description); + { + if (sp && cmd->argcompletion) + { + struct cmdargcompletionctx_s ctx; + ctx.cb.cb = Cmd_CompleteCheckArg; + ctx.cmd = cmd; + ctx.prefix = partial; + ctx.prefixlen = sp-partial; + ctx.match = &match; + ctx.desc = cmd->description; + cmd->argcompletion(1, sp, &ctx.cb); + } + else + Cmd_CompleteCheck(cmd->name, &match, cmd->description); + } for (a=cmd_alias ; a ; a=a->next) if (!Q_strncasecmp (partial, a->name, len) && (matchnum == -1 || !partial[len] || strlen(a->name) == len)) Cmd_CompleteCheck(a->name, &match, ""); @@ -3675,12 +3771,12 @@ void Cmd_Init (void) // // register our commands // - Cmd_AddCommand ("cfg_save",Cmd_WriteConfig_f); + Cmd_AddCommandAD ("cfg_save",Cmd_WriteConfig_f, Cmd_Exec_c, NULL); - Cmd_AddCommand ("cfg_load",Cmd_Exec_f); + Cmd_AddCommandAD ("cfg_load",Cmd_Exec_f, Cmd_Exec_c, NULL); Cmd_AddCommand ("cfg_reset",Cmd_Reset_f); - Cmd_AddCommand ("exec",Cmd_Exec_f); + Cmd_AddCommandAD ("exec",Cmd_Exec_f, Cmd_Exec_c, NULL); Cmd_AddCommand ("echo",Cmd_Echo_f); Cmd_AddCommand ("alias",Cmd_Alias_f); Cmd_AddCommand ("newalias",Cmd_Alias_f); diff --git a/engine/common/cmd.h b/engine/common/cmd.h index 510254bce..e9a312a19 100644 --- a/engine/common/cmd.h +++ b/engine/common/cmd.h @@ -71,6 +71,12 @@ then searches for a command or variable that matches the first token. */ typedef void (*xcommand_t) (void); +struct xcommandargcompletioncb_s +{ + void(*cb)(const char *arg, struct xcommandargcompletioncb_s *ctx); + //private stuff follows. +}; +typedef void (*xcommandargcompletion_t)(int argn, char *partial, struct xcommandargcompletioncb_s *ctx); int Cmd_Level(char *name); void Cmd_EnumerateLevel(int level, char *buf, size_t bufsize); @@ -83,6 +89,7 @@ void Cmd_RemoveCommands (xcommand_t function); //unregister all commands that us void Cmd_RemoveCommand (char *cmd_name); qboolean Cmd_AddCommand (char *cmd_name, xcommand_t function); qboolean Cmd_AddCommandD (char *cmd_name, xcommand_t function, char *description); +qboolean Cmd_AddCommandAD (char *cmd_name, xcommand_t function, xcommandargcompletion_t argcomplete, char *description); // called by the init functions of other parts of the program to // register commands and functions to call for them. // The cmd_name is referenced later, so it should not be in temp memory diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index 99b3f55a2..ba008e019 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.c @@ -1975,11 +1975,12 @@ static qbyte *Q1BSP_ClusterPVS (model_t *model, int cluster, pvsbuffer_t *buffer memset(buffer->buffer, 0xff, model->pvsbytes); return buffer->buffer; } - cluster++; if (merge == PVM_FAST && model->pvs) return model->pvs + cluster * model->pvsbytes; + cluster++; + if (!buffer) buffer = &mod_tempvis; diff --git a/engine/common/world.h b/engine/common/world.h index 4f737bb93..f499052a7 100644 --- a/engine/common/world.h +++ b/engine/common/world.h @@ -197,6 +197,7 @@ struct world_s unsigned int framenum; int lastcheck; // used by PF_checkclient double lastchecktime; // for monster ai + qbyte *lastcheckpvs; // for monster ai float defaultgravityscale; //0 in QW, 1 for anything else (inc csqc) diff --git a/engine/d3d/d3d_backend.c b/engine/d3d/d3d_backend.c index b0775b6ca..7020b804d 100644 --- a/engine/d3d/d3d_backend.c +++ b/engine/d3d/d3d_backend.c @@ -3621,12 +3621,13 @@ void D3D9BE_VBO_Destroy(vboarray_t *vearray, void *mem) void D3D9BE_Scissor(srect_t *srect) { RECT rect; + if (srect) { rect.left = (srect->x) * vid.fbpwidth; rect.right = (srect->x + srect->width) * vid.fbpwidth; - rect.top = (srect->y) * vid.fbpheight; - rect.bottom = (srect->y + srect->height) * vid.fbpheight; + rect.top = (1 - (srect->height + srect->y))*vid.fbpheight; //our api was made for gl. :( + rect.bottom = (1 - (srect->y))*vid.fbpheight; //our api was made for gl. :( } else { diff --git a/engine/dotnet2005/ftequake.vcproj b/engine/dotnet2005/ftequake.vcproj index 815ccff9c..029772092 100644 --- a/engine/dotnet2005/ftequake.vcproj +++ b/engine/dotnet2005/ftequake.vcproj @@ -25119,6 +25119,250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -25343,6 +25587,226 @@ RelativePath="..\gl\gl_font.c" > + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -26906,6 +27370,232 @@ /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -27375,250 +28065,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -28291,226 +28737,6 @@ /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -29861,232 +30087,6 @@ /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 if (perm & PERMUTATION_LIGHTSTYLES) @@ -3230,19 +3237,17 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm, else #endif { - vec4_t colscale[4]; if (shaderstate.curentity->model && (shaderstate.curentity->model->engineflags & MDLF_NEEDOVERBRIGHT) && !shaderstate.force2d) { float sc = (1<pvs = NULL; mod->phs = NULL; +#ifndef CLIENTONLY + sv.world.lastcheckpvs = NULL; //if the server has that cached, flush it just in case. +#endif + return true; } @@ -5181,7 +5185,8 @@ TRACE(("LoadBrushModel %i\n", __LINE__)); submod->radius = RadiusFromBounds (submod->mins, submod->maxs); - submod->numclusters = bm->visleafs; + submod->numclusters = (i==0)?bm->visleafs:0; + submod->pvsbytes = ((submod->numclusters+31)>>3)&~3; if (i) submod->entities_raw = NULL; diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index a8fa6849f..1a4281b87 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -1933,6 +1933,7 @@ struct shader_field_names_s shader_unif_names[] = /*ent properties*/ {"e_vblend", SP_E_VBLEND}, {"e_lmscale", SP_E_LMSCALE}, /*overbright shifting*/ + {"e_vlscale", SP_E_VLSCALE}, /*no lightmaps, no overbrights*/ {"e_origin", SP_E_ORIGIN}, {"e_time", SP_E_TIME}, {"e_eyepos", SP_E_EYEPOS}, @@ -5278,7 +5279,7 @@ void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, cons if (!TEXVALID(tex->bump) && *mapname) tex->bump = R_LoadHiResTexture(va("%s_norm", mapname), NULL, imageflags|IF_TRYBUMP); if (!TEXVALID(tex->bump) && (r_shadow_bumpscale_basetexture.ival||*imagename=='#'||gl_load24bit.ival)) - tex->bump = Image_GetTexture(va("%s_norm", imagename), subpath, imageflags|IF_TRYBUMP, (r_shadow_bumpscale_basetexture.ival||*imagename=='#')?mipdata[0]:NULL, palette, width, height, TF_HEIGHT8PAL); + tex->bump = Image_GetTexture(va("%s_norm", imagename), subpath, imageflags|IF_TRYBUMP|(*imagename=='#'?IF_LINEAR:0), (r_shadow_bumpscale_basetexture.ival||*imagename=='#')?mipdata[0]:NULL, palette, width, height, TF_HEIGHT8PAL); } if (loadflags & SHADER_HASTOPBOTTOM) diff --git a/engine/gl/r_bishaders.h b/engine/gl/r_bishaders.h index 7ec4a5da3..10837d319 100644 --- a/engine/gl/r_bishaders.h +++ b/engine/gl/r_bishaders.h @@ -4229,7 +4229,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "varying vec2 tc;\n" "varying vec4 vc;\n" "uniform vec4 e_colourident;\n" -"uniform vec4 e_lmscale;\n" +"uniform vec4 e_vlscale;\n" "void main ()\n" "{\n" "vec4 col = texture2D(s_t0, tc);\n" @@ -4237,7 +4237,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "if (col.a < float(MASK))\n" "discard;\n" "#endif\n" -"gl_FragColor = fog4blend(col * vc * e_colourident * e_lmscale);\n" +"gl_FragColor = fog4blend(col * vc * e_colourident * e_vlscale);\n" "}\n" "#endif\n" }, diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index ddf12b083..de0a69ea4 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -3564,11 +3564,10 @@ static void QCBUILTIN PF_TraceToss (pubprogfuncs_t *prinst, struct globalvars_s //============================================================================ pvsbuffer_t checkpvsbuffer; -qbyte *checkpvs; vec3_t checkorg; extern cvar_t sv_nopvs; -int PF_newcheckclient (pubprogfuncs_t *prinst, int check) +void PF_newcheckclient (pubprogfuncs_t *prinst, world_t *w) { int i; // qbyte *pvs; @@ -3577,15 +3576,15 @@ int PF_newcheckclient (pubprogfuncs_t *prinst, int check) // cycle to the next one - if (check < 1) - check = 1; - if (check > sv.allocated_client_slots) - check = sv.allocated_client_slots; + if (w->lastcheck < 1) + w->lastcheck = 1; + if (w->lastcheck > sv.allocated_client_slots) + w->lastcheck = sv.allocated_client_slots; - if (check == sv.allocated_client_slots) + if (w->lastcheck == sv.allocated_client_slots) i = 1; else - i = check + 1; + i = w->lastcheck + 1; for ( ; ; i++) { @@ -3594,7 +3593,7 @@ int PF_newcheckclient (pubprogfuncs_t *prinst, int check) ent = EDICT_NUM(prinst, i); - if (i == check) + if (i == w->lastcheck) break; // didn't find anything else if (ED_ISFREE(ent)) @@ -3611,14 +3610,14 @@ int PF_newcheckclient (pubprogfuncs_t *prinst, int check) // get the PVS for the entity VectorAdd (ent->v->origin, ent->v->view_ofs, checkorg); if (sv.world.worldmodel->type == mod_heightmap || sv_nopvs.ival) - checkpvs = NULL; + w->lastcheckpvs = NULL; else { cluster = sv.world.worldmodel->funcs.ClusterForPoint(sv.world.worldmodel, checkorg); - checkpvs = sv.world.worldmodel->funcs.ClusterPVS (sv.world.worldmodel, cluster, &checkpvsbuffer, PVM_FAST); + w->lastcheckpvs = sv.world.worldmodel->funcs.ClusterPVS (sv.world.worldmodel, cluster, &checkpvsbuffer, PVM_FAST); } - return i; + w->lastcheck = i; } /* @@ -3637,7 +3636,6 @@ name checkclient () ================= */ #define MAX_CHECK 16 -int c_invis, c_notvis; int PF_checkclient_Internal (pubprogfuncs_t *prinst) { edict_t *ent, *self; @@ -3649,7 +3647,7 @@ int PF_checkclient_Internal (pubprogfuncs_t *prinst) // find a new check if on a new frame if (w->physicstime - w->lastchecktime >= 0.1) { - w->lastcheck = PF_newcheckclient (prinst, w->lastcheck); + PF_newcheckclient (prinst, w); w->lastchecktime = w->physicstime; } @@ -3668,18 +3666,16 @@ int PF_checkclient_Internal (pubprogfuncs_t *prinst) if (DotProduct(dist, dist) > 2048*2048) return 0; - if (checkpvs) + if (w->lastcheckpvs) { clust = w->worldmodel->funcs.ClusterForPoint(w->worldmodel, view); - if ( (clust<0) || !(checkpvs[clust>>3] & (1<<(clust&7)) ) ) + if ( (clust<0) || !(w->lastcheckpvs[clust>>3] & (1<<(clust&7)) ) ) { - c_notvis++; return 0; } } -// might be able to see it -c_invis++; +// might be able to see it. the qc will do some tracelines to ensure that it can. return w->lastcheck; } diff --git a/engine/server/savegame.c b/engine/server/savegame.c index 6a56674bd..3b401c5a6 100644 --- a/engine/server/savegame.c +++ b/engine/server/savegame.c @@ -1292,6 +1292,38 @@ void SV_Savegame (const char *savename, qboolean mapchange) } } + +static int QDECL CompleteSaveList (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath) +{ + struct xcommandargcompletioncb_s *ctx = parm; + char trimmed[256]; + size_t l; + Q_strncpyz(trimmed, name+6, sizeof(trimmed)); + l = strlen(trimmed); + if (l >= 9 && !Q_strcasecmp(trimmed+l-9, "/info.fsv")) + { + trimmed[l-9] = 0; + ctx->cb(trimmed, ctx); + } + return true; +} +static int QDECL CompleteSaveListLegacy (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath) +{ + struct xcommandargcompletioncb_s *ctx = parm; + char stripped[64]; + COM_StripExtension(name, stripped, sizeof(stripped)); + ctx->cb(stripped, ctx); + return true; +} +void SV_Savegame_c(int argn, char *partial, struct xcommandargcompletioncb_s *ctx) +{ + if (argn == 1) + { + COM_EnumerateFiles(va("saves/%s*/info.fsv", partial), CompleteSaveList, ctx); + COM_EnumerateFiles(va("%s*.sav", partial), CompleteSaveListLegacy, ctx); + } +} + void SV_Savegame_f (void) { if (Cmd_Argc() <= 2) diff --git a/engine/server/server.h b/engine/server/server.h index c814308ac..1dcef38bc 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -628,6 +628,7 @@ typedef struct client_s #endif unsigned int zquake_extensions; unsigned int max_net_ents; /*highest entity number the client can receive (limited by either protocol or client's buffer size)*/ + unsigned int max_net_staticents; /*limit to the number of static ents supported by the client*/ unsigned int max_net_clients; /*max number of player slots supported by the client */ unsigned int maxmodels; /*max models supported by whatever the protocol is*/ @@ -1563,6 +1564,7 @@ int SV_MVD_GotQTVRequest(vfsfile_t *clientstream, char *headerstart, char *heade // savegame.c void SV_LegacySavegame_f(void); void SV_Savegame_f (void); +void SV_Savegame_c(int argn, char *partial, struct xcommandargcompletioncb_s *ctx); void SV_Loadgame_f (void); void SV_AutoSave(void); void SV_FlushLevelCache(void); diff --git a/engine/server/sv_ccmds.c b/engine/server/sv_ccmds.c index af8461e18..d23e21eac 100644 --- a/engine/server/sv_ccmds.c +++ b/engine/server/sv_ccmds.c @@ -403,6 +403,37 @@ static void SV_MapList_f(void) COM_EnumerateFiles("maps/*.hmp", ShowMapList, NULL); } +static int QDECL CompleteMapList (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath) +{ + struct xcommandargcompletioncb_s *ctx = parm; + char stripped[64]; + if (name[5] == 'b' && name[6] == '_') //skip box models + return true; + + COM_StripExtension(name+5, stripped, sizeof(stripped)); + ctx->cb(stripped, ctx); + return true; +} +static int QDECL CompleteMapListExt (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath) +{ + struct xcommandargcompletioncb_s *ctx = parm; + if (name[5] == 'b' && name[6] == '_') //skip box models + return true; + + ctx->cb(name+5, ctx); + return true; +} +static void SV_Map_c(int argn, char *partial, struct xcommandargcompletioncb_s *ctx) +{ + if (argn == 1) + { + COM_EnumerateFiles(va("maps/%s*.bsp", partial), CompleteMapList, ctx); + COM_EnumerateFiles(va("maps/%s*.map", partial), CompleteMapListExt, ctx); + COM_EnumerateFiles(va("maps/%s*.cm", partial), CompleteMapList, ctx); + COM_EnumerateFiles(va("maps/%s*.hmp", partial), CompleteMapList, ctx); + } +} + //static void gtcallback(struct cvar_s *var, char *oldvalue) //{ // Con_Printf("g_gametype changed\n"); @@ -2978,13 +3009,13 @@ void SV_InitOperatorCommands (void) Cmd_AddCommand ("mod", SV_SendGameCommand_f); Cmd_AddCommand ("killserver", SV_KillServer_f); - Cmd_AddCommand ("map", SV_Map_f); Cmd_AddCommandD ("precaches", SV_PrecacheList_f, "Displays a list of current server precaches."); + Cmd_AddCommandAD ("map", SV_Map_f, SV_Map_c, "Changes map. If a second argument is specified then that is normally the name of the initial start spot."); #ifdef Q3SERVER - Cmd_AddCommand ("spmap", SV_Map_f); + Cmd_AddCommandAD ("spmap", SV_Map_f, SV_Map_c, NULL); #endif - Cmd_AddCommand ("gamemap", SV_Map_f); - Cmd_AddCommand ("changelevel", SV_Map_f); + Cmd_AddCommandAD ("gamemap", SV_Map_f, SV_Map_c, NULL); + Cmd_AddCommandAD ("changelevel", SV_Map_f, SV_Map_c, NULL); Cmd_AddCommand ("listmaps", SV_MapList_f); Cmd_AddCommand ("maplist", SV_MapList_f); diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 1f55a16e5..c42fbf497 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -458,9 +458,6 @@ void SV_CalcPHS (void) return; } - if (model->pvsbytes > 4096) - return; - //FIXME: this can take a significant time on some maps, and should ideally be pushed to a worker thread. num = model->numclusters; rowbytes = model->pvsbytes; @@ -514,7 +511,7 @@ void SV_CalcPHS (void) if (f) { VFS_READ(f, hdr, sizeof(hdr)); - if (memcmp(hdr, "QPHS\1\0\0\0", 8) || VFS_GETLEN(f) != rowbytes*num + 8) + if (!memcmp(hdr, "QPHS\1\0\0\0", 8) && VFS_GETLEN(f) == rowbytes*num + 8) { VFS_READ(f, model->phs, rowbytes*num); VFS_CLOSE(f); diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index a829d1238..1ec15faa1 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -1882,6 +1882,7 @@ void SV_ClientProtocolExtensionsChanged(client_t *client) if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) { client->max_net_clients = ISQWCLIENT(client)?QWMAX_CLIENTS:NQMAX_CLIENTS; + client->max_net_staticents = ~0u; //unlimited in both fte+qss. //you need to reconnect for this to update, of course. so make sure its not *too* low... client->max_net_ents = bound(512, pr_maxedicts.ival, MAX_EDICTS); @@ -1895,7 +1896,8 @@ void SV_ClientProtocolExtensionsChanged(client_t *client) client->max_net_ents += 512; if (client->fteprotocolextensions & PEXT_ENTITYDBL2) client->max_net_ents += 1024; - + client->max_net_staticents = 512; //the ezquake limit, too few people use vanilla to really care about that (it would be too unstable anyway). fodquake has no limit. + if (client->fteprotocolextensions & PEXT_MODELDBL) client->maxmodels = 512; } @@ -1903,6 +1905,7 @@ void SV_ClientProtocolExtensionsChanged(client_t *client) { client->max_net_clients = 255; client->max_net_ents = bound(512, pr_maxedicts.ival, 32768); + client->max_net_staticents = 1024; //its quite low, proportionally. client->maxmodels = MAX_PRECACHE_MODELS; //protocol limit of 16 bits. 15 bits for late precaches. client limit of 1k client->datagram.maxsize = sizeof(host_client->datagram_buf); @@ -1911,6 +1914,7 @@ void SV_ClientProtocolExtensionsChanged(client_t *client) { client->max_net_clients = NQMAX_CLIENTS; client->max_net_ents = bound(512, pr_maxedicts.ival, 32768); //fitzquake supports 65535, but our writeentity builtin works differently, which causes problems. + client->max_net_staticents = 4096; //quakespasm has 4k, more than 3k starts to have issues with the msg_init buffer size. client->maxmodels = MAX_PRECACHE_MODELS; maxpacketentities = client->max_net_ents; @@ -1924,6 +1928,7 @@ void SV_ClientProtocolExtensionsChanged(client_t *client) client->max_net_ents = bound(512, pr_maxedicts.ival, 8192); else client->max_net_ents = bound(512, pr_maxedicts.ival, 600); + client->max_net_staticents = 128; //yeah, its low. } if (client->fteprotocolextensions2 & PEXT2_MAXPLAYERS) @@ -5107,10 +5112,10 @@ void SV_InitLocal (void) #endif #endif Cmd_AddCommand ("savegame_legacy", SV_LegacySavegame_f); - Cmd_AddCommand ("savegame", SV_Savegame_f); - Cmd_AddCommand ("loadgame", SV_Loadgame_f); - Cmd_AddCommand ("save", SV_Savegame_f); - Cmd_AddCommand ("load", SV_Loadgame_f); + Cmd_AddCommandAD ("savegame", SV_Savegame_f, SV_Savegame_c, NULL); + Cmd_AddCommandAD ("loadgame", SV_Loadgame_f, SV_Savegame_c, NULL); + Cmd_AddCommandAD ("save", SV_Savegame_f, SV_Savegame_c, NULL); + Cmd_AddCommandAD ("load", SV_Loadgame_f, SV_Savegame_c, NULL); SV_MVDInit(); diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index c68cd85b9..347645237 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -1312,9 +1312,12 @@ void SV_SendClientPrespawnInfo(client_t *client) if (client->prespawn_stage == PRESPAWN_SPAWNSTATIC) { + int maxstatics = sv.num_static_entities; + if (maxstatics > 1024 && ISDPCLIENT(client)) + maxstatics = 1024; while (client->netchan.message.cursize < maxsize) //static entities { - if (client->prespawn_idx >= sv.num_static_entities) + if (client->prespawn_idx >= maxstatics) { client->prespawn_stage++; client->prespawn_idx = 0; diff --git a/engine/shaders/glsl/defaultsprite.glsl b/engine/shaders/glsl/defaultsprite.glsl index e3d195714..cf3b6b272 100644 --- a/engine/shaders/glsl/defaultsprite.glsl +++ b/engine/shaders/glsl/defaultsprite.glsl @@ -20,7 +20,7 @@ uniform sampler2D s_t0; varying vec2 tc; varying vec4 vc; uniform vec4 e_colourident; -uniform vec4 e_lmscale; +uniform vec4 e_vlscale; void main () { vec4 col = texture2D(s_t0, tc); @@ -28,6 +28,6 @@ void main () if (col.a < float(MASK)) discard; #endif - gl_FragColor = fog4blend(col * vc * e_colourident * e_lmscale); + gl_FragColor = fog4blend(col * vc * e_colourident * e_vlscale); } #endif diff --git a/engine/vk/vk_backend.c b/engine/vk/vk_backend.c index 981243c4f..311b6b4f5 100644 --- a/engine/vk/vk_backend.c +++ b/engine/vk/vk_backend.c @@ -2948,7 +2948,7 @@ static void BE_CreatePipeline(program_t *p, unsigned int shaderflags, unsigned i pipeCreateInfo.renderPass = (permu&PERMUTATION_BEM_DEPTHONLY)?vk.shadow_renderpass:vk.renderpass[0]; pipeCreateInfo.subpass = 0; pipeCreateInfo.basePipelineHandle = VK_NULL_HANDLE; - pipeCreateInfo.basePipelineIndex = -1; //not sure what this is about. + pipeCreateInfo.basePipelineIndex = -1; //used to create derivatives for pipelines created in the same call. // pipeCreateInfo.flags = VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT; diff --git a/engine/vk/vk_init.c b/engine/vk/vk_init.c index 3fc3f7033..7401cee02 100644 --- a/engine/vk/vk_init.c +++ b/engine/vk/vk_init.c @@ -2585,7 +2585,7 @@ qboolean VK_SCR_UpdateScreen (void) { VkImageMemoryBarrier imgbarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER}; imgbarrier.pNext = NULL; - imgbarrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT|VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + imgbarrier.srcAccessMask = /*VK_ACCESS_TRANSFER_READ_BIT|*/VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; imgbarrier.dstAccessMask = 0; imgbarrier.oldLayout = fblayout; imgbarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;