diff --git a/engine/Makefile b/engine/Makefile index 9b06498ad..7a2f4b7ae 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -1269,7 +1269,7 @@ ifeq ($(FTE_TARGET),web) # ASMJS_MEMORY?=2147483648 #2048mb WEB_MEMORY?=$(ASMJS_MEMORY) JSLIBS=--js-library web/ftejslib.js -s LEGACY_GL_EMULATION=0 - EMCC_ARGS=$(JSLIBS) $(WEB_PREJS) --shell-file web/fteshell.html -s ERROR_ON_UNDEFINED_SYMBOLS=1 + EMCC_ARGS=$(JSLIBS) $(WEB_PREJS) -s ERROR_ON_UNDEFINED_SYMBOLS=1 RELEASE_CFLAGS=-DOMIT_QCC -DGL_STATIC -DFTE_TARGET_WEB DEBUG_CFLAGS=-g -DOMIT_QCC -DGL_STATIC -DFTE_TARGET_WEB RELEASE_LDFLAGS=-s ASM_JS=1 -O3 -s TOTAL_MEMORY=$(ASMJS_MEMORY) $(EMCC_ARGS) @@ -1699,14 +1699,14 @@ EMSCRIPTENPATH=$(realpath $(EMSCRIPTENROOT)):$(realpath $(EMSCRIPTENROOT)/clang/ web-rel: @$(MAKE) gl-rel FTE_TARGET=web PATH="$(EMSCRIPTENPATH)" CC="emcc.bat" - cp $(BASE_DIR)/fteshell.html $(RELEASE_DIR)/ftewebgl.html + cp $(BASE_DIR)/web/fteshell.html $(RELEASE_DIR)/ftewebgl.html @gzip -f $(RELEASE_DIR)/ftewebgl.html @gzip -f $(RELEASE_DIR)/ftewebgl.js @gzip -f $(RELEASE_DIR)/ftewebgl.js.mem web-dbg: @$(MAKE) gl-dbg FTE_TARGET=web PATH="$(EMSCRIPTENPATH)" CC="emcc.bat" - cp $(BASE_DIR)/fteshell.html $(RELEASE_DIR)/ftewebgl.html + cp $(BASE_DIR)/web/fteshell.html $(RELEASE_DIR)/ftewebgl.html @gzip -f $(DEBUG_DIR)/ftewebgl.html @gzip -f $(DEBUG_DIR)/ftewebgl.js @gzip -f $(DEBUG_DIR)/ftewebgl.js.map diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index cad376322..6665e6717 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -41,6 +41,7 @@ extern cvar_t cl_nolerp_netquake; extern cvar_t r_torch; extern cvar_t r_shadows; extern cvar_t r_showbboxes; +extern cvar_t gl_simpleitems; extern cvar_t cl_gibfilter, cl_deadbodyfilter; extern int cl_playerindex; @@ -3674,8 +3675,51 @@ void CL_LinkPacketEntities (void) ent->fatness = state->fatness/16.0; #endif - // rotate binary objects locally - if (modelflags & MF_ROTATE) + //swap items with sprites if desired. + if (gl_simpleitems.ival && ent->skinnum >= 0 && ent->skinnum < countof(model->simpleskin) && model) + { + if (!model->simpleskin[ent->skinnum]) + { + char basename[64], name[MAX_QPATH]; + COM_FileBase(model->name, basename, sizeof(basename)); + if (!strncmp(model->name, "maps/", 5)) + Q_snprintfz(name, sizeof(name), "textures/bmodels/simple_%s_%i.tga", basename, ent->skinnum); + else + Q_snprintfz(name, sizeof(name), "textures/models/simple_%s_%i.tga", basename, ent->skinnum); + model->simpleskin[ent->skinnum] = R_RegisterShader(name, 0, va("{\nprogram defaultsprite\nsurfaceparm noshadows\nsurfaceparm nodlight\nsort seethrough\n{\nmap \"%s\"\nalphafunc ge128\n}\n}\n", name)); + } + VectorCopy(le->angles, angles); + + if (R_GetShaderSizes(model->simpleskin[ent->skinnum], NULL, NULL, false) > 0) + { + float tr[2]; + ent->forcedshader = model->simpleskin[ent->skinnum]; + ent->rtype = RT_SPRITE; + ent->scale *= 16; + + tr[0] = sin(le->angles[1] * M_PI / 180.0); + tr[1] = cos(le->angles[1] * M_PI / 180.0); + ent->origin[1] += tr[0] * (model->maxs[0] + model->mins[0])*0.5 + tr[1] * (model->maxs[1] + model->mins[1])*0.5; + ent->origin[0] += tr[1] * (model->maxs[1] + model->mins[1])*0.5 - tr[0] * (model->maxs[0] + model->mins[0])*0.5; + ent->origin[2] += model->mins[2]; + + ent->origin[2] += ent->scale; + + if (cl_item_bobbing.value) + ent->origin[2] += 5+sin(cl.time*3+(ent->origin[0]+ent->origin[1])/8)*5.5; //don't let it into the ground + } + else if (modelflags & MF_ROTATE) + { //surely there's a more sane way to handle this. + angles[0] = 0; + angles[1] = autorotate; + angles[2] = 0; + + if (cl_item_bobbing.value) + ent->origin[2] += 5+sin(cl.time*3+(state->origin[0]+state->origin[1])/8)*5.5; //don't let it into the ground + } + } + // rotate pickup objects locally + else if (modelflags & MF_ROTATE) { angles[0] = 0; angles[1] = autorotate; diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 73c549a14..c2bed3897 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -1487,7 +1487,7 @@ qboolean CLQ2_SendCmd (sizebuf_t *buf) } #endif -qboolean CLQW_SendCmd (sizebuf_t *buf) +qboolean CLQW_SendCmd (sizebuf_t *buf, qboolean actuallysend) { int seq_hash; qboolean dontdrop = false; @@ -1588,7 +1588,7 @@ qboolean CLQW_SendCmd (sizebuf_t *buf) else cl.inframes[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = -1; - if (cl.sendprespawn) + if (cl.sendprespawn || !actuallysend) buf->cursize = st; //don't send movement commands while we're still supposedly downloading. mvdsv does not like that. else { @@ -1618,7 +1618,7 @@ void CL_SendCmd (double frametime, qboolean mainloop) int i, plnum; usercmd_t *cmd; float wantfps; - qboolean fullsend; + int fullsend; //-1: send for sequence, with no usercmd. 0: update input frame, but don't send anything. 1: time for a new usercmd static float pps_balance = 0; static int dropcount = 0; @@ -1758,7 +1758,9 @@ void CL_SendCmd (double frametime, qboolean mainloop) wantfps = cl_netfps.value; fullsend = true; - if (!runningindepphys) + if (sv.state && cls.state != ca_active) + fullsend = -1; + else if (!runningindepphys) { // while we're not playing send a slow keepalive fullsend to stop mvdsv from screwing up if (cls.state < ca_active && !cls.download) @@ -1898,7 +1900,7 @@ void CL_SendCmd (double frametime, qboolean mainloop) #endif case CP_QUAKEWORLD: msecs -= (double)msecstouse; - dontdrop = CLQW_SendCmd (&buf); + dontdrop = CLQW_SendCmd (&buf, fullsend == true); break; #ifdef Q2CLIENT case CP_QUAKE2: diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 49c1d7981..4fbc432c5 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -160,6 +160,7 @@ cvar_t requiredownloads = CVARFD("requiredownloads","1", CVAR_ARCHIVE, "0=join cvar_t cl_muzzleflash = CVAR("cl_muzzleflash", "1"); +cvar_t gl_simpleitems = CVARF("gl_simpleitems", "0", CVAR_ARCHIVE); cvar_t cl_item_bobbing = CVARF("cl_model_bobbing", "0", CVAR_ARCHIVE); cvar_t cl_countpendingpl = CVARD("cl_countpendingpl", "0", "If set to 1, packet loss percentages will show packets still in transit as lost, even if they might still be received."); @@ -3752,6 +3753,7 @@ void CL_Init (void) Cvar_Register (&cl_noblink, "Console controls"); //for lack of a better group Cvar_Register (&cl_item_bobbing, "Item effects"); + Cvar_Register (&gl_simpleitems, "Item effects"); Cvar_Register (&cl_staticsounds, "Item effects"); @@ -4802,7 +4804,9 @@ double Host_Frame (double time) */ Mod_Think(); //think even on idle (which means small walls and a fast cpu can get more surfaces done. - if ((cl_netfps.value>0 || cls.demoplayback || cl_threadedphysics.ival)) + if (sv.state && cls.state != ca_active) + maxfps = 0; + else if ((cl_netfps.value>0 || cls.demoplayback || cl_threadedphysics.ival)) { //limit the fps freely, and expect the netfps to cope. maxfpsignoreserver = true; maxfps = cl_maxfps.ival; diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index f178e5a6d..0f04efbb7 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -4188,7 +4188,8 @@ void CL_ParseStaticSound (qboolean large) { extern cvar_t cl_staticsounds; vec3_t org; - int sound_num, vol, atten; + int sound_num; + float vol, atten; int i; for (i=0 ; i<3 ; i++) @@ -4197,8 +4198,8 @@ void CL_ParseStaticSound (qboolean large) sound_num = (unsigned short)MSG_ReadShort(); else sound_num = MSG_ReadByte (); - vol = MSG_ReadByte (); - atten = MSG_ReadByte (); + vol = MSG_ReadByte ()/255.0; + atten = MSG_ReadByte ()/64.0; vol *= cl_staticsounds.value; if (vol < 0) diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index bfaef20e3..bfd6763d3 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -1874,12 +1874,10 @@ void SCR_ImageName (char *mapname) #ifdef GLQUAKE if (qrenderer == QR_OPENGL) { - GL_BeginRendering (); SCR_DrawLoading(false); SCR_SetUpToDrawConsole(); if (Key_Dest_Has(kdm_console) || !*levelshotname) SCR_DrawConsole(!!*levelshotname); - GL_EndRendering(); } #endif scr_drawloading = false; diff --git a/engine/client/m_mp3.c b/engine/client/m_mp3.c index 2bcf62288..7855a41d0 100644 --- a/engine/client/m_mp3.c +++ b/engine/client/m_mp3.c @@ -7,6 +7,7 @@ #include "glquake.h"//fixme #endif #include "shader.h" +#include "gl_draw.h" #if !defined(NOMEDIA) #if defined(_WIN32) && !defined(WINRT) && !defined(NOMEDIAMENU) @@ -2475,14 +2476,16 @@ qboolean Media_ShowFilm(void) else if (cin) { int cw = cin->outwidth, ch = cin->outheight; - float ratiox, ratioy; + float ratiox, ratioy, aspect; if (cin->cursormove) cin->cursormove(cin, mousecursor_x/(float)vid.width, mousecursor_y/(float)vid.height); if (cin->setsize) cin->setsize(cin, vid.pixelwidth, vid.pixelheight); //FIXME: should have a proper aspect ratio setting. RoQ files are always power of two, which makes things ugly. - if (1) + if (cin->getsize) + cin->getsize(cin, &cw, &ch, &aspect); + else { cw = 4; ch = 3; @@ -3136,6 +3139,9 @@ void Media_RecordFrame (void) return; //skip until we're tracking the right player. } + if (R2D_Flush) + R2D_Flush(); + //submit the current video frame. audio will be mixed to match. buffer = VID_GetRGBInfo(0, &truewidth, &trueheight); if (buffer) @@ -3246,6 +3252,22 @@ void Media_InitFakeSoundDevice (int speed, int channels, int samplebits) if (capture_fakesounddevice) return; + //when we're recording a demo, we'll be timedemoing it as it were. + //this means that the actual sound devices and the fake device will be going at different rates + //which really confuses any stream decoding, like music. + //so just kill all actual sound devices. + if (recordingdemo) + { + soundcardinfo_t *next; + for (sc = sndcardinfo; sc; sc=next) + { + next = sc->next; + sc->Shutdown(sc); + Z_Free(sc); + sndcardinfo = next; + } + } + if (!snd_speed) snd_speed = speed; @@ -3289,6 +3311,9 @@ void Media_StopRecordFilm_f (void) S_ShutdownCard(capture_fakesounddevice); capture_fakesounddevice = NULL; + if (recordingdemo) //start up their regular audio devices again. + Cmd_ExecuteString("snd_restart", RESTRICT_LOCAL); + recordingdemo=false; if (currentcapture_funcs) diff --git a/engine/client/m_options.c b/engine/client/m_options.c index 3b4ec2ea9..23b4c483a 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -729,6 +729,7 @@ const char *presetexec[] = "seta cl_demoreel 0;" "seta cl_gibfilter 1;" "if cl_deadbodyfilter == 0 then seta cl_deadbodyfilter 1;" //as useful as 2 is, some mods use death frames for crouching etc. + "seta gl_simpleitems 1;" , // fast options "gl_texturemode ln;" @@ -743,6 +744,7 @@ const char *presetexec[] = "r_waterstyle 1;" "r_lavastyle 1;" "r_nolightdir 0;" + "seta gl_simpleitems 0;" , //vanilla options. "r_part_density 1;" diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 821ce9ac4..b1f382f31 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -5044,6 +5044,7 @@ static struct { {"max", PF_max, 95}, // #95 float(float a, floats) max (DP_QC_MINMAXBOUND) {"bound", PF_bound, 96}, // #96 float(float minimum, float val, float maximum) bound (DP_QC_MINMAXBOUND) {"pow", PF_pow, 97}, // #97 float(float value) pow (DP_QC_SINCOSSQRTPOW) + {"logarithm", PF_Logarithm, 0}, {"findfloat", PF_FindFloat, 98}, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT) {"findentity", PF_FindFloat, 98}, // #98 entity(entity start, .float fld, float match) findfloat (DP_QC_FINDFLOAT) {"checkextension", PF_checkextension, 99}, // #99 float(string extname) checkextension (EXT_CSQC) @@ -5510,6 +5511,7 @@ static struct { {"loadfromdata", PF_loadfromdata, 529}, {"loadfromfile", PF_loadfromfile, 530}, + {"log", PF_Logarithm, 532}, {"stopsound", PF_stopsound, 0}, {"soundupdate", PF_soundupdate, 0}, diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index cc0627450..17c6a444a 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -1916,6 +1916,7 @@ static struct { {"max", PF_max, 44}, {"bound", PF_bound, 45}, {"pow", PF_pow, 46}, + {"logarithm", PF_Logarithm, 0}, {"copyentity", PF_CopyEntity, 47}, {"fopen", PF_fopen, 48}, {"fclose", PF_fclose, 49}, @@ -2117,6 +2118,8 @@ static struct { {"buf_cvarlist", PF_buf_cvarlist, 517}, {"cvar_description", PF_cvar_description, 518}, //gap + {"log", PF_Logarithm, 532}, + //gap {"soundlength", PF_soundlength, 534}, {"buf_loadfile", PF_buf_loadfile, 535}, {"buf_writefile", PF_buf_writefile, 536}, diff --git a/engine/client/snd_al.c b/engine/client/snd_al.c index 406700fac..a01df6ad4 100644 --- a/engine/client/snd_al.c +++ b/engine/client/snd_al.c @@ -14,9 +14,11 @@ FIXME: a capture device would be useful (voice chat). #ifdef AVAIL_OPENAL #ifdef FTE_TARGET_WEB +#include //emscripten provides an openal -> webaudio wrapper. its not the best, but does get the job done. #define OPENAL_STATIC //our javascript port doesn't support dynamic linking (bss+data segments get too messy). #define SDRVNAME "WebAudio" //IE doesn't support webaudio, resulting in noticable error messages about no openal, which is technically incorrect. So lets be clear about this. + qboolean firefoxstaticsounds; //FireFox bugs out with static sounds. they all end up full volume AND THIS IS REALLY LOUD AND REALLY ANNOYING. #else #define SDRVNAME "OpenAL" #endif @@ -516,6 +518,11 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, unsigned if (chnum >= NUM_SOURCES) return; +#ifdef FTE_TARGET_WEB + if (firefoxstaticsounds && chan->dist_mult >= 3.0 / sound_nominal_clip_dist) + sfx = NULL; +#endif + src = oali->source[chnum]; if (!src) { @@ -716,7 +723,7 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, unsigned //this is disgustingly shit. //logically we want to set the distance divisor to 1 and the rolloff factor to dist_mult. //but openal clamps in an annoying order (probably to keep things signed in hardware) and webaudio refuses infinity, so we need to special case no attenuation to get around the issue - if (chan->dist_mult < 0.000001) + if (!chan->dist_mult) { palSourcef(src, AL_ROLLOFF_FACTOR, 0); palSourcef(src, AL_REFERENCE_DISTANCE, 0); @@ -767,6 +774,12 @@ static void S_Info (void) static qboolean OpenAL_InitLibrary(void) { +#if FTE_TARGET_WEB + firefoxstaticsounds = !!strstr(emscripten_run_script_string("navigator.userAgent"), "Firefox"); + if (firefoxstaticsounds) + Con_Printf("Firefox detected - disabling static sounds to avoid SORRY, I CAN'T HEAR YOU\n"); +#endif + #ifdef OPENAL_STATIC return true; #else diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 9090dfec5..2d20e582b 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -2670,8 +2670,8 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation) ss->sfx = sfx; ss->rate = 1<origin); - ss->master_vol = vol; - ss->dist_mult = (attenuation/64) / sound_nominal_clip_dist; + ss->master_vol = vol*255; + ss->dist_mult = attenuation / sound_nominal_clip_dist; ss->pos = 0; ss->flags = CF_FORCELOOP; diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 02a9b65ce..acc283af0 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -602,7 +602,6 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI { case EXCEPTION_ACCESS_VIOLATION: case EXCEPTION_DATATYPE_MISALIGNMENT: - case EXCEPTION_BREAKPOINT: case EXCEPTION_SINGLE_STEP: case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: case EXCEPTION_FLT_DENORMAL_OPERAND: @@ -624,9 +623,16 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI case EXCEPTION_INVALID_HANDLE: // case EXCEPTION_POSSIBLE_DEADLOCK: break; + case EXCEPTION_BREAKPOINT: + hKernel = LoadLibrary ("kernel32"); + pIsDebuggerPresent = (void*)GetProcAddress(hKernel, "IsDebuggerPresent"); + if (pIsDebuggerPresent && pIsDebuggerPresent()) + return EXCEPTION_CONTINUE_SEARCH; + break; + return EXCEPTION_CONTINUE_EXECUTION; default: //because windows is a steaming pile of shite, we have to ignore any software-generated exceptions, because most of them are not in fact fatal, *EVEN IF THEY CLAIM TO BE NON-CONTINUABLE* - return exceptionCode; + return EXCEPTION_CONTINUE_SEARCH; } #ifdef PRINTGLARRAYS diff --git a/engine/client/view.c b/engine/client/view.c index bd1e005b6..02c9756da 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -1631,24 +1631,28 @@ static void SCR_DrawAutoID(vec3_t org, player_info_t *pl, qboolean isteam) //display health bar if (scr_autoid_health.ival) { - if (health < 0) - health = 0; - r = health / 100; - health -= r*100; + float frac = health / 100; + if (frac < 0) + frac = 0; + r = frac; + frac -= r; if (r > countof(healthcolours)-2) { r = countof(healthcolours)-2; - health = 100; + frac = 1; } h += 8; y -= 8; R2D_ImageColours(healthcolours[r][0], healthcolours[r][1], healthcolours[r][2], healthcolours[r][3]*alpha); - R2D_FillBlock(x - barwidth*0.5 + barwidth * health/100.0, y, barwidth * (100-health)/100.0, 8); + R2D_FillBlock(x - barwidth*0.5 + barwidth * frac, y, barwidth * (1-frac), 8); r++; R2D_ImageColours(healthcolours[r][0], healthcolours[r][1], healthcolours[r][2], healthcolours[r][3]*alpha); - R2D_FillBlock(x - barwidth*0.5, y, barwidth * health/100.0, 8); + R2D_FillBlock(x - barwidth*0.5, y, barwidth * frac, 8); } + if (health <= 0) //armour+weapons are not relevant when dead + return; + if (scr_autoid_armour.ival) { //display armour bar above that diff --git a/engine/client/zqtp.c b/engine/client/zqtp.c index f4059aae8..2f4c75773 100644 --- a/engine/client/zqtp.c +++ b/engine/client/zqtp.c @@ -2938,7 +2938,7 @@ more: { item_t *item; entnum = FindNearestItem (org, it_ammo|it_pack|it_runes, &item); - if (!item && seat < 0) + if (!item) return; TP_ItemTaken (item->cvar->string, item->itemflag, org, entnum, item, seat); } diff --git a/engine/common/fs.c b/engine/common/fs.c index da30a525f..f4f91d176 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -2573,7 +2573,7 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths) /*set some stuff so our regular qw client appears more like hexen2. sv_mintic is required to 'fix' the ravenstaff so that its projectiles don't impact upon each other*/ #define HEX2CFG "set com_parseutf8 -1\nset gl_font gfx/hexen2\nset in_builtinkeymap 0\nset_calc cl_playerclass int (random * 5) + 1\nset sv_maxspeed 640\ncl_run 0\nset watervis 1\nset r_lavaalpha 1\nset r_lavastyle -2\nset r_wateralpha 0.5\nset sv_pupglow 1\ngl_shaftlight 0.5\nsv_mintic 0.015\nset mod_warnmodels 0\nset cl_model_bobbing 1\nsv_sound_land \"fx/thngland.wav\"\n" /*yay q2!*/ -#define Q2CFG "com_nogamedirnativecode 0\n" +#define Q2CFG "com_nogamedirnativecode 0\nset sv_bigcoords 0\n" /*Q3's ui doesn't like empty model/headmodel/handicap cvars, even if the gamecode copes*/ #define Q3CFG "gl_overbright 2\nseta model sarge\nseta headmodel sarge\nseta handicap 100\ncom_nogamedirnativecode 0\n" //#define RMQCFG "sv_bigcoords 1\n" @@ -2822,6 +2822,10 @@ void FS_PureMode(int puremode, char *purenamelist, char *purecrclist, char *refn { qboolean pureflush; + //if we're the server, we can't be impure. + if (sv.state) + return; + if (puremode == fs_puremode && fs_pureseed == pureseed) { if ((!purenamelist && !fs_purenames) || !strcmp(fs_purenames?fs_purenames:"", purenamelist?purenamelist:"")) diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index cb1d8c730..84c4976b2 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -3102,6 +3102,16 @@ void QCBUILTIN PF_vtos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) RETURN_TSTRING(pr_string_temp); } +void QCBUILTIN PF_Logarithm (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + //log2(v) = ln(v)/ln(2) + double r; + r = log(G_FLOAT(OFS_PARM0)); + if (prinst->callargc > 1) + r /= log(G_FLOAT(OFS_PARM1)); + G_FLOAT(OFS_RETURN) = r; +} + void QCBUILTIN PF_strunzone(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { diff --git a/engine/common/pr_common.h b/engine/common/pr_common.h index e25f294f8..f0075b233 100644 --- a/engine/common/pr_common.h +++ b/engine/common/pr_common.h @@ -135,6 +135,7 @@ void QCBUILTIN PF_min (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_max (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_registercvar (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_pow (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +void QCBUILTIN PF_Logarithm (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_asin (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_acos (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_atan (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); diff --git a/engine/dotnet2005/ftequake.sln b/engine/dotnet2005/ftequake.sln index bf450ed4e..7aa9e47a6 100644 --- a/engine/dotnet2005/ftequake.sln +++ b/engine/dotnet2005/ftequake.sln @@ -51,6 +51,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odeplug", "..\..\plugins\od EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ezhud", "..\..\plugins\ezhud\ezhud.vcproj", "{E475BFF0-6766-48BA-BE44-931C068AC5B0}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cef", "..\..\plugins\cef\cef.vcproj", "{F756A3D2-025A-43D4-9829-4074753B774B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution D3DDebug|Win32 = D3DDebug|Win32 @@ -741,6 +743,52 @@ Global {E475BFF0-6766-48BA-BE44-931C068AC5B0}.Release|Win32.ActiveCfg = Release|Win32 {E475BFF0-6766-48BA-BE44-931C068AC5B0}.Release|Win32.Build.0 = Release|Win32 {E475BFF0-6766-48BA-BE44-931C068AC5B0}.Release|x64.ActiveCfg = Release|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.D3DDebug|Win32.ActiveCfg = Debug|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.D3DDebug|Win32.Build.0 = Debug|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.D3DDebug|x64.ActiveCfg = Debug|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.D3DDebug|x64.Build.0 = Debug|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.D3DRelease|Win32.ActiveCfg = Release|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.D3DRelease|Win32.Build.0 = Release|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.D3DRelease|x64.ActiveCfg = Release|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.D3DRelease|x64.Build.0 = Release|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.Debug Dedicated Server|Win32.ActiveCfg = Debug|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.Debug Dedicated Server|x64.ActiveCfg = Debug|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.Debug Dedicated Server|x64.Build.0 = Debug|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.Debug|Win32.ActiveCfg = Debug|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.Debug|Win32.Build.0 = Debug|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.Debug|x64.ActiveCfg = Debug|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.Debug|x64.Build.0 = Debug|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.GLDebug|Win32.ActiveCfg = Debug|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.GLDebug|Win32.Build.0 = Debug|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.GLDebug|x64.ActiveCfg = Debug|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.GLDebug|x64.Build.0 = Debug|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.GLRelease|Win32.ActiveCfg = Release|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.GLRelease|Win32.Build.0 = Release|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.GLRelease|x64.ActiveCfg = Release|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.GLRelease|x64.Build.0 = Release|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.MDebug|Win32.ActiveCfg = Debug|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.MDebug|Win32.Build.0 = Debug|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.MDebug|x64.ActiveCfg = Debug|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.MDebug|x64.Build.0 = Debug|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.MinGLDebug|Win32.Build.0 = Debug|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.MinGLDebug|x64.ActiveCfg = Debug|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.MinGLDebug|x64.Build.0 = Debug|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.MinGLRelease|Win32.ActiveCfg = Release|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.MinGLRelease|Win32.Build.0 = Release|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.MinGLRelease|x64.ActiveCfg = Release|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.MinGLRelease|x64.Build.0 = Release|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.MRelease|Win32.ActiveCfg = Release|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.MRelease|Win32.Build.0 = Release|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.MRelease|x64.ActiveCfg = Release|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.MRelease|x64.Build.0 = Release|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.Release Dedicated Server|Win32.ActiveCfg = Release|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.Release Dedicated Server|x64.ActiveCfg = Release|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.Release Dedicated Server|x64.Build.0 = Release|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.Release|Win32.ActiveCfg = Release|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.Release|Win32.Build.0 = Release|Win32 + {F756A3D2-025A-43D4-9829-4074753B774B}.Release|x64.ActiveCfg = Release|x64 + {F756A3D2-025A-43D4-9829-4074753B774B}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -761,6 +809,7 @@ Global {82285268-9C3B-44AD-BBE7-40670F9D2628} = {8CED01C6-2C61-4EC5-90B6-574D9756D773} {ED16B405-BDCD-4EB8-BF70-761964301368} = {8CED01C6-2C61-4EC5-90B6-574D9756D773} {E475BFF0-6766-48BA-BE44-931C068AC5B0} = {8CED01C6-2C61-4EC5-90B6-574D9756D773} + {F756A3D2-025A-43D4-9829-4074753B774B} = {8CED01C6-2C61-4EC5-90B6-574D9756D773} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution AMDCaProjectFile = C:\Games\Quake\wip\engine\dotnet2005\CodeAnalyst\ftequake.caw diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 6dde88b67..c3dcc036e 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -2249,6 +2249,8 @@ static void R_Sprite_GenerateTrisoup(entity_t *e, int bemode) batchflags |= BEF_FORCECOLOURMOD; if (shader->flags & SHADER_NODLIGHT) batchflags |= BEF_NODLIGHT; +// if (shader->flags & RF_TWOSIDED) +// batchflags |= BEF_FORCETWOSIDED; if ((batchflags & BEF_NODLIGHT) || (shader->flags & SHADER_NODLIGHT) || bemode != BEM_STANDARD) { @@ -2330,8 +2332,8 @@ static void R_Sprite_GenerateTrisoup(entity_t *e, int bemode) if (!frame) { - genframe.up = genframe.left = -1; - genframe.down = genframe.right = 1; + genframe.down = genframe.left = -1; + genframe.up = genframe.right = 1; sprtype = SPR_VP_PARALLEL; frame = &genframe; } diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index b7d7c9138..47eeedb9b 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -1327,7 +1327,8 @@ static float *FTableForFunc ( unsigned int func ) void Shader_LightPass(const char *shortname, shader_t *s, const void *args) { char shadertext[8192*2]; - sprintf(shadertext, LIGHTPASS_SHADER, ""); + extern cvar_t r_drawflat; + sprintf(shadertext, LIGHTPASS_SHADER, r_drawflat.ival?"#FLAT":""); Shader_DefaultScript(shortname, s, shadertext); } diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index 3c65af163..beffa1f9a 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -61,10 +61,6 @@ void GLDraw_Init (void) { R2D_Init(); - TRACE(("dbg: GLDraw_ReInit: GL_BeginRendering\n")); - GL_BeginRendering (); - TRACE(("dbg: GLDraw_ReInit: SCR_DrawLoading\n")); - qglDisable(GL_SCISSOR_TEST); GL_Set2D(false); @@ -78,7 +74,8 @@ void GLDraw_Init (void) } TRACE(("dbg: GLDraw_ReInit: GL_EndRendering\n")); - GL_EndRendering (); + if (R2D_Flush) + R2D_Flush(); VID_SwapBuffers(); GL_SetupSceneProcessingTextures(); diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index e2d35e6c9..a033ab415 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -941,6 +941,7 @@ typedef struct model_s int entitiescrc; struct doll_s *dollinfo; + shader_t *simpleskin[4]; struct { texture_t *tex; diff --git a/engine/gl/gl_rmisc.c b/engine/gl/gl_rmisc.c index cea7bbf6a..453bb1581 100644 --- a/engine/gl/gl_rmisc.c +++ b/engine/gl/gl_rmisc.c @@ -518,9 +518,10 @@ void GLR_TimeRefresh_f (void) time = stop-start; Con_Printf ("%f seconds (%f fps)\n", time, frames/time); + if (R2D_Flush) + R2D_Flush(); if (qglDrawBuffer) qglDrawBuffer (GL_BACK); - GL_EndRendering (); VID_SwapBuffers(); } diff --git a/engine/gl/gl_screen.c b/engine/gl/gl_screen.c index f44d8c947..c730cf3d0 100644 --- a/engine/gl/gl_screen.c +++ b/engine/gl/gl_screen.c @@ -83,12 +83,12 @@ void GLSCR_UpdateScreen (void) scr_disabled_for_loading = false; } else - { - GL_BeginRendering (); + { scr_drawloading = true; SCR_DrawLoading (true); scr_drawloading = false; - GL_EndRendering (); + if (R2D_Flush) + R2D_Flush(); VID_SwapBuffers(); RSpeedEnd(RSPEED_TOTALREFRESH); return; @@ -104,7 +104,6 @@ void GLSCR_UpdateScreen (void) Shader_DoReload(); - GL_BeginRendering (); qglDisable(GL_SCISSOR_TEST); #ifdef VM_UI uimenu = UI_MenuState(); @@ -125,7 +124,8 @@ void GLSCR_UpdateScreen (void) if (key_dest_mask & kdm_console) Con_DrawConsole(vid.height/2, false); SCR_DrawCursor(); - GL_EndRendering (); + if (R2D_Flush) + R2D_Flush(); VID_SwapBuffers(); RSpeedEnd(RSPEED_TOTALREFRESH); return; @@ -139,7 +139,8 @@ void GLSCR_UpdateScreen (void) Media_RecordFrame(); #endif R2D_BrightenScreen(); - GL_EndRendering (); + if (R2D_Flush) + R2D_Flush(); GL_Set2D (false); VID_SwapBuffers(); RSpeedEnd(RSPEED_TOTALREFRESH); @@ -156,18 +157,6 @@ void GLSCR_UpdateScreen (void) if (r_clear.ival) { - int i = r_clear.ival&7; - vec3_t cleartab[] = - { - {0,0,0}, //black - {1,0,0}, //red - {0,1,0}, //green - {1,1,0}, // - {0,0,1}, //blue - {1,0,1}, // - {0,1,1}, // - {1,1,1} //white - }; GL_ForceDepthWritable(); qglClearColor((r_clear.ival&1)?1:0, (r_clear.ival&2)?1:0, (r_clear.ival&4)?1:0, 1); qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -223,13 +212,13 @@ void GLSCR_UpdateScreen (void) Media_RecordFrame(); #endif - RSpeedEnd(RSPEED_TOTALREFRESH); - RSpeedShow(); if (R2D_Flush) R2D_Flush(); + RSpeedEnd(RSPEED_TOTALREFRESH); + RSpeedShow(); + RSpeedRemark(); - GL_EndRendering (); VID_SwapBuffers(); RSpeedEnd(RSPEED_FINISH); @@ -312,7 +301,7 @@ char *GLVID_GetRGBInfo(int prepadbytes, int *truewidth, int *trueheight) if (gammaworks) { - c = prepadbytes+(*truewidth), (*trueheight)*3; + c = prepadbytes+(*truewidth)*(*trueheight)*3; for (i=prepadbytes ; iflags |= SHADER_ENTITY_MERGABLE; } +static qboolean Shader_ParseProgramCvar(char *script, cvar_t **cvarrefs, char **cvarnames, int *cvartypes, int cvartype) +{ + char body[MAX_QPATH]; + char *out; + char *namestart; + while (*script == ' ' || *script == '\t') + script++; + namestart = script; + while ((*script >= 'A' && *script <= 'Z') || (*script >= 'a' && *script <= 'z') || (*script >= '0' && *script <= '9') || *script == '_') + script++; + + cvartypes[0] = cvartype; + cvarnames[0] = Z_Malloc(script - namestart + 1); + memcpy(cvarnames[0], namestart, script - namestart); + cvarnames[0][script - namestart] = 0; + cvarnames[1] = NULL; + + while (*script == ' ' || *script == '\t') + script++; + if (*script == '=') + { + script++; + while (*script == ' ' || *script == '\t') + script++; + + out = body; + while (out < com_token+countof(body) && *script != '\n') + *out++; + cvarrefs[0] = Cvar_Get(cvarnames[0], body, 0, "GLSL Variables"); + } + else + cvarrefs[0] = Cvar_Get(cvarnames[0], "", 0, "GLSL Variables"); + return true; +} + /*program text is already loaded, this function parses the 'header' of it to see which permutations it provides, and how many times we need to recompile it*/ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *script, int qrtype, int ver, char *blobfilename) { @@ -989,6 +1024,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip qboolean geom = false; qboolean tess = false; + cvar_t *cvarrefs[64]; char *cvarnames[64]; int cvartypes[64]; int cvarcount = 0; @@ -1129,51 +1165,18 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip } else if (!strncmp(script, "!!cvarf", 7)) { - script += 7; - while (*script == ' ' || *script == '\t') - script++; - end = script; - while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') || *end == '_') - end++; if (cvarcount+1 != sizeof(cvarnames)/sizeof(cvarnames[0])) - { - cvartypes[cvarcount] = SP_CVARF; - cvarnames[cvarcount++] = script; - cvarnames[cvarcount] = NULL; - } - script = end; + cvarcount += Shader_ParseProgramCvar(script+7, &cvarrefs[cvarcount], &cvarnames[cvarcount], &cvartypes[cvarcount], SP_CVARF); } else if (!strncmp(script, "!!cvari", 7)) { - script += 7; - while (*script == ' ' || *script == '\t') - script++; - end = script; - while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') || *end == '_') - end++; if (cvarcount+1 != sizeof(cvarnames)/sizeof(cvarnames[0])) - { - cvartypes[cvarcount] = SP_CVARI; - cvarnames[cvarcount++] = script; - cvarnames[cvarcount] = NULL; - } - script = end; + cvarcount += Shader_ParseProgramCvar(script+7, &cvarrefs[cvarcount], &cvarnames[cvarcount], &cvartypes[cvarcount], SP_CVARI); } else if (!strncmp(script, "!!cvarv", 7)) { - script += 7; - while (*script == ' ' || *script == '\t') - script++; - end = script; - while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') || *end == '_') - end++; if (cvarcount+1 != sizeof(cvarnames)/sizeof(cvarnames[0])) - { - cvartypes[cvarcount] = SP_CVAR3F; - cvarnames[cvarcount++] = script; - cvarnames[cvarcount] = NULL; - } - script = end; + cvarcount += Shader_ParseProgramCvar(script+7, &cvarrefs[cvarcount], &cvarnames[cvarcount], &cvartypes[cvarcount], SP_CVAR3F); } else if (!strncmp(script, "!!permu", 7)) { @@ -1456,7 +1459,10 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip } if (sh_config.pProgAutoFields) - sh_config.pProgAutoFields(prog, name, cvarnames, cvartypes); + sh_config.pProgAutoFields(prog, name, cvarrefs, cvarnames, cvartypes); + + while(cvarcount) + Z_Free((char*)cvarnames[--cvarcount]); if (blobfile && blobadded) { @@ -1498,7 +1504,7 @@ void Shader_UnloadProg(program_t *prog) sh_config.pDeleteProg(prog, p); } - free(prog); + Z_Free(prog); } static void Shader_FlushGenerics(void) { @@ -1553,6 +1559,13 @@ static void Shader_LoadGeneric(sgeneric_t *g, int qrtype) *blobname = 0; } + if (sh_config.pDeleteProg) + { + int p; + for (p = 0; p < PERMUTATIONS; p++) + sh_config.pDeleteProg(&g->prog, p); + } + if (file) { Con_DPrintf("Loaded %s from disk\n", va(sh_config.progpath, basicname)); @@ -1601,7 +1614,7 @@ static program_t *Shader_FindGeneric(char *name, int qrtype) if (!sh_config.progs_supported) return NULL; - g = malloc(sizeof(*g) + strlen(name)+1); + g = BZ_Malloc(sizeof(*g) + strlen(name)+1); memset(g, 0, sizeof(*g)); g->name = (char*)(g+1); strcpy(g->name, name); @@ -1621,6 +1634,7 @@ static void Shader_ReloadGenerics(void) sgeneric_t *g; for (g = sgenerics; g; g = g->next) { + //this happens if some cvar changed that affects the glsl itself. supposedly. Shader_LoadGeneric(g, qrenderer); } @@ -1809,12 +1823,12 @@ static void Shader_SLProgramName (shader_t *shader, shaderpass_t *pass, char **p programbody = Shader_ParseBody(shader->name, ptr); if (programbody) { - shader->prog = malloc(sizeof(*shader->prog)); + shader->prog = BZ_Malloc(sizeof(*shader->prog)); memset(shader->prog, 0, sizeof(*shader->prog)); shader->prog->refs = 1; if (!Shader_LoadPermutations(shader->name, shader->prog, programbody, qrtype, 0, NULL)) { - free(shader->prog); + BZ_Free(shader->prog); shader->prog = NULL; } @@ -5221,7 +5235,6 @@ void Shader_DefaultBSPVertex(const char *shortname, shader_t *s, const void *arg s->numdeforms = 0; s->flags = SHADER_DEPTHWRITE|SHADER_CULL_FRONT; s->sort = SHADER_SORT_OPAQUE; - s->uses = 1; } void Shader_DefaultBSPFlare(const char *shortname, shader_t *s, const void *args) { @@ -5250,7 +5263,6 @@ void Shader_DefaultBSPFlare(const char *shortname, shader_t *s, const void *args s->numdeforms = 0; s->flags = SHADER_FLARE; s->sort = SHADER_SORT_ADDITIVE; - s->uses = 1; s->flags |= SHADER_NODRAW; } @@ -5473,7 +5485,6 @@ static void Shader_ReadShader(shader_t *s, char *shadersource, int parsemode) // set defaults s->flags = SHADER_CULL_FRONT; - s->uses = 1; while (Shader_ReadShaderTerms(s, &shadersource, parsemode, &conddepth, sizeof(cond)/sizeof(cond[0]), cond)) { @@ -5532,6 +5543,11 @@ static qboolean Shader_ParseShader(char *parsename, shader_t *s) } void R_UnloadShader(shader_t *shader) { + if (shader->uses <= 0) + { + Con_Printf("Shader double free (%s %i)\n", shader->name, shader->usageflags); + return; + } if (--shader->uses == 0) Shader_Free(shader); } @@ -5619,15 +5635,16 @@ static shader_t *R_LoadShader (const char *name, unsigned int usageflags, shader r_numshaders = f+1; if (!s->defaulttextures) - { s->defaulttextures = Z_Malloc(sizeof(*s->defaulttextures)); - s->numdefaulttextures = 0; - } + else + memset(s->defaulttextures, 0, sizeof(*s->defaulttextures)); + s->numdefaulttextures = 0; Q_strncpyz(s->name, cleanname, sizeof(s->name)); s->usageflags = usageflags; s->generator = defaultgen; s->width = 0; s->height = 0; + s->uses = 1; if (genargs) s->genargs = strdup(genargs); else diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index 4df24e5a2..e799b71a3 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -2250,14 +2250,18 @@ static qboolean GLSlang_LoadBlob(program_t *prog, const char *name, unsigned int static void GLSlang_DeleteProg(program_t *prog, unsigned int permu) { - if (prog->permu[permu].h.glsl.handle) + if (prog->permu[permu].h.loaded) { qglDeleteProgramObject_(prog->permu[permu].h.glsl.handle); prog->permu[permu].h.glsl.handle = 0; + + BZ_Free(prog->permu[permu].parm); + prog->permu[permu].parm = NULL; + prog->permu[permu].numparms = 0; } } -static void GLSlang_ProgAutoFields(program_t *prog, const char *progname, char **cvarnames, int *cvartypes) +static void GLSlang_ProgAutoFields(program_t *prog, const char *progname, cvar_t **cvars, char **cvarnames, int *cvartypes) { static const char *defaultsamplers[] = { @@ -2286,10 +2290,9 @@ static void GLSlang_ProgAutoFields(program_t *prog, const char *progname, char * #define ALTLIGHTMAPSAMP 13 #define ALTDELUXMAPSAMP 16 - unsigned int i, j, p; + unsigned int i, p; int uniformloc; char tmpname[128]; - cvar_t *cvar[128]; struct programpermu_s *pp; //figure out visible attributes @@ -2311,7 +2314,6 @@ static void GLSlang_ProgAutoFields(program_t *prog, const char *progname, char * } } - memset(cvar, 0, sizeof(cvar)); prog->numsamplers = 0; prog->defaulttextures = 0; for (p = 0; p < PERMUTATIONS; p++) @@ -2336,35 +2338,19 @@ static void GLSlang_ProgAutoFields(program_t *prog, const char *progname, char * } pp->parm[pp->numparms].type = shader_unif_names[i].ptype; pp->parm[pp->numparms].handle = uniformloc; + pp->parm[pp->numparms].pval = NULL; pp->numparms++; } } /*set cvar uniforms*/ /*FIXME: enumerate cvars automatically instead*/ - for (i = 0; cvarnames[i] && i < countof(cvar); i++) - { - char *tmpval; - - if (!cvar[i]) - { - for (j = 0; cvarnames[i][j] && (unsigned char)cvarnames[i][j] > 32 && j < sizeof(tmpname)-1; j++) - tmpname[j] = cvarnames[i][j]; - tmpname[j] = 0; - tmpval = strchr(tmpname, '='); - if (tmpval) - *tmpval++ = 0; - else - tmpval = "0"; - while(j > 0 && (tmpname[j-1] == ' ' || tmpname[j-1] == '\t')) - tmpname[--j] = 0; - cvar[i] = Cvar_Get(tmpname, tmpval, CVAR_SHADERSYSTEM, "glsl cvars"); - if (!cvar[i]) - continue; - //cvar[i]->flags |= CVAR_SHADERSYSTEM; - } + for (i = 0; cvarnames[i]; i++) + { + if (!cvars[i]) + continue; - uniformloc = qglGetUniformLocationARB(pp->h.glsl.handle, va("cvar_%s", cvar[i]->name)); + uniformloc = qglGetUniformLocationARB(pp->h.glsl.handle, va("cvar_%s", cvarnames[i])); if (uniformloc >= 0) { if (pp->numparms >= maxparms) @@ -2373,7 +2359,7 @@ static void GLSlang_ProgAutoFields(program_t *prog, const char *progname, char * pp->parm = BZ_Realloc(pp->parm, sizeof(*pp->parm) * maxparms); } pp->parm[pp->numparms].type = cvartypes[i]; - pp->parm[pp->numparms].pval = cvar[i]; + pp->parm[pp->numparms].pval = cvars[i]; pp->parm[pp->numparms].handle = uniformloc; pp->numparms++; } diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index 0664cbfd7..6a92998fe 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -154,9 +154,6 @@ void Mod_LightmapAllocBlock(lmalloc_t *lmallocator, int w, int h, unsigned short void GL_InitFogTexture(void); -#define GL_BeginRendering() -#define GL_EndRendering() - // Function prototypes for the Texture Object Extension routines typedef GLboolean (APIENTRY *ARETEXRESFUNCPTR)(GLsizei, const GLuint *, const GLboolean *); diff --git a/engine/gl/shader.h b/engine/gl/shader.h index 9450e457a..af2865624 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -684,7 +684,7 @@ typedef struct qboolean (*pLoadBlob) (program_t *prog, const char *name, unsigned int permu, vfsfile_t *blobfile); qboolean (*pCreateProgram) (program_t *prog, const char *name, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *tcs, const char *tes, const char *geom, const char *frag, qboolean noerrors, vfsfile_t *blobfile); qboolean (*pValidateProgram)(program_t *prog, const char *name, unsigned int permu, qboolean noerrors, vfsfile_t *blobfile); - void (*pProgAutoFields) (program_t *prog, const char *name, char **cvarnames, int *cvartypes); + void (*pProgAutoFields) (program_t *prog, const char *name, cvar_t **cvars, char **cvarnames, int *cvartypes); } sh_config_t; extern sh_config_t sh_config; #endif diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index a9442b773..eac2a7009 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -6282,7 +6282,7 @@ void log(string name, float console, string text) ================= */ -static void QCBUILTIN PF_log(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) +static void QCBUILTIN PF_logtext(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { char name[MAX_OSPATH], *text; vfsfile_t *file; @@ -9383,7 +9383,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"mvdstrcpy", PF_MVDSV_strcpy, 0, 0, 0, 97, D("void(string dst, string src)",NULL), true}, {"strstr", PF_strstr, 0, 0, 0, 98, D("string(string str, string sub)",NULL), true}, {"mvdstrncpy", PF_MVDSV_strncpy, 0, 0, 0, 99, D("void(string dst, string src, float count)",NULL), true}, - {"log", PF_log, 0, 0, 0, 100, D("void(string name, float console, string text)",NULL), true}, + {"log", PF_logtext, 0, 0, 0, 100, D("void(string name, float console, string text)",NULL), true}, // {"redirectcmd", PF_redirectcmd, 0, 0, 0, 101, D("void(entity to, string str)",NULL), true}, {"mvdcalltimeofday",PF_calltimeofday, 0, 0, 0, 102, D("void()",NULL), true}, {"forcedemoframe", PF_forcedemoframe, 0, 0, 0, 103, D("void(float now)",NULL), true}, @@ -9442,6 +9442,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"max", PF_max, 0, 0, 0, 95, D("float(float a, float b, ...)", "Returns the highest value of its arguments.")},// (DP_QC_MINMAXBOUND) {"bound", PF_bound, 0, 0, 0, 96, D("float(float minimum, float val, float maximum)", "Returns val, unless minimum is higher, or maximum is less.")},// (DP_QC_MINMAXBOUND) {"pow", PF_pow, 0, 0, 0, 97, "float(float value, float exp)"}, + {"logarithm", PF_Logarithm, 0, 0, 0, 0, D("float(float v, optional float base)", "Determines the logarithm of the input value according to the specified base. This can be used to calculate how much something was shifted by.")}, {"tj_cvar_string", PF_cvar_string, 0, 0, 0, 97, D("string(string cvarname)",NULL), true}, //telejano //DP_QC_FINDFLOAT {"findfloat", PF_FindFloat, 0, 0, 0, 98, D("entity(entity start, .float fld, float match)", "Equivelent to the find builtin, but instead of comparing strings, this builtin compares floats. This builtin requires multiple calls in order to scan all entities - set start to the previous call's return value.\nworld is returned when there are no more entities.")}, // #98 (DP_QC_FINDFLOAT) @@ -9979,7 +9980,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"precache_vwep_model",PF_precache_vwep_model,0,0, 0, 532, "float(string mname)"}, //end mvdsv extras //restart dp extras -// {"log", PF_Fixme, 0, 0, 0, 532, "float(string mname)", true}, +// {"log", PF_Logarithm, 0, 0, 0, 532, "float(float v, float base)", true}, {"soundupdate", PF_Fixme, 0, 0, 0, 0, D("float(entity e, float channel, string newsample, float volume, float attenuation, float pitchpct, float flags, float timeoffset)", "Changes the properties of the current sound being played on the given entity channel. newsample may be empty, and will be ignored in this case. timeoffset is relative to the current position (subtract the result of getsoundtime for absolute positions). Negative volume can be used to stop the sound. Return value is a fractional value based upon the number of audio devices that could be updated - test against TRUE rather than non-zero.")}, {"getsoundtime", PF_Ignore, 0, 0, 0, 533, D("float(entity e, float channel)", "Returns the current playback time of the sample on the given entity's channel. Beware CHAN_AUTO (in csqc, channels are not limited by network protocol).")}, {"soundlength", PF_Ignore, 0, 0, 0, 534, D("float(string sample)", "Provides a way to query the duration of a sound sample, allowing you to set up a timer to chain samples.")}, diff --git a/engine/shaders/glsl/rtlight.glsl b/engine/shaders/glsl/rtlight.glsl index f844d5b36..a8eaa146a 100644 --- a/engine/shaders/glsl/rtlight.glsl +++ b/engine/shaders/glsl/rtlight.glsl @@ -111,34 +111,34 @@ void main () #ifdef FRAGMENT_SHADER #include "sys/fog.h" -uniform sampler2D s_t0; //diffuse +uniform sampler2D s_diffuse; //diffuse #if defined(BUMP) || defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK) -uniform sampler2D s_t1; //normalmap +uniform sampler2D s_normalmap; //normalmap #endif #ifdef SPECULAR -uniform sampler2D s_t2; //specular +uniform sampler2D s_specular; //specular #endif #ifdef CUBE -uniform samplerCube s_t3; //projected cubemap +uniform samplerCube s_projectionmap; //projected cubemap #endif #ifdef PCF #ifdef CUBESHADOW -uniform samplerCubeShadow s_t4; //shadowmap +uniform samplerCubeShadow s_shadowmap; //shadowmap #else #if 0//def GL_ARB_texture_gather -uniform sampler2D s_t4; +uniform sampler2D s_shadowmap; #else -uniform sampler2DShadow s_t4; +uniform sampler2DShadow s_shadowmap; #endif #endif #endif #ifdef LOWER -uniform sampler2D s_t5; //pants colours +uniform sampler2D s_lower; //pants colours uniform vec3 e_lowercolour; #endif #ifdef UPPER -uniform sampler2D s_t6; //shirt colours +uniform sampler2D s_upper; //shirt colours uniform vec3 e_uppercolour; #endif @@ -162,7 +162,7 @@ vec3 ShadowmapCoord(void) return ((vtexprojcoord.xyz-vec3(0.0,0.0,0.015))/vtexprojcoord.w + vec3(1.0, 1.0, 1.0)) * vec3(0.5, 0.5, 0.5); //#elif defined(CUBESHADOW) // vec3 shadowcoord = vshadowcoord.xyz / vshadowcoord.w; -// #define dosamp(x,y) shadowCube(s_t4, shadowcoord + vec2(x,y)*texscale.xy).r +// #define dosamp(x,y) shadowCube(s_shadowmap, shadowcoord + vec2(x,y)*texscale.xy).r #else //figure out which axis to use //texture is arranged thusly: @@ -207,7 +207,7 @@ float ShadowmapFilter(void) #if 0//def GL_ARB_texture_gather vec2 ipart, fpart; - #define dosamp(x,y) textureGatherOffset(s_t4, ipart.xy, vec2(x,y))) + #define dosamp(x,y) textureGatherOffset(s_shadowmap, ipart.xy, vec2(x,y))) vec4 tl = step(shadowcoord.z, dosamp(-1.0, -1.0)); vec4 bl = step(shadowcoord.z, dosamp(-1.0, 1.0)); vec4 tr = step(shadowcoord.z, dosamp(1.0, -1.0)); @@ -222,10 +222,10 @@ float ShadowmapFilter(void) #else #ifdef USE_ARB_SHADOW //with arb_shadow, we can benefit from hardware acclerated pcf, for smoother shadows - #define dosamp(x,y) shadow2D(s_t4, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx)).r + #define dosamp(x,y) shadow2D(s_shadowmap, shadowcoord.xyz + (vec3(x,y,0.0)*l_shadowmapscale.xyx)).r #else //this will probably be a bit blocky. - #define dosamp(x,y) float(texture2D(s_t4, shadowcoord.xy + (vec2(x,y)*l_shadowmapscale.xy)).r >= shadowcoord.z) + #define dosamp(x,y) float(texture2D(s_shadowmap, shadowcoord.xy + (vec2(x,y)*l_shadowmapscale.xy)).r >= shadowcoord.z) #endif float s = 0.0; #if r_glsl_pcf >= 1 && r_glsl_pcf < 5 @@ -263,25 +263,29 @@ void main () { //read raw texture samples (offsetmapping munges the tex coords first) #ifdef OFFSETMAPPING - vec2 tcoffsetmap = offsetmap(s_t1, tcbase, eyevector); + vec2 tcoffsetmap = offsetmap(s_normalmap, tcbase, eyevector); #define tcbase tcoffsetmap #endif - vec3 bases = vec3(texture2D(s_t0, tcbase)); +#if defined(FLAT) + vec3 bases = vec3(1.0); +#else + vec3 bases = vec3(texture2D(s_diffuse, tcbase)); +#endif #ifdef UPPER - vec4 uc = texture2D(s_t6, tcbase); + vec4 uc = texture2D(s_upper, tcbase); bases.rgb += uc.rgb*e_uppercolour*uc.a; #endif #ifdef LOWER - vec4 lc = texture2D(s_t5, tcbase); + vec4 lc = texture2D(s_lower, tcbase); bases.rgb += lc.rgb*e_lowercolour*lc.a; #endif #if defined(BUMP) || defined(SPECULAR) || defined(REFLECTCUBEMASK) - vec3 bumps = normalize(vec3(texture2D(s_t1, tcbase)) - 0.5); + vec3 bumps = normalize(vec3(texture2D(s_normalmap, tcbase)) - 0.5); #elif defined(REFLECTCUBEMASK) vec3 bumps = vec3(0.0,0.0,1.0); #endif #ifdef SPECULAR - vec4 specs = texture2D(s_t2, tcbase); + vec4 specs = texture2D(s_specular, tcbase); #endif float colorscale = max(1.0 - (dot(lightvector, lightvector)/(l_lightradius*l_lightradius)), 0.0); @@ -315,7 +319,7 @@ void main () #ifdef CUBE /*filter the colour by the cubemap projection*/ - diff *= textureCube(s_t3, vtexprojcoord.xyz).rgb; + diff *= textureCube(s_projectionmap, vtexprojcoord.xyz).rgb; #endif #if defined(SPOT) @@ -333,7 +337,7 @@ void main () #if defined(PROJECTION) /*2d projection, not used*/ -// diff *= texture2d(s_t3, shadowcoord); +// diff *= texture2d(s_projectionmap, shadowcoord); #endif gl_FragColor.rgb = fog3additive(diff*colorscale*l_lightcolour); diff --git a/plugins/jabber/jabberclient.c b/plugins/jabber/jabberclient.c index c5662f278..aafb657a5 100644 --- a/plugins/jabber/jabberclient.c +++ b/plugins/jabber/jabberclient.c @@ -2783,6 +2783,7 @@ static qboolean JCL_BindReply(jclient_t *jcl, xmltree_t *tree, struct iq_s *iq) } static qboolean JCL_BuddyVCardReply(jclient_t *jcl, xmltree_t *tree, struct iq_s *iq) { + char myself[256]; char photodata[65536]; xmltree_t *vc, *photo, *photobinval; const char *nickname; @@ -2791,6 +2792,12 @@ static qboolean JCL_BuddyVCardReply(jclient_t *jcl, xmltree_t *tree, struct iq_s buddy_t *b; char *from = iq->to; + if (!*from) + { + Q_snprintf(myself, sizeof(myself), "%s@%s", jcl->username, jcl->domain); + from = myself; + } + if (jcl->avatarupdate == iq) { if (!tree) @@ -2894,8 +2901,6 @@ static qboolean JCL_MyVCardReply(jclient_t *jcl, xmltree_t *tree, struct iq_s *i //hack the from parametmer so it looks legit Q_snprintf(photodata, sizeof(photodata), "%s@%s", jcl->username, jcl->domain); - if (!tree) - XML_AddParameter(tree, "from", photodata); //make sure our image is loaded etc JCL_BuddyVCardReply(jcl, tree, iq);