From 5db396f822488e6c176e82bf614103dfc0a0d456 Mon Sep 17 00:00:00 2001
From: havoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Fri, 16 Sep 2011 08:56:11 +0000
Subject: [PATCH] added network protocol for sound speed (ushort speed*4000,
 not compatible with FTEQW, different flag) added optional pitchchange
 parameter to pointsound

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11355 d7cf8633-e32d-0410-b094-e92efae38249
::stable-branch::merge=3579ea0a97797b72298e63b723b65e46ea264b14
---
 cl_parse.c  |  8 ++++++++
 protocol.h  |  1 +
 server.h    |  4 ++--
 sv_main.c   | 18 ++++++++++++++----
 sv_phys.c   |  4 ++--
 svvm_cmds.c | 10 ++++++----
 6 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/cl_parse.c b/cl_parse.c
index 460070ca..1e81ddef 100644
--- a/cl_parse.c
+++ b/cl_parse.c
@@ -210,6 +210,7 @@ void CL_ParseStartSoundPacket(int largesoundindex)
 	int 	volume;
 	int 	field_mask;
 	float 	attenuation;
+	float	speed;
 
 	if (cls.protocol == PROTOCOL_QUAKEWORLD)
 	{
@@ -224,6 +225,8 @@ void CL_ParseStartSoundPacket(int largesoundindex)
 			attenuation = MSG_ReadByte () / 64.0;
 		else
 			attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
+	
+		speed = 1.0f;
 
 		ent = (channel>>3)&1023;
 		channel &= 7;
@@ -244,6 +247,11 @@ void CL_ParseStartSoundPacket(int largesoundindex)
 		else
 			attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;
 
+		if (field_mask & SND_SPEEDUSHORT4000)
+			speed = ((unsigned short)MSG_ReadShort ()) / 4000.0f;
+		else
+			speed = 1.0f;
+
 		if (field_mask & SND_LARGEENTITY)
 		{
 			ent = (unsigned short) MSG_ReadShort ();
diff --git a/protocol.h b/protocol.h
index 50a5215b..9d694f0f 100644
--- a/protocol.h
+++ b/protocol.h
@@ -165,6 +165,7 @@ void Protocol_Names(char *buffer, size_t buffersize);
 #define	SND_LOOPING		(1<<2)		// a long
 #define	SND_LARGEENTITY	(1<<3)		// a short and a byte (instead of a short)
 #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)
 
 
 // defaults for clientinfo messages
diff --git a/server.h b/server.h
index f2bc1f79..34c68e2d 100644
--- a/server.h
+++ b/server.h
@@ -495,8 +495,8 @@ void SV_Init (void);
 
 void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count);
 void SV_StartEffect (vec3_t org, int modelindex, int startframe, int framecount, int framerate);
-void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int volume, float attenuation, qboolean reliable);
-void SV_StartPointSound (vec3_t origin, const char *sample, int volume, float attenuation);
+void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int volume, float attenuation, qboolean reliable, float speed);
+void SV_StartPointSound (vec3_t origin, const char *sample, int volume, float attenuation, float speed);
 
 void SV_ConnectClient (int clientnum, netconn_t *netconnection);
 void SV_DropClient (qboolean crash);
diff --git a/sv_main.c b/sv_main.c
index aa7ce320..c60e15b0 100644
--- a/sv_main.c
+++ b/sv_main.c
@@ -699,10 +699,10 @@ Larger attenuations will drop off.  (max 4 attenuation)
 
 ==================
 */
-void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int volume, float attenuation, qboolean reliable)
+void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int volume, float attenuation, qboolean reliable, float speed)
 {
 	sizebuf_t *dest;
-	int sound_num, field_mask, i, ent;
+	int sound_num, field_mask, i, ent, speed4000;
 
 	dest = (reliable ? &sv.reliable_datagram : &sv.datagram);
 
@@ -736,6 +736,7 @@ void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int v
 
 	ent = PRVM_NUM_FOR_EDICT(entity);
 
+	speed4000 = (int)(speed * 40.0f);
 	field_mask = 0;
 	if (volume != DEFAULT_SOUND_PACKET_VOLUME)
 		field_mask |= SND_VOLUME;
@@ -745,6 +746,8 @@ void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int v
 		field_mask |= SND_LARGEENTITY;
 	if (sound_num >= 256)
 		field_mask |= SND_LARGESOUND;
+	if (speed4000 && speed4000 != 4000)
+		field_mask |= SND_SPEEDUSHORT4000;
 
 // directed messages go only to the entity they are targeted on
 	MSG_WriteByte (dest, svc_sound);
@@ -753,6 +756,8 @@ void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int v
 		MSG_WriteByte (dest, volume);
 	if (field_mask & SND_ATTENUATION)
 		MSG_WriteByte (dest, (int)(attenuation*64));
+	if (field_mask & SND_SPEEDUSHORT4000)
+		MSG_WriteShort (dest, speed4000);
 	if (field_mask & SND_LARGEENTITY)
 	{
 		MSG_WriteShort (dest, ent);
@@ -785,9 +790,9 @@ function, therefore the check for it is omitted.
 
 ==================
 */
-void SV_StartPointSound (vec3_t origin, const char *sample, int volume, float attenuation)
+void SV_StartPointSound (vec3_t origin, const char *sample, int volume, float attenuation, float speed)
 {
-	int sound_num, field_mask, i;
+	int sound_num, field_mask, i, speed4000;
 
 	if (volume < 0 || volume > 255)
 	{
@@ -809,6 +814,7 @@ void SV_StartPointSound (vec3_t origin, const char *sample, int volume, float at
 	if (!sound_num)
 		return;
 
+	speed4000 = (int)(speed * 40.0f);
 	field_mask = 0;
 	if (volume != DEFAULT_SOUND_PACKET_VOLUME)
 		field_mask |= SND_VOLUME;
@@ -816,6 +822,8 @@ void SV_StartPointSound (vec3_t origin, const char *sample, int volume, float at
 		field_mask |= SND_ATTENUATION;
 	if (sound_num >= 256)
 		field_mask |= SND_LARGESOUND;
+	if (speed4000 && speed4000 != 4000)
+		field_mask |= SND_SPEEDUSHORT4000;
 
 // directed messages go only to the entity they are targeted on
 	MSG_WriteByte (&sv.datagram, svc_sound);
@@ -824,6 +832,8 @@ void SV_StartPointSound (vec3_t origin, const char *sample, int volume, float at
 		MSG_WriteByte (&sv.datagram, volume);
 	if (field_mask & SND_ATTENUATION)
 		MSG_WriteByte (&sv.datagram, (int)(attenuation*64));
+	if (field_mask & SND_SPEEDUSHORT4000)
+		MSG_WriteShort (&sv.datagram, speed4000);
 	// Always write entnum 0 for the world entity
 	MSG_WriteShort (&sv.datagram, (0<<3) | 0);
 	if (field_mask & SND_LARGESOUND)
diff --git a/sv_phys.c b/sv_phys.c
index 629727c6..a3f84f4b 100644
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -2523,7 +2523,7 @@ void SV_CheckWaterTransition (prvm_edict_t *ent)
 	{ // Contents Transition Function Invalid; Potentially Play Water Sound
 		// check if the entity crossed into or out of water
 		if (sv_sound_watersplash.string && ((PRVM_serveredictfloat(ent, watertype) == CONTENTS_WATER || PRVM_serveredictfloat(ent, watertype) == CONTENTS_SLIME) != (cont == CONTENTS_WATER || cont == CONTENTS_SLIME)))
-			SV_StartSound (ent, 0, sv_sound_watersplash.string, 255, 1, false);
+			SV_StartSound (ent, 0, sv_sound_watersplash.string, 255, 1, false, 1.0f);
 	}
 
 	if (cont <= CONTENTS_WATER)
@@ -2768,7 +2768,7 @@ void SV_Physics_Step (prvm_edict_t *ent)
 				else
 				// Check for Engine Landing Sound
 				if(sv_sound_land.string)
-					SV_StartSound(ent, 0, sv_sound_land.string, 255, 1, false);
+					SV_StartSound(ent, 0, sv_sound_land.string, 255, 1, false, 1.0f);
 			}
 			ent->priv.server->waterposition_forceupdate = true;
 		}
diff --git a/svvm_cmds.c b/svvm_cmds.c
index 30d17453..310af6d8 100644
--- a/svvm_cmds.c
+++ b/svvm_cmds.c
@@ -533,7 +533,7 @@ static void VM_SV_sound (void)
 	if (prog->argc < 6)
 		pitchchange = 0;
 	else
-		pitchchange = PRVM_G_FLOAT(OFS_PARM5);
+		pitchchange = PRVM_G_FLOAT(OFS_PARM5) * 0.01f;
 
 	if (prog->argc < 7)
 	{
@@ -567,7 +567,7 @@ static void VM_SV_sound (void)
 		return;
 	}
 
-	SV_StartSound (entity, channel, sample, volume, attenuation, flags & CHANFLAG_RELIABLE);
+	SV_StartSound (entity, channel, sample, volume, attenuation, flags & CHANFLAG_RELIABLE, pitchchange);
 }
 
 /*
@@ -585,14 +585,16 @@ static void VM_SV_pointsound(void)
 	const char	*sample;
 	int 		volume;
 	float		attenuation;
+	float		pitchchange;
 	vec3_t		org;
 
-	VM_SAFEPARMCOUNT(4, VM_SV_pointsound);
+	VM_SAFEPARMCOUNTRANGE(4, 5, VM_SV_pointsound);
 
 	VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
 	sample = PRVM_G_STRING(OFS_PARM1);
 	volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
 	attenuation = PRVM_G_FLOAT(OFS_PARM3);
+	pitchchange = prog->argc < 5 ? 0 : PRVM_G_FLOAT(OFS_PARM4) * 0.01f;
 
 	if (volume < 0 || volume > 255)
 	{
@@ -606,7 +608,7 @@ static void VM_SV_pointsound(void)
 		return;
 	}
 
-	SV_StartPointSound (org, sample, volume, attenuation);
+	SV_StartPointSound (org, sample, volume, attenuation, pitchchange);
 }
 
 /*
-- 
2.39.5