diff --git a/engine/client/cl_cg.c b/engine/client/cl_cg.c index 93b062de2..1e8b52a62 100644 --- a/engine/client/cl_cg.c +++ b/engine/client/cl_cg.c @@ -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); diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 0d4100125..7a96239d2 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -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)); diff --git a/engine/client/in_generic.c b/engine/client/in_generic.c index 6671218aa..be8c30d00 100644 --- a/engine/client/in_generic.c +++ b/engine/client/in_generic.c @@ -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] = { diff --git a/engine/client/render.h b/engine/client/render.h index 5f648227a..9b361c630 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -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*/ diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 8493241a4..adb0ddbbc 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -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 diff --git a/engine/client/snd_al.c b/engine/client/snd_al.c index 3f6be24fd..d219f1362 100644 --- a/engine/client/snd_al.c +++ b/engine/client/snd_al.c @@ -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 diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 1e435deff..65a8b52ff 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -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<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<rate = 1<name, token, sizeof(token)); diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index 99206373e..8e0f02fcd 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -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); diff --git a/engine/d3d/d3d_image.c b/engine/d3d/d3d_image.c index 21b674a66..481ece5d2 100644 --- a/engine/d3d/d3d_image.c +++ b/engine/d3d/d3d_image.c @@ -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: diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 343548112..2c30f97a1 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -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 ; ifuncs.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... } diff --git a/engine/gl/r_bishaders.h b/engine/gl/r_bishaders.h index f3b49fcb4..f97c95ad5 100644 --- a/engine/gl/r_bishaders.h +++ b/engine/gl/r_bishaders.h @@ -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" diff --git a/engine/gl/shader.h b/engine/gl/shader.h index ea7de0c94..548f4fc45 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -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 diff --git a/engine/server/net_preparse.c b/engine/server/net_preparse.c index 3cb792153..4810f1500 100644 --- a/engine/server/net_preparse.c +++ b/engine/server/net_preparse.c @@ -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; } diff --git a/engine/server/sv_nchan.c b/engine/server/sv_nchan.c index 90c369646..ae1babc5f 100644 --- a/engine/server/sv_nchan.c +++ b/engine/server/sv_nchan.c @@ -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; diff --git a/engine/shaders/glsl/defaultskybox.glsl b/engine/shaders/glsl/defaultskybox.glsl index 32008b693..bfbb17cda 100644 --- a/engine/shaders/glsl/defaultskybox.glsl +++ b/engine/shaders/glsl/defaultskybox.glsl @@ -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