summaryrefslogtreecommitdiff
path: root/source/mvd_parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/mvd_parse.c')
-rw-r--r--source/mvd_parse.c79
1 files changed, 77 insertions, 2 deletions
diff --git a/source/mvd_parse.c b/source/mvd_parse.c
index 7637ce4..ae06936 100644
--- a/source/mvd_parse.c
+++ b/source/mvd_parse.c
@@ -460,10 +460,21 @@ are able to postition sounds on BSP models properly.
static void MVD_ParseSound( mvd_t *mvd, int extrabits ) {
int flags, index;
int volume, attenuation, offset, sendchan;
+ int entnum;
+ vec3_t origin;
+ udpClient_t *client;
+ client_t *cl;
+ byte *mask;
+ cleaf_t *leaf;
+ int area, cluster;
+ player_state_t *ps;
+ sound_packet_t *msg;
+ edict_t *entity;
flags = MSG_ReadByte();
index = MSG_ReadByte();
+ volume = attenuation = offset = 0;
if( flags & SND_VOLUME )
volume = MSG_ReadByte();
if( flags & SND_ATTENUATION )
@@ -472,7 +483,65 @@ static void MVD_ParseSound( mvd_t *mvd, int extrabits ) {
offset = MSG_ReadByte();
// entity relative
- sendchan = MSG_ReadShort();
+ sendchan = MSG_ReadShort();
+ entnum = sendchan >> 3;
+ if( entnum < 0 || entnum >= MAX_EDICTS ) {
+ MVD_Destroy( mvd, "%s: bad entnum: %d", __func__, entnum );
+ }
+
+ entity = &mvd->edicts[entnum];
+
+ LIST_FOR_EACH( udpClient_t, client, &mvd->udpClients, entry ) {
+ cl = client->cl;
+
+ // do not send unreliables to connecting clients
+ if( cl->state != cs_spawned || cl->download || cl->nodata ) {
+ continue;
+ }
+
+ // PHS cull this sound
+ if( extrabits & 1 ) {
+ // get client viewpos
+ ps = &client->ps;
+ VectorMA( ps->viewoffset, 0.125f, ps->pmove.origin, origin );
+ leaf = CM_PointLeaf( &mvd->cm, origin );
+ area = CM_LeafArea( leaf );
+ if( !CM_AreasConnected( &mvd->cm, area, entity->areanum ) ) {
+ // doors can legally straddle two areas, so
+ // we may need to check another one
+ if( !entity->areanum2 || !CM_AreasConnected( &mvd->cm, area, entity->areanum2 ) ) {
+ continue; // blocked by a door
+ }
+ }
+ cluster = CM_LeafCluster( leaf );
+ mask = CM_ClusterPHS( &mvd->cm, cluster );
+ if( !SV_EdictPV( &mvd->cm, entity, mask ) ) {
+ continue; // not in PHS
+ }
+ }
+
+ // reliable sounds will always have position explicitly set
+ if( extrabits & 2 ) {
+ continue; // TODO
+ }
+
+ if( LIST_EMPTY( &cl->freemsg ) ) {
+ Com_WPrintf( "Out of message slots for %s!\n", cl->name );
+ continue;
+ }
+
+ msg = LIST_FIRST( sound_packet_t, &cl->freemsg, entry );
+
+ msg->flags = flags;
+ msg->index = index;
+ msg->volume = volume;
+ msg->attenuation = attenuation;
+ msg->timeofs = offset;
+ msg->sendchan = sendchan;
+
+ List_Remove( &msg->entry );
+ List_Append( &cl->soundmsg, &msg->entry );
+ }
//PF_StartSound( ent, channel, index, volume, attenuation, offset );
}
@@ -665,6 +734,7 @@ MVD_ParseFrame
*/
static void MVD_ParseFrame( mvd_t *mvd ) {
int length;
+ int i;
// read portalbits
length = MSG_ReadByte();
@@ -692,6 +762,11 @@ static void MVD_ParseFrame( mvd_t *mvd ) {
Com_Printf( "%3i:packetentities\n", msg_read.readcount - 1 );
}
+ // reset events
+ for( i = 0; i < mvd->pool.num_edicts; i++ ) {
+ mvd->edicts[i].s.event = 0;
+ }
+
MVD_ParsePacketEntities( mvd );
if( mvd_shownet->integer > 1 ) {
@@ -769,7 +844,7 @@ static void MVD_ParseServerData( mvd_t *mvd ) {
}
if( !mvd->players ) {
- mvd->players = MVD_Malloc( sizeof( mvd_player_t ) * index );
+ mvd->players = MVD_Mallocz( sizeof( mvd_player_t ) * index );
mvd->maxclients = index;
} else if( index != mvd->maxclients ) {
MVD_Destroy( mvd, "Unexpected maxclients change" );