From: dresk Date: Sun, 26 Aug 2007 19:02:29 +0000 (+0000) Subject: Added pointsound QC function to CL and SV VMs (extension DP_SV_POINTSOUND, #483)... X-Git-Tag: xonotic-v0.1.0preview~2937 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=4ed0394dfb5ec223db2b82a53db57acc442c7fde;p=xonotic%2Fdarkplaces.git Added pointsound QC function to CL and SV VMs (extension DP_SV_POINTSOUND, #483). This function is very similar to sound, though instead of providing an entity, an origin is provided, and the channel parameter is omitted (since no entity is being tracked). 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 --- diff --git a/clvm_cmds.c b/clvm_cmds.c index 9e8cbb43..27ba2521 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -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 diff --git a/server.h b/server.h index 11af4fcc..d7df3880 100644 --- 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); diff --git a/sv_main.c b/sv_main.c index 19f35f72..17dbf2c3 100644 --- a/sv_main.c +++ b/sv_main.c @@ -595,6 +595,69 @@ void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int v SV_FlushBroadcastMessages(); } +/* +================== +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(); +} + /* ============================================================================== diff --git a/svvm_cmds.c b/svvm_cmds.c index b0cfa775..0c7e3907 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -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 " @@ -474,6 +475,45 @@ static void VM_SV_sound (void) SV_StartSound (entity, channel, sample, volume, attenuation); } +/* +================= +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 @@ -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