Make sure skyrooms show only the entities inside the skyroom (disabling non-static entities if their pvs is not reliable).

Make sure q2's skyaxis/skyrotate stuff actually works properly on skyboxes.
Add a cvar to spin skyrooms too (separate from skyboxes, allowing for double spins though probably only one will be useful).
Fix win32+reversedns issue.
Fix a splitscreen networking bug.



git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5492 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2019-07-19 02:13:19 +00:00
parent e0fe3c8dec
commit df8440d682
21 changed files with 196 additions and 81 deletions

View File

@ -1300,6 +1300,7 @@ int CG_Refresh(void)
if (!cgvm)
return false;
r_refdef.skyroom_enabled = false;
time = cl.time*1000;
VM_Call(cgvm, CG_DRAW_ACTIVE_FRAME, time, 0, false);

View File

@ -4347,24 +4347,37 @@ static void CLQ2_ParseConfigString (void)
}
else if (i == Q2CS_SKY)
R_SetSky(s);
else if (i == Q2CS_SKYAXIS)
else if (i == Q2CS_SKYAXIS || i == Q2CS_SKYROTATE)
{
s = COM_Parse(s);
if (s)
if (i == Q2CS_SKYROTATE)
cl.skyrotate = atof(s);
else
{
cl.skyaxis[0] = atof(com_token);
s = COM_Parse(s);
if (s)
{
cl.skyaxis[1] = atof(com_token);
cl.skyaxis[0] = atof(com_token);
s = COM_Parse(s);
if (s)
cl.skyaxis[2] = atof(com_token);
{
cl.skyaxis[1] = atof(com_token);
s = COM_Parse(s);
if (s)
cl.skyaxis[2] = atof(com_token);
}
}
}
if (cl.skyrotate)
{
if (cl.skyaxis[0]||cl.skyaxis[1]||cl.skyaxis[2])
Cvar_Set(&r_skybox_orientation, va("%g %g %g %g", cl.skyaxis[0], cl.skyaxis[1], cl.skyaxis[2], cl.skyrotate));
else
Cvar_Set(&r_skybox_orientation, va("0 0 1 %g", cl.skyrotate));
}
else
Cvar_Set(&r_skybox_orientation, "");
}
else if (i == Q2CS_SKYROTATE)
cl.skyrotate = atof(s);
else if (i == Q2CS_STATUSBAR)
{
Q_strncpyz(cl.q2statusbar, s, sizeof(cl.q2statusbar));

View File

@ -76,12 +76,12 @@ void QDECL joyaxiscallback(cvar_t *var, char *oldvalue)
static cvar_t joy_advaxis[6] =
{
#define ADVAXISDESC (const char *)"Provides a way to remap each joystick/controller axis.\nShould be set to one of: moveforward, moveback, lookup, lookdown, turnleft, turnright, moveleft, moveright, moveup, movedown, rollleft, rollright"
CVARCD("joyadvaxisx", "moveright", joyaxiscallback, ADVAXISDESC),
CVARCD("joyadvaxisy", "moveforward", joyaxiscallback, ADVAXISDESC),
CVARCD("joyadvaxisz", "", joyaxiscallback, ADVAXISDESC),
CVARCD("joyadvaxisr", "turnright", joyaxiscallback, ADVAXISDESC),
CVARCD("joyadvaxisu", "lookup", joyaxiscallback, ADVAXISDESC),
CVARCD("joyadvaxisv", "", joyaxiscallback, ADVAXISDESC)
CVARCD("joyadvaxisx", "moveright", joyaxiscallback, ADVAXISDESC), //left rightwards axis
CVARCD("joyadvaxisy", "moveforward", joyaxiscallback, ADVAXISDESC), //left downwards axis
CVARCD("joyadvaxisz", "", joyaxiscallback, ADVAXISDESC), //typically left trigger (use it as a button)
CVARCD("joyadvaxisr", "turnright", joyaxiscallback, ADVAXISDESC), //right rightwards axis
CVARCD("joyadvaxisu", "lookup", joyaxiscallback, ADVAXISDESC), //right downwards axis
CVARCD("joyadvaxisv", "", joyaxiscallback, ADVAXISDESC) //typically right trigger
};
static cvar_t joy_advaxisscale[6] =
{

View File

@ -294,6 +294,7 @@ typedef struct
vec3_t skyroom_pos; /*the camera position for sky rooms*/
qboolean skyroom_enabled; /*whether a skyroom position is defined*/
int firstvisedict; /*so we can skip visedicts in skies*/
pxrect_t pxrect; /*vrect, but in pixels rather than virtual coords*/
qboolean externalview; /*draw external models and not viewmodels*/

View File

@ -57,7 +57,6 @@ void R_ForceSky_f(void)
{
if (Cmd_Argc() < 2)
{
extern cvar_t r_skyboxname;
if (*r_skyboxname.string)
Con_Printf("Current user skybox is %s\n", r_skyboxname.string);
else if (*cl.skyname)
@ -195,6 +194,7 @@ cvar_t r_part_rain = CVARFD ("r_part_rain", "0",
"Enable particle effects to emit off of surfaces. Mainly used for weather or lava/slime effects.");
cvar_t r_skyboxname = CVARFC ("r_skybox", "",
CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM, R_SkyBox_Changed);
cvar_t r_skybox_orientation = CVARFD ("r_glsl_skybox_orientation", "0 0 0 0", CVAR_SHADERSYSTEM, "Defines the axis around which skyboxes will rotate (the first three values). The fourth value defines the speed the skybox rotates at, in degrees per second.");
cvar_t r_softwarebanding_cvar = CVARFD ("r_softwarebanding", "0", CVAR_SHADERSYSTEM|CVAR_RENDERERLATCH|CVAR_ARCHIVE, "Utilise the Quake colormap in order to emulate 8bit software rendering. This results in banding as well as other artifacts that some believe adds character. Also forces nearest sampling on affected surfaces (palette indicies do not interpolate well).");
qboolean r_softwarebanding;
cvar_t r_speeds = CVAR ("r_speeds", "0");
@ -832,6 +832,7 @@ void Renderer_Init(void)
Cvar_Register (&r_skyfog, GRAPHICALNICETIES);
Cvar_Register (&r_skyboxname, GRAPHICALNICETIES);
Cvar_Register (&r_skybox_orientation, GRAPHICALNICETIES);
Cmd_AddCommand("sky", R_ForceSky_f); //QS compat
Cmd_AddCommand("loadsky", R_ForceSky_f);//DP compat

View File

@ -308,7 +308,7 @@ static void S_Shutdown_f(void);
*/
static cvar_t s_al_debug = CVARD("s_al_debug", "0", "Enables periodic checks for OpenAL errors.");
static cvar_t s_al_use_reverb = CVARD("s_al_use_reverb", "1", "Controls whether reverb effects will be used. Set to 0 to block them. Reverb requires gamecode to configure the reverb properties, other than underwater.");
static cvar_t s_al_max_distance = CVARFC("s_al_max_distance", "1000",0,OnChangeALSettings);
//static cvar_t s_al_max_distance = CVARFC("s_al_max_distance", "1000",0,OnChangeALSettings);
static cvar_t s_al_speedofsound = CVARFCD("s_al_speedofsound", "343.3",0,OnChangeALSettings, "Configures the speed of sound, in game units per second. This affects doppler.");
static cvar_t s_al_dopplerfactor = CVARFCD("s_al_dopplerfactor", "1.0",0,OnChangeALSettings, "Multiplies the strength of doppler effects.");
static cvar_t s_al_distancemodel = CVARFCD("s_al_distancemodel", legacyval("2","0"),0,OnChangeALSettings, "Controls how sounds fade with distance.\n0: Inverse (most realistic)\n1: Inverse Clamped\n2: Linear (Quake-like)\n3: Linear Clamped\n4: Exponential\n5: Exponential Clamped\n6: None");
@ -499,7 +499,7 @@ static void QDECL OpenAL_CvarInit(void)
{
Cvar_Register(&s_al_debug, SOUNDVARS);
Cvar_Register(&s_al_use_reverb, SOUNDVARS);
Cvar_Register(&s_al_max_distance, SOUNDVARS);
// Cvar_Register(&s_al_max_distance, SOUNDVARS);
Cvar_Register(&s_al_dopplerfactor, SOUNDVARS);
Cvar_Register(&s_al_distancemodel, SOUNDVARS);
Cvar_Register(&s_al_reference_distance, SOUNDVARS);
@ -620,7 +620,7 @@ static void OpenAL_ChannelUpdate(soundcardinfo_t *sc, channel_t *chan, unsigned
//alcMakeContextCurrent
#ifdef FTE_TARGET_WEB
if (firefoxstaticsounds && chan->dist_mult >= 3.0 / sound_nominal_clip_dist)
if (firefoxstaticsounds && chan->dist_mult >= 3.0 / snd_nominaldistance.value)
sfx = NULL;
#endif

View File

@ -59,7 +59,7 @@ static struct
vec3_t right;
vec3_t up;
} listener[MAX_SPLITS];
vec_t sound_nominal_clip_dist=1000.0;
cvar_t snd_nominaldistance = CVARAFD("s_nominaldistance", "1000", "snd_soundradius", CVAR_CHEAT, "This cvar defines how far an attenuation=1 sound can be heard.");
#define MAX_SFX 8192
sfx_t *known_sfx; // hunk allocated [MAX_SFX]
@ -2290,6 +2290,7 @@ void S_Init (void)
Cvar_Register(&precache, "Sound controls");
Cvar_Register(&loadas8bit, "Sound controls");
Cvar_Register(&bgmvolume, "Sound controls");
Cvar_Register(&snd_nominaldistance, "Sound controls");
Cvar_Register(&ambient_level, "Sound controls");
Cvar_Register(&ambient_fade, "Sound controls");
Cvar_Register(&snd_noextraupdate, "Sound controls");
@ -2916,7 +2917,7 @@ static void S_UpdateSoundCard(soundcardinfo_t *sc, qboolean updateonly, channel_
else
VectorClear(target_chan->velocity);
target_chan->flags = flags;
target_chan->dist_mult = attenuation / sound_nominal_clip_dist;
target_chan->dist_mult = attenuation / snd_nominaldistance.value;
target_chan->master_vol = vol;
target_chan->entnum = entnum;
target_chan->entchannel = entchannel;
@ -3330,7 +3331,7 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation)
ss->rate = 1<<PITCHSHIFT;
VectorCopy (origin, ss->origin);
ss->master_vol = vol*255;
ss->dist_mult = attenuation / sound_nominal_clip_dist;
ss->dist_mult = attenuation / snd_nominaldistance.value;
ss->pos = 0;
ss->flags = CF_FORCELOOP;
@ -3678,7 +3679,7 @@ static void S_Q2_AddEntitySounds(soundcardinfo_t *sc)
c->flags = CF_CLI_AUTOSOUND|CF_FORCELOOP;
c->entnum = sc->ChannelUpdate?entnums[count]:0;
c->entchannel = 0;
c->dist_mult = 3 / sound_nominal_clip_dist;
c->dist_mult = 3 / snd_nominaldistance.value;
c->master_vol = 255 * 1;
c->pos = 0<<PITCHSHIFT; //q2 does weird stuff with the pos. we just forceloop and detect when it became irrelevant. this is required for stream decoding or openal
c->rate = 1<<PITCHSHIFT;

View File

@ -294,7 +294,7 @@ void SNDVC_MicInput(qbyte *buffer, int samples, int freq, int width);
extern int snd_speed;
extern vec_t sound_nominal_clip_dist;
extern cvar_t snd_nominaldistance;
extern cvar_t loadas8bit;
extern cvar_t bgmvolume;

View File

@ -104,6 +104,7 @@ cvar_t crosshairimage = CVARD("crosshairimage", "", "Enables the use of an ext
cvar_t crosshairalpha = CVAR("crosshairalpha", "1");
cvar_t v_skyroom_origin = CVARD("r_skyroom_origin", "", "Specifies the center position of the skyroom's view. Skyrooms are drawn instead of skyboxes (typically with their own skybox around them). Entities in skyrooms will be drawn only when r_ignoreentpvs is 0. Can also be set with the _skyroom worldspawn key. This is overriden by csqc's VF_SKYROOM_CAMERA.");
cvar_t v_skyroom_orientation = CVARD("r_skyroom_orientation", "", "Specifies the orientation and spin of the skyroom.");
static cvar_t gl_cshiftpercent = CVAR("gl_cshiftpercent", "100");
cvar_t gl_cshiftenabled = CVARFD("gl_polyblend", "1", CVAR_ARCHIVE, "Controls whether temporary whole-screen colour changes should be honoured or not. Change gl_cshiftpercent if you want to adjust the intensity.\nThis does not affect v_cshift commands sent from the server.");
@ -1520,6 +1521,7 @@ void V_ClearRefdef(playerview_t *pv)
r_refdef.flags = 0;
r_refdef.skyroom_enabled = false;
r_refdef.firstvisedict = 0; //just in case.
r_refdef.areabitsknown = false;
@ -2582,6 +2584,7 @@ void V_Init (void)
Cvar_Register (&v_deathtilt, VIEWVARS);
Cvar_Register (&v_skyroom_origin, VIEWVARS);
Cvar_Register (&v_skyroom_orientation, VIEWVARS);
Cvar_Register (&scr_autoid, VIEWVARS);
Cvar_Register (&scr_autoid_team, VIEWVARS);

View File

@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// wad.c
#include "quakedef.h"
#include "shader.h"
void *wadmutex;
@ -922,6 +923,16 @@ void Mod_ParseInfoFromEntityLump(model_t *wmodel) //actually, this should be in
}
}
if (cl.skyrotate)
{
if (cl.skyaxis[0]||cl.skyaxis[1]||cl.skyaxis[2])
Cvar_Set(&r_skybox_orientation, va("%g %g %g %g", cl.skyaxis[0], cl.skyaxis[1], cl.skyaxis[2], cl.skyrotate));
else
Cvar_Set(&r_skybox_orientation, va("0 0 1 %g", cl.skyrotate));
}
else
Cvar_Set(&r_skybox_orientation, "");
if (wmodel)
{
COM_FileBase (wmodel->name, token, sizeof(token));

View File

@ -85,16 +85,18 @@ FTE_ALIGN(4) qbyte net_message_buffer[MAX_OVERALLMSGLEN];
#endif
#if defined(_WIN32)
int (WINAPI *pgetaddrinfo) (
#define getaddrinfo pgetaddrinfo
#define freeaddrinfo pfreeaddrinfo
#define getnameinfo pgetnameinfo
static int (WSAAPI *getaddrinfo) (
const char* nodename,
const char* servname,
const struct addrinfo* hints,
struct addrinfo** res
);
void (WSAAPI *pfreeaddrinfo) (struct addrinfo*);
#else
#define pgetaddrinfo getaddrinfo
#define pfreeaddrinfo freeaddrinfo
static void (WSAAPI *freeaddrinfo) (struct addrinfo*);
static int (WSAAPI *getnameinfo) (const struct sockaddr *addr, socklen_t addrlen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags);
#endif
#if defined(HAVE_IPV4) && defined(HAVE_SERVER)
@ -586,6 +588,7 @@ qboolean NET_AddressSmellsFunny(netadr_t *a)
}
}
#if _POSIX_C_SOURCE >= 200112L || defined(getnameinfo)
static void NET_AdrToStringDoResolve(void *ctx, void *data, size_t a, size_t b)
{
netadr_t *n = data;
@ -598,7 +601,11 @@ static void NET_AdrToStringDoResolve(void *ctx, void *data, size_t a, size_t b)
else
{
ssz = NetadrToSockadr(n, &s);
if (getnameinfo((struct sockaddr *)&s, ssz, adrstring, NI_MAXHOST, NULL, 0, NI_NUMERICSERV|NI_DGRAM))
if (
#ifdef getnameinfo
!getnameinfo ||
#endif
getnameinfo((struct sockaddr *)&s, ssz, adrstring, NI_MAXHOST, NULL, 0, NI_NUMERICSERV|NI_DGRAM))
{
NET_BaseAdrToString(adrstring, NI_MAXHOST, n);
}
@ -614,6 +621,14 @@ void NET_AdrToStringResolve (netadr_t *adr, void (*resolved)(void *ctx, void *da
*(void**)(n+1) = resolved;
COM_AddWork(WG_LOADER, NET_AdrToStringDoResolve, ctx, n, a, b);
}
#else
void NET_AdrToStringResolve (netadr_t *adr, void (*resolved)(void *ctx, void *data, size_t a, size_t b), void *ctx, size_t a, size_t b)
{
char adrstring[NI_MAXHOST];
NET_BaseAdrToString(adrstring, countof(adrstring), adr);
resolved(ctx, Z_StrDup(adrstring), a, b);
}
#endif
char *NET_AdrToString (char *s, int len, netadr_t *a)
{
@ -1156,10 +1171,10 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin
else
#endif
#ifdef HAVE_IPV6
#ifdef pgetaddrinfo
if (1)
#ifdef getaddrinfo
if (getaddrinfo)
#else
if (pgetaddrinfo)
if (1)
#endif
{
struct addrinfo *addrinfo = NULL;
@ -1209,7 +1224,7 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin
len = sizeof(dupbase)-1;
strncpy(dupbase, s+1, len);
dupbase[len] = '\0';
error = pgetaddrinfo(dupbase, (port[1] == ':')?port+2:NULL, &udp6hint, &addrinfo);
error = getaddrinfo(dupbase, (port[1] == ':')?port+2:NULL, &udp6hint, &addrinfo);
}
}
else
@ -1227,12 +1242,12 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin
len = sizeof(dupbase)-1;
strncpy(dupbase, s, len);
dupbase[len] = '\0';
error = pgetaddrinfo(dupbase, port+1, &udp6hint, &addrinfo);
error = getaddrinfo(dupbase, port+1, &udp6hint, &addrinfo);
}
else
error = EAI_NONAME;
if (error) //failed, try string with no port.
error = pgetaddrinfo(s, NULL, &udp6hint, &addrinfo); //remember, this func will return any address family that could be using the udp protocol... (ip4 or ip6)
error = getaddrinfo(s, NULL, &udp6hint, &addrinfo); //remember, this func will return any address family that could be using the udp protocol... (ip4 or ip6)
}
restime = Sys_DoubleTime()-restime;
@ -1273,7 +1288,7 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin
#endif
}
}
pfreeaddrinfo (addrinfo);
freeaddrinfo (addrinfo);
for (i = 0; i < result; i++)
{
@ -1299,7 +1314,7 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin
else
#endif
{
#if defined(HAVE_IPV4) && !defined(pgetaddrinfo) && !defined(HAVE_IPV6)
#if defined(HAVE_IPV4) && defined(getaddrinfo) && !defined(HAVE_IPV6)
char copy[128];
char *colon;
@ -3051,7 +3066,7 @@ int FTENET_GetLocalAddress(int port, qboolean ipx, qboolean ipv4, qboolean ipv6,
found++;
}
}
pfreeaddrinfo(result);
freeaddrinfo(result);
/*if none found, fill in the 0.0.0.0 or whatever*/
if (!found && maxaddresses)
@ -7864,6 +7879,7 @@ void NET_Init (void)
{
{(void**)&pgetaddrinfo, "getaddrinfo"},
{(void**)&pfreeaddrinfo, "freeaddrinfo"},
{(void**)&pgetnameinfo, "getnameinfo"},
{NULL, NULL}
};
Sys_LoadLibrary("ws2_32.dll", fncs);

View File

@ -29,6 +29,8 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
qboolean swap = false;
unsigned int blockwidth, blockheight, blockbytes;
//NOTE: d3d9 formats are written as little-endian packed formats, so RR GG BB AA -> 0xAABBGGRR
//whereas fte formats vary depending on whether they're packed or byte-aligned.
switch(mips->encoding)
{
case PTI_L8_SRGB:
@ -54,13 +56,13 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
break;
case PTI_RGBA8_SRGB:
case PTI_RGBA8:
// fmt = D3DFMT_A8B8G8R8; /*how do we check
// fmt = D3DFMT_A8B8G8R8; //not supported by most drivers, for some reason. we need to emulate it with some swapping
fmt = D3DFMT_A8R8G8B8;
swap = true;
break;
case PTI_RGBX8_SRGB:
case PTI_RGBX8:
// fmt = D3DFMT_X8B8G8R8;
// fmt = D3DFMT_X8B8G8R8; //not supported by most drivers, for some reason. we need to emulate it with some swapping
fmt = D3DFMT_X8R8G8B8;
swap = true;
break;
@ -95,6 +97,7 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
//bc4-7 not supported on d3d9.
//etc2 have no chance.
//astc? lul!
case PTI_EMULATED: //no idea
default:

View File

@ -2791,7 +2791,7 @@ void BE_GenModelBatches(batch_t **batches, const dlight_t *dl, unsigned int bemo
}
// draw sprites seperately, because of alpha blending
for (i=0 ; i<cl_numvisedicts ; i++)
for (i=r_refdef.firstvisedict ; i<cl_numvisedicts ; i++)
{
ent = &cl_visedicts[i];

View File

@ -44,7 +44,6 @@ cvar_t r_vertexlight = CVARFD("r_vertexlight", "0", CVAR_SHADERSYSTEM, "Hack loa
cvar_t r_forceprogramify = CVARAFD("r_forceprogramify", "0", "dpcompat_makeshitup", CVAR_SHADERSYSTEM, "Reduce the shader to a single texture, and then make stuff up about its mother. The resulting fist fight results in more colour when you shine a light upon its face.\nSet to 2 to ignore 'depthfunc equal' and 'tcmod scale' in order to tolerate bizzare shaders made for a bizzare engine.\nBecause most shaders made for DP are by people who _clearly_ have no idea what the heck they're doing, you'll typically need the '2' setting.");
cvar_t dpcompat_nopremulpics = CVARFD("dpcompat_nopremulpics", "0", CVAR_SHADERSYSTEM, "By default FTE uses premultiplied alpha for hud/2d images, while DP does not (which results in halos with low-res content). Unfortunately DDS files would need to be recompressed, resulting in visible issues.");
extern cvar_t r_glsl_offsetmapping_reliefmapping;
extern cvar_t r_fastturb, r_fastsky, r_skyboxname;
extern cvar_t r_drawflat;
extern cvar_t r_shaderblobs;
extern cvar_t r_tessellation;
@ -1444,7 +1443,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
for(;;)
{
size_t len;
int i, j;
int i;
char *type, *idx, *next;
char *token = com_token;

View File

@ -3062,7 +3062,7 @@ static void Sh_DrawStencilLightShadows(dlight_t *dl, qbyte *lvis, qbyte *vvis, q
return; //FIXME: uses glBegin
// draw sprites seperately, because of alpha blending
for (i=0 ; i<cl_numvisedicts ; i++)
for (i=r_refdef.firstvisedict ; i<cl_numvisedicts ; i++)
{
ent = &cl_visedicts[i];

View File

@ -121,6 +121,8 @@ qboolean R_DrawSkyroom(shader_t *skyshader)
{
float vmat[16];
refdef_t oldrefdef;
extern cvar_t r_ignoreentpvs; //legacy value is 1...
extern cvar_t v_skyroom_orientation;
if (r_viewcluster == -1)
return false; //don't draw the skyroom if the camera is outside.
@ -133,6 +135,8 @@ qboolean R_DrawSkyroom(shader_t *skyshader)
oldrefdef = r_refdef;
r_refdef.recurse+=1;
if (r_ignoreentpvs.ival) //if we're ignoring ent pvs then we're probably drawing lots of ents in the skybox that shouldn't be there
r_refdef.firstvisedict = cl_numvisedicts;
r_refdef.externalview = true; //an out-of-body experience...
r_refdef.skyroom_enabled = false;
r_refdef.forcevis = false;
@ -149,18 +153,19 @@ qboolean R_DrawSkyroom(shader_t *skyshader)
if (r_worldentity.model->funcs.PointContents(r_worldentity.model, NULL, r_refdef.skyroom_pos) & FTECONTENTS_SOLID)
Con_DPrintf("Skyroom position %.1f %.1f %.1f in solid\n", r_refdef.skyroom_pos[0], r_refdef.skyroom_pos[1], r_refdef.skyroom_pos[2]);
/*if (cl.skyrotate)
if (*v_skyroom_orientation.string)
{
vec3_t axis[3];
float ang = cl.skyrotate * cl.time;
if (!cl.skyaxis[0]&&!cl.skyaxis[1]&&!cl.skyaxis[2])
VectorSet(cl.skyaxis, 0,0,1);
RotatePointAroundVector(axis[0], cl.skyaxis, vpn, ang);
RotatePointAroundVector(axis[1], cl.skyaxis, vright, ang);
RotatePointAroundVector(axis[2], cl.skyaxis, vup, ang);
float ang = v_skyroom_orientation.vec4[3] * cl.time;
if (!v_skyroom_orientation.vec4[0]&&!v_skyroom_orientation.vec4[1]&&!v_skyroom_orientation.vec4[2])
VectorSet(v_skyroom_orientation.vec4, 0,0,1);
VectorNormalize(v_skyroom_orientation.vec4);
RotatePointAroundVector(axis[0], v_skyroom_orientation.vec4, vpn, ang);
RotatePointAroundVector(axis[1], v_skyroom_orientation.vec4, vright, ang);
RotatePointAroundVector(axis[2], v_skyroom_orientation.vec4, vup, ang);
Matrix4x4_CM_ModelViewMatrixFromAxis(vmat, axis[0], axis[1], axis[2], r_refdef.vieworg);
}
else*/
else
Matrix4x4_CM_ModelViewMatrixFromAxis(vmat, vpn, vright, vup, r_refdef.vieworg);
R_SetFrustum (r_refdef.m_projection_std, vmat);
@ -218,6 +223,12 @@ qboolean R_DrawSkyChain (batch_t *batch)
skyshader = batch->shader;
if (skyshader->prog) //glsl is expected to do the whole skybox/warpsky thing itself, with no assistance from this legacy code.
{
if (r_refdef.flags & RDF_SKIPSKY)
{
if (r_worldentity.model->fromgame != fg_quake3)
GL_SkyForceDepth(batch);
return true;
}
//if the first pass is transparent in some form, then be prepared to give it a skyroom behind.
return false; //draw as normal...
}

View File

@ -4595,6 +4595,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"!!permu FOG\n"
"!!samps reflectcube\n"
"!!cvardf r_skyfog=0.5\n"
"!!cvard4 r_glsl_skybox_orientation=0 0 0 0\n"
"#include \"sys/defs.h\"\n"
"#include \"sys/fog.h\"\n"
@ -4602,10 +4603,26 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"varying vec3 pos;\n"
"#ifdef VERTEX_SHADER\n"
"mat3 rotateAroundAxis(vec4 axis) //xyz axis, with angle in w\n"
"{\n"
"#define skyang axis.w*(3.14/180.0)*e_time\n"
"axis.xyz = normalize(axis.xyz);\n"
"float s = sin(skyang);\n"
"float c = cos(skyang);\n"
"float oc = 1.0 - c;\n"
"return mat3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,\n"
"oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,\n"
"oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c);\n"
"};\n"
"void main ()\n"
"{\n"
"pos = v_position.xyz - e_eyepos;\n"
"pos.y = -pos.y;\n"
"if (r_glsl_skybox_orientation.xyz != vec3(0.0))\n"
"pos = pos*rotateAroundAxis(r_glsl_skybox_orientation);\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"

View File

@ -1026,4 +1026,6 @@ void CL_DrawDebugPlane(float *normal, float dist, float r, float g, float b, qbo
void CLQ1_AddOrientedCylinder(shader_t *shader, float radius, float height, qboolean capsule, float *matrix, float r, float g, float b, float a);
void CLQ1_AddOrientedSphere(shader_t *shader, float radius, float *matrix, float r, float g, float b, float a);
void CLQ1_AddOrientedHalfSphere(shader_t *shader, float radius, float gap, float *matrix, float r, float g, float b, float a);
extern cvar_t r_fastturb, r_fastsky, r_skyboxname, r_skybox_orientation;
#endif

View File

@ -708,6 +708,7 @@ void NPP_NQFlush(void)
case svc_intermission:
// if (writedest == &sv.reliable_datagram)
{
sizebuf_t *msg;
client_t *cl;
int i;
#ifdef HEXEN2
@ -739,42 +740,43 @@ void NPP_NQFlush(void)
#ifdef HEXEN2
if (h2finale)
{
ClientReliableCheckBlock(cl, 6 + strlen(h2title) + 3 + strlen(h2finale) + 1);
ClientReliableWrite_Byte(cl, svc_finale);
msg = ClientReliable_StartWrite(cl, 6 + strlen(h2title) + 3 + strlen(h2finale) + 1);
MSG_WriteByte(msg, svc_finale);
ClientReliableWrite_Byte(cl, '/');
ClientReliableWrite_Byte(cl, 'F');
ClientReliableWrite_Byte(cl, 'f'); //hexen2-style finale
MSG_WriteByte(msg, '/');
MSG_WriteByte(msg, 'F');
MSG_WriteByte(msg, 'f'); //hexen2-style finale
ClientReliableWrite_Byte(cl, '/');
ClientReliableWrite_Byte(cl, 'I');
ClientReliableWrite_SZ(cl, h2title, strlen(h2title));
ClientReliableWrite_Byte(cl, ':'); //image
MSG_WriteByte(msg, '/');
MSG_WriteByte(msg, 'I');
SZ_Write(msg, h2title, strlen(h2title));
MSG_WriteByte(msg, ':'); //image
ClientReliableWrite_Byte(cl, '/');
ClientReliableWrite_Byte(cl, 'P'); //image should be a background.
MSG_WriteByte(msg, '/');
MSG_WriteByte(msg, 'P'); //image should be a background.
ClientReliableWrite_String(cl, h2finale);
MSG_WriteString(msg, h2finale);
}
else
#endif
if (cl->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
{ //special intermission mode to leave the view attached to the viewentity (as required for nq - especially rogue's finale) instead of hacking it to some specific point
ClientReliableCheckBlock(cl, 5);
ClientReliableWrite_Byte(cl, svc_finale);
ClientReliableWrite_String(cl, "/FI");
msg = ClientReliable_StartWrite(cl, 5);
MSG_WriteByte(msg, svc_finale);
MSG_WriteString(msg, "/FI");
}
else
{
ClientReliableCheckBlock(cl, 16);
ClientReliableWrite_Byte(cl, svc_intermission);
ClientReliableWrite_Coord(cl, cl->edict->v->origin[0]);
ClientReliableWrite_Coord(cl, cl->edict->v->origin[1]);
ClientReliableWrite_Coord(cl, cl->edict->v->origin[2]+cl->edict->v->view_ofs[2]);
ClientReliableWrite_Angle(cl, cl->edict->v->angles[0]);
ClientReliableWrite_Angle(cl, cl->edict->v->angles[1]);
ClientReliableWrite_Angle(cl, cl->edict->v->angles[2]);
msg = ClientReliable_StartWrite(cl, 23);
MSG_WriteByte(msg, svc_intermission);
MSG_WriteCoord(msg, cl->edict->v->origin[0]);
MSG_WriteCoord(msg, cl->edict->v->origin[1]);
MSG_WriteCoord(msg, cl->edict->v->origin[2]+cl->edict->v->view_ofs[2]);
MSG_WriteAngle(msg, cl->edict->v->angles[0]);
MSG_WriteAngle(msg, cl->edict->v->angles[1]);
MSG_WriteAngle(msg, cl->edict->v->angles[2]);
}
ClientReliable_FinishWrite(cl);
}
}
bufferlen = 0;
@ -937,8 +939,9 @@ void NPP_NQFlush(void)
if (!requireextension || cldest->fteprotocolextensions & requireextension)
if (bufferlen && ISQWCLIENT(cldest))
{
ClientReliableCheckBlock(cldest, bufferlen);
ClientReliableWrite_SZ(cldest, buffer, bufferlen);
sizebuf_t *msg = ClientReliable_StartWrite(cldest, bufferlen);
SZ_Write(msg, buffer, bufferlen);
ClientReliable_FinishWrite(cldest);
}
cldest = NULL;
}
@ -2004,8 +2007,9 @@ void NPP_QWFlush(void)
if (!requireextension || cldest->fteprotocolextensions & requireextension)
if (bufferlen && !ISQWCLIENT(cldest))
{
ClientReliableCheckBlock(cldest, bufferlen);
ClientReliableWrite_SZ(cldest, buffer, bufferlen);
sizebuf_t *msg = ClientReliable_StartWrite(cldest, bufferlen);
SZ_Write(msg, buffer, bufferlen);
ClientReliable_FinishWrite(cldest);
}
cldest = NULL;
}

View File

@ -105,8 +105,21 @@ sizebuf_t *ClientReliable_StartWrite(client_t *cl, int maxsize)
#endif
if (cl->controller)
Con_Printf("Writing to slave client's message buffer\n");
ClientReliableCheckBlock(cl, maxsize);
{
client_t *sp;
int pnum = 0;
for (sp = cl->controller; sp; sp = sp->controlled)
{
if (sp == cl)
break;
pnum++;
}
cl = cl->controller;
ClientReliableWrite_Begin (cl, svcfte_choosesplitclient, 2+maxsize);
ClientReliableWrite_Byte (cl, pnum);
}
else
ClientReliableCheckBlock(cl, maxsize);
if (cl->num_backbuf)
return &cl->backbuf;
@ -115,6 +128,8 @@ sizebuf_t *ClientReliable_StartWrite(client_t *cl, int maxsize)
}
void ClientReliable_FinishWrite(client_t *cl)
{
if (cl->controller)
cl = cl->controller;
if (cl->num_backbuf)
{
cl->backbuf_size[cl->num_backbuf - 1] = cl->backbuf.cursize;

View File

@ -1,6 +1,7 @@
!!permu FOG
!!samps reflectcube
!!cvardf r_skyfog=0.5
!!cvard4 r_glsl_skybox_orientation=0 0 0 0
#include "sys/defs.h"
#include "sys/fog.h"
@ -8,10 +9,26 @@
varying vec3 pos;
#ifdef VERTEX_SHADER
mat3 rotateAroundAxis(vec4 axis) //xyz axis, with angle in w
{
#define skyang axis.w*(3.14/180.0)*e_time
axis.xyz = normalize(axis.xyz);
float s = sin(skyang);
float c = cos(skyang);
float oc = 1.0 - c;
return mat3(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s,
oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s,
oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c);
};
void main ()
{
pos = v_position.xyz - e_eyepos;
pos.y = -pos.y;
if (r_glsl_skybox_orientation.xyz != vec3(0.0))
pos = pos*rotateAroundAxis(r_glsl_skybox_orientation);
gl_Position = ftetransform();
}
#endif