From e9ae3fdb030105a588aee869b5e631429a876065 Mon Sep 17 00:00:00 2001
From: Spoike <acceptthis@users.sourceforge.net>
Date: Sun, 5 Dec 2004 08:19:54 +0000
Subject: [PATCH] Added support for DP-P6

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@559 fc73d0e0-1445-4013-8a0c-d673dee63da5
---
 engine/client/cl_input.c |  91 ++++++++++++++-
 engine/client/cl_parse.c | 242 ++++++++++++++++-----------------------
 2 files changed, 186 insertions(+), 147 deletions(-)

diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c
index 2f2a1926b..95cbccae9 100644
--- a/engine/client/cl_input.c
+++ b/engine/client/cl_input.c
@@ -545,6 +545,69 @@ void CL_FinishMove (usercmd_t *cmd, int msecs, int pnum)
 	cmd->upmove = MakeChar (cmd->upmove);
 }
 
+cvar_t cl_prydoncursor = {"cl_prydoncursor", "0"};
+void CL_UpdatePrydonCursor(float cursor_screen[2], vec3_t cursor_start, vec3_t cursor_impact, int *entnum)
+{
+	float modelview[16];
+	vec3_t cursor_end;
+	trace_t tr;
+
+	vec3_t temp, scale;
+
+	if (!cl_prydoncursor.value)
+	{	//center the cursor
+		cursor_screen[0] = 0;
+		cursor_screen[1] = 0;
+	}
+
+	/*
+	if (cl.cmd.cursor_screen[0] < -1)
+	{
+		cl.viewangles[YAW] -= m_yaw.value * (cl.cmd.cursor_screen[0] - -1) * vid.realwidth * sensitivity.value * cl.viewzoom;
+		cl.cmd.cursor_screen[0] = -1;
+	}
+	if (cl.cmd.cursor_screen[0] > 1)
+	{
+		cl.viewangles[YAW] -= m_yaw.value * (cl.cmd.cursor_screen[0] - 1) * vid.realwidth * sensitivity.value * cl.viewzoom;
+		cl.cmd.cursor_screen[0] = 1;
+	}
+	if (cl.cmd.cursor_screen[1] < -1)
+	{
+		cl.viewangles[PITCH] += m_pitch.value * (cl.cmd.cursor_screen[1] - -1) * vid.realheight * sensitivity.value * cl.viewzoom;
+		cl.cmd.cursor_screen[1] = -1;
+	}
+	if (cl.cmd.cursor_screen[1] > 1)
+	{
+		cl.viewangles[PITCH] += m_pitch.value * (cl.cmd.cursor_screen[1] - 1) * vid.realheight * sensitivity.value * cl.viewzoom;
+		cl.cmd.cursor_screen[1] = 1;
+	}
+	*/
+//	cursor_screen[0] = bound(-1, cursor_screen[0], 1);
+//	cursor_screen[1] = bound(-1, cursor_screen[1], 1);
+
+	scale[0] = -tan(r_refdef.fov_x * M_PI / 360.0);
+	scale[1] = -tan(r_refdef.fov_y * M_PI / 360.0);
+	scale[2] = 1;
+
+	// trace distance
+	VectorScale(scale, 1000000, scale);
+
+
+	VectorCopy(cl.simorg[0], cursor_start);
+	temp[0] = cursor_screen[2] * scale[2];
+	temp[1] = cursor_screen[0] * scale[0];
+	temp[2] = cursor_screen[1] * scale[1];
+
+	ML_ModelViewMatrix(modelview, cl.viewangles[0], cl.simorg[0]);
+	Matrix4_Transform3(modelview, temp, cursor_end);
+
+	tr = PM_PlayerTrace(cursor_start, cursor_end);
+	VectorCopy(tr.endpos, cursor_impact);
+//	CL_SelectTraceLine(cursor_start, cursor_end, cursor_impact, entnum);
+	// makes sparks where cursor is
+	//CL_SparkShower(cl.cmd.cursor_impact, cl.cmd.cursor_normal, 5, 0);
+}
+
 #ifdef NQPROT
 void CLNQ_SendMove (usercmd_t		*cmd, int pnum)
 {
@@ -552,6 +615,10 @@ void CLNQ_SendMove (usercmd_t		*cmd, int pnum)
 	int i;
 	sizebuf_t	buf;
 	qbyte	data[128];
+
+	float cursor_screen[2];
+	vec3_t cursor_start, cursor_impact;
+	int cursor_entitynumber=0;//I hate warnings as errors
 	
 	buf.maxsize = 128;
 	buf.cursize = 0;
@@ -583,8 +650,13 @@ void CLNQ_SendMove (usercmd_t		*cmd, int pnum)
 	if (in_button7.state[pnum] & 3)	bits |=  64; in_button7.state[pnum] &= ~2;
 	if (in_button8.state[pnum] & 3)	bits |= 128; in_button8.state[pnum] &= ~2;
 
-	
-    MSG_WriteByte (&buf, bits);
+	if (nq_dp_protocol == 6)
+	{
+		CL_UpdatePrydonCursor(cursor_screen, cursor_start, cursor_impact, &cursor_entitynumber);
+		MSG_WriteLong (&buf, bits);
+	}
+	else
+		MSG_WriteByte (&buf, bits);
 
 	if (in_impulsespending[pnum])
 	{
@@ -596,6 +668,21 @@ void CLNQ_SendMove (usercmd_t		*cmd, int pnum)
 		MSG_WriteByte (&buf, 0);
 
 
+	if (nq_dp_protocol == 6)
+	{
+		MSG_WriteShort (&buf, cursor_screen[0] * 32767.0f);
+		MSG_WriteShort (&buf, cursor_screen[1] * 32767.0f);
+		MSG_WriteFloat (&buf, cursor_start[0]);
+		MSG_WriteFloat (&buf, cursor_start[1]);
+		MSG_WriteFloat (&buf, cursor_start[2]);
+		MSG_WriteFloat (&buf, cursor_impact[0]);
+		MSG_WriteFloat (&buf, cursor_impact[1]);
+		MSG_WriteFloat (&buf, cursor_impact[2]);
+		MSG_WriteShort (&buf, cursor_entitynumber);
+	}
+
+
+
 //
 // deliver the message
 //
diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c
index ed2627134..e01db919d 100644
--- a/engine/client/cl_parse.c
+++ b/engine/client/cl_parse.c
@@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 void CL_GetNumberedEntityInfo (int num, float *org, float *ang);
 void CLNQ_ParseDarkPlaces5Entities(void);
+void CL_SetStat (int pnum, int stat, int value);
 
 void R_ParseParticleEffect2 (void);
 void R_ParseParticleEffect3 (void);
@@ -1438,6 +1439,7 @@ void CLNQ_ParseServerData(void)		//Doesn't change gamedir - use with caution.
 	sizeofangle = 1;
 
 	nq_dp_protocol = 0;
+	cls.z_ext = 0;
 
 	if (protover == 250)
 		Host_EndGame ("Nehahra demo net protocol is not supported\n");
@@ -1448,6 +1450,15 @@ void CLNQ_ParseServerData(void)		//Doesn't change gamedir - use with caution.
 		sizeofcoord = 4;
 		sizeofangle = 2;
 	}
+	else if (protover == 3503)
+	{
+		//darkplaces6 (it's a small difference from dp5)
+		nq_dp_protocol = 6;
+		sizeofcoord = 4;
+		sizeofangle = 2;
+
+		cls.z_ext = Z_EXT_VIEWHEIGHT;
+	}
 	else if (protover != NQ_PROTOCOL_VERSION)
 	{
 		Host_EndGame ("Server returned version %i, not %i\nYou will need to use a different client.", protover, NQ_PROTOCOL_VERSION);
@@ -1628,7 +1639,7 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
 #define	DEFAULT_VIEWHEIGHT	22
 void CLNQ_ParseClientdata (int bits)
 {
-	int		i, j;
+	int		i;
 
 	bits &= 0xffff;
 
@@ -1638,9 +1649,9 @@ void CLNQ_ParseClientdata (int bits)
 		bits |= (MSG_ReadByte() << 24);
 	
 	if (bits & SU_VIEWHEIGHT)
-		cl.viewheight[0] = MSG_ReadChar ();
-	else
-		cl.viewheight[0] = DEFAULT_VIEWHEIGHT;
+		CL_SetStat(0, STAT_VIEWHEIGHT, MSG_ReadChar ());
+	else if (nq_dp_protocol != 6)
+		CL_SetStat(0, STAT_VIEWHEIGHT, DEFAULT_VIEWHEIGHT);
 
 	if (bits & SU_IDEALPITCH)
 		/*cl.idealpitch =*/ MSG_ReadChar ();
@@ -1664,7 +1675,7 @@ void CLNQ_ParseClientdata (int bits)
 
 		if (bits & (SU_VELOCITY1<<i) )
 		{
-			if (nq_dp_protocol == 5)
+			if (nq_dp_protocol == 5 || nq_dp_protocol == 6)
 				/*cl.simvel[0][i] =*/ MSG_ReadFloat();
 			else
 			/*cl.mvelocity[0][i] =*/ MSG_ReadChar()/**16*/;
@@ -1673,164 +1684,62 @@ void CLNQ_ParseClientdata (int bits)
 //			cl.mvelocity[0][i] = 0;
 	}
 
-// [always sent]	if (bits & SU_ITEMS)
-	i = MSG_ReadLong ();
+	if (bits & SU_ITEMS)
+		CL_SetStat(0, STAT_ITEMS, MSG_ReadLong());
 
-	if (cl.stats[0][STAT_ITEMS] != i)
-	{	// set flash times
-		Sbar_Changed ();
-		for (j=0 ; j<32 ; j++)
-			if ( (i & (1<<j)) && !(cl.stats[0][STAT_ITEMS] & (1<<j)))
-				cl.item_gettime[0][j] = cl.time;
-		cl.stats[0][STAT_ITEMS] = i;
-	}
-		
 //	cl.onground = (bits & SU_ONGROUND) != 0;
 //	cl.inwater = (bits & SU_INWATER) != 0;
 
-	if (nq_dp_protocol == 5)
+	if (nq_dp_protocol == 6)
 	{
-		if (bits & SU_WEAPONFRAME)
-			i = MSG_ReadShort ();
-		else
-			i = 0;
+	}
+	else if (nq_dp_protocol == 5)
+	{
+		CL_SetStat(0, STAT_WEAPONFRAME, (bits & SU_WEAPONFRAME)?(unsigned short)MSG_ReadShort():0);
+		CL_SetStat(0, STAT_ARMOR, (bits & SU_ARMOR)?MSG_ReadShort():0);
+		CL_SetStat(0, STAT_WEAPON, (bits & SU_WEAPON)?MSG_ReadShort():0);
 
-		cl.stats[0][STAT_WEAPONFRAME] = i;
+		CL_SetStat(0, STAT_HEALTH, MSG_ReadShort());
 
-		if (bits & SU_ARMOR)
-			i = MSG_ReadShort ();
-		else
-			i = 0;
-		if (cl.stats[0][STAT_ARMOR] != i)
-		{
-			cl.stats[0][STAT_ARMOR] = i;
-			Sbar_Changed ();
-		}
+		CL_SetStat(0, STAT_AMMO, MSG_ReadShort());
 
-		if (bits & SU_WEAPON)
-			i = MSG_ReadShort ();
-		else
-			i = 0;
-		if (cl.stats[0][STAT_WEAPON] != i)
-		{
-			cl.stats[0][STAT_WEAPON] = i;
-			Sbar_Changed ();
-		}
-		
-		i = MSG_ReadShort ();
-		if (cl.stats[0][STAT_HEALTH] != i)
-		{
-			cl.stats[0][STAT_HEALTH] = i;
-			Sbar_Changed ();
-		}
-
-		i = MSG_ReadShort ();
-		if (cl.stats[0][STAT_AMMO] != i)
-		{
-			cl.stats[0][STAT_AMMO] = i;
-			Sbar_Changed ();
-		}
-
-		for (i=0 ; i<4 ; i++)
-		{
-			j = MSG_ReadShort ();
-			if (cl.stats[0][STAT_SHELLS+i] != j)
-			{
-				cl.stats[0][STAT_SHELLS+i] = j;
-				Sbar_Changed ();
-			}
-		}
-
-		i = MSG_ReadShort ();
+		CL_SetStat(0, STAT_SHELLS, MSG_ReadShort());
+		CL_SetStat(0, STAT_NAILS, MSG_ReadShort());
+		CL_SetStat(0, STAT_ROCKETS, MSG_ReadShort());
+		CL_SetStat(0, STAT_CELLS, MSG_ReadShort());
 
+		CL_SetStat(0, STAT_ACTIVEWEAPON, (unsigned short)MSG_ReadShort());
 	}
 	else
 	{
-		if (bits & SU_WEAPONFRAME)
-			i = MSG_ReadByte ();
-		else
-			i = 0;
+		CL_SetStat(0, STAT_WEAPONFRAME, (bits & SU_WEAPONFRAME)?(unsigned char)MSG_ReadByte():0);
+		CL_SetStat(0, STAT_ARMOR, (bits & SU_ARMOR)?MSG_ReadByte():0);
+		CL_SetStat(0, STAT_WEAPON, (bits & SU_WEAPON)?MSG_ReadByte():0);
 
-		cl.stats[0][STAT_WEAPONFRAME] = i;
+		CL_SetStat(0, STAT_HEALTH, MSG_ReadShort());
 
-		if (bits & SU_ARMOR)
-			i = MSG_ReadByte ();
-		else
-			i = 0;
-		if (cl.stats[0][STAT_ARMOR] != i)
-		{
-			cl.stats[0][STAT_ARMOR] = i;
-			Sbar_Changed ();
-		}
+		CL_SetStat(0, STAT_AMMO, MSG_ReadByte());
 
-		if (bits & SU_WEAPON)
-			i = MSG_ReadByte ();
-		else
-			i = 0;
-		if (cl.stats[0][STAT_WEAPON] != i)
-		{
-			cl.stats[0][STAT_WEAPON] = i;
-			Sbar_Changed ();
-		}
-		
-		i = MSG_ReadShort ();
-		if (cl.stats[0][STAT_HEALTH] != i)
-		{
-			cl.stats[0][STAT_HEALTH] = i;
-			Sbar_Changed ();
-		}
+		CL_SetStat(0, STAT_SHELLS, MSG_ReadByte());
+		CL_SetStat(0, STAT_NAILS, MSG_ReadByte());
+		CL_SetStat(0, STAT_ROCKETS, MSG_ReadByte());
+		CL_SetStat(0, STAT_CELLS, MSG_ReadByte());
 
-		i = MSG_ReadByte ();
-		if (cl.stats[0][STAT_AMMO] != i)
-		{
-			cl.stats[0][STAT_AMMO] = i;
-			Sbar_Changed ();
-		}
-
-		for (i=0 ; i<4 ; i++)
-		{
-			j = MSG_ReadByte ();
-			if (cl.stats[0][STAT_SHELLS+i] != j)
-			{
-				cl.stats[0][STAT_SHELLS+i] = j;
-				Sbar_Changed ();
-			}
-		}
-
-		i = MSG_ReadByte ();
+		CL_SetStat(0, STAT_ACTIVEWEAPON, (unsigned short)MSG_ReadShort());
 	}
 
-	if (standard_quake)
-	{
-		if (cl.stats[0][STAT_ACTIVEWEAPON] != i)
-		{
-			cl.stats[0][STAT_ACTIVEWEAPON] = i;
-			Sbar_Changed ();
-		}
-	}
-	else
-	{
-		if (cl.stats[0][STAT_ACTIVEWEAPON] != (1<<i))
-		{
-			cl.stats[0][STAT_ACTIVEWEAPON] = (1<<i);
-			Sbar_Changed ();
-		}
-	}
-
-
-
 	if (bits & DPSU_VIEWZOOM)
 	{
-		if (nq_dp_protocol == 5)
+		if (nq_dp_protocol == 5 || nq_dp_protocol == 6)
 			i = (unsigned short) MSG_ReadShort();
 		else
 			i = MSG_ReadByte();
 		if (i < 2)
 			i = 2;
-//		cl.viewzoomnew = (float) i * (1.0f / 255.0f);
+		CL_SetStat(0, STAT_VIEWZOOM, i);
 	}
-//	else
-//		cl.viewzoomnew = 1;
+	else if (nq_dp_protocol != 6)
+		CL_SetStat(0, STAT_VIEWZOOM, 255);
 }
 #endif
 /*
@@ -2605,11 +2514,11 @@ void CL_SetStat (int pnum, int stat, int value)
 		return;
 //		Host_EndGame ("CL_SetStat: %i is invalid", stat);
 
-	Sbar_Changed ();
+	if (cl.stats[pnum][stat] != value)
+		Sbar_Changed ();
 	
 	if (stat == STAT_ITEMS)
 	{	// set flash times
-		Sbar_Changed ();
 		for (j=0 ; j<32 ; j++)
 			if ( (value & (1<<j)) && !(cl.stats[pnum][stat] & (1<<j)))
 				cl.item_gettime[pnum][j] = cl.time;
@@ -4138,6 +4047,44 @@ void CLNQ_ParseServerMessage (void)
 			vid.recalc_refdef = true;	// leave full screen intermission			
 			break;
 
+		case 54://svc_precache:
+			{
+				int i = (unsigned short)MSG_ReadShort();
+				char *s = MSG_ReadString();
+				if (i < 32768)
+				{
+					if (i >= 1 && i < MAX_MODELS)
+					{
+						model_t *model;
+						CL_CheckOrDownloadFile(s, true);
+						model = Mod_ForName(s, i == 1);
+						if (!model)
+							Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s);
+						cl.model_precache[i] = model;
+						strcpy (cl.model_name[i], s);
+					}
+					else
+						Con_Printf("svc_precache: model index %i outside range %i...%i\n", i, 1, MAX_MODELS);
+				}
+				else
+				{
+					i -= 32768;
+					if (i >= 1 && i < MAX_SOUNDS)
+					{
+						sfx_t *sfx;
+						CL_CheckOrDownloadFile(va("sounds/%s", s), true);
+						sfx = S_PrecacheSound (s);
+						if (!sfx)
+							Con_Printf("svc_precache: S_PrecacheSound(\"%s\") failed\n", s);
+						cl.sound_precache[i] = sfx;
+						strcpy (cl.sound_name[i], s);
+					}
+					else
+						Con_Printf("svc_precache: sound index %i outside range %i...%i\n", i, 1, MAX_SOUNDS);
+				}
+			}
+			break;
+
 		case svc_cdtrack:
 			cl.cdtrack = MSG_ReadByte ();
 			MSG_ReadByte ();
@@ -4186,7 +4133,7 @@ void CLNQ_ParseServerMessage (void)
 			cl.last_servermessage = realtime;
 			cl.gametime = MSG_ReadFloat();
 			cl.gametimemark = realtime;
-			if (nq_dp_protocol!=5)
+			if (nq_dp_protocol<5)
 			{
 				cls.netchan.incoming_sequence++;
 //				cl.frames[(cls.netchan.incoming_sequence-1)&UPDATE_MASK].packet_entities = cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities;
@@ -4241,6 +4188,11 @@ void CLNQ_ParseServerMessage (void)
 			j = MSG_ReadLong ();
 			CL_SetStat (0, i, j);
 			break;
+		case 51://svc_updatestat:
+			i = MSG_ReadByte ();			
+			j = MSG_ReadByte ();
+			CL_SetStat (0, i, j);
+			break;
 		case svc_setangle:
 			for (i=0 ; i<3 ; i++)
 				cl.viewangles[0][i] = MSG_ReadAngle ();
@@ -4308,11 +4260,11 @@ void CLNQ_ParseServerMessage (void)
 			break;
 
 		case 57://svc_entities
-	if (cls.signon == 4 - 1)
-	{	// first update is the final signon stage
-		cls.signon = 4;
-		CLNQ_SignonReply ();
-	}	
+			if (cls.signon == 4 - 1)
+			{	// first update is the final signon stage
+				cls.signon = 4;
+				CLNQ_SignonReply ();
+			}	
 			//well, it's really any protocol, but we're only going to support version 5.
 			CLNQ_ParseDarkPlaces5Entities();
 			break;