From 92b6f0dcac0ced4c6f54767ed50df7ea034234db Mon Sep 17 00:00:00 2001 From: Cloudwalk Date: Sat, 17 Oct 2020 16:59:16 -0400 Subject: [PATCH] Implement protocol 666 (Fitzquake/Quakespasm) on the clientside --- cl_ents5.c | 2 +- cl_ents_nq.c | 47 ++++++++++++++++++---------------- cl_input.c | 57 ++++++++++++++++++++++------------------- cl_parse.c | 61 ++++++++++++++++++++++++++++++++++---------- cl_parse.h | 2 +- cl_protocol_basenq.h | 2 +- cl_protocol_baseqw.h | 2 +- cl_protocol_ext.h | 37 ++++++++++++++++++++++++++- cl_protocol_fq.c | 8 ++++++ makefile.inc | 1 + protocol.c | 9 +++---- protocol.h | 47 +++++++++++++++++++++++++++++----- sbar.c | 2 +- snd_main.c | 2 +- 14 files changed, 199 insertions(+), 80 deletions(-) create mode 100644 cl_protocol_fq.c diff --git a/cl_ents5.c b/cl_ents5.c index 54239052..3c0c5936 100644 --- a/cl_ents5.c +++ b/cl_ents5.c @@ -294,7 +294,7 @@ void EntityFrame5_CL_ReadFrame(void) // read the number of this frame to echo back in next input packet framenum = MSG_ReadLong(&cl_message); CL_NewFrameReceived(framenum); - if (cls.protocol != &protocol_netquake && cls.protocol != &protocol_quakedp && cls.protocol != &protocol_nehahramovie && cls.protocol != &protocol_dpp1 && cls.protocol != &protocol_dpp2 && cls.protocol != &protocol_dpp3 && cls.protocol != &protocol_dpp4 && cls.protocol != &protocol_dpp5 && cls.protocol != &protocol_dpp6) + if (cls.protocol != &protocol_netquake && cls.protocol != &protocol_quakedp && cls.protocol != &protocol_nehahramovie && cls.protocol != &protocol_dpp1 && cls.protocol != &protocol_dpp2 && cls.protocol != &protocol_dpp3 && cls.protocol != &protocol_dpp4 && cls.protocol != &protocol_dpp5 && cls.protocol != &protocol_dpp6 && cls.protocol != &protocol_fitzquake) cls.servermovesequence = MSG_ReadLong(&cl_message); // read entity numbers until we find a 0x8000 // (which would be remove world entity, but is actually a terminator) diff --git a/cl_ents_nq.c b/cl_ents_nq.c index 3d1b1752..00054d84 100644 --- a/cl_ents_nq.c +++ b/cl_ents_nq.c @@ -35,16 +35,8 @@ void EntityFrameQuake_ReadEntity(int bits) ent = cl.entities + num; - // note: this inherits the 'active' state of the baseline chosen - // (state_baseline is always active, state_current may not be active if - // the entity was missing in the last frame) - if (bits & U_DELTA) - s = ent->state_current; - else - { - s = ent->state_baseline; - s.active = ACTIVE_NETWORK; - } + s = ent->state_baseline; + s.active = ACTIVE_NETWORK; cl.isquakeentity[num] = true; if (cl.lastquakeentity < num) @@ -70,18 +62,29 @@ void EntityFrameQuake_ReadEntity(int bits) if (bits & U_ORIGIN3) s.origin[2] = cls.protocol->ReadCoord(&cl_message); if (bits & U_ANGLE3) s.angles[2] = cls.protocol->ReadAngle(&cl_message); if (bits & U_STEP) s.flags |= RENDER_STEP; - if (bits & U_ALPHA) s.alpha = MSG_ReadByte(&cl_message); - if (bits & U_SCALE) s.scale = MSG_ReadByte(&cl_message); - if (bits & U_EFFECTS2) s.effects = (s.effects & 0x00FF) | (MSG_ReadByte(&cl_message) << 8); - if (bits & U_GLOWSIZE) s.glowsize = MSG_ReadByte(&cl_message); - if (bits & U_GLOWCOLOR) s.glowcolor = MSG_ReadByte(&cl_message); - if (bits & U_COLORMOD) {int c = MSG_ReadByte(&cl_message);s.colormod[0] = (unsigned char)(((c >> 5) & 7) * (32.0f / 7.0f));s.colormod[1] = (unsigned char)(((c >> 2) & 7) * (32.0f / 7.0f));s.colormod[2] = (unsigned char)((c & 3) * (32.0f / 3.0f));} - if (bits & U_GLOWTRAIL) s.flags |= RENDER_GLOWTRAIL; - if (bits & U_FRAME2) s.frame = (s.frame & 0x00FF) | (MSG_ReadByte(&cl_message) << 8); - if (bits & U_MODEL2) s.modelindex = (s.modelindex & 0x00FF) | (MSG_ReadByte(&cl_message) << 8); - if (bits & U_VIEWMODEL) s.flags |= RENDER_VIEWMODEL; - if (bits & U_EXTERIORMODEL) s.flags |= RENDER_EXTERIORMODEL; - + if (cls.protocol != &protocol_fitzquake) + { + if (bits & U_ALPHA) s.alpha = MSG_ReadByte(&cl_message); + if (bits & U_SCALE) s.scale = MSG_ReadByte(&cl_message); + if (bits & U_EFFECTS2) s.effects = (s.effects & 0x00FF) | (MSG_ReadByte(&cl_message) << 8); + if (bits & U_GLOWSIZE) s.glowsize = MSG_ReadByte(&cl_message); + if (bits & U_GLOWCOLOR) s.glowcolor = MSG_ReadByte(&cl_message); + if (bits & U_COLORMOD) {int c = MSG_ReadByte(&cl_message);s.colormod[0] = (unsigned char)(((c >> 5) & 7) * (32.0f / 7.0f));s.colormod[1] = (unsigned char)(((c >> 2) & 7) * (32.0f / 7.0f));s.colormod[2] = (unsigned char)((c & 3) * (32.0f / 3.0f));} + if (bits & U_GLOWTRAIL) s.flags |= RENDER_GLOWTRAIL; + if (bits & U_FRAME2) s.frame = (s.frame & 0x00FF) | (MSG_ReadByte(&cl_message) << 8); + if (bits & U_MODEL2) s.modelindex = (s.modelindex & 0x00FF) | (MSG_ReadByte(&cl_message) << 8); + if (bits & U_VIEWMODEL) s.flags |= RENDER_VIEWMODEL; + if (bits & U_EXTERIORMODEL) s.flags |= RENDER_EXTERIORMODEL; + } + else + { + if (bits & U_ALPHA_FQ) s.alpha = MSG_ReadByte(&cl_message); + if (bits & U_SCALE_FQ) MSG_ReadByte(&cl_message); // ignored + if (bits & U_FRAME2_FQ) s.frame = (s.frame & 0x00FF) | (MSG_ReadByte(&cl_message) << 8); + if (bits & U_MODEL2_FQ) s.modelindex = (s.modelindex & 0x00FF) | (MSG_ReadByte(&cl_message) << 8); + // Cloudwalk: idk??? + if (bits & U_LERPFINISH_FQ) ent->persistent.lerpdeltatime = s.time + ((float)(MSG_ReadByte(&cl_message)) / 255); + } // LadyHavoc: to allow playback of the Nehahra movie if (cls.protocol == &protocol_nehahramovie && (bits & U_EXTEND1)) { diff --git a/cl_input.c b/cl_input.c index 8c812018..ffb719b5 100644 --- a/cl_input.c +++ b/cl_input.c @@ -1779,31 +1779,35 @@ void CL_SendMove(void) bits = 0; if (in_attack.state & 3) bits |= 1; if (in_jump.state & 3) bits |= 2; - if (in_button3.state & 3) bits |= 4; - if (in_button4.state & 3) bits |= 8; - if (in_button5.state & 3) bits |= 16; - if (in_button6.state & 3) bits |= 32; - if (in_button7.state & 3) bits |= 64; - if (in_button8.state & 3) bits |= 128; - if (in_use.state & 3) bits |= 256; - if (key_dest != key_game || key_consoleactive) bits |= 512; - if (cl_prydoncursor.integer > 0) bits |= 1024; - if (in_button9.state & 3) bits |= 2048; - if (in_button10.state & 3) bits |= 4096; - if (in_button11.state & 3) bits |= 8192; - if (in_button12.state & 3) bits |= 16384; - if (in_button13.state & 3) bits |= 32768; - if (in_button14.state & 3) bits |= 65536; - if (in_button15.state & 3) bits |= 131072; - if (in_button16.state & 3) bits |= 262144; - // button bits 19-31 unused currently - // rotate/zoom view serverside if PRYDON_CLIENTCURSOR cursor is at edge of screen - if(cl_prydoncursor.integer > 0) - { - if (cl.cmd.cursor_screen[0] <= -1) bits |= 8; - if (cl.cmd.cursor_screen[0] >= 1) bits |= 16; - if (cl.cmd.cursor_screen[1] <= -1) bits |= 32; - if (cl.cmd.cursor_screen[1] >= 1) bits |= 64; + + if (cls.protocol != &protocol_fitzquake) + { + if (in_button3.state & 3) bits |= 4; + if (in_button4.state & 3) bits |= 8; + if (in_button5.state & 3) bits |= 16; + if (in_button6.state & 3) bits |= 32; + if (in_button7.state & 3) bits |= 64; + if (in_button8.state & 3) bits |= 128; + if (in_use.state & 3) bits |= 256; + if (key_dest != key_game || key_consoleactive) bits |= 512; + if (cl_prydoncursor.integer > 0) bits |= 1024; + if (in_button9.state & 3) bits |= 2048; + if (in_button10.state & 3) bits |= 4096; + if (in_button11.state & 3) bits |= 8192; + if (in_button12.state & 3) bits |= 16384; + if (in_button13.state & 3) bits |= 32768; + if (in_button14.state & 3) bits |= 65536; + if (in_button15.state & 3) bits |= 131072; + if (in_button16.state & 3) bits |= 262144; + // button bits 19-31 unused currently + // rotate/zoom view serverside if PRYDON_CLIENTCURSOR cursor is at edge of screen + if(cl_prydoncursor.integer > 0) + { + if (cl.cmd.cursor_screen[0] <= -1) bits |= 8; + if (cl.cmd.cursor_screen[0] >= 1) bits |= 16; + if (cl.cmd.cursor_screen[1] <= -1) bits |= 32; + if (cl.cmd.cursor_screen[1] >= 1) bits |= 64; + } } // set buttons and impulse @@ -1962,6 +1966,7 @@ void CL_SendMove(void) cl.qw_deltasequence[cls.netcon->outgoing_unreliable_sequence & QW_UPDATE_MASK] = -1; break; case PROTOCOL_QUAKE: + case PROTOCOL_FITZQUAKE: case PROTOCOL_NEHAHRAMOVIE: case PROTOCOL_NEHAHRABJP: case PROTOCOL_NEHAHRABJP2: @@ -1970,7 +1975,7 @@ void CL_SendMove(void) MSG_WriteByte (&buf, clc_move); MSG_WriteFloat (&buf, cl.cmd.time); // last server packet time // 3 bytes (6 bytes in proquake) - if (cls.proquake_servermod == 1) // MOD_PROQUAKE + if (cls.proquake_servermod == 1 || cls.protocol->num == PROTOCOL_FITZQUAKE) // MOD_PROQUAKE { for (i = 0;i < 3;i++) MSG_WriteAngle16i (&buf, cl.cmd.viewangles[i]); diff --git a/cl_parse.c b/cl_parse.c index e6469cbf..8a6282ad 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -1966,11 +1966,15 @@ CL_ParseBaseline void CL_ParseBaseline (entity_t *ent, int large) { int i; + int bits; ent->state_baseline = defaultstate; // FIXME: set ent->state_baseline.number? ent->state_baseline.active = true; - if (large) + + bits = (cls.protocol == &protocol_fitzquake && large) ? MSG_ReadByte(&cl_message) : 0; + + if (cls.protocol != &protocol_fitzquake && large) { ent->state_baseline.modelindex = (unsigned short) MSG_ReadShort(&cl_message); ent->state_baseline.frame = (unsigned short) MSG_ReadShort(&cl_message); @@ -1982,8 +1986,8 @@ void CL_ParseBaseline (entity_t *ent, int large) } else { - ent->state_baseline.modelindex = MSG_ReadByte(&cl_message); - ent->state_baseline.frame = MSG_ReadByte(&cl_message); + ent->state_baseline.modelindex = (bits & B_LARGEMODEL) ? (unsigned short) MSG_ReadShort(&cl_message) : MSG_ReadByte(&cl_message); + ent->state_baseline.frame = (bits & B_LARGEFRAME) ? (unsigned short) MSG_ReadShort(&cl_message) : MSG_ReadByte(&cl_message); } ent->state_baseline.colormap = MSG_ReadByte(&cl_message); ent->state_baseline.skin = MSG_ReadByte(&cl_message); @@ -1992,6 +1996,9 @@ void CL_ParseBaseline (entity_t *ent, int large) ent->state_baseline.origin[i] = cls.protocol->ReadCoord(&cl_message); ent->state_baseline.angles[i] = cls.protocol->ReadAngle(&cl_message); } + + ent->state_baseline.alpha = (bits & B_ALPHA) ? MSG_ReadByte(&cl_message) : ent->state_baseline.alpha; //johnfitz -- PROTOCOL_FITZQUAKE + ent->state_previous = ent->state_current = ent->state_baseline; } @@ -2012,7 +2019,7 @@ void CL_ParseClientdata (void) VectorCopy (cl.mvelocity[0], cl.mvelocity[1]); cl.mviewzoom[1] = cl.mviewzoom[0]; - if (cls.protocol == &protocol_netquake || cls.protocol == &protocol_quakedp || cls.protocol == &protocol_nehahramovie || cls.protocol == &protocol_nehahrabjp || cls.protocol == &protocol_nehahrabjp2 || cls.protocol == &protocol_nehahrabjp3 || cls.protocol == &protocol_dpp1 || cls.protocol == &protocol_dpp2 || cls.protocol == &protocol_dpp3 || cls.protocol == &protocol_dpp4 || cls.protocol == &protocol_dpp5) + if (cls.protocol == &protocol_fitzquake || cls.protocol == &protocol_netquake || cls.protocol == &protocol_quakedp || cls.protocol == &protocol_nehahramovie || cls.protocol == &protocol_nehahrabjp || cls.protocol == &protocol_nehahrabjp2 || cls.protocol == &protocol_nehahrabjp3 || cls.protocol == &protocol_dpp1 || cls.protocol == &protocol_dpp2 || cls.protocol == &protocol_dpp3 || cls.protocol == &protocol_dpp4 || cls.protocol == &protocol_dpp5) { cl.stats[STAT_VIEWHEIGHT] = DEFAULT_VIEWHEIGHT; cl.stats[STAT_ITEMS] = 0; @@ -2046,12 +2053,12 @@ void CL_ParseClientdata (void) { if (bits & (SU_PUNCH1<render.framegroupblend[0].start = lhrandom(-10, -1); ent->render.skinnum = ent->state_baseline.skin; ent->render.effects = ent->state_baseline.effects; - ent->render.alpha = 1; + ent->render.alpha = ent->state_baseline.alpha; //VectorCopy (ent->state_baseline.origin, ent->render.origin); //VectorCopy (ent->state_baseline.angles, ent->render.angles); @@ -2164,13 +2197,13 @@ void CL_ParseStatic (int large) CL_ParseStaticSound =================== */ -void CL_ParseStaticSound (int large) +void CL_ParseStaticSound (int large, int version) { vec3_t org; int sound_num, vol, atten; cls.protocol->ReadVector(&cl_message, org); - if (large) + if (large || version == 2) sound_num = (unsigned short) MSG_ReadShort(&cl_message); else sound_num = MSG_ReadByte(&cl_message); @@ -3322,7 +3355,7 @@ void CL_ParseServerMessage(void) if(protocol != &protocol_quakeworld) { // if the high bit of the command byte is set, it is a fast update - if (cmd & 128) + if (cmd & U_SIGNAL) { // LadyHavoc: fix for bizarre problem in MSVC that I do not understand (if I assign the string pointer directly it ends up storing a NULL pointer) temp = "entity"; diff --git a/cl_parse.h b/cl_parse.h index 9f8067be..12edf6d4 100644 --- a/cl_parse.h +++ b/cl_parse.h @@ -17,7 +17,7 @@ void CL_KeepaliveMessage(qbool readmessages); // call this during loading of lar void CL_ParseBaseline (struct entity_s *ent, int large); void CL_ParseClientdata (void); void CL_ParseStatic (int large); -void CL_ParseStaticSound (int large); +void CL_ParseStaticSound (int large, int version); void CL_ParseEffect (void); void CL_ParseEffect2 (void); void CL_ParseServerInfo (void); diff --git a/cl_protocol_basenq.h b/cl_protocol_basenq.h index 7d2b473f..72c7d4dd 100644 --- a/cl_protocol_basenq.h +++ b/cl_protocol_basenq.h @@ -255,7 +255,7 @@ static void Netmsg_svc_foundsecret (protocol_t *protocol) static void Netmsg_svc_spawnstaticsound (protocol_t *protocol) { - CL_ParseStaticSound (protocol == &protocol_nehahrabjp2 || protocol == &protocol_nehahrabjp3 ? true : false); + CL_ParseStaticSound (protocol == &protocol_nehahrabjp2 || protocol == &protocol_nehahrabjp3 ? true : false, 1); } static void Netmsg_svc_intermission (protocol_t *protocol) diff --git a/cl_protocol_baseqw.h b/cl_protocol_baseqw.h index f8346157..c7cdfd33 100644 --- a/cl_protocol_baseqw.h +++ b/cl_protocol_baseqw.h @@ -174,7 +174,7 @@ static void Netmsg_svc_updatestatlong(protocol_t *protocol) static void Netmsg_svc_spawnstaticsound(protocol_t *protocol) { - CL_ParseStaticSound (false); + CL_ParseStaticSound (false, 1); } static void Netmsg_svc_cdtrack(protocol_t *protocol) diff --git a/cl_protocol_ext.h b/cl_protocol_ext.h index 2784f0ec..dac69abe 100644 --- a/cl_protocol_ext.h +++ b/cl_protocol_ext.h @@ -138,7 +138,7 @@ static void Netmsg_svc_csqcentities (protocol_t *protocol) // 58 // [short] en static void Netmsg_svc_spawnstaticsound2 (protocol_t *protocol) // 59 // [coord3] [short] samp [byte] vol [byte] aten { - CL_ParseStaticSound (true); + CL_ParseStaticSound (true, 2); } static void Netmsg_svc_trailparticles (protocol_t *protocol) // 60 // [short] entnum [short] effectnum [vector] start [vector] end @@ -155,6 +155,22 @@ static void Netmsg_svc_pointparticles1 (protocol_t *protocol) // 62 // [short] { CL_ParsePointParticles1(); } + +static void Netmsg_svc_bf (protocol_t *protocol) +{ + Cbuf_InsertText (&cmd_client, "bf"); +} + +static void Netmsg_svc_fog (protocol_t *protocol) +{ + // STUB + MSG_ReadByte(&cl_message); + MSG_ReadByte(&cl_message); + MSG_ReadByte(&cl_message); + MSG_ReadByte(&cl_message); + MSG_ReadShort(&cl_message); +} + #define NETMSG_DPEXT_SVC \ NETMSG_BASENQ_SVC, \ {"svc_showlmp", Netmsg_svc_showlmp}, \ @@ -185,3 +201,22 @@ static void Netmsg_svc_pointparticles1 (protocol_t *protocol) // 62 // [short] {"svc_trailparticles", Netmsg_svc_trailparticles}, \ {"svc_pointparticles", Netmsg_svc_pointparticles}, \ {"svc_pointparticles1", Netmsg_svc_pointparticles1} + +#define NETMSG_FQ_SVC \ + NETMSG_BASENQ_SVC, \ + {NULL, NULL}, \ + {NULL, NULL}, \ + {"svc_skybox", Netmsg_svc_skybox}, \ + {NULL, NULL}, \ + {NULL, NULL}, \ + {"svc_bf", Netmsg_svc_bf}, \ + {"svc_fog", Netmsg_svc_fog}, \ + {"svc_spawnbaseline2", Netmsg_svc_spawnbaseline2}, \ + {"svc_spawnstatic2", Netmsg_svc_spawnstatic2}, \ + {"svc_spawnstaticsound2", Netmsg_svc_spawnstaticsound2}, \ + {NULL, NULL}, \ + {NULL, NULL}, \ + {NULL, NULL}, \ + {NULL, NULL}, \ + {NULL, NULL}, \ + {NULL, NULL} diff --git a/cl_protocol_fq.c b/cl_protocol_fq.c new file mode 100644 index 00000000..97c6ba7b --- /dev/null +++ b/cl_protocol_fq.c @@ -0,0 +1,8 @@ +#include "quakedef.h" +#include "cl_protocol_ext.h" + +protocol_netmsg_t netmsg_fq_svc = +{ + .size = 50, + .msg = {NETMSG_FQ_SVC} +}; \ No newline at end of file diff --git a/makefile.inc b/makefile.inc index a3f62c5c..fbc9d239 100644 --- a/makefile.inc +++ b/makefile.inc @@ -92,6 +92,7 @@ OBJ_COMMON= \ cl_parse.o \ cl_particles.o \ cl_protocol_dpp7.o \ + cl_protocol_fq.o \ cl_protocol_nq.o \ cl_protocol_qw.o \ cl_screen.o \ diff --git a/protocol.c b/protocol.c index 8fb94c77..d8e616c5 100644 --- a/protocol.c +++ b/protocol.c @@ -267,13 +267,12 @@ protocol_t protocol_fitzquake = .num = 666, .max_edicts = MAX_EDICTS, .WriteCoord = MSG_WriteCoord13i, - .WriteAngle = MSG_WriteAngle16i, + .WriteAngle = MSG_WriteAngle8i, .WriteVector = MSG_WriteVector13i, .ReadCoord = MSG_ReadCoord13i, - .ReadAngle = MSG_ReadAngle16i, - .ReadVector = MSG_ReadVector13i - //.ReadFrame = EntityFrameFQ_CL_ReadFrame, - //.svc = &netmsg_fitzquake_svc, + .ReadAngle = MSG_ReadAngle8i, + .ReadVector = MSG_ReadVector13i, + .svc = &netmsg_fq_svc, //.clc = &netmsg_base_clc }; diff --git a/protocol.h b/protocol.h index 30c2eece..6554c0a4 100644 --- a/protocol.h +++ b/protocol.h @@ -100,8 +100,10 @@ extern protocol_t protocol_nehahramovie; extern protocol_t protocol_nehahrabjp; extern protocol_t protocol_nehahrabjp2; extern protocol_t protocol_nehahrabjp3; +extern protocol_t protocol_fitzquake; extern protocol_netmsg_t netmsg_nq_svc; +extern protocol_netmsg_t netmsg_fq_svc; extern protocol_netmsg_t netmsg_qw_svc; extern protocol_netmsg_t netmsg_dpext_svc; extern protocol_netmsg_t netmsg_base_clc; @@ -215,6 +217,14 @@ void Protocol_Names(char *buffer, size_t buffersize); #define U_GLOWCOLOR (1<<21) // 1 byte, palette index, default is 254 (white), this IS used for darklight (allowing colored darklight), however the particles from a darklight are always black, not sent if default value (even if glowsize or glowtrail is set) #define U_COLORMOD (1<<22) // 1 byte, 3 bit red, 3 bit green, 2 bit blue, this lets you tint an object artifically, so you could make a red rocket, or a blue fiend... #define U_EXTEND2 (1<<23) // another byte to follow + +// PROTOCOL_FITZQUAKE +#define U_ALPHA_FQ (1<<16) +#define U_FRAME2_FQ (1<<17) +#define U_MODEL2_FQ (1<<18) +#define U_LERPFINISH_FQ (1<<19) +#define U_SCALE_FQ (1<<20) + // LadyHavoc: second extend byte #define U_GLOWTRAIL (1<<24) // leaves a trail of particles (of color .glowcolor, or black if it is a negative glowsize) #define U_VIEWMODEL (1<<25) // attachs the model to the view (origin and angles become relative to it), only shown to owner, a more powerful alternative to .weaponmodel and such @@ -246,13 +256,13 @@ void Protocol_Names(char *buffer, size_t buffersize); #define SU_PUNCHVEC2 (1<<17) #define SU_PUNCHVEC3 (1<<18) #define SU_VIEWZOOM (1<<19) // byte factor (0 = 0.0 (not valid), 255 = 1.0) -#define SU_UNUSED20 (1<<20) -#define SU_UNUSED21 (1<<21) -#define SU_UNUSED22 (1<<22) +#define SU_NAILS2 (1<<20) // 1 byte, this is .ammo_nails & 0xFF00 (second byte) +#define SU_ROCKETS2 (1<<21) // 1 byte, this is .ammo_rockets & 0xFF00 (second byte) +#define SU_CELLS2 (1<<22) // 1 byte, this is .ammo_cells & 0xFF00 (second byte) #define SU_EXTEND2 (1<<23) // another byte to follow, future expansion // second extend byte -#define SU_UNUSED24 (1<<24) -#define SU_UNUSED25 (1<<25) +#define SU_WEAPONFRAME2 (1<<24) // 1 byte, this is .weaponframe & 0xFF00 (second byte) +#define SU_WEAPONALPHA (1<<25) // 1 byte, this is alpha for weaponmodel, uses ENTALPHA_ENCODE, not sent if ENTALPHA_DEFAULT #define SU_UNUSED26 (1<<26) #define SU_UNUSED27 (1<<27) #define SU_UNUSED28 (1<<28) @@ -260,6 +270,12 @@ void Protocol_Names(char *buffer, size_t buffersize); #define SU_UNUSED30 (1<<30) #define SU_EXTEND3 (1<<31) // another byte to follow, future expansion +// PROTOCOL_FITZQUAKE +#define SU_WEAPON2 (1<<16) // 1 byte, this is .weaponmodel & 0xFF00 (second byte) +#define SU_ARMOR2 (1<<17) // 1 byte, this is .armorvalue & 0xFF00 (second byte) +#define SU_AMMO2 (1<<18) // 1 byte, this is .currentammo & 0xFF00 (second byte) +#define SU_SHELLS2 (1<<19) // 1 byte, this is .ammo_shells & 0xFF00 (second byte) + // a sound with no channel is a local only sound #define SND_VOLUME (1<<0) // a byte #define SND_ATTENUATION (1<<1) // a byte @@ -268,11 +284,22 @@ void Protocol_Names(char *buffer, size_t buffersize); #define SND_LARGESOUND (1<<4) // a short (instead of a byte) #define SND_SPEEDUSHORT4000 (1<<5) // ushort speed*4000 (speed is usually 1.0, a value of 0.0 is the same as 1.0) +// PROTOCOL_FITZQUAKE: flags for entity baseline messages +#define B_LARGEMODEL (1<<0) // modelindex is short instead of byte +#define B_LARGEFRAME (1<<1) // frame is short instead of byte +#define B_ALPHA (1<<2) // 1 byte, uses ENTALPHA_ENCODE, not sent if ENTALPHA_DEFAULT + +// PROTOCOL_FITZQUAKE: alpha encoding +#define ENTALPHA_DEFAULT 0 //entity's alpha is "default" (i.e. water obeys r_wateralpha) -- must be zero so zeroed out memory works +#define ENTALPHA_ZERO 1 //entity is invisible (lowest possible alpha) +#define ENTALPHA_ONE 255 //entity is fully opaque (highest possible alpha) +#define ENTALPHA_ENCODE(a) (((a)==0)?ENTALPHA_DEFAULT:Q_rint(CLAMP(1,(a)*254.0f+1,255))) //server convert to byte to send to client +#define ENTALPHA_DECODE(a) (((a)==ENTALPHA_DEFAULT)?1.0f:((float)(a)-1)/(254)) //client convert to float for rendering +#define ENTALPHA_TOSAVE(a) (((a)==ENTALPHA_DEFAULT)?0.0f:(((a)==ENTALPHA_ZERO)?-1.0f:((float)(a)-1)/(254))) //server convert to float for savegame // defaults for clientinfo messages #define DEFAULT_VIEWHEIGHT 22 - // game types sent by serverinfo // these determine which intermission screen plays #define GAME_COOP 0 @@ -340,6 +367,13 @@ void Protocol_Names(char *buffer, size_t buffersize); #define svc_hidelmp 36 // [string] slotname #define svc_skybox 37 // [string] skyname +// PROTOCOL_FITZQUAKE +#define svc_bf 40 +#define svc_fog_fq 41 // [byte] density [byte] red [byte] green [byte] blue [float] time +#define svc_spawnbaseline2_fq 42 // support for large modelindex, large framenum, alpha, using flags +#define svc_spawnstatic2_fq 43 // support for large modelindex, large framenum, alpha, using flags +#define svc_spawnstaticsound2_fq 44 // [coord3] [short] samp [byte] vol [byte] aten + // LadyHavoc: my svc_ range, 50-69 #define svc_downloaddata 50 // [int] start [short] size #define svc_updatestatubyte 51 // [byte] stat [byte] value @@ -493,6 +527,7 @@ typedef struct framegroupblend_s float lerp; // time frame began playing (for framegroup animations) double start; + double finish; // Server sent us a more accurate interval. Use it instead of 0.1 } framegroupblend_t; diff --git a/sbar.c b/sbar.c index 5c583564..b30d33a6 100644 --- a/sbar.c +++ b/sbar.c @@ -1879,7 +1879,7 @@ void Sbar_DeathmatchOverlay (void) MSG_WriteByte(&cls.netcon->message, clc_stringcmd); MSG_WriteString(&cls.netcon->message, "pings"); } - else if (cls.protocol == &protocol_netquake || cls.protocol == &protocol_quakedp || cls.protocol == &protocol_nehahramovie || cls.protocol == &protocol_nehahrabjp || cls.protocol == &protocol_nehahrabjp2 || cls.protocol == &protocol_nehahrabjp3 || cls.protocol == &protocol_dpp1 || cls.protocol == &protocol_dpp2 || cls.protocol == &protocol_dpp3 || cls.protocol == &protocol_dpp4 || cls.protocol == &protocol_dpp5 || cls.protocol == &protocol_dpp6/* || cls.protocol == &protocol_dpp7*/) + else if (cls.protocol == &protocol_netquake || cls.protocol == &protocol_fitzquake || cls.protocol == &protocol_quakedp || cls.protocol == &protocol_nehahramovie || cls.protocol == &protocol_nehahrabjp || cls.protocol == &protocol_nehahrabjp2 || cls.protocol == &protocol_nehahrabjp3 || cls.protocol == &protocol_dpp1 || cls.protocol == &protocol_dpp2 || cls.protocol == &protocol_dpp3 || cls.protocol == &protocol_dpp4 || cls.protocol == &protocol_dpp5 || cls.protocol == &protocol_dpp6/* || cls.protocol == &protocol_dpp7*/) { // these servers usually lack the pings command and so a less efficient "ping" command must be sent, which on modern DP servers will also reply with a pingplreport command after the ping listing static int ping_anyway_counter = 0; diff --git a/snd_main.c b/snd_main.c index c937db12..70fe4d9f 100644 --- a/snd_main.c +++ b/snd_main.c @@ -1566,7 +1566,7 @@ static void S_PlaySfxOnChannel (sfx_t *sfx, channel_t *target_chan, unsigned int // If it's a static sound if (isstatic) { - if (sfx->loopstart >= sfx->total_length && (cls.protocol == &protocol_netquake || cls.protocol == &protocol_quakeworld)) + if (sfx->loopstart >= sfx->total_length && (cls.protocol == &protocol_netquake || cls.protocol == &protocol_fitzquake || cls.protocol == &protocol_quakeworld)) Con_DPrintf("Quake compatibility warning: Static sound \"%s\" is not looped\n", sfx->name); target_chan->distfade = attenuation / (64.0f * snd_soundradius.value); } -- 2.39.2