Added pointsound QC function to CL and SV VMs (extension DP_SV_POINTSOUND, #483)...
authordresk <dresk@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 26 Aug 2007 19:02:29 +0000 (19:02 +0000)
committerdresk <dresk@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 26 Aug 2007 19:02:29 +0000 (19:02 +0000)
This function requires no modification to the protocol layer (since origin was always sent with sound calls, along with an entity).

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7537 d7cf8633-e32d-0410-b094-e92efae38249

clvm_cmds.c
server.h
sv_main.c
svvm_cmds.c

index 9e8cbb4..27ba252 100644 (file)
@@ -162,6 +162,37 @@ static void VM_CL_sound (void)
        S_StartSound(32768 + PRVM_NUM_FOR_EDICT(entity), channel, S_FindName(sample), entity->fields.client->origin, volume, attenuation);
 }
 
+// #483 void(vector origin, string sample, float volume, float attenuation) pointsound
+static void VM_CL_pointsound(void)
+{
+       const char                      *sample;
+       float                           volume;
+       float                           attenuation;
+       vec3_t                          org;
+
+       VM_SAFEPARMCOUNT(4, VM_CL_pointsound);
+
+       VectorCopy( PRVM_G_VECTOR(OFS_PARM0), org);
+       sample = PRVM_G_STRING(OFS_PARM1);
+       volume = PRVM_G_FLOAT(OFS_PARM2);
+       attenuation = PRVM_G_FLOAT(OFS_PARM3);
+
+       if (volume < 0 || volume > 1)
+       {
+               VM_Warning("VM_CL_pointsound: volume must be in range 0-1\n");
+               return;
+       }
+
+       if (attenuation < 0 || attenuation > 4)
+       {
+               VM_Warning("VM_CL_pointsound: attenuation must be in range 0-4\n");
+               return;
+       }
+
+       // Send World Entity as Entity to Play Sound (for CSQC, that is 32768)
+       S_StartSound(32768, 0, S_FindName(sample), org, volume, attenuation);
+}
+
 // #14 entity() spawn
 static void VM_CL_spawn (void)
 {
@@ -3202,7 +3233,7 @@ VM_tokenizebyseparator,                   // #479 float(string s) tokenizebyseparator (DP_QC_TOK
 VM_strtolower,                                 // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
 VM_strtoupper,                                 // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
 VM_cvar_defstring,                             // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
-NULL,                                                  // #483
+VM_CL_pointsound,                              // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
 NULL,                                                  // #484
 NULL,                                                  // #485
 NULL,                                                  // #486
index 11af4fc..d7df388 100644 (file)
--- a/server.h
+++ b/server.h
@@ -411,6 +411,7 @@ 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);
+void SV_StartPointSound (vec3_t origin, const char *sample, int volume, float attenuation);
 
 void SV_ConnectClient (int clientnum, netconn_t *netconnection);
 void SV_DropClient (qboolean crash);
index 19f35f7..17dbf2c 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -596,6 +596,69 @@ void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int v
 }
 
 /*
+==================
+SV_StartPointSound
+
+Nearly the same logic as SV_StartSound, except an origin
+instead of an entity is provided and channel is omitted.
+
+The entity sent to the client is 0 (world) and the channel
+is 0 (CHAN_AUTO).  SND_LARGEENTITY will never occur in this
+function, therefore the check for it is omitted.
+
+==================
+*/
+void SV_StartPointSound (vec3_t origin, const char *sample, int volume, float attenuation)
+{
+       int sound_num, field_mask, i;
+
+       if (volume < 0 || volume > 255)
+       {
+               Con_Printf ("SV_StartPointSound: volume = %i\n", volume);
+               return;
+       }
+
+       if (attenuation < 0 || attenuation > 4)
+       {
+               Con_Printf ("SV_StartPointSound: attenuation = %f\n", attenuation);
+               return;
+       }
+
+       if (sv.datagram.cursize > MAX_PACKETFRAGMENT-21)
+               return;
+
+       // find precache number for sound
+       sound_num = SV_SoundIndex(sample, 1);
+       if (!sound_num)
+               return;
+
+       field_mask = 0;
+       if (volume != DEFAULT_SOUND_PACKET_VOLUME)
+               field_mask |= SND_VOLUME;
+       if (attenuation != DEFAULT_SOUND_PACKET_ATTENUATION)
+               field_mask |= SND_ATTENUATION;
+       if (sound_num >= 256)
+               field_mask |= SND_LARGESOUND;
+
+// directed messages go only to the entity they are targeted on
+       MSG_WriteByte (&sv.datagram, svc_sound);
+       MSG_WriteByte (&sv.datagram, field_mask);
+       if (field_mask & SND_VOLUME)
+               MSG_WriteByte (&sv.datagram, volume);
+       if (field_mask & SND_ATTENUATION)
+               MSG_WriteByte (&sv.datagram, (int)(attenuation*64));
+       // Always write entnum 0 for the world entity
+       MSG_WriteShort (&sv.datagram, (0<<3) | 0);
+       if (field_mask & SND_LARGESOUND)
+               MSG_WriteShort (&sv.datagram, sound_num);
+       else
+               MSG_WriteByte (&sv.datagram, sound_num);
+       for (i = 0;i < 3;i++)
+               MSG_WriteCoord (&sv.datagram, origin[i], sv.protocol);
+       SV_FlushBroadcastMessages();
+}
+
+/*
 ==============================================================================
 
 CLIENT SPAWNING
index b0cfa77..0c7e390 100644 (file)
@@ -105,6 +105,7 @@ char *vm_sv_extensions =
 "DP_SV_PING "
 "DP_SV_PLAYERPHYSICS "
 "DP_SV_POINTPARTICLES "
+"DP_SV_POINTSOUND "
 "DP_SV_PRECACHEANYTIME "
 "DP_SV_PRINT "
 "DP_SV_PUNCHVECTOR "
@@ -476,6 +477,45 @@ static void VM_SV_sound (void)
 
 /*
 =================
+VM_SV_pointsound
+
+Follows the same logic as VM_SV_sound, except instead of
+an entity, an origin for the sound is provided, and channel
+is omitted (since no entity is being tracked).
+
+=================
+*/
+static void VM_SV_pointsound(void)
+{
+       const char      *sample;
+       int             volume;
+       float           attenuation;
+       vec3_t          org;
+
+       VM_SAFEPARMCOUNT(4, 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);
+
+       if (volume < 0 || volume > 255)
+       {
+               VM_Warning("SV_StartPointSound: volume must be in range 0-1\n");
+               return;
+       }
+
+       if (attenuation < 0 || attenuation > 4)
+       {
+               VM_Warning("SV_StartPointSound: attenuation must be in range 0-4\n");
+               return;
+       }
+
+       SV_StartPointSound (org, sample, volume, attenuation);
+}
+
+/*
+=================
 VM_SV_traceline
 
 Used for use tracing and shot targeting
@@ -3168,7 +3208,7 @@ VM_tokenizebyseparator,                   // #479 float(string s) tokenizebyseparator (DP_QC_TOK
 VM_strtolower,                                 // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
 VM_strtoupper,                                 // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
 VM_cvar_defstring,                             // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
-NULL,                                                  // #483
+VM_SV_pointsound,                              // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
 NULL,                                                  // #484
 NULL,                                                  // #485
 NULL,                                                  // #486