diff --git a/qw/include/net_svc.h b/qw/include/net_svc.h index 6cc730cc3..1046179d6 100644 --- a/qw/include/net_svc.h +++ b/qw/include/net_svc.h @@ -206,10 +206,18 @@ net_status_t NET_SVC_Damage_Parse (net_svc_damage_t *block, msg_t *msg); net_status_t NET_SVC_ServerData_Emit (net_svc_serverdata_t *block, sizebuf_t *buf); net_status_t NET_SVC_ServerData_Parse (net_svc_serverdata_t *block, msg_t *msg); +net_status_t NET_SVC_Sound_Emit (net_svc_sound_t *block, sizebuf_t *buf); net_status_t NET_SVC_Sound_Parse (net_svc_sound_t *block, msg_t *msg); +net_status_t NET_SVC_SpawnBaseline_Emit (net_svc_spawnbaseline_t *block, + sizebuf_t *buf); net_status_t NET_SVC_SpawnBaseline_Parse (net_svc_spawnbaseline_t *block, msg_t *msg); -net_status_t NET_SVC_SpawnStatic_Parse (net_svc_spawnstatic_t *block, msg_t *msg); +net_status_t NET_SVC_SpawnStatic_Emit (net_svc_spawnstatic_t *block, + sizebuf_t *buf); +net_status_t NET_SVC_SpawnStatic_Parse (net_svc_spawnstatic_t *block, + msg_t *msg); +net_status_t NET_SVC_TempEntity_Emit (net_svc_tempentity_t *block, + sizebuf_t *buf); net_status_t NET_SVC_TempEntity_Parse (net_svc_tempentity_t *block, msg_t *msg); net_status_t NET_SVC_SpawnStaticSound_Parse (net_svc_spawnstaticsound_t *block, msg_t *msg); diff --git a/qw/include/server.h b/qw/include/server.h index be8aaf737..b1f7fac5e 100644 --- a/qw/include/server.h +++ b/qw/include/server.h @@ -498,8 +498,8 @@ void SV_Printf (const char *fmt, ...) __attribute__((format(printf,1,2))); void SV_SendClientMessages (void); void SV_Multicast (vec3_t origin, int to); -void SV_StartSound (struct edict_s *entity, int channel, const char *sample, int volume, - float attenuation); +void SV_StartSound (struct edict_s *entity, int channel, const char *sample, + float volume, float attenuation); void SV_ClientPrintf (client_t *cl, int level, const char *fmt, ...) __attribute__((format(printf,3,4))); void SV_BroadcastPrintf (int level, const char *fmt, ...) __attribute__((format(printf,2,3))); void SV_BroadcastCommand (const char *fmt, ...) __attribute__((format(printf,1,2))); diff --git a/qw/source/net_svc.c b/qw/source/net_svc.c index f120ba733..9469e9aba 100644 --- a/qw/source/net_svc.c +++ b/qw/source/net_svc.c @@ -146,6 +146,30 @@ NET_SVC_ServerData_Parse (net_svc_serverdata_t *block, msg_t *msg) return msg->badread; } +net_status_t +NET_SVC_Sound_Emit (net_svc_sound_t *block, sizebuf_t *buf) +{ + int i, header; + + header = block->channel; + header |= block->entity << 3; + if (block->volume != DEFAULT_SOUND_PACKET_VOLUME) + header |= SND_VOLUME; + if (block->attenuation != DEFAULT_SOUND_PACKET_VOLUME) + header |= SND_ATTENUATION; + + MSG_WriteShort (buf, header); + if (header & SND_VOLUME) + MSG_WriteByte (buf, block->volume * 255); + if (header & SND_ATTENUATION) + MSG_WriteByte (buf, block->attenuation * 64); + MSG_WriteByte (buf, block->sound_num); + for (i = 0; i < 3; i++) + MSG_WriteCoord (buf, block->position[i]); + + return buf->overflowed; +} + net_status_t NET_SVC_Sound_Parse (net_svc_sound_t *block, msg_t *msg) { @@ -173,6 +197,25 @@ NET_SVC_Sound_Parse (net_svc_sound_t *block, msg_t *msg) return msg->badread; } +net_status_t +NET_SVC_SpawnBaseline_Emit (net_svc_spawnbaseline_t *block, sizebuf_t *buf) +{ + int i; + + MSG_WriteShort (buf, block->num); + MSG_WriteByte (buf, block->modelindex); + MSG_WriteByte (buf, block->frame); + MSG_WriteByte (buf, block->colormap); + MSG_WriteByte (buf, block->skinnum); + + for (i = 0; i < 3; i++) { + MSG_WriteCoord (buf, block->origin[i]); + MSG_WriteAngle (buf, block->angles[i]); + } + + return buf->overflowed; +} + net_status_t NET_SVC_SpawnBaseline_Parse (net_svc_spawnbaseline_t *block, msg_t *msg) { @@ -193,6 +236,23 @@ NET_SVC_SpawnBaseline_Parse (net_svc_spawnbaseline_t *block, msg_t *msg) return msg->badread; } +net_status_t +NET_SVC_SpawnStatic_Emit (net_svc_spawnstatic_t *block, sizebuf_t *buf) +{ + int i; + + MSG_WriteByte (buf, block->modelindex); + MSG_WriteByte (buf, block->frame); + MSG_WriteByte (buf, block->colormap); + MSG_WriteByte (buf, block->skinnum); + for (i = 0; i < 3; i++) { + MSG_WriteCoord (buf, block->origin[i]); + MSG_WriteAngle (buf, block->angles[i]); + } + + return buf->overflowed; +} + net_status_t NET_SVC_SpawnStatic_Parse (net_svc_spawnstatic_t *block, msg_t *msg) { @@ -204,7 +264,7 @@ NET_SVC_SpawnStatic_Parse (net_svc_spawnstatic_t *block, msg_t *msg) block->skinnum = MSG_ReadByte (msg); // these are interlaced? bad drugs... - for (i = 0; i < 3; i ++) { + for (i = 0; i < 3; i++) { block->origin[i] = MSG_ReadCoord (msg); block->angles[i] = MSG_ReadAngle (msg); } @@ -212,6 +272,54 @@ NET_SVC_SpawnStatic_Parse (net_svc_spawnstatic_t *block, msg_t *msg) return msg->badread; } +net_status_t +NET_SVC_TempEntity_Emit (net_svc_tempentity_t *block, sizebuf_t *buf) +{ + int i; + + MSG_WriteByte (buf, block->type); + switch (block->type) { + case TE_WIZSPIKE: + case TE_KNIGHTSPIKE: + case TE_SPIKE: + case TE_SUPERSPIKE: + case TE_EXPLOSION: + case TE_TAREXPLOSION: + case TE_LAVASPLASH: + case TE_TELEPORT: + case TE_LIGHTNINGBLOOD: + for (i = 0; i < 3; i++) + MSG_WriteCoord (buf, block->position[i]); + break; + case TE_LIGHTNING1: + case TE_LIGHTNING2: + case TE_LIGHTNING3: + case TE_BEAM: + MSG_WriteShort (buf, block->beamentity); + for (i = 0; i < 3; i++) + MSG_WriteShort (buf, block->position[i]); + for (i = 0; i < 3; i++) + MSG_WriteCoord (buf, block->beamend[i]); + break; + case TE_EXPLOSION2: + for (i = 0; i < 3; i++) + MSG_WriteCoord (buf, block->position[i]); + MSG_WriteByte (buf, block->colorstart); + MSG_WriteByte (buf, block->colorlength); + break; + case TE_GUNSHOT: + case TE_BLOOD: + MSG_WriteByte (buf, block->gunshotcount); + for (i = 0; i < 3; i++) + MSG_WriteCoord (buf, block->position[i]); + break; + default: + return NET_ERROR; + } + + return buf->overflowed; +} + net_status_t NET_SVC_TempEntity_Parse (net_svc_tempentity_t *block, msg_t *msg) { @@ -253,6 +361,8 @@ NET_SVC_TempEntity_Parse (net_svc_tempentity_t *block, msg_t *msg) for (i = 0; i < 3; i++) block->position[i] = MSG_ReadCoord (msg); break; + default: + return NET_ERROR; } return msg->badread; diff --git a/qw/source/sv_init.c b/qw/source/sv_init.c index 3d7a11d5a..0d137158a 100644 --- a/qw/source/sv_init.c +++ b/qw/source/sv_init.c @@ -45,6 +45,7 @@ static const char rcsid[] = #include "compat.h" #include "crudefile.h" +#include "net_svc.h" #include "server.h" #include "sv_progs.h" #include "world.h" @@ -103,8 +104,9 @@ SV_FlushSignon (void) void SV_CreateBaseline (void) { - int i, entnum; + int entnum; edict_t *svent; + net_svc_spawnbaseline_t block; for (entnum = 0; entnum < sv.num_edicts; entnum++) { svent = EDICT_NUM (&sv_pr_state, entnum); @@ -142,19 +144,15 @@ SV_CreateBaseline (void) SV_FlushSignon (); // add to the message + block.num = entnum; + block.modelindex = ((entity_state_t*)svent->data)->modelindex; + block.frame = ((entity_state_t*)svent->data)->frame; + block.colormap = ((entity_state_t*)svent->data)->colormap; + block.skinnum = ((entity_state_t*)svent->data)->skinnum; + VectorCopy (((entity_state_t*)svent->data)->origin, block.origin); + VectorCopy (((entity_state_t*)svent->data)->angles, block.angles); MSG_WriteByte (&sv.signon, svc_spawnbaseline); - MSG_WriteShort (&sv.signon, entnum); - - MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->modelindex); - MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->frame); - MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->colormap); - MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->skinnum); - for (i = 0; i < 3; i++) { - MSG_WriteCoord (&sv.signon, - ((entity_state_t*)svent->data)->origin[i]); - MSG_WriteAngle (&sv.signon, - ((entity_state_t*)svent->data)->angles[i]); - } + NET_SVC_SpawnBaseline_Emit (&block, &sv.signon); } } diff --git a/qw/source/sv_phys.c b/qw/source/sv_phys.c index b39597af2..65da83a40 100644 --- a/qw/source/sv_phys.c +++ b/qw/source/sv_phys.c @@ -607,14 +607,14 @@ SV_CheckWaterTransition (edict_t *ent) if (cont <= CONTENTS_WATER) { if (SVfloat (ent, watertype) == CONTENTS_EMPTY) { // just crossed into water - SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); + SV_StartSound (ent, 0, "misc/h2ohit1.wav", 1, 1); } SVfloat (ent, watertype) = cont; SVfloat (ent, waterlevel) = 1; } else { if (SVfloat (ent, watertype) != CONTENTS_EMPTY) { // just crossed into water - SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); + SV_StartSound (ent, 0, "misc/h2ohit1.wav", 1, 1); } SVfloat (ent, watertype) = CONTENTS_EMPTY; SVfloat (ent, waterlevel) = cont; @@ -717,7 +717,7 @@ SV_Physics_Step (edict_t *ent) if ((int) SVfloat (ent, flags) & FL_ONGROUND) // just hit ground { if (hitsound) - SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1); + SV_StartSound (ent, 0, "demon/dland2.wav", 1, 1); } } // regular thinking diff --git a/qw/source/sv_pr_cmds.c b/qw/source/sv_pr_cmds.c index e9ac1a47c..883d96b77 100644 --- a/qw/source/sv_pr_cmds.c +++ b/qw/source/sv_pr_cmds.c @@ -45,6 +45,7 @@ static const char rcsid[] = #include "compat.h" #include "crudefile.h" +#include "net_svc.h" #include "server.h" #include "sv_pr_cmds.h" #include "sv_progs.h" @@ -327,13 +328,13 @@ PF_sound (progs_t *pr) { const char *sample; edict_t *entity; - float attenuation; - int channel, volume; + float volume, attenuation; + int channel; entity = G_EDICT (pr, OFS_PARM0); channel = G_FLOAT (pr, OFS_PARM1); sample = G_STRING (pr, OFS_PARM2); - volume = G_FLOAT (pr, OFS_PARM3) * 255; + volume = G_FLOAT (pr, OFS_PARM3); attenuation = G_FLOAT (pr, OFS_PARM4); SV_StartSound (entity, channel, sample, volume, attenuation); @@ -1142,25 +1143,21 @@ int SV_ModelIndex (const char *name); void PF_makestatic (progs_t *pr) { - const char *model; edict_t *ent; - int i; + net_svc_spawnstatic_t block; ent = G_EDICT (pr, OFS_PARM0); - MSG_WriteByte (&sv.signon, svc_spawnstatic); - - model = PR_GetString (pr, SVstring (ent, model)); // SV_Printf ("Model: %d %s\n", SVstring (ent, model), model); - MSG_WriteByte (&sv.signon, SV_ModelIndex (model)); + block.modelindex = SV_ModelIndex (PR_GetString (pr, SVstring (ent, model))); + block.frame = SVfloat (ent, frame); + block.colormap = SVfloat (ent, colormap); + block.skinnum = SVfloat (ent, skin); + VectorCopy (SVvector (ent, origin), block.origin); + VectorCopy (SVvector (ent, angles), block.angles); - MSG_WriteByte (&sv.signon, SVfloat (ent, frame)); - MSG_WriteByte (&sv.signon, SVfloat (ent, colormap)); - MSG_WriteByte (&sv.signon, SVfloat (ent, skin)); - for (i = 0; i < 3; i++) { - MSG_WriteCoord (&sv.signon, SVvector (ent, origin)[i]); - MSG_WriteAngle (&sv.signon, SVvector (ent, angles)[i]); - } + MSG_WriteByte (&sv.signon, svc_spawnstatic); + NET_SVC_SpawnStatic_Emit (&block, &sv.signon); // throw the entity away now ED_Free (pr, ent); diff --git a/qw/source/sv_send.c b/qw/source/sv_send.c index efa4a9353..05242ead8 100644 --- a/qw/source/sv_send.c +++ b/qw/source/sv_send.c @@ -429,16 +429,16 @@ SV_Multicast (vec3_t origin, int to) Larger attenuations will drop off. (max 4 attenuation) */ void -SV_StartSound (edict_t *entity, int channel, const char *sample, int volume, - float attenuation) +SV_StartSound (edict_t *entity, int channel, const char *sample, + float volume, float attenuation) { - int ent, field_mask, sound_num, i; + int i, sound_num; qboolean use_phs; qboolean reliable = false; - vec3_t origin; + net_svc_sound_t block; - if (volume < 0 || volume > 255) - SV_Error ("SV_StartSound: volume = %i", volume); + if (volume < 0 || volume > 1) + SV_Error ("SV_StartSound: volume = %f", volume); if (attenuation < 0 || attenuation > 4) SV_Error ("SV_StartSound: attenuation = %f", attenuation); @@ -457,7 +457,9 @@ SV_StartSound (edict_t *entity, int channel, const char *sample, int volume, return; } - ent = NUM_FOR_EDICT (&sv_pr_state, entity); + block.sound_num = sound_num; + + block.entity = NUM_FOR_EDICT (&sv_pr_state, entity); if ((channel & 8) || !sv_phs->int_val) // no PHS flag { @@ -472,37 +474,34 @@ SV_StartSound (edict_t *entity, int channel, const char *sample, int volume, // if (channel == CHAN_BODY || channel == CHAN_VOICE) // reliable = true; - channel = (ent << 3) | channel; + block.channel = channel; - field_mask = 0; - if (volume != DEFAULT_SOUND_PACKET_VOLUME) - channel |= SND_VOLUME; - if (attenuation != DEFAULT_SOUND_PACKET_ATTENUATION) - channel |= SND_ATTENUATION; + block.volume = volume; + // 4 * 64 == 256, which overflows a byte. 4 is the stated max for + // it, and I don't want to break any progs, so I just nudge it + // down instead + if (attenuation == 4) + attenuation = 3.999; + block.attenuation = attenuation; // use the entity origin unless it is a bmodel if (SVfloat (entity, solid) == SOLID_BSP) { for (i = 0; i < 3; i++) - origin[i] = SVvector (entity, origin)[i] + 0.5 * + block.position[i] = SVvector (entity, origin)[i] + 0.5 * (SVvector (entity, mins)[i] + SVvector (entity, maxs)[i]); } else { - VectorCopy (SVvector (entity, origin), origin); + VectorCopy (SVvector (entity, origin), block.position); } MSG_WriteByte (&sv.multicast, svc_sound); - MSG_WriteShort (&sv.multicast, channel); - if (channel & SND_VOLUME) - MSG_WriteByte (&sv.multicast, volume); - if (channel & SND_ATTENUATION) - MSG_WriteByte (&sv.multicast, attenuation * 64); - MSG_WriteByte (&sv.multicast, sound_num); - for (i = 0; i < 3; i++) - MSG_WriteCoord (&sv.multicast, origin[i]); + NET_SVC_Sound_Emit (&block, &sv.multicast); if (use_phs) - SV_Multicast (origin, reliable ? MULTICAST_PHS_R : MULTICAST_PHS); + SV_Multicast (block.position, + reliable ? MULTICAST_PHS_R : MULTICAST_PHS); else - SV_Multicast (origin, reliable ? MULTICAST_ALL_R : MULTICAST_ALL); + SV_Multicast (block.position, + reliable ? MULTICAST_ALL_R : MULTICAST_ALL); } /* FRAME UPDATES */