From 93aba48cdc9d1ea40235d58bb3f3a99d6128d534 Mon Sep 17 00:00:00 2001 From: Spoike Date: Sat, 30 Apr 2011 17:21:10 +0000 Subject: [PATCH] TA couple of fixes. Meshes now have the right lighting if they were cached before rendering. npFTE startup/shutdown/restartup is more robust and is less likely to crash browsers. Re-added the r_shadows cvar. It now provides blob shadows. Hopefully fixes mingw voip crash, may need mingw upgrade, sorry in advance moodles. git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3784 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_ents.c | 253 ++- engine/client/cl_main.c | 23 +- engine/client/cl_parse.c | 6 - engine/client/cl_ui.c | 2 +- engine/client/client.h | 14 +- engine/client/clq2_ents.c | 2 +- engine/client/console.c | 27 +- engine/client/r_2d.c | 5 +- engine/client/r_surf.c | 40 +- engine/client/render.h | 9 +- engine/client/renderer.c | 43 +- engine/client/snd_directx.c | 4 +- engine/client/snd_dma.c | 5 +- engine/client/sys_linux.c | 3 + engine/client/sys_npfte.c | 6 +- engine/client/sys_plugfte.c | 13 +- engine/client/sys_sdl.c | 5 +- engine/client/sys_win.c | 28 +- engine/common/com_mesh.c | 41 +- engine/common/console.h | 1 + engine/common/cvar.c | 2 +- engine/common/fs.c | 1 - engine/common/sys.h | 3 +- engine/dotnet2005/ftequake.sln | 72 +- engine/dotnet2005/ftequake.vcproj | 4 +- engine/dotnet2005/npfte.vcproj | 2854 +---------------------------- engine/gl/gl_alias.c | 69 +- engine/gl/gl_backend.c | 156 +- engine/gl/gl_model.c | 3 +- engine/gl/gl_rlight.c | 16 +- engine/gl/gl_rsurf.c | 13 +- engine/gl/gl_shader.c | 117 +- engine/gl/gl_shadow.c | 3 + engine/gl/gl_vidnt.c | 112 +- engine/gl/shader.h | 5 +- engine/server/sv_sys_unix.c | 4 + engine/server/sv_sys_win.c | 4 + fteqtv/libqtvc/msvc_sucks.c | 4 + fteqtv/qtv.h | 17 +- fteqtv/qw.c | 4 +- 40 files changed, 743 insertions(+), 3250 deletions(-) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 0ad072a3..3163a309 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -36,6 +36,7 @@ extern cvar_t v_powerupshell; extern cvar_t cl_nolerp; extern cvar_t cl_nolerp_netquake; extern cvar_t r_torch; +extern cvar_t r_shadows; extern cvar_t cl_gibfilter, cl_deadbodyfilter; extern int cl_playerindex; @@ -1388,6 +1389,116 @@ int V_AddLight (int entsource, vec3_t org, float quant, float r, float g, float return CL_NewDlightRGB (entsource, org, quant, -0.1, r, g, b) - cl_dlights; } +void CLQ1_AddShadow(entity_t *ent) +{ + float radius; + vec3_t shadoworg; + vec3_t eang; + vec3_t axis[3]; + float tx, ty, tz; + float *verts; + shader_t *s; + int v, num; + scenetris_t *t; + + if (!r_shadows.value || !ent->model || ent->model->type != mod_alias) + return; + + s = R_RegisterShader("shadowshader", + "{\n" + "polygonoffset\n" + "{\n" + "map $diffuse\n" + "blendfunc blend\n" + "rgbgen vertex\n" + "alphagen vertex\n" + "}\n" + "}\n"); + s->defaulttextures.base = balltexture; + + tx = ent->model->maxs[0] - ent->model->mins[0]; + ty = ent->model->maxs[1] - ent->model->mins[1]; + + if (tx > ty) + radius = tx; + else + radius = ty; + radius/=2; + + shadoworg[0] = ent->origin[0]; + shadoworg[1] = ent->origin[1]; + shadoworg[2] = ent->origin[2] + ent->model->mins[2]; + + eang[0] = 0; + eang[1] = ent->angles[1]; + eang[2] = 0; + AngleVectors(eang, axis[0], axis[1], axis[2]); + VectorNegate(axis[2], axis[2]); + + num = Q1BSP_ClipDecal(shadoworg, axis[2], axis[1], axis[0], radius, &verts); + + if (!num) + return; + num*=3; + + tx = DotProduct(shadoworg, axis[1]) + 0.5*radius; + ty = DotProduct(shadoworg, axis[0]) + 0.5*radius; + tz = DotProduct(shadoworg, axis[2]); + + /*reuse the previous trigroup if its the same shader*/ + if (cl_numstris && cl_stris[cl_numstris-1].shader == s) + t = &cl_stris[cl_numstris-1]; + else + { + if (cl_numstris == cl_maxstris) + { + cl_maxstris += 8; + cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris); + } + t = &cl_stris[cl_numstris++]; + t->shader = s; + t->numidx = 0; + t->numvert = 0; + t->firstidx = cl_numstrisidx; + t->firstvert = cl_numstrisvert; + } + + + if (cl_numstrisvert + num > cl_maxstrisvert) + { + cl_maxstrisvert = cl_numstrisvert + num; + + cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert); + cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(vec2_t)*cl_maxstrisvert); + cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(vec4_t)*cl_maxstrisvert); + } + if (cl_maxstrisidx < cl_numstrisidx+num) + { + cl_maxstrisidx = cl_numstrisidx+num + 64; + cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx); + } + + + for (v = 0; v < num; v++) + { + VectorCopy(verts, cl_strisvertv[cl_numstrisvert+v]); + cl_strisvertt[cl_numstrisvert+v][0] = (DotProduct(verts, axis[1]) - tx)/radius; + cl_strisvertt[cl_numstrisvert+v][1] = -(DotProduct(verts, axis[0]) - ty)/radius; + cl_strisvertc[cl_numstrisvert+v][0] = 0; + cl_strisvertc[cl_numstrisvert+v][1] = 0; + cl_strisvertc[cl_numstrisvert+v][2] = 0; + cl_strisvertc[cl_numstrisvert+v][3] = r_shadows.value * (1-((DotProduct(verts, axis[2]) - tz)/(radius/2))); + verts+=3; + } + for (v = 0; v < num; v++) + { + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+v - t->firstvert; + } + + t->numvert += num; + t->numidx += num; + cl_numstrisvert += num; +} void CLQ1_AddPowerupShell(entity_t *ent, qboolean viewweap, unsigned int effects) { entity_t *shell; @@ -1612,61 +1723,70 @@ static void CL_TransitionPacketEntities(packet_entities_t *newpack, packet_entit le->orglerpdeltatime = 0.1; le->orglerpstarttime = oldpack->servertime; - } - else if (snew->dpflags & RENDER_STEP) - { - float lfrac; - //ignore the old packet entirely, except for maybe its time. - if (!VectorEquals(le->neworigin, snew->origin) || !VectorEquals(le->newangle, snew->angles)) - { - le->orglerpdeltatime = bound(0, oldpack->servertime - le->orglerpstarttime, 0.1); //clamp to 10 tics per second - le->orglerpstarttime = oldpack->servertime; - VectorCopy(le->neworigin, le->oldorigin); - VectorCopy(le->newangle, le->oldangle); - - VectorCopy(snew->origin, le->neworigin); - VectorCopy(snew->angles, le->newangle); - } - - lfrac = (servertime - le->orglerpstarttime) / le->orglerpdeltatime; - lfrac = bound(0, lfrac, 1); - for (i = 0; i < 3; i++) - { - le->origin[i] = le->oldorigin[i] + lfrac*(le->neworigin[i] - le->oldorigin[i]); - - for (j = 0; j < 3; j++) - { - a1 = le->oldangle[i]; - a2 = le->newangle[i]; - if (a1 - a2 > 180) - a1 -= 360; - if (a1 - a2 < -180) - a1 += 360; - le->angles[i] = a1 + lfrac * (a2 - a1); - } - } + le->isnew = true; + VectorCopy(le->origin, le->lastorigin); } else { - //lerp based purely on the packet times, - for (i = 0; i < 3; i++) - { - le->origin[i] = sold->origin[i] + frac*(move[i]); + le->isnew = false; + VectorCopy(le->origin, le->lastorigin); - for (j = 0; j < 3; j++) + if (snew->dpflags & RENDER_STEP) + { + float lfrac; + //ignore the old packet entirely, except for maybe its time. + if (!VectorEquals(le->neworigin, snew->origin) || !VectorEquals(le->newangle, snew->angles)) { - a1 = sold->angles[i]; - a2 = snew->angles[i]; - if (a1 - a2 > 180) - a1 -= 360; - if (a1 - a2 < -180) - a1 += 360; - le->angles[i] = a1 + frac * (a2 - a1); + le->orglerpdeltatime = bound(0, oldpack->servertime - le->orglerpstarttime, 0.1); //clamp to 10 tics per second + le->orglerpstarttime = oldpack->servertime; + + VectorCopy(le->neworigin, le->oldorigin); + VectorCopy(le->newangle, le->oldangle); + + VectorCopy(snew->origin, le->neworigin); + VectorCopy(snew->angles, le->newangle); + } + + lfrac = (servertime - le->orglerpstarttime) / le->orglerpdeltatime; + lfrac = bound(0, lfrac, 1); + for (i = 0; i < 3; i++) + { + le->origin[i] = le->oldorigin[i] + lfrac*(le->neworigin[i] - le->oldorigin[i]); + + for (j = 0; j < 3; j++) + { + a1 = le->oldangle[i]; + a2 = le->newangle[i]; + if (a1 - a2 > 180) + a1 -= 360; + if (a1 - a2 < -180) + a1 += 360; + le->angles[i] = a1 + lfrac * (a2 - a1); + } } } - le->orglerpdeltatime = 0.1; - le->orglerpstarttime = oldpack->servertime; + else + { + //lerp based purely on the packet times, + for (i = 0; i < 3; i++) + { + le->origin[i] = sold->origin[i] + frac*(move[i]); + + for (j = 0; j < 3; j++) + { + a1 = sold->angles[i]; + a2 = snew->angles[i]; + if (a1 - a2 > 180) + a1 -= 360; + if (a1 - a2 < -180) + a1 += 360; + le->angles[i] = a1 + frac * (a2 - a1); + } + } + le->orglerpdeltatime = 0.1; + le->orglerpstarttime = oldpack->servertime; + } } CL_UpdateNetFrameLerpState(sold == snew, snew->frame, le); @@ -1843,6 +1963,7 @@ void CL_LinkPacketEntities (void) #endif ent = &cl_visedicts[cl_numvisedicts]; + ent->light_known = 0; ent->forcedshader = NULL; le = &cl.lerpents[state->number]; @@ -2022,7 +2143,7 @@ void CL_LinkPacketEntities (void) angles[2] = 0; if (cl_item_bobbing.value) - ent->origin[2] += 5+sin(cl.time*3+(state->origin[0]+state->origin[1]+state->origin[2]))*5.5; //don't let it into the ground + ent->origin[2] += 5+sin(cl.time*3+(state->origin[0]+state->origin[1])/8)*5.5; //don't let it into the ground } else { @@ -2049,6 +2170,7 @@ void CL_LinkPacketEntities (void) CL_RotateAroundTag(ent, state->number, state->tagentity, state->tagindex); } + CLQ1_AddShadow(ent); CLQ1_AddPowerupShell(ent, false, state->effects); // add automatic particle trails @@ -2058,22 +2180,14 @@ void CL_LinkPacketEntities (void) if (!cls.allow_anyparticles && !(model->flags & ~EF_ROTATE)) continue; - // scan the old entity display list for a matching - for (i=0 ; ikeynum) - { - VectorCopy (cl_oldvisedicts[i].origin, old_origin); - break; - } - } - if (i == cl_oldnumvisedicts) + if (le->isnew) { pe->DelinkTrailstate(&(cl.lerpents[state->number].trailstate)); pe->DelinkTrailstate(&(cl.lerpents[state->number].emitstate)); continue; // not in last message } + VectorCopy(le->lastorigin, old_origin); for (i=0 ; i<3 ; i++) { if ( abs(old_origin[i] - ent->origin[i]) > 128) @@ -2236,6 +2350,7 @@ void CL_LinkProjectiles (void) break; // object list is full ent = &cl_visedicts[cl_numvisedicts]; cl_numvisedicts++; + ent->light_known = 0; ent->keynum = 0; if (pr->modelindex < 1) @@ -2860,6 +2975,7 @@ void CL_LinkPlayers (void) break; // object list is full ent = &cl_visedicts[cl_numvisedicts]; cl_numvisedicts++; + ent->light_known = 0; ent->keynum = j+1; ent->flags = 0; ent->model = model; @@ -2898,6 +3014,11 @@ void CL_LinkPlayers (void) // the player object gets added with flags | 2 for (pnum = 0; pnum < cl.splitclients; pnum++) { + if (j == (cl.viewentity[pnum]?cl.viewentity[pnum]:cl.playernum[pnum])) + { + ent->flags |= Q2RF_EXTERNALMODEL; + ent->externalmodelview |= (1<origin[0] = cl.simorg[pnum][0]; ent->origin[1] = cl.simorg[pnum][1]; ent->origin[2] = cl.simorg[pnum][2]+cl.crouch[pnum]; - } - if (j == (cl.viewentity[pnum]?cl.viewentity[pnum]:cl.playernum[pnum])) - { - ent->flags |= Q2RF_EXTERNALMODEL; - ent->externalmodelview |= (1<command.impulse) CL_AddVWeapModel (ent, cl.model_precache_vwep[state->command.impulse]); + CLQ1_AddShadow(ent); CLQ1_AddPowerupShell(ent, false, state->effects); if (r_torch.ival) @@ -3319,14 +3437,7 @@ Made up of: clients, packet_entities, nails, and tents */ void CL_SwapEntityLists(void) { - cl_oldnumvisedicts = cl_numvisedicts; - cl_oldvisedicts = cl_visedicts; - if (cl_visedicts == cl_visedicts_list[0]) - cl_visedicts = cl_visedicts_list[1]; - else - cl_visedicts = cl_visedicts_list[0]; -// cl_oldvisedicts = cl_visedicts_list[(cls.netchan.incoming_sequence-1)&1]; -// cl_visedicts = cl_visedicts_list[cls.netchan.incoming_sequence&1]; + cl_visedicts = cl_visedicts_list; cl_numvisedicts = 0; cl_numstrisidx = 0; diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index c4869243..d39f4bd8 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -195,9 +195,9 @@ int rtlights_first, rtlights_max; // refresh list // this is double buffered so the last frame // can be scanned for oldorigins of trailing objects -int cl_numvisedicts, cl_oldnumvisedicts; -entity_t *cl_visedicts, *cl_oldvisedicts; -entity_t cl_visedicts_list[2][MAX_VISEDICTS]; +int cl_numvisedicts; +entity_t *cl_visedicts; +entity_t cl_visedicts_list[MAX_VISEDICTS]; scenetris_t *cl_stris; vecV_t *cl_strisvertv; @@ -1047,6 +1047,12 @@ void CL_ClearState (void) cl.fog_colour[1] = 0.3; cl.fog_colour[2] = 0.3; + cl.allocated_client_slots = MAX_CLIENTS; +#ifndef CLIENTONLY + if (sv.state) + cl.allocated_client_slots = sv.allocated_client_slots; +#endif + SZ_Clear (&cls.netchan.message); r_worldentity.model = NULL; @@ -3627,6 +3633,9 @@ void Host_Init (quakeparms_t *parms) Cvar_Init(); Memory_Init (parms->membase, parms->memsize); + /*memory is working, its safe to printf*/ + Con_Init (); + Sys_Init(); COM_ParsePlusSets(); @@ -3646,7 +3655,6 @@ void Host_Init (quakeparms_t *parms) // W_LoadWadFile ("gfx.wad"); Key_Init (); - Con_Init (); M_Init (); IN_Init (); S_Init (); @@ -3840,6 +3848,11 @@ void Host_Shutdown(void) } host_initialized = false; + //disconnect server/client/etc + CL_Disconnect_f(); + //Kill renderer + R_ShutdownRenderer(); + #ifdef VM_UI UI_Stop(); #endif @@ -3863,12 +3876,14 @@ void Host_Shutdown(void) Validation_FlushFileList(); Cmd_Shutdown(); + Con_Shutdown(); Memory_DeInit(); #ifndef CLIENTONLY memset(&sv, 0, sizeof(sv)); memset(&svs, 0, sizeof(svs)); #endif + Sys_Shutdown(); } #ifdef CLIENTONLY diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 76ac0696..1536405a 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -2043,12 +2043,6 @@ void CL_ParseServerData (void) SCR_SetLoadingStage(LS_CLIENT); SCR_BeginLoadingPlaque(); - cl.allocated_client_slots = MAX_CLIENTS; -#ifndef CLIENTONLY - if (sv.state) - cl.allocated_client_slots = sv.allocated_client_slots; -#endif - // parse protocol version number // allow 2.2 and 2.29 demos to play #ifdef PROTOCOL_VERSION_FTE diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index 39af8eff..109a4f4e 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -387,7 +387,7 @@ void VQ3_AddEntity(const q3refEntity_t *q3) { entity_t ent; if (!cl_visedicts) - cl_visedicts = cl_visedicts_list[0]; + cl_visedicts = cl_visedicts_list; memset(&ent, 0, sizeof(ent)); ent.model = VM_FROMMHANDLE(q3->hModel); ent.framestate.g[FS_REG].frame[0] = q3->frame; diff --git a/engine/client/client.h b/engine/client/client.h index 6ca582f8..8172bca3 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -453,6 +453,10 @@ typedef struct { vec3_t origin; //current render position vec3_t angles; + //previous rendering frame (for trails) + vec3_t lastorigin; + qboolean isnew; + //intermediate values for frame lerping float framelerpdeltatime; float newframestarttime; @@ -463,8 +467,8 @@ typedef struct { //intermediate values for origin lerping of stepping things float orglerpdeltatime; float orglerpstarttime; - vec3_t neworigin; - vec3_t oldorigin; + vec3_t neworigin; /*origin that we're lerping towards*/ + vec3_t oldorigin; /*origin that we're lerping away from*/ vec3_t newangle; vec3_t oldangle; } lerpents_t; @@ -784,9 +788,9 @@ void CLNQ_BeginServerConnect(void); char *CL_TryingToConnect(void); #define MAX_VISEDICTS 1024 -extern int cl_numvisedicts, cl_oldnumvisedicts; -extern entity_t *cl_visedicts, *cl_oldvisedicts; -extern entity_t cl_visedicts_list[2][MAX_VISEDICTS]; +extern int cl_numvisedicts; +extern entity_t *cl_visedicts; +extern entity_t cl_visedicts_list[MAX_VISEDICTS]; /*these are for q3 really*/ typedef struct { diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index 0ec01210..14dd66a6 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -2061,7 +2061,7 @@ void CLQ2_AddEntities (void) r_refdef.currentplayernum = 0; - cl_visedicts = cl_visedicts_list[cls.netchan.incoming_sequence&1]; + cl_visedicts = cl_visedicts_list; cl_numvisedicts = 0; cl_numstrisidx = 0; diff --git a/engine/client/console.c b/engine/client/console.c index 48c175fc..75e91f23 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -97,10 +97,21 @@ int Con_IsActive (console_t *con) { return (con == con_current) | (con->unseentext*2); } -/*kills a console_t object. will never destroy the main console*/ +/*kills a console_t object. will never destroy the main console (which will only be cleared)*/ void Con_Destroy (console_t *con) { console_t *prev; + conline_t *t; + /*purge the lines from the console*/ + while (con->current) + { + t = con->current; + con->current = t->older; + Z_Free(t); + } + con->display = con->current = con->oldest = NULL; + selstartline = NULL; + selendline = NULL; if (con == &con_main) return; @@ -505,6 +516,8 @@ void Con_Init (void) con_main.linebuffered = Con_ExecuteLine; con_main.commandcompletion = true; + + con_initialized = true; Con_Printf ("Console initialized.\n"); // @@ -531,11 +544,19 @@ void Con_Init (void) Cmd_AddCommand ("conclose", Cmd_ConClose_f); Cmd_AddCommand ("conactivate", Cmd_ConActivate_f); - con_initialized = true; - Log_Init(); } +void Con_Shutdown(void) +{ + while(con_main.next) + { + Con_Destroy(con_main.next); + } + Con_Destroy(&con_main); + con_initialized = false; +} + /* ================ Con_Print diff --git a/engine/client/r_2d.c b/engine/client/r_2d.c index ff72daee..5a32803e 100644 --- a/engine/client/r_2d.c +++ b/engine/client/r_2d.c @@ -912,8 +912,9 @@ void R2D_Crosshair_Update(void) unsigned char *x; c = crosshair.ival; - - if (crosshairimage.string[0] && c == 1) + if (!crosshairimage.string) + return; + else if (crosshairimage.string[0] && c == 1) { shader_crosshair->defaulttextures.base = R_LoadHiResTexture (crosshairimage.string, "crosshairs", IF_NOMIPMAP|IF_NOGAMMA); if (TEXVALID(shader_crosshair->defaulttextures.base)) diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 93897993..d81dd791 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -55,13 +55,16 @@ extern cvar_t r_loadlits; extern cvar_t r_stainfadetime; extern cvar_t r_stainfadeammount; +static int lightmap_shift; int Surf_LightmapShift (model_t *model) { extern cvar_t gl_overbright_all, gl_lightmap_shift; if (gl_overbright_all.ival || (model->engineflags & MDLF_NEEDOVERBRIGHT)) - return bound(0, gl_lightmap_shift.ival, 2); - return 0; + lightmap_shift = bound(0, gl_lightmap_shift.ival, 2); + else + lightmap_shift = 0; + return lightmap_shift; } void Surf_RebuildLightmap (void) @@ -1162,7 +1165,7 @@ R_RenderDynamicLightmaps Multitexture ================ */ -void Surf_RenderDynamicLightmaps (msurface_t *fa, int shift) +void Surf_RenderDynamicLightmaps (msurface_t *fa) { qbyte *base, *luxbase; stmap *stainbase; @@ -1256,13 +1259,13 @@ dynamic: base += fa->light_t * LMBLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes; stainbase = lightmap[fa->lightmaptexturenum]->stainmaps; stainbase += (fa->light_t * LMBLOCK_WIDTH + fa->light_s) * 3; - Surf_BuildLightMap (fa, base, luxbase, stainbase, shift, r_ambient.value*255); + Surf_BuildLightMap (fa, base, luxbase, stainbase, lightmap_shift, r_ambient.value*255); RSpeedEnd(RSPEED_DYNAMIC); } } -void Surf_RenderAmbientLightmaps (msurface_t *fa, int shift, int ambient) +void Surf_RenderAmbientLightmaps (msurface_t *fa, int ambient) { qbyte *base, *luxbase; stmap *stainbase; @@ -1342,7 +1345,7 @@ dynamic: base += fa->light_t * LMBLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes; stainbase = lightmap[fa->lightmaptexturenum]->stainmaps; stainbase += (fa->light_t * LMBLOCK_WIDTH + fa->light_s) * 3; - Surf_BuildLightMap (fa, base, luxbase, stainbase, shift, -1-ambient); + Surf_BuildLightMap (fa, base, luxbase, stainbase, lightmap_shift, -1-ambient); RSpeedEnd(RSPEED_DYNAMIC); } @@ -1403,7 +1406,7 @@ static qbyte *R_MarkLeafSurfaces_Q1 (void) surf = tex->vbo.meshlist[j]; if (surf) { - Surf_RenderDynamicLightmaps (surf, shift); + Surf_RenderDynamicLightmaps (surf); tex->vbo.meshlist[j] = NULL; surf->sbatch->mesh[surf->sbatch->meshes++] = surf->mesh; @@ -1426,7 +1429,6 @@ static void Surf_RecursiveWorldNode (mnode_t *node, unsigned int clipflags) msurface_t *surf, **mark; mleaf_t *pleaf; double dot; - int shift; start: @@ -1502,8 +1504,6 @@ start: { surf = cl.worldmodel->surfaces + node->firstsurface; - shift = Surf_LightmapShift(cl.worldmodel); - if (dot < 0 -BACKFACE_EPSILON) side = SURF_PLANEBACK; else if (dot > BACKFACE_EPSILON) @@ -1517,7 +1517,7 @@ start: if (((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))) continue; // wrong side - Surf_RenderDynamicLightmaps (surf, shift); + Surf_RenderDynamicLightmaps (surf); surf->sbatch->mesh[surf->sbatch->meshes++] = surf->mesh; } } @@ -1537,7 +1537,6 @@ static void Surf_RecursiveQ2WorldNode (mnode_t *node) msurface_t *surf, **mark; mleaf_t *pleaf; double dot; - int shift; int sidebit; @@ -1610,8 +1609,6 @@ static void Surf_RecursiveQ2WorldNode (mnode_t *node) // recurse down the children, front side first Surf_RecursiveQ2WorldNode (node->children[side]); - shift = Surf_LightmapShift(currentmodel); - // draw stuff for ( c = node->numsurfaces, surf = currentmodel->surfaces + node->firstsurface; c ; c--, surf++) { @@ -1623,7 +1620,7 @@ static void Surf_RecursiveQ2WorldNode (mnode_t *node) surf->visframe = r_framecount+1;//-1; - Surf_RenderDynamicLightmaps (surf, shift); + Surf_RenderDynamicLightmaps (surf); surf->sbatch->mesh[surf->sbatch->meshes++] = surf->mesh; } @@ -1885,7 +1882,6 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent) if (model->fromgame != fg_quake3 && model->fromgame != fg_doom3) { int k; - int shift; currententity = ent; currentmodel = ent->model; @@ -1903,24 +1899,24 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent) } } - shift = Surf_LightmapShift(model); + Surf_LightmapShift(model); if ((ent->drawflags & MLS_MASKIN) == MLS_ABSLIGHT) { //update lightmaps. for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++) - Surf_RenderAmbientLightmaps (s, shift, ent->abslight); + Surf_RenderAmbientLightmaps (s, ent->abslight); } else if (ent->drawflags & DRF_TRANSLUCENT) { //update lightmaps. for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++) - Surf_RenderAmbientLightmaps (s, shift, 255); + Surf_RenderAmbientLightmaps (s, 255); } else { //update lightmaps. for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++) - Surf_RenderDynamicLightmaps (s, shift); + Surf_RenderDynamicLightmaps (s); } currententity = NULL; } @@ -2055,6 +2051,8 @@ void Surf_DrawWorld (void) { RSpeedRemark(); + Surf_LightmapShift(cl.worldmodel); + #ifdef Q2BSPS if (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3) { @@ -2101,6 +2099,7 @@ void Surf_DrawWorld (void) { vis = R_MarkLeaves_Q1 (); VectorCopy (r_refdef.vieworg, modelorg); + Surf_RecursiveWorldNode (cl.worldmodel->nodes, 0xf); } } @@ -2111,7 +2110,6 @@ void Surf_DrawWorld (void) TRACE(("dbg: calling BE_DrawWorld\n")); BE_DrawWorld(vis); - /*FIXME: move this away*/ if (cl.worldmodel->fromgame == fg_quake || cl.worldmodel->fromgame == fg_halflife) Surf_LessenStains(); diff --git a/engine/client/render.h b/engine/client/render.h index 9054072b..2f90e5b9 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -86,6 +86,11 @@ typedef struct entity_s vec4_t shaderRGBAf; float shaderTime; + int light_known; + vec3_t light_avg; /*midpoint level*/ + vec3_t light_range; /*avg + this = max, avg - this = min*/ + vec3_t light_dir; + vec3_t oldorigin; vec3_t oldangles; @@ -191,8 +196,8 @@ void Surf_DeInit(void); void Surf_Clear(struct model_s *mod); void Surf_BuildLightmaps(void); void Surf_BuildSurfaceDisplayList (struct model_s *mod, struct msurface_s *fa); -void Surf_RenderDynamicLightmaps (struct msurface_s *fa, int shift); -void Surf_RenderAmbientLightmaps (struct msurface_s *fa, int shift, int ambient); +void Surf_RenderDynamicLightmaps (struct msurface_s *fa); +void Surf_RenderAmbientLightmaps (struct msurface_s *fa, int ambient); int Surf_LightmapShift (struct model_s *model); #ifndef LMBLOCK_WIDTH #define LMBLOCK_WIDTH 128 diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 5919a2ea..2206d11e 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -215,25 +215,27 @@ cvar_t vid_gl_context_es2 = SCVAR ("vid_gl_context_es2", "0"); //requires v #endif #if defined(GLQUAKE) || defined(D3DQUAKE) -cvar_t gl_ati_truform = SCVAR ("gl_ati_truform", "0"); -cvar_t gl_ati_truform_type = SCVAR ("gl_ati_truform_type", "1"); -cvar_t gl_ati_truform_tesselation = SCVAR ("gl_ati_truform_tesselation", "3"); -cvar_t gl_blend2d = SCVAR ("gl_blend2d", "1"); -cvar_t gl_blendsprites = SCVAR ("gl_blendsprites", "1"); -cvar_t gl_bump = SCVARF ("gl_bump", "0", +cvar_t gl_ati_truform = CVAR ("gl_ati_truform", "0"); +cvar_t gl_ati_truform_type = CVAR ("gl_ati_truform_type", "1"); +cvar_t gl_ati_truform_tesselation = CVAR ("gl_ati_truform_tesselation", "3"); +cvar_t gl_blend2d = CVAR ("gl_blend2d", "1"); +cvar_t gl_blendsprites = CVAR ("gl_blendsprites", "1"); +cvar_t gl_bump = CVARF ("gl_bump", "0", CVAR_ARCHIVE | CVAR_RENDERERLATCH); -cvar_t gl_compress = SCVARF ("gl_compress", "0", +cvar_t r_deluxemapping = CVARAF ("r_deluxemapping", "0", "r_glsl_deluxemapping", + CVAR_ARCHIVE | CVAR_RENDERERLATCH); +cvar_t gl_compress = CVARF ("gl_compress", "0", CVAR_ARCHIVE); cvar_t gl_conback = CVARFC ("gl_conback", "", CVAR_RENDERERCALLBACK, R2D_Conback_Callback); -cvar_t gl_contrast = SCVAR ("gl_contrast", "1"); -cvar_t gl_detail = SCVARF ("gl_detail", "0", +cvar_t gl_contrast = CVAR ("gl_contrast", "1"); +cvar_t gl_detail = CVARF ("gl_detail", "0", CVAR_ARCHIVE); -cvar_t gl_detailscale = SCVAR ("gl_detailscale", "5"); -cvar_t gl_font = SCVARF ("gl_font", "", +cvar_t gl_detailscale = CVAR ("gl_detailscale", "5"); +cvar_t gl_font = CVARF ("gl_font", "", CVAR_RENDERERCALLBACK); -cvar_t gl_lateswap = SCVAR ("gl_lateswap", "0"); -cvar_t gl_lerpimages = SCVAR ("gl_lerpimages", "1"); +cvar_t gl_lateswap = CVAR ("gl_lateswap", "0"); +cvar_t gl_lerpimages = CVAR ("gl_lerpimages", "1"); cvar_t gl_lightmap_shift = CVARFC ("gl_lightmap_shift", "1", CVAR_ARCHIVE, Surf_RebuildLightmap_Callback); @@ -292,6 +294,8 @@ cvar_t gl_triplebuffer = SCVARF ("gl_triplebuffer", "1", cvar_t r_noportals = SCVAR ("r_noportals", "0"); cvar_t r_noaliasshadows = SCVARF ("r_noaliasshadows", "0", CVAR_ARCHIVE); +cvar_t r_shadows = SCVARF ("r_shadows", "0", + CVAR_ARCHIVE); cvar_t r_shadow_bumpscale_basetexture = SCVAR ("r_shadow_bumpscale_basetexture", "4"); cvar_t r_shadow_bumpscale_bumpmap = SCVAR ("r_shadow_bumpscale_bumpmap", "10"); @@ -377,6 +381,7 @@ void GLRenderer_Init(void) Cvar_Register (&gl_smoothcrosshair, GRAPHICALNICETIES); Cvar_Register (&gl_bump, GRAPHICALNICETIES); + Cvar_Register (&r_deluxemapping, GRAPHICALNICETIES); Cvar_Register (&r_glsl_offsetmapping, GRAPHICALNICETIES); Cvar_Register (&r_glsl_offsetmapping_scale, GRAPHICALNICETIES); @@ -595,6 +600,7 @@ void Renderer_Init(void) Cvar_Register (&r_fb_bmodels, GRAPHICALNICETIES); Cvar_Register (&r_fb_models, GRAPHICALNICETIES); Cvar_Register (&r_skin_overlays, GRAPHICALNICETIES); + Cvar_Register (&r_shadows, GRAPHICALNICETIES); Cvar_Register (&r_replacemodels, GRAPHICALNICETIES); @@ -1585,6 +1591,8 @@ TRACE(("dbg: R_ApplyRenderer: clearing world\n")); #endif Cvar_ForceCallback(&r_particlesystem); + CL_InitDlights(); + TRACE(("dbg: R_ApplyRenderer: starting on client state\n")); if (cl.worldmodel) { @@ -1775,7 +1783,7 @@ TRACE(("dbg: R_RestartRenderer_f\n")); } if (!newr.renderer) { - Con_Printf("vid_renderer unset or invalid. Using default.\n"); + Con_Printf("vid_renderer unset or unsupported. Using default.\n"); //gotta do this after main hunk is saved off. #if defined(GLQUAKE) Cmd_ExecuteString("setrenderer gl\n", RESTRICT_LOCAL); @@ -1873,7 +1881,6 @@ TRACE(("dbg: R_RestartRenderer_f\n")); TRACE(("dbg: R_RestartRenderer_f success\n")); M_Reinit(); - CL_InitDlights(); } void R_SetRenderer_f (void) @@ -2287,7 +2294,7 @@ qbyte *R_CalcVis_Q1 (void) qbyte *R_MarkLeaves_Q1 (void) { - qbyte fatvis[MAX_MAP_LEAFS/8]; + static qbyte fatvis[MAX_MAP_LEAFS/8]; static qbyte *vis; mnode_t *node; int i; @@ -2318,7 +2325,9 @@ qbyte *R_MarkLeaves_Q1 (void) vis = fatvis; } else - vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL, 0); + { + vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, fatvis, sizeof(fatvis)); + } for (i=0 ; inumleafs ; i++) { diff --git a/engine/client/snd_directx.c b/engine/client/snd_directx.c index 513aa082..e5619800 100644 --- a/engine/client/snd_directx.c +++ b/engine/client/snd_directx.c @@ -46,7 +46,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define iDirectSoundEnumerate(a,b,c) pDirectSoundEnumerate(a,b) HRESULT (WINAPI *pDirectSoundCreate)(GUID FAR *lpGUID, LPDIRECTSOUND FAR *lplpDS, IUnknown FAR *pUnkOuter); -#if defined(VOICECHAT) && !defined(__MINGW32__) +#if defined(VOICECHAT) HRESULT (WINAPI *pDirectSoundCaptureCreate)(GUID FAR *lpGUID, LPDIRECTSOUNDCAPTURE FAR *lplpDS, IUnknown FAR *pUnkOuter); #endif HRESULT (WINAPI *pDirectSoundEnumerate)(LPDSENUMCALLBACKA lpCallback, LPVOID lpContext ); @@ -899,7 +899,7 @@ int (*pDSOUND_InitCard) (soundcardinfo_t *sc, int cardnum) = &DSOUND_InitCard; -#if defined(VOICECHAT) && defined(AVAIL_DSOUND) && !defined(__MINGW32__) +#if defined(VOICECHAT) && defined(AVAIL_DSOUND) typedef struct diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index dbb9f3b8..4fdc3703 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -425,7 +425,7 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf) s_speex.driver = &OSS_Capture; /*no way to capture audio, give up*/ - if (!s_speex.driver) + if (!s_speex.driver || !s_speex.driver->Init) return; /*see if we can init speex...*/ @@ -1062,8 +1062,7 @@ void S_Init (void) snd_initialized = true; - if (!known_sfx) - known_sfx = Hunk_AllocName (MAX_SFX*sizeof(sfx_t), "sfx_t"); + known_sfx = Hunk_AllocName (MAX_SFX*sizeof(sfx_t), "sfx_t"); num_sfx = 0; // create a piece of DMA memory diff --git a/engine/client/sys_linux.c b/engine/client/sys_linux.c index becec06a..6070be83 100644 --- a/engine/client/sys_linux.c +++ b/engine/client/sys_linux.c @@ -225,6 +225,9 @@ void Sys_Quit (void) void Sys_Init(void) { } +void Sys_Shutdown(void) +{ +} void Sys_Error (const char *error, ...) { diff --git a/engine/client/sys_npfte.c b/engine/client/sys_npfte.c index 9f12cda8..8cb9cba0 100644 --- a/engine/client/sys_npfte.c +++ b/engine/client/sys_npfte.c @@ -253,7 +253,6 @@ NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save) } NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window) { - extern cvar_t vid_width; struct context *ctx = instance->pdata; struct contextpublic *pub = (struct contextpublic*)ctx; @@ -525,10 +524,10 @@ bool npscript_getProperty(NPObject *npobj, NPIdentifier name, NPVariant *result) } else { - ns = browserfuncs->memalloc(len); + ns = browserfuncs->memalloc(len+1); if (ns) { - memcpy(ns, strval, len); + memcpy(ns, strval, len+1); STRINGZ_TO_NPVARIANT(ns, *result); success = true; } @@ -683,7 +682,6 @@ NPError OSCALL NP_GetValue(void *instance, NPPVariable variable, void *value) NPError OSCALL NP_GetEntryPoints (NPPluginFuncs* pFuncs) { - MessageBox(NULL, "Foo", "Foo", 0); if (pFuncs->size < sizeof(NPPluginFuncs)) return NPERR_INVALID_FUNCTABLE_ERROR; pFuncs->size = sizeof(NPPluginFuncs); diff --git a/engine/client/sys_plugfte.c b/engine/client/sys_plugfte.c index 08f5c87c..e040baae 100644 --- a/engine/client/sys_plugfte.c +++ b/engine/client/sys_plugfte.c @@ -364,7 +364,7 @@ int Plug_PluginThread(void *ctxptr) { ctx->shutdown = false; VS_DebugLocation(__FILE__, __LINE__, "Sys_Shutdown"); - NPQTV_Sys_Shutdown(); + Host_Shutdown(); /*will shut down the host*/ } else if (ctx->resetvideo) { @@ -390,7 +390,7 @@ int Plug_PluginThread(void *ctxptr) #else __except (EXCEPTION_EXECUTE_HANDLER) { - NPQTV_Sys_Shutdown(); + Host_Shutdown(); MessageBox(sys_parentwindow, "Sorry, FTE plugin crashed.\nYou probably should restart your browser", "FTE crashed", 0); } #endif @@ -463,8 +463,6 @@ struct context *Plug_CreateContext(void *sysctx, const struct browserfuncs *func if (!sysctx || !funcs) return NULL; -// MessageBox(0, "hello", "this one", 0); - ctx = malloc(sizeof(struct context)); if (!ctx) return NULL; @@ -499,14 +497,13 @@ qboolean Plug_ChangeWindow(struct context *ctx, void *whnd, int width, int heigh ctx->windowhnd = whnd; ctx->resetvideo = 2; } - if (ctx->windowwidth != width && ctx->windowheight != height) + if (ctx->windowwidth != width || ctx->windowheight != height) { ctx->windowwidth = width; ctx->windowheight = height; - - if (ctx->pub.running && !ctx->resetvideo) - ctx->resetvideo = true; } + if (ctx->pub.running && !ctx->resetvideo) + ctx->resetvideo = true; Plug_LockPlugin(ctx, false); while(ctx->pub.running && ctx->resetvideo) diff --git a/engine/client/sys_sdl.c b/engine/client/sys_sdl.c index 45ea1498..319dfab3 100644 --- a/engine/client/sys_sdl.c +++ b/engine/client/sys_sdl.c @@ -388,7 +388,10 @@ void Sys_Init(void) { SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_CDROM | SDL_INIT_NOPARACHUTE); } - +void Sys_Shutdown(void) +{ + SDL_Quit(); +} diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 1a88bb62..0884629b 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -689,6 +689,16 @@ void Sys_Init (void) } +void Sys_Shutdown(void) +{ + if (host_parms.membase) + { + VirtualFree(host_parms.membase, 0, MEM_RELEASE); + host_parms.membase = 0; + } +} + + void VARGS Sys_Error (const char *error, ...) { va_list argptr; @@ -714,7 +724,15 @@ void VARGS Sys_Error (const char *error, ...) SetHookState(false); #endif +#ifdef NPQTV + { + extern jmp_buf host_abort; + /*jump to start of main loop (which exits the main loop)*/ + longjmp (host_abort, 1); + } +#else exit (1); +#endif } void VARGS Sys_Printf (char *fmt, ...) @@ -759,6 +777,7 @@ void Sys_Quit (void) #ifdef NPQTV { extern jmp_buf host_abort; + /*jump to start of main loop (which exits the main loop)*/ longjmp (host_abort, 1); } #else @@ -1236,15 +1255,6 @@ void NPQTV_Sys_MainLoop(void) } } -void NPQTV_Sys_Shutdown(void) -{ - //disconnect server/client/etc - CL_Disconnect_f(); - R_ShutdownRenderer(); - - Host_Shutdown(); -} - void Sys_RecentServer(char *command, char *target, char *title, char *desc) { } diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 96d0741b..0aa4ccd8 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -890,9 +890,6 @@ vecV_t *tempVertexCoords; int numTempNormals; vec3_t *tempNormals; -avec3_t shadevector; -avec3_t ambientlight; -avec3_t shadelight; //#define SSE_INTRINSICS #ifdef SSE_INTRINSICS #include @@ -907,12 +904,13 @@ void R_LightArraysByte_BGR(vecV_t *coords, byte_vec4_t *colours, int vertcount, byte_vec4_t ambientlightb; byte_vec4_t shadelightb; + float *lightdir = currententity->light_dir; for (i = 0; i < 3; i++) { - l = ambientlight[2-i]*255; + l = currententity->light_avg[2-i]*255; ambientlightb[i] = bound(0, l, 255); - l = shadelight[2-i]*255; + l = currententity->light_range[2-i]*255; shadelightb[i] = bound(0, l, 255); } @@ -928,21 +926,17 @@ void R_LightArraysByte_BGR(vecV_t *coords, byte_vec4_t *colours, int vertcount, } else { - byte_vec4_t meanambient; - /*dotproduct will return a value between 1 and -1, so increase the ambient to be correct for normals facing away from the light*/ - VectorMA(ambientlightb, 1, shadelightb, meanambient); - for (i = vertcount-1; i >= 0; i--) { - l = DotProduct(normals[i], shadevector); + l = DotProduct(normals[i], lightdir); c = l*shadelightb[0]; - c += meanambient[0]; + c += ambientlightb[0]; colours[i][0] = bound(0, c, 255); c = l*shadelightb[1]; - c += meanambient[1]; + c += ambientlightb[1]; colours[i][1] = bound(0, c, 255); c = l*shadelightb[2]; - c += meanambient[2]; + c += ambientlightb[2]; colours[i][2] = bound(0, c, 255); } } @@ -954,18 +948,19 @@ void R_LightArrays(vecV_t *coords, avec4_t *colours, int vertcount, vec3_t *norm int i; float l; - if (VectorCompare(ambientlight, shadelight)) + float *lightdir = currententity->light_dir; + + if (!currententity->light_range[0] && !currententity->light_range[1] && !currententity->light_range[2]) { for (i = vertcount-1; i >= 0; i--) { - colours[i][0] = ambientlight[0]; - colours[i][1] = ambientlight[1]; - colours[i][2] = ambientlight[2]; + colours[i][0] = currententity->light_avg[0]; + colours[i][1] = currententity->light_avg[1]; + colours[i][2] = currententity->light_avg[2]; } } else { - vec3_t meanambient; #ifdef SSE_INTRINSICS __m128 va, vs, vl, vr; va = _mm_load_ps(ambientlight); @@ -974,11 +969,9 @@ void R_LightArrays(vecV_t *coords, avec4_t *colours, int vertcount, vec3_t *norm vs.m128_f32[3] = 1; #endif /*dotproduct will return a value between 1 and -1, so increase the ambient to be correct for normals facing away from the light*/ - VectorMA(ambientlight, 1, shadelight, meanambient); - for (i = vertcount-1; i >= 0; i--) { - l = DotProduct(normals[i], shadevector); + l = DotProduct(normals[i], currententity->light_dir); #ifdef SSE_INTRINSICS vl = _mm_load1_ps(&l); vr = _mm_mul_ss(va,vl); @@ -987,9 +980,9 @@ void R_LightArrays(vecV_t *coords, avec4_t *colours, int vertcount, vec3_t *norm _mm_storeu_ps(colours[i], vr); //stomp on colour[i][3] (will be set to 1) #else - colours[i][0] = l*shadelight[0]+meanambient[0]; - colours[i][1] = l*shadelight[1]+meanambient[1]; - colours[i][2] = l*shadelight[2]+meanambient[2]; + colours[i][0] = l*currententity->light_range[0]+currententity->light_avg[0]; + colours[i][1] = l*currententity->light_range[1]+currententity->light_avg[1]; + colours[i][2] = l*currententity->light_range[2]+currententity->light_avg[2]; #endif } } diff --git a/engine/common/console.h b/engine/common/console.h index 10946e50..972ea425 100644 --- a/engine/common/console.h +++ b/engine/common/console.h @@ -128,6 +128,7 @@ void Con_DrawCharacter (int cx, int line, int num); void Con_CheckResize (void); void Con_ForceActiveNow(void); void Con_Init (void); +void Con_Shutdown (void); void Con_DrawConsole (int lines, qboolean noback); char *Con_CopyConsole(void); void Con_Print (char *txt); diff --git a/engine/common/cvar.c b/engine/common/cvar.c index 0872edff..09c9dcc7 100644 --- a/engine/common/cvar.c +++ b/engine/common/cvar.c @@ -979,7 +979,7 @@ qboolean Cvar_Register (cvar_t *variable, const char *groupname) if (variable->name2) Hash_AddInsensative(&cvar_hash, variable->name2, variable, &variable->hbn2); - variable->string = (char*)Z_Malloc (1); + variable->string = NULL; if (variable->flags & CVAR_FREEDEFAULT) variable->defaultstr = Cvar_DefaultAlloc(initial); diff --git a/engine/common/fs.c b/engine/common/fs.c index 7ebae119..523b9ec2 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -1303,7 +1303,6 @@ static void FS_AddDataFiles(const char *purepath, const char *pathto, searchpath vfs = search->funcs->OpenVFS(search->handle, &loc, "r"); if (!vfs) break; - Con_Printf("Opened %s\n", pakfile); handle = funcs->OpenNew (vfs, pakfile); if (!handle) break; diff --git a/engine/common/sys.h b/engine/common/sys.h index d22818d7..f814c9ae 100644 --- a/engine/common/sys.h +++ b/engine/common/sys.h @@ -112,7 +112,6 @@ void Sys_DestroyConditional(void *condv); #ifdef NPQTV qboolean NPQTV_Sys_Startup(int argc, char *argv[]); void NPQTV_Sys_MainLoop(void); -void NPQTV_Sys_Shutdown(void); #endif #ifdef _WIN32 @@ -120,3 +119,5 @@ int StartLocalServer(int close); #endif void Sys_Init (void); +void Sys_Shutdown(void); + diff --git a/engine/dotnet2005/ftequake.sln b/engine/dotnet2005/ftequake.sln index 900284b4..64144994 100644 --- a/engine/dotnet2005/ftequake.sln +++ b/engine/dotnet2005/ftequake.sln @@ -6,10 +6,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftequake_SDL", "ftequake_SD EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "npfte", "npfte.vcproj", "{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "botlib", "..\..\plugins\botlib\botlib.vcproj", "{77725D10-5A04-4CB3-887D-F23AB5652DA9}" -EndProject Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "FTEQuake", "..\setup\setup.vdproj", "{E0EE8B50-3A75-42A9-B80A-787675979B0C}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qtvprox", "..\..\fteqtv\qtvprox.vcproj", "{1A353DA0-F351-4C0D-A21D-E2B460600B20}" + ProjectSection(ProjectDependencies) = postProject + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365} = {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution D3DDebug|Win32 = D3DDebug|Win32 @@ -141,38 +144,6 @@ Global {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|Win32.Build.0 = GLRelease|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|x64.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|x64.Build.0 = GLRelease|x64 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.D3DDebug|Win32.ActiveCfg = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.D3DDebug|Win32.Build.0 = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.D3DDebug|x64.ActiveCfg = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.Debug|Win32.ActiveCfg = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.Debug|Win32.Build.0 = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.Debug|x64.ActiveCfg = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.GLDebug|Win32.ActiveCfg = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.GLDebug|Win32.Build.0 = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.GLDebug|x64.ActiveCfg = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.GLRelease|Win32.ActiveCfg = Release|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.GLRelease|x64.ActiveCfg = Release|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.MDebug|Win32.ActiveCfg = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.MDebug|Win32.Build.0 = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.MDebug|x64.ActiveCfg = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.MinGLDebug|Win32.Build.0 = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.MinGLDebug|x64.ActiveCfg = Debug|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.MinGLRelease|Win32.ActiveCfg = Release|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.MinGLRelease|Win32.Build.0 = Release|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.MinGLRelease|x64.ActiveCfg = Release|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.MRelease|Win32.ActiveCfg = Release|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.MRelease|Win32.Build.0 = Release|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.MRelease|x64.ActiveCfg = Release|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.Release Dedicated Server|Win32.Build.0 = Release|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.Release Dedicated Server|x64.ActiveCfg = Release|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.Release|Win32.ActiveCfg = Release|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.Release|Win32.Build.0 = Release|Win32 - {77725D10-5A04-4CB3-887D-F23AB5652DA9}.Release|x64.ActiveCfg = Release|Win32 {E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DDebug|Win32.ActiveCfg = Debug {E0EE8B50-3A75-42A9-B80A-787675979B0C}.D3DDebug|x64.ActiveCfg = Debug {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Debug Dedicated Server|Win32.ActiveCfg = Debug @@ -195,6 +166,39 @@ Global {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Release Dedicated Server|x64.ActiveCfg = Release {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Release|Win32.ActiveCfg = Release {E0EE8B50-3A75-42A9-B80A-787675979B0C}.Release|x64.ActiveCfg = Release + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.D3DDebug|Win32.ActiveCfg = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.D3DDebug|Win32.Build.0 = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.D3DDebug|x64.ActiveCfg = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Debug|Win32.ActiveCfg = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Debug|Win32.Build.0 = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Debug|x64.ActiveCfg = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.GLDebug|Win32.ActiveCfg = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.GLDebug|Win32.Build.0 = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.GLDebug|x64.ActiveCfg = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.GLRelease|Win32.ActiveCfg = Release|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.GLRelease|Win32.Build.0 = Release|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.GLRelease|x64.ActiveCfg = Release|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MDebug|Win32.ActiveCfg = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MDebug|Win32.Build.0 = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MDebug|x64.ActiveCfg = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MinGLDebug|Win32.Build.0 = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MinGLDebug|x64.ActiveCfg = Debug|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MinGLRelease|Win32.ActiveCfg = Release|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MinGLRelease|Win32.Build.0 = Release|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MinGLRelease|x64.ActiveCfg = Release|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MRelease|Win32.ActiveCfg = Release|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MRelease|Win32.Build.0 = Release|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.MRelease|x64.ActiveCfg = Release|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Release Dedicated Server|Win32.Build.0 = Release|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Release Dedicated Server|x64.ActiveCfg = Release|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Release|Win32.ActiveCfg = Release|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Release|Win32.Build.0 = Release|Win32 + {1A353DA0-F351-4C0D-A21D-E2B460600B20}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/engine/dotnet2005/ftequake.vcproj b/engine/dotnet2005/ftequake.vcproj index e3cf5ddc..1d0292bc 100644 --- a/engine/dotnet2005/ftequake.vcproj +++ b/engine/dotnet2005/ftequake.vcproj @@ -1688,11 +1688,12 @@ EnableIntrinsicFunctions="true" FavorSizeOrSpeed="1" OmitFramePointers="true" + WholeProgramOptimization="true" AdditionalIncludeDirectories="../libs/speex,..\client,../libs/freetype2/include,../common,../server,../gl,../sw,../qclib,../libs,../libs/dxsdk7/include" PreprocessorDefinitions="NDEBUG;GLQUAKE;WIN32;_WINDOWS" StringPooling="true" ExceptionHandling="0" - RuntimeLibrary="0" + BufferSecurityCheck="false" EnableEnhancedInstructionSet="0" FloatingPointModel="2" UsePrecompiledHeader="2" @@ -1701,7 +1702,6 @@ AssemblerListingLocation=".\ftequake___Win32_GLRelease/" ObjectFile=".\ftequake___Win32_GLRelease/" ProgramDataBaseFileName=".\ftequake___Win32_GLRelease/" - BrowseInformation="1" WarningLevel="3" SuppressStartupBanner="true" CallingConvention="1" diff --git a/engine/dotnet2005/npfte.vcproj b/engine/dotnet2005/npfte.vcproj index c8441431..17be5d7b 100644 --- a/engine/dotnet2005/npfte.vcproj +++ b/engine/dotnet2005/npfte.vcproj @@ -11112,194 +11112,6 @@ /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -16046,216 +15858,6 @@ /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -19294,6 +18896,10 @@ RelativePath="..\client\r_2d.c" > + + @@ -27818,2458 +27424,6 @@ > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 1c863be0..4ce81b12 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -53,7 +53,6 @@ extern cvar_t r_skin_overlays; #ifndef SERVERONLY static hashtable_t skincolourmapped; -extern avec3_t shadevector, shadelight, ambientlight; //changes vertex lighting values #if 0 @@ -707,18 +706,25 @@ static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel) int i; vec3_t dist; float add; + vec3_t shadelight, ambientlight; + if (e->light_known) + return e->light_known-1; + + e->light_dir[0] = 0; e->light_dir[1] = 1; e->light_dir[2] = 0; if (clmodel->engineflags & MDLF_FLAME) { - shadelight[0] = shadelight[1] = shadelight[2] = 1; - ambientlight[0] = ambientlight[1] = ambientlight[2] = 1; - return true; + e->light_avg[0] = e->light_avg[1] = e->light_avg[2] = 1; + e->light_range[0] = e->light_range[1] = e->light_range[2] = 0; + e->light_known = 2; + return e->light_known-1; } if ((e->drawflags & MLS_MASKIN) == MLS_FULLBRIGHT || (e->flags & Q2RF_FULLBRIGHT)) { - shadelight[0] = shadelight[1] = shadelight[2] = 1; - ambientlight[0] = ambientlight[1] = ambientlight[2] = 1; - return true; + e->light_avg[0] = e->light_avg[1] = e->light_avg[2] = 1; + e->light_range[0] = e->light_range[1] = e->light_range[2] = 0; + e->light_known = 2; + return e->light_known-1; } if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) @@ -805,7 +811,9 @@ static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel) { ambientlight[0] = ambientlight[1] = ambientlight[2] = 1; shadelight[0] = shadelight[1] = shadelight[2] = 1; - return true; + + e->light_known = 2; + return e->light_known-1; } else { @@ -846,21 +854,21 @@ static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel) //#define SHOWLIGHTDIR { //lightdir is absolute, shadevector is relative - shadevector[0] = DotProduct(lightdir, e->axis[0]); - shadevector[1] = DotProduct(lightdir, e->axis[1]); - shadevector[2] = DotProduct(lightdir, e->axis[2]); + e->light_dir[0] = DotProduct(lightdir, e->axis[0]); + e->light_dir[1] = DotProduct(lightdir, e->axis[1]); + e->light_dir[2] = DotProduct(lightdir, e->axis[2]); if (e->flags & Q2RF_WEAPONMODEL) { vec3_t temp; - temp[0] = DotProduct(shadevector, vpn); - temp[1] = -DotProduct(shadevector, vright); - temp[2] = DotProduct(shadevector, vup); + temp[0] = DotProduct(e->light_dir, vpn); + temp[1] = -DotProduct(e->light_dir, vright); + temp[2] = DotProduct(e->light_dir, vup); - VectorCopy(temp, shadevector); + VectorCopy(temp, e->light_dir); } - VectorNormalize(shadevector); + VectorNormalize(e->light_dir); } @@ -877,7 +885,12 @@ static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel) shadelight[1] += sin(cl.time)*0.25; shadelight[2] += sin(cl.time)*0.25; } - return false; + + VectorMA(ambientlight, 0.5, shadelight, e->light_avg); + VectorSubtract(shadelight, ambientlight, e->light_range); + + e->light_known = 1; + return e->light_known-1; } void R_GAlias_DrawBatch(batch_t *batch) @@ -1487,6 +1500,13 @@ static void R_DB_LightningBeam(batch_t *batch) static mesh_t mesh; static mesh_t *meshptr = &mesh; + if (batch->ent == &r_worldentity) + { + mesh.numindexes = 0; + mesh.numindexes = 0; + return; + } + scale *= -10; if (!scale) scale = 10; @@ -1551,6 +1571,13 @@ static void R_DB_RailgunBeam(batch_t *batch) static index_t indexarray[6] = {0, 1, 2, 0, 2, 3}; static vec4_t colors[4]; + if (batch->ent == &r_worldentity) + { + mesh.numindexes = 0; + mesh.numindexes = 0; + return; + } + if (!e->forcedshader) return; @@ -1609,7 +1636,6 @@ static void R_DB_Sprite(batch_t *batch) vec3_t forward, right, up; msprite_t *psprite; vec3_t sprorigin; - unsigned int fl = 0; unsigned int sprtype; static vec2_t texcoords[4]={{0, 1},{0,0},{1,0},{1,1}}; @@ -1619,6 +1645,12 @@ static void R_DB_Sprite(batch_t *batch) static mesh_t mesh; static mesh_t *meshptr = &mesh; + if (batch->ent == &r_worldentity) + { + mesh.numindexes = 0; + mesh.numindexes = 0; + return; + } if (e->flags & Q2RF_WEAPONMODEL && r_refdef.currentplayernum >= 0) { @@ -1712,7 +1744,6 @@ static void R_DB_Sprite(batch_t *batch) VectorMA (point, frame->right, right, vertcoords[3]); batch->ent = &r_worldentity; - batch->flags |= fl; batch->mesh = &meshptr; memset(&mesh, 0, sizeof(mesh)); diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 08f96b6c..dedb76e5 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -13,6 +13,8 @@ #include #endif +extern cvar_t gl_overbright; + #define LIGHTPASS_GLSL_SHARED "\ varying vec2 tcbase;\n\ varying vec3 lightvector;\n\ @@ -230,10 +232,17 @@ char *defaultglsl2program = LIGHTPASS_GLSL_SHARED LIGHTPASS_GLSL_VERTEX LIGHTPASS_GLSL_FRAGMENT ; +//!!permu LOWER +//!!permu UPPER + static const char LIGHTPASS_SHADER[] = "\ {\n\ program\n\ {\n\ + !!permu BUMP\n\ + !!permu SPECULAR\n\ + !!permu FULLBRIGHT\n\ + !!permu OFFSETMAPPING\n\ #define LIGHTPASS\n\ %s\n\ }\n\ @@ -341,6 +350,7 @@ struct { qboolean force2d; int currenttmu; + int blendmode[SHADER_PASS_MAX]; int texenvmode[SHADER_PASS_MAX]; int currenttextures[SHADER_PASS_MAX]; GLenum curtexturetype[SHADER_PASS_MAX]; @@ -416,6 +426,57 @@ void GL_TexEnv(GLenum mode) } } +static void BE_SetPassBlendMode(int tmu, int pbm) +{ + if (shaderstate.blendmode[tmu] != pbm) + { + shaderstate.blendmode[tmu] = pbm; + if (shaderstate.currenttmu != tmu) + GL_SelectTexture(tmu); + + switch (pbm) + { + case PBM_DOTPRODUCT: + GL_TexEnv(GL_COMBINE_ARB); + qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB); + qglTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1); + break; + case PBM_REPLACELIGHT: + if (shaderstate.identitylighting != 1) + goto forcemod; + GL_TexEnv(GL_REPLACE); + break; + case PBM_REPLACE: + GL_TexEnv(GL_REPLACE); + break; + case PBM_DECAL: + if (tmu == 0) + goto forcemod; + GL_TexEnv(GL_DECAL); + break; + case PBM_ADD: + if (tmu == 0) + goto forcemod; + GL_TexEnv(GL_ADD); + break; + case PBM_OVERBRIGHT: + GL_TexEnv(GL_COMBINE_ARB); + qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + qglTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1<base:r_nulltex; break; case T_GEN_NORMALMAP: - t = shaderstate.curtexnums?shaderstate.curtexnums->bump:r_nulltex; + t = shaderstate.curtexnums?shaderstate.curtexnums->bump:r_nulltex; /*FIXME: nulltex is not correct*/ break; case T_GEN_SPECULAR: t = shaderstate.curtexnums->specular; @@ -1850,11 +1911,10 @@ static void GenerateColourMods(const shaderpass_t *pass) } if (r_nolightdir.ival) { - extern avec3_t ambientlight, shadelight; qglDisableClientState(GL_COLOR_ARRAY); - qglColor4f( ambientlight[0]*0.5+shadelight[0], - ambientlight[1]*0.5+shadelight[1], - ambientlight[2]*0.5+shadelight[2], + qglColor4f( shaderstate.curentity->light_avg[0], + shaderstate.curentity->light_avg[1], + shaderstate.curentity->light_avg[2], shaderstate.curentity->shaderRGBAf[3]); qglShadeModel(GL_FLAT); return; @@ -2090,6 +2150,7 @@ static void BE_SubmitMeshChain(void) { mesh = shaderstate.meshes[0]; qglDrawRangeElements(GL_TRIANGLES, mesh->vbofirstvert, mesh->vbofirstvert+mesh->numvertexes, mesh->numindexes, GL_INDEX_TYPE, shaderstate.sourcevbo->indicies + mesh->vbofirstelement); + RQuantAdd(RQUANT_DRAWS, 1); return; } else @@ -2120,6 +2181,7 @@ static void BE_SubmitMeshChain(void) ilst[endi++] = mesh->vbofirstvert + mesh->indexes[starti++]; } qglDrawRangeElements(GL_TRIANGLES, startv, endv, endi, GL_INDEX_TYPE, ilst); + RQuantAdd(RQUANT_DRAWS, 1); } @@ -2201,7 +2263,6 @@ static void DrawPass(const shaderpass_t *pass) tmu = 0; for (; i < lastpass; i++) { - extern cvar_t gl_overbright; if (pass[i].texgen == T_GEN_UPPEROVERLAY && !TEXVALID(shaderstate.curtexnums->upperoverlay)) continue; if (pass[i].texgen == T_GEN_LOWEROVERLAY && !TEXVALID(shaderstate.curtexnums->loweroverlay)) @@ -2212,50 +2273,7 @@ static void DrawPass(const shaderpass_t *pass) BE_GeneratePassTC(pass, i); - switch (pass[i].blendmode) - { - case PBM_DOTPRODUCT: - GL_TexEnv(GL_COMBINE_ARB); - qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); - qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); - qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB); - qglTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1); - break; - case PBM_REPLACE: - GL_TexEnv(GL_REPLACE); - break; - case PBM_DECAL: - if (tmu == 0) - goto forcemod; - GL_TexEnv(GL_DECAL); - break; - case PBM_ADD: - if (tmu == 0) - goto forcemod; - GL_TexEnv(GL_ADD); - break; - case PBM_OVERBRIGHT: - GL_TexEnv(GL_COMBINE_ARB); - qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); - qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); - qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); - { - float o; - if (gl_overbright.value >= 2) - o = 4.0; - else if (gl_overbright.value >= 1) - o = 2.0; - else - o = 1.0; - qglTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, o); - } - break; - default: - case PBM_MODULATE: - forcemod: - GL_TexEnv(GL_MODULATE); - break; - } + BE_SetPassBlendMode(tmu, pass[i].blendmode); tmu++; } @@ -2269,7 +2287,6 @@ static void DrawPass(const shaderpass_t *pass) BE_SubmitMeshChain(); } -extern avec3_t shadevector, shadelight, ambientlight; static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned int perm) { vec3_t param3; @@ -2351,6 +2368,12 @@ static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned case SP_ENTCOLOURS: qglUniform4fvARB(p->handle[perm], 1, (GLfloat*)shaderstate.curentity->shaderRGBAf); break; + case SP_ENTCOLOURSIDENT: + if (shaderstate.flags & BEF_FORCECOLOURMOD) + qglUniform4fvARB(p->handle[perm], 1, (GLfloat*)shaderstate.curentity->shaderRGBAf); + else + qglUniform4fARB(p->handle[perm], 1, 1, 1, shaderstate.curentity->shaderRGBAf[3]); + break; case SP_TOPCOLOURS: R_FetchTopColour(&r, &g, &b); param3[0] = r/255.0f; @@ -2453,14 +2476,13 @@ static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned } break; case SP_E_L_DIR: - qglUniform3fvARB(p->handle[perm], 1, shadevector); + qglUniform3fvARB(p->handle[perm], 1, (float*)shaderstate.curentity->light_dir); break; case SP_E_L_MUL: - qglUniform3fvARB(p->handle[perm], 1, shadelight); + qglUniform3fvARB(p->handle[perm], 1, (float*)shaderstate.curentity->light_range); break; case SP_E_L_AMBIENT: - VectorMA(ambientlight, 1, shadelight, param3); - qglUniform3fvARB(p->handle[perm], 1, param3); + qglUniform3fvARB(p->handle[perm], 1, (float*)shaderstate.curentity->light_avg); break; default: @@ -2591,7 +2613,7 @@ void GLBE_SelectMode(backendmode_t mode) } qglShadeModel(GL_FLAT); //replace mode please - GL_TexEnv(GL_REPLACE); + BE_SetPassBlendMode(0, PBM_REPLACE); //we don't write or blend anything (maybe alpha test... but mneh) BE_SendPassBlendDepthMask(SBITS_MISC_DEPTHCLOSERONLY | SBITS_MASK_BITS); @@ -2615,7 +2637,7 @@ void GLBE_SelectMode(backendmode_t mode) //we don't write or blend anything (maybe alpha test... but mneh) BE_SendPassBlendDepthMask(SBITS_MISC_DEPTHWRITE | SBITS_MASK_BITS); - GL_TexEnv(GL_REPLACE); + BE_SetPassBlendMode(0, PBM_REPLACE); GL_CullFace(SHADER_CULL_FRONT); } #ifdef RTLIGHTS @@ -2655,7 +2677,7 @@ void GLBE_SelectMode(backendmode_t mode) qglDisableClientState(GL_COLOR_ARRAY); qglColor4f(1, 1, 1, 1); qglShadeModel(GL_FLAT); - GL_TexEnv(GL_MODULATE); + BE_SetPassBlendMode(0, PBM_MODULATE); BE_SendPassBlendDepthMask(SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA | SBITS_MISC_DEPTHEQUALONLY); } #endif @@ -2874,7 +2896,7 @@ static void DrawMeshes(void) { GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex, false); } - GL_TexEnv(GL_REPLACE); + BE_SetPassBlendMode(0, PBM_REPLACE); BE_SendPassBlendDepthMask(shaderstate.curshader->passes[0].shaderbits); GL_ApplyVertexPointer(); @@ -3264,12 +3286,24 @@ void GLBE_DrawWorld (qbyte *vis) r_worldentity.axis[1][1] = 1; r_worldentity.axis[2][2] = 1; + if (gl_overbright.modified) + { + int i; + gl_overbright.modified = false; + if (gl_overbright.ival > 2) + gl_overbright.ival = 2; + + for (i = 0; i < SHADER_PASS_MAX; i++) + shaderstate.blendmode[i] = -1; + } + #ifdef RTLIGHTS if (r_shadow_realtime_world.value && gl_config.arb_shader_objects) shaderstate.identitylighting = r_shadow_realtime_world_lightmaps.value; else #endif shaderstate.identitylighting = 1; +// shaderstate.identitylighting /= 1<fromgame == fg_halflife || loadmodel->fromgame == fg_quake2 || loadmodel->fromgame == fg_quake3) mapcomeswith24bitcolouredlighting = true; - if (!mapcomeswith24bitcolouredlighting && r_loadlits.value && gl_bumpmappingpossible) //fixme: adjust the light intensities. + if (!mapcomeswith24bitcolouredlighting && r_loadlits.ival && gl_bumpmappingpossible && r_deluxemapping.ival) //fixme: adjust the light intensities. { //the map util has a '-scalecos X' parameter. use 0 if you're going to use only just lux. without lux scalecos 0 is hideous. char luxname[MAX_QPATH]; if (!luxdata) diff --git a/engine/gl/gl_rlight.c b/engine/gl/gl_rlight.c index c9c9e0e3..6c0ea308 100644 --- a/engine/gl/gl_rlight.c +++ b/engine/gl/gl_rlight.c @@ -931,6 +931,7 @@ void GLQ1BSP_LightPointValues(model_t *model, vec3_t point, vec3_t res_diffuse, { vec3_t end; float *r; + extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_lightmaps; if (!cl.worldmodel->lightdata || r_fullbright.ival) { @@ -973,10 +974,11 @@ void GLQ1BSP_LightPointValues(model_t *model, vec3_t point, vec3_t res_diffuse, res_diffuse[0] = r[0]; res_diffuse[1] = r[1]; res_diffuse[2] = r[2]; - - res_ambient[0] = 0; - res_ambient[1] = 0; - res_ambient[2] = 0; + + /*bright on one side, dark on the other, but not too dark*/ + res_ambient[0] = r[0]/3; + res_ambient[1] = r[1]/3; + res_ambient[2] = r[2]/3; res_dir[0] = r[3]; res_dir[1] = r[4]; @@ -985,6 +987,12 @@ void GLQ1BSP_LightPointValues(model_t *model, vec3_t point, vec3_t res_diffuse, res_dir[1] = res_dir[2] = 1; VectorNormalize(res_dir); } + + if (r_shadow_realtime_world.ival) + { + VectorScale(res_diffuse, r_shadow_realtime_world_lightmaps.value, res_diffuse); + VectorScale(res_ambient, r_shadow_realtime_world_lightmaps.value, res_ambient); + } } #endif diff --git a/engine/gl/gl_rsurf.c b/engine/gl/gl_rsurf.c index 933b4743..cc04ce60 100644 --- a/engine/gl/gl_rsurf.c +++ b/engine/gl/gl_rsurf.c @@ -66,23 +66,26 @@ static qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int if (!qglGenBuffersARB) return false; - qglGenBuffersARB(2, vbos); + qglGenBuffersARB(1+(elementsize>0), vbos); GL_SelectVBO(vbos[0]); qglBufferDataARB(GL_ARRAY_BUFFER_ARB, vsize, vdata, GL_STATIC_DRAW_ARB); - GL_SelectEBO(vbos[1]); - qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementsize, edata, GL_STATIC_DRAW_ARB); + if (elementsize>0) + { + GL_SelectEBO(vbos[1]); + qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementsize, edata, GL_STATIC_DRAW_ARB); + } if (qglGetError()) { GL_SelectVBO(0); GL_SelectEBO(0); - qglDeleteBuffersARB(2, vbos); + qglDeleteBuffersARB(1+(elementsize>0), vbos); return false; } //opengl ate our data, fixup the vbo arrays to point to the vbo instead of the raw data - if (vbo->indicies) + if (vbo->indicies && elementsize) { vbo->vboe = vbos[1]; vbo->indicies = (index_t*)((char*)vbo->indicies - (char*)edata); diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 17b5b672..c0291555 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -37,6 +37,7 @@ static qboolean shader_rescan_needed; //cvars that affect shader generation cvar_t r_vertexlight = SCVAR("r_vertexlight", "0"); +extern cvar_t r_deluxemapping; extern cvar_t r_fastturb, r_fastsky, r_skyboxname; extern cvar_t r_drawflat; @@ -220,7 +221,7 @@ static qboolean Shader_EvaluateCondition(char **ptr) if (!Q_stricmp(token, "lightmap")) conditiontrue = conditiontrue == !r_fullbright.value; else if (!Q_stricmp(token, "deluxmap") ) - conditiontrue = conditiontrue == !!gl_bump.value; + conditiontrue = conditiontrue == (r_deluxemapping.value && gl_bump.value); //normalmaps are generated if they're not already known. else if (!Q_stricmp(token, "normalmap") ) @@ -725,7 +726,7 @@ static void Shader_EntityMergable ( shader_t *shader, shaderpass_t *pass, char * shader->flags |= SHADER_ENTITY_MERGABLE; } -static void Shader_ProgAutoFields(program_t *prog); +static void Shader_ProgAutoFields(program_t *prog, char **cvarfnames); /*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 void Shader_LoadPermutations(program_t *prog, char *script, int qrtype) { @@ -744,14 +745,32 @@ static void Shader_LoadPermutations(program_t *prog, char *script, int qrtype) int p, n, pn; char *end; + char *cvarfnames[64]; + int cvarfcount = 0; + + cvarfnames[cvarfcount] = NULL; + for(;;) { while (*script == ' ' || *script == '\r' || *script == '\n' || *script == '\t') script++; - if (!strncmp(script, "!!permu", 7)) + if (!strncmp(script, "!!cvarf", 7)) { script += 7; - while (*script == ' ' || *script == '\r' || *script == '\n' || *script == '\t') + while (*script == ' ' || *script == '\t') + script++; + end = script; + while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') || *end == '_') + end++; + if (cvarfcount+1 != sizeof(cvarfnames)/sizeof(cvarfnames[0])) + cvarfnames[cvarfcount++] = script; + cvarfnames[cvarfcount] = NULL; + script = end; + } + else if (!strncmp(script, "!!permu", 7)) + { + script += 7; + while (*script == ' ' || *script == '\t') script++; end = script; while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') || *end == '_') @@ -809,7 +828,7 @@ static void Shader_LoadPermutations(program_t *prog, char *script, int qrtype) #endif } - Shader_ProgAutoFields(prog); + Shader_ProgAutoFields(prog, cvarfnames); } typedef struct sgeneric_s { @@ -967,6 +986,7 @@ struct sbuiltin_s "#endif\n" }, {QR_OPENGL/*ES*/, 100, "defaultwarp", + "!!cvarf r_wateralpha\n" //"#version 100\n" "varying mediump vec2 tc;\n" "#ifdef VERTEX_SHADER\n" @@ -984,7 +1004,7 @@ struct sbuiltin_s "#ifdef FRAGMENT_SHADER\n" "uniform sampler2D watertexture;\n" "uniform mediump float e_time;\n" - "uniform lowp float wateralpha;\n" + "uniform lowp float r_wateralpha;\n" "void main (void)\n" "{\n" @@ -993,11 +1013,12 @@ struct sbuiltin_s " ntc.t = tc.t + sin(tc.s+e_time)*0.125;\n" " lowp vec3 ts = vec3(texture2D(watertexture, ntc));\n" - " gl_FragColor = vec4(ts, wateralpha);\n" + " gl_FragColor = vec4(ts, r_wateralpha);\n" "}\n" "#endif\n" }, {QR_OPENGL, 110, "defaultwarp", + "!!cvarf r_wateralpha\n" "#version 110\n" "varying vec2 tc;\n" "#ifdef VERTEX_SHADER\n" @@ -1011,7 +1032,7 @@ struct sbuiltin_s "#ifdef FRAGMENT_SHADER\n" "uniform sampler2D s_t0;\n" "uniform float e_time;\n" - "uniform float wateralpha;\n" + "uniform float r_wateralpha;\n" "void main (void)\n" "{\n" @@ -1020,7 +1041,7 @@ struct sbuiltin_s " ntc.t = tc.t + sin(tc.s+e_time)*0.125;\n" " vec3 ts = vec3(texture2D(s_t0, ntc));\n" - " gl_FragColor = vec4(ts, wateralpha);\n" + " gl_FragColor = vec4(ts, r_wateralpha);\n" "}\n" "#endif\n" }, @@ -1147,6 +1168,7 @@ struct sbuiltin_s "#endif\n" "varying mediump vec2 tc;\n" "varying lowp vec3 light;\n" + "uniform vec4 e_colourident;\n" "void main (void)\n" "{\n" @@ -1165,8 +1187,7 @@ struct sbuiltin_s " vec4 fb = texture2D(s_t3, tc);\n" " col.rgb = mix(col.rgb, fb.rgb, fb.a);\n" "#endif\n" - " gl_FragColor.rgb = col.rgb;\n" /*'default' skin has an rgbgen of identity*/ - " gl_FragColor.a = col.a * e_colour.a;\n" /*it also has an alphagen of identity too, but generate an alpha anyway, as its normally not blended and thus ignores colour*/ + " gl_FragColor = col * e_colourident;\n" "}\n" "#endif\n" }, @@ -1211,7 +1232,7 @@ struct sbuiltin_s "#endif\n" "varying vec2 tc;\n" "varying vec3 light;\n" - "uniform vec4 e_colour;\n" + "uniform vec4 e_colourident;\n" "void main (void)\n" "{\n" @@ -1230,8 +1251,7 @@ struct sbuiltin_s " vec4 fb = texture2D(s_t3, tc);\n" " col.rgb = mix(col.rgb, fb.rgb, fb.a);\n" "#endif\n" - " gl_FragColor.rgb = col.rgb;\n" /*'default' skin has an rgbgen of identity*/ - " gl_FragColor.a = col.a * e_colour.a;\n" /*it also has an alphagen of identity too, but generate an alpha anyway, as its normally not blended and thus ignores colour*/ + " gl_FragColor = col * e_colourident;\n" "}\n" "#endif\n" }, @@ -1364,11 +1384,13 @@ static program_t *Shader_LoadGeneric(char *name, int qrtype) return NULL; } -static void Shader_ProgAutoFields(program_t *prog) +static void Shader_ProgAutoFields(program_t *prog, char **cvarfnames) { unsigned int i, p; qboolean found; int uniformloc; + char tmpname[128]; + cvar_t *cvar; static struct { char *name; @@ -1395,6 +1417,7 @@ static void Shader_ProgAutoFields(program_t *prog) {"e_time", SP_TIME}, {"e_eyepos", SP_EYEPOS}, {"e_colour", SP_ENTCOLOURS}, + {"e_colourident", SP_ENTCOLOURSIDENT}, {"e_topcolour", SP_TOPCOLOURS}, {"e_bottomcolour", SP_BOTTOMCOLOURS}, {"e_light_dir", SP_E_L_DIR}, @@ -1409,16 +1432,24 @@ static void Shader_ProgAutoFields(program_t *prog) if (gl_config.nofixedfunc) prog->nofixedcompat = true; - for (p = 0; p < PERMUTATIONS; p++) + /*set cvar unirforms*/ + for (i = 0; cvarfnames[i]; i++) { - if (!prog->handle[p].glsl) + for (p = 0; cvarfnames[i][p] && (unsigned char)cvarfnames[i][p] > 32 && p < sizeof(tmpname)-1; p++) + tmpname[p] = cvarfnames[i][p]; + tmpname[p] = 0; + cvar = Cvar_FindVar(tmpname); + if (!cvar) continue; - GLSlang_UseProgram(prog->handle[p].glsl); - for (i = 0; i < 8; i++) + cvar->flags |= CVAR_SHADERSYSTEM; + for (p = 0; p < PERMUTATIONS; p++) { - uniformloc = qglGetUniformLocationARB(prog->handle[p].glsl, va("s_t%i", i)); + if (!prog->handle[p].glsl) + continue; + GLSlang_UseProgram(prog->handle[p].glsl); + uniformloc = qglGetUniformLocationARB(prog->handle[p].glsl, u[i].name); if (uniformloc != -1) - qglUniform1iARB(uniformloc, i); + qglUniform1fARB(uniformloc, cvar->value); } } for (i = 0; u[i].name; i++) @@ -1446,6 +1477,19 @@ static void Shader_ProgAutoFields(program_t *prog) prog->nofixedcompat = true; } } + /*set texture uniforms*/ + for (p = 0; p < PERMUTATIONS; p++) + { + if (!prog->handle[p].glsl) + continue; + GLSlang_UseProgram(prog->handle[p].glsl); + for (i = 0; i < 8; i++) + { + uniformloc = qglGetUniformLocationARB(prog->handle[p].glsl, va("s_t%i", i)); + if (uniformloc != -1) + qglUniform1iARB(uniformloc, i); + } + } GLSlang_UseProgram(0); } #endif @@ -2861,9 +2905,19 @@ void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2) return; } - if (pass2->rgbgen != RGB_GEN_IDENTITY || pass2->alphagen != ALPHA_GEN_IDENTITY) + /*identity alpha is required for merging*/ + if (pass->alphagen != ALPHA_GEN_IDENTITY || pass2->alphagen != ALPHA_GEN_IDENTITY) return; - if (pass->rgbgen != RGB_GEN_IDENTITY || pass->alphagen != ALPHA_GEN_IDENTITY) + + /*rgbgen must be identity too except if the later pass is identity_ligting, in which case all is well and we can switch the first pass to identity_lighting instead*/ + if (pass2->rgbgen == RGB_GEN_IDENTITY_LIGHTING && pass2->blendmode == PBM_MODULATE && pass->rgbgen == RGB_GEN_IDENTITY) + { + pass->blendmode = PBM_REPLACELIGHT; + pass->rgbgen = RGB_GEN_IDENTITY_LIGHTING; + pass2->rgbgen = RGB_GEN_IDENTITY; + } + /*rgbgen must be identity (or the first is identity_lighting)*/ + else if (pass2->rgbgen != RGB_GEN_IDENTITY || (pass->rgbgen != RGB_GEN_IDENTITY && pass->rgbgen != RGB_GEN_IDENTITY_LIGHTING)) return; /*if its alphatest, don't merge with anything other than lightmap*/ @@ -2880,7 +2934,7 @@ void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2) } else if (pass->numMergedPasses < be_maxpasses) { - if ( pass->blendmode == PBM_REPLACE ) + if (pass->blendmode == PBM_REPLACE || pass->blendmode == PBM_REPLACELIGHT) { if ((pass2->blendmode == PBM_DECAL && config_tex_env_combine) || (pass2->blendmode == PBM_ADD && config_env_add) || @@ -2903,7 +2957,7 @@ void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2) } else return; - if (pass2->texgen == T_GEN_LIGHTMAP) + if (pass2->texgen == T_GEN_LIGHTMAP && pass2->blendmode == PBM_MODULATE) pass2->blendmode = PBM_OVERBRIGHT; } @@ -3003,10 +3057,14 @@ void Shader_Finish (shader_t *s) s->flags = 0; if (!(s->flags & SHADER_SKY)) { + char name[MAX_QPATH]; + Q_strncpyz(name, s->name, sizeof(name)); Shader_Free(s); memset(s, 0, sizeof(*s)); - Shader_DefaultScript(s->name, s, + Q_strncpyz(s->name, name, sizeof(s->name)); + + Shader_DefaultScript(name, s, "{\n" "sort sky\n" "{\n" @@ -3202,7 +3260,10 @@ done:; { if (sp->rgbgen == RGB_GEN_UNKNOWN) { - sp->rgbgen = RGB_GEN_IDENTITY; + if (sp->flags & SHADER_PASS_LIGHTMAP) + sp->rgbgen = RGB_GEN_IDENTITY_LIGHTING; + else + sp->rgbgen = RGB_GEN_IDENTITY; } Shader_SetBlendmode (sp); @@ -3397,7 +3458,7 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args) if (!builtin) builtin = ( "{\n" - "if gl_bump\n" + "if $deluxmap\n" "[\n" "{\n" "map $normalmap\n" diff --git a/engine/gl/gl_shadow.c b/engine/gl/gl_shadow.c index 0fb22d08..e3ad2460 100644 --- a/engine/gl/gl_shadow.c +++ b/engine/gl/gl_shadow.c @@ -1587,6 +1587,7 @@ static void Sh_WorldLightingPass(void) qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), s->texinfo->texture->vbo.coord); } qglDrawRangeElements(GL_TRIANGLES, s->mesh->vbofirstvert, s->mesh->numvertexes, s->mesh->numindexes, GL_INDEX_TYPE, (index_t*)(s->mesh->vbofirstelement*sizeof(index_t))); + RQuantAdd(RQUANT_LITFACES, s->mesh->numindexes); } } @@ -1674,6 +1675,7 @@ static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e) qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), surf->mesh->xyz_array); qglDrawArrays(GL_POLYGON, 0, surf->mesh->numvertexes); // qglDrawRangeElements(GL_TRIANGLES, 0, surf->mesh->numvertexes, surf->mesh->numindexes, GL_INDEX_TYPE, surf->mesh->indexes); + RQuantAdd(RQUANT_SHADOWFACES, surf->mesh->numvertexes); for (v = 0; v < surf->mesh->numvertexes; v++) { @@ -1745,6 +1747,7 @@ static void Sh_DrawStencilLightShadows(dlight_t *dl, qbyte *lvis, qbyte *vvis, q //draw cached world shadow mesh qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), sm->verts); qglDrawRangeElements(GL_TRIANGLES, 0, sm->numverts, sm->numindicies, GL_INDEX_TYPE, sm->indicies); + RQuantAdd(RQUANT_SHADOWFACES, sm->numindicies); //qglEnable(GL_POLYGON_OFFSET_FILL); //qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit); diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index d2e22727..fa9702d3 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -310,19 +310,38 @@ qboolean GLInitialise (char *renderer) return true; } -void CenterWindow(HWND hWndCenter, int width, int height, BOOL lefttopjustify) +/*doesn't consider parent offsets*/ +RECT centerrect(unsigned int parentwidth, unsigned int parentheight, unsigned int cwidth, unsigned int cheight) { -// RECT rect; - int CenterX, CenterY; + RECT r; + if (!vid_width.ival) + cwidth = parentwidth; + if (!vid_height.ival) + cheight = parentwidth; - CenterX = (GetSystemMetrics(SM_CXSCREEN) - width) / 2; - CenterY = (GetSystemMetrics(SM_CYSCREEN) - height) / 2; - if (CenterX > CenterY*2) - CenterX >>= 1; // dual screens - CenterX = (CenterX < 0) ? 0: CenterX; - CenterY = (CenterY < 0) ? 0: CenterY; - SetWindowPos (hWndCenter, NULL, CenterX, CenterY, 0, 0, - SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); + if (parentwidth < cwidth) + { + r.left = 0; + r.right = parentwidth; + } + else + { + r.left = (parentwidth - cwidth) / 2; + r.right = r.left + cwidth; + } + + if (parentheight < cheight) + { + r.top = 0; + r.bottom = parentheight; + } + else + { + r.top = (parentheight - cheight) / 2; + r.bottom = r.top + cheight; + } + + return r; } qboolean VID_SetWindowedMode (rendererstate_t *info) @@ -330,7 +349,7 @@ qboolean VID_SetWindowedMode (rendererstate_t *info) { int i; HDC hdc; - int lastmodestate, wwidth, wheight; + int lastmodestate, wwidth, wheight, pwidth, pheight; RECT rect; hdc = GetDC(NULL); @@ -357,24 +376,8 @@ qboolean VID_SetWindowedMode (rendererstate_t *info) WindowStyle = WS_CHILDWINDOW|WS_OVERLAPPED; ExWindowStyle = 0; - //if (vid_fullscreen.ival < 0) - { - WindowRect.right = sys_parentwidth; - WindowRect.bottom = sys_parentheight; - } - - if (WindowRect.right > sys_parentwidth) - WindowRect.right = sys_parentwidth; - else if (WindowRect.right < sys_parentwidth) - WindowRect.left = (sys_parentwidth - WindowRect.right)/2; - - if (WindowRect.bottom > sys_parentheight) - WindowRect.bottom = sys_parentheight; - else if (WindowRect.bottom < sys_parentheight) - WindowRect.top = (sys_parentheight - WindowRect.bottom)/2; - - WindowRect.right += WindowRect.left; - WindowRect.bottom += WindowRect.top; + pwidth = sys_parentwidth; + pheight = sys_parentheight; } else #endif @@ -384,6 +387,13 @@ qboolean VID_SetWindowedMode (rendererstate_t *info) ExWindowStyle = 0; WindowStyle |= WS_SIZEBOX | WS_MAXIMIZEBOX; + + pwidth = GetSystemMetrics(SM_CXSCREEN); + pheight = GetSystemMetrics(SM_CYSCREEN); + + /*Assume dual monitors, and chop the width to try to put it on only one screen*/ + if (pwidth >= pheight*2) + pwidth /= 2; } DIBWidth = WindowRect.right - WindowRect.left; @@ -395,15 +405,17 @@ qboolean VID_SetWindowedMode (rendererstate_t *info) wwidth = rect.right - rect.left; wheight = rect.bottom - rect.top; + WindowRect = centerrect(pwidth, pheight, wwidth, wheight); + // Create the DIB window dibwindow = CreateWindowEx ( ExWindowStyle, WINDOW_CLASS_NAME, FULLENGINENAME, WindowStyle, - rect.left, rect.top, - wwidth, - wheight, + WindowRect.left, WindowRect.top, + WindowRect.right - WindowRect.left, + WindowRect.bottom - WindowRect.top, sys_parentwindow, NULL, global_hInstance, @@ -438,13 +450,10 @@ qboolean VID_SetWindowedMode (rendererstate_t *info) } } #endif - - // Center and show the DIB window - CenterWindow(dibwindow, WindowRect.right - WindowRect.left, - WindowRect.bottom - WindowRect.top, false); } - else - SetFocus(dibwindow); + + ShowWindow (dibwindow, SW_SHOWDEFAULT); + SetFocus(dibwindow); // ShowWindow (dibwindow, SW_SHOWDEFAULT); // UpdateWindow (dibwindow); @@ -459,7 +468,6 @@ qboolean VID_SetWindowedMode (rendererstate_t *info) PatBlt(hdc,0,0,WindowRect.right,WindowRect.bottom,BLACKNESS); ReleaseDC(dibwindow, hdc); - if ((i = COM_CheckParm("-conwidth")) != 0) vid.width = Q_atoi(com_argv[i+1]); else @@ -509,7 +517,7 @@ qboolean VID_SetFullDIBMode (rendererstate_t *info) int lastmodestate, wwidth, wheight; RECT rect; - if (leavecurrentmode && Q_strcasecmp(info->glrenderer, "D3D")) //don't do this with d3d - d3d should set it's own video mode. + if (leavecurrentmode) //don't do this with d3d - d3d should set it's own video mode. { //make windows change res. gdevmode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; if (info->bpp) @@ -1062,7 +1070,7 @@ void VID_Wait_Override_Callback(struct cvar_s *var, char *oldvalue) qwglSwapIntervalEXT(_vid_wait_override.value); } -void VID_Size_Override_Callback(struct cvar_s *var, char *oldvalue) +void GLVID_Recenter_f(void) { int nw = vid_width.value; int nh = vid_height.value; @@ -1071,16 +1079,12 @@ void VID_Size_Override_Callback(struct cvar_s *var, char *oldvalue) if (sys_parentwindow && modestate==MS_WINDOWED) { - if (nw > sys_parentwidth) - nw = sys_parentwidth; - else - nx = (sys_parentwidth - nw)/2; - if (nh > sys_parentheight) - nh = sys_parentheight; - else - ny = (sys_parentheight - nh)/2; + WindowRect = centerrect(sys_parentwidth, sys_parentheight, vid_width.value, vid_height.value); + MoveWindow(mainwindow, WindowRect.left, WindowRect.top, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top, FALSE); - MoveWindow(mainwindow, nx, ny, nw, nh, FALSE); + Cvar_ForceCallback(&vid_conautoscale); + Cvar_ForceCallback(&vid_conwidth); + VID_UpdateWindowStatus (mainwindow); } } @@ -1818,9 +1822,11 @@ void GLVID_DeInit (void) Cvar_Unhook(&_vid_wait_override); Cvar_Unhook(&vid_wndalpha); + Cmd_RemoveCommand("vid_recenter"); UnregisterClass(WINDOW_CLASS_NAME, global_hInstance); } + /* =================== VID_Init @@ -1875,10 +1881,10 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) S_Restart_f(); Cvar_Hook(&_vid_wait_override, VID_Wait_Override_Callback); - Cvar_Hook(&vid_width, VID_Size_Override_Callback); - Cvar_Hook(&vid_height, VID_Size_Override_Callback); Cvar_Hook(&vid_wndalpha, VID_WndAlpha_Override_Callback); + Cmd_AddRemCommand("vid_recenter", GLVID_Recenter_f); + vid_initialized = true; vid_initializing = false; diff --git a/engine/gl/shader.h b/engine/gl/shader.h index 4ec95481..5e2765b9 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -149,7 +149,8 @@ typedef struct shaderpass_s { PBM_DECAL, PBM_ADD, PBM_DOTPRODUCT, - PBM_REPLACE + PBM_REPLACE, + PBM_REPLACELIGHT } blendmode; enum { @@ -272,6 +273,7 @@ typedef struct { /*entity properties*/ SP_ENTCOLOURS, + SP_ENTCOLOURSIDENT, SP_TOPCOLOURS, SP_BOTTOMCOLOURS, SP_TIME, @@ -434,6 +436,7 @@ mfog_t *CM_FogForOrigin(vec3_t org); #define BEF_PUSHDEPTH 32 //additional polygon offset #define BEF_NODLIGHT 64 //don't use a dlight pass #define BEF_NOSHADOWS 128 //don't appear in shadows +#define BEF_FORCECOLOURMOD 256 //q3 shaders default to 'rgbgen identity', and ignore ent colours. this forces ent colours to be considered #ifdef GLQUAKE void GLBE_Init(void); diff --git a/engine/server/sv_sys_unix.c b/engine/server/sv_sys_unix.c index cffe7663..209be873 100644 --- a/engine/server/sv_sys_unix.c +++ b/engine/server/sv_sys_unix.c @@ -630,6 +630,10 @@ void Sys_Init (void) Cvar_Register (&sys_linebuffer, "System configuration"); } +void Sys_Shutdown (void) +{ +} + /* ============= main diff --git a/engine/server/sv_sys_win.c b/engine/server/sv_sys_win.c index 85e1c1f3..843c6ad0 100644 --- a/engine/server/sv_sys_win.c +++ b/engine/server/sv_sys_win.c @@ -1076,6 +1076,10 @@ void Sys_Init (void) hconsoleout = GetStdHandle(STD_OUTPUT_HANDLE); } +void Sys_Shutdown (void) +{ +} + /* ================== main diff --git a/fteqtv/libqtvc/msvc_sucks.c b/fteqtv/libqtvc/msvc_sucks.c index 0ec8535e..845f9eb7 100644 --- a/fteqtv/libqtvc/msvc_sucks.c +++ b/fteqtv/libqtvc/msvc_sucks.c @@ -23,6 +23,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include +#if _MSC_VER >= 1300 + #define vsnprintf q_vsnprintf /*msvc doesn't null terminate. its insecute and thus useless*/ +#endif + static int vsnprintf_calcsize(const char *fmt, va_list va) { void *mem; diff --git a/fteqtv/qtv.h b/fteqtv/qtv.h index 12e1ab04..1cb1d6a5 100644 --- a/fteqtv/qtv.h +++ b/fteqtv/qtv.h @@ -51,6 +51,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MACOSX #endif +#include +/*work around fucked MSVC functions. we use our own for these*/ +#if _MSC_VER >= 1300 + #include + #ifndef _CRT_SECURE_NO_WARNINGS + #define _CRT_SECURE_NO_WARNINGS + #endif + #define vsnprintf q_vsnprintf /*msvc doesn't null terminate. its insecute and thus useless*/ + #define stricmp _stricmp /*msvc just doesn't work properly*/ + #define chdir _chdir + #define gwtcwd _getcwd +#endif + #ifdef _WIN32 #include #include //this includes windows.h and is the reason for much compiling slowness with windows builds. @@ -114,9 +127,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #if !defined(__MINGW32_VERSION) #define unlink _unlink //why do MS have to be so awkward? int snprintf(char *buffer, int buffersize, char *format, ...) PRINTFWARNING(3); - #if !defined(_VC80_UPGRADE) - int vsnprintf(char *buffer, int buffersize, char *format, va_list argptr); - #endif + int vsnprintf(char *buffer, int buffersize, const char *format, va_list argptr); #else #define unlink remove //seems mingw misses something #endif diff --git a/fteqtv/qw.c b/fteqtv/qw.c index d48eb992..084be2b2 100644 --- a/fteqtv/qw.c +++ b/fteqtv/qw.c @@ -3156,7 +3156,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean if (news != INVALID_SOCKET) { - if (cluster->tcpsocket != INVALID_SOCKET) + if (cluster->tcpsocket[1] != INVALID_SOCKET) closesocket(cluster->tcpsocket[1]); cluster->tcpsocket[1] = news; cluster->tcplistenportnum = newp; @@ -3174,7 +3174,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean if (news != INVALID_SOCKET) { - if (cluster->tcpsocket != INVALID_SOCKET) + if (cluster->tcpsocket[0] != INVALID_SOCKET) closesocket(cluster->tcpsocket[0]); cluster->tcpsocket[0] = news; cluster->tcplistenportnum = newp;