Handle sound flags, providing reliable+unicast flags. Also handle other sound flags+networking that only fte clients will benefit from right now.

This commit is contained in:
Shpoike 2021-07-06 00:25:06 +01:00
parent 3fae242613
commit 7bdf911d3a
9 changed files with 179 additions and 38 deletions

View file

@ -1157,9 +1157,9 @@ static void CL_ParseStartSoundPacket(void)
if (cl.protocol == PROTOCOL_VERSION_BJP3)
field_mask |= SND_LARGESOUND;
//spike -- extra channel flags
//spike -- extra flags
if (field_mask & SND_FTE_MOREFLAGS)
field_mask |= MSG_ReadByte()<<8;
field_mask |= MSG_ReadUInt64()<<8;
if (field_mask & SND_VOLUME)
volume = MSG_ReadByte ();

View file

@ -929,6 +929,29 @@ void MSG_WriteLong (sizebuf_t *sb, int c)
buf[3] = c>>24;
}
void MSG_WriteUInt64 (sizebuf_t *sb, unsigned long long c)
{ //0* 10*,*, 110*,*,* etc, up to 0xff followed by 8 continuation bytes
byte *buf;
int b = 0;
unsigned long long l = 128;
while (c > l-1u)
{ //count the extra bytes we need
b++;
l <<= 7; //each byte we add gains 8 bits, but we spend one on length.
}
buf = (byte*)SZ_GetSpace (sb, 1+b);
*buf++ = 0xffu<<(8-b) | (c >> (b*8));
while(b --> 0)
*buf++ = (c >> (b*8))&0xff;
}
void MSG_WriteInt64 (sizebuf_t *sb, long long c)
{ //move the sign bit into the low bit and avoid sign extension for more efficient length coding.
if (c < 0)
MSG_WriteUInt64(sb, ((unsigned long long)(-1-c)<<1)|1);
else
MSG_WriteUInt64(sb, c<<1);
}
void MSG_WriteFloat (sizebuf_t *sb, float f)
{
union
@ -1099,6 +1122,30 @@ int MSG_ReadLong (void)
return c;
}
unsigned long long MSG_ReadUInt64 (void)
{ //0* 10*,*, 110*,*,* etc, up to 0xff followed by 8 continuation bytes
byte l=0x80, v, b = 0;
unsigned long long r;
v = MSG_ReadByte();
for (; v&l; l>>=1)
{
v-=l;
b++;
}
r = v<<(b*8);
while(b --> 0)
r |= MSG_ReadByte()<<(b*8);
return r;
}
long long MSG_ReadInt64 (void)
{ //we do some fancy bit recoding for more efficient length coding.
unsigned long long c = MSG_ReadUInt64();
if (c&1)
return -1-(long long)(c>>1);
else
return (long long)(c>>1);
}
float MSG_ReadFloat (void)
{
union

View file

@ -100,6 +100,8 @@ void MSG_WriteChar (sizebuf_t *sb, int c);
void MSG_WriteByte (sizebuf_t *sb, int c);
void MSG_WriteShort (sizebuf_t *sb, int c);
void MSG_WriteLong (sizebuf_t *sb, int c);
void MSG_WriteUInt64 (sizebuf_t *sb, unsigned long long c);
void MSG_WriteInt64 (sizebuf_t *sb, long long c);
void MSG_WriteFloat (sizebuf_t *sb, float f);
void MSG_WriteStringUnterminated (sizebuf_t *sb, const char *s);
void MSG_WriteString (sizebuf_t *sb, const char *s);
@ -118,6 +120,8 @@ int MSG_ReadChar (void);
int MSG_ReadByte (void);
int MSG_ReadShort (void);
int MSG_ReadLong (void);
unsigned long long MSG_ReadUInt64 (void);
long long MSG_ReadInt64 (void);
float MSG_ReadFloat (void);
const char *MSG_ReadString (void);

View file

@ -241,8 +241,9 @@ qpic_t *Draw_PicFromWad2 (const char *name, unsigned int texflags)
Con_SafePrintf ("W_GetLumpName: %s not found\n", name);
return pic_nul; //johnfitz
}
if (info->type != TYP_QPIC) Sys_Error ("Draw_PicFromWad: lump \"%s\" is not a qpic", name);
if (info->size < sizeof(int)*2 || 8+p->width*p->height < info->size) Sys_Error ("Draw_PicFromWad: pic \"%s\" truncated", name);
if (info->type != TYP_QPIC) {Con_SafePrintf ("Draw_PicFromWad: lump \"%s\" is not a qpic\n", name); return pic_nul;}
if (info->size < sizeof(int)*2) {Con_SafePrintf ("Draw_PicFromWad: pic \"%s\" is too small for its qpic header (%u bytes)\n", name, info->size); return pic_nul;}
if (8+p->width*p->height < info->size) Sys_Error ("Draw_PicFromWad: pic \"%s\" truncated (%u*%u requires %u bytes)\n", name, p->width,p->height, 8+p->width*p->height);
//Spike -- if we're loading external images, and one exists, then use that instead.
if (draw_load24bit && (gl.gltexture=TexMgr_LoadImage (NULL, name, 0, 0, SRC_EXTERNAL, NULL, va("gfx/%s", name), 0, texflags|TEXPREF_MIPMAP|TEXPREF_ALLOWMISSING)))

View file

@ -654,6 +654,9 @@ static void PF_sound (void)
edict_t *entity;
int volume;
float attenuation;
float ratepct;
unsigned int flags;
float offset;
entity = G_EDICT(OFS_PARM0);
channel = G_FLOAT(OFS_PARM1);
@ -661,12 +664,23 @@ static void PF_sound (void)
volume = G_FLOAT(OFS_PARM3) * 255;
attenuation = G_FLOAT(OFS_PARM4);
ratepct = (qcvm->argc<6)?100:G_FLOAT(OFS_PARM5);
flags = (qcvm->argc<7)?0:G_FLOAT(OFS_PARM6);
offset = (qcvm->argc<8)?0:G_FLOAT(OFS_PARM7);
if (!*sample)
{
PR_RunWarning("PF_sound: empty string\n");
return;
}
if (ratepct && ratepct != 100)
Con_DPrintf("sound() rate scaling is not supported\n");
if (flags)
Con_DPrintf("sound() flags %#x not supported\n", flags);
if (offset)
Con_DPrintf("sound() time offsets are not supported\n");
/* Spike -- these checks are redundant
if (volume < 0 || volume > 255)
Host_Error ("SV_StartSound: volume = %i", volume);

View file

@ -2088,6 +2088,16 @@ static void PF_getsurfaceclippedpoint(void)
getsurface_clippointpoly(model, surf, point, result, 0x7fffffff);
}
enum
{
SPA_POSITION = 0,
SPA_S_AXIS = 1,
SPA_T_AXIS = 2,
SPA_R_AXIS = 3, //normal
SPA_TEXCOORDS0 = 4,
SPA_LIGHTMAP0_TEXCOORDS = 5,
SPA_LIGHTMAP0_COLOR = 6,
};
static void PF_getsurfacepointattribute(void)
{
edict_t *ed = G_EDICT(OFS_PARM0);
@ -2109,11 +2119,11 @@ static void PF_getsurfacepointattribute(void)
G_FLOAT(OFS_RETURN+1) = 0;
G_FLOAT(OFS_RETURN+2) = 0;
break;
case 0: //xyz coord
case SPA_POSITION:
VectorCopy(v->position, G_VECTOR(OFS_RETURN));
break;
case 1: //s dir
case 2: //t dir
case SPA_S_AXIS:
case SPA_T_AXIS:
{
//figure out how similar to the normal it is, and negate any influence, so that its perpendicular
float sc = -DotProduct(fa->plane->normal, fa->texinfo->vecs[attribute-1]);
@ -2121,22 +2131,22 @@ static void PF_getsurfacepointattribute(void)
VectorNormalize(G_VECTOR(OFS_RETURN));
}
break;
case 3: //normal
case SPA_R_AXIS: //normal
VectorCopy(fa->plane->normal, G_VECTOR(OFS_RETURN));
if (fa->flags & SURF_PLANEBACK)
VectorInverse(G_VECTOR(OFS_RETURN));
break;
case 4: //st coord
case SPA_TEXCOORDS0:
G_FLOAT(OFS_RETURN+0) = (DotProduct(v->position, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3]) / fa->texinfo->texture->width;
G_FLOAT(OFS_RETURN+1) = (DotProduct(v->position, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3]) / fa->texinfo->texture->height;
G_FLOAT(OFS_RETURN+2) = 0;
break;
case 5: //lmst coord, not actually very useful
case SPA_LIGHTMAP0_TEXCOORDS: //lmst coord, not actually very useful
G_FLOAT(OFS_RETURN+0) = (DotProduct(v->position, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3] - fa->texturemins[0] + (fa->light_s+.5)*(1<<fa->lmshift)) / (LMBLOCK_WIDTH*(1<<fa->lmshift));
G_FLOAT(OFS_RETURN+1) = (DotProduct(v->position, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3] - fa->texturemins[1] + (fa->light_t+.5)*(1<<fa->lmshift)) / (LMBLOCK_HEIGHT*(1<<fa->lmshift));
G_FLOAT(OFS_RETURN+2) = 0;
break;
case 6: //colour
case SPA_LIGHTMAP0_COLOR: //colour
G_FLOAT(OFS_RETURN+0) = 1;
G_FLOAT(OFS_RETURN+1) = 1;
G_FLOAT(OFS_RETURN+2) = 1;
@ -8256,6 +8266,14 @@ void PR_DumpPlatform_f(void)
fprintf(f, "const float CHAN_VOICE = %i;\n", 2);
fprintf(f, "const float CHAN_ITEM = %i;\n", 3);
fprintf(f, "const float CHAN_BODY = %i;\n", 4);
fprintf(f, "const float SPA_POSITION = %i;\n", SPA_POSITION);
fprintf(f, "const float SPA_S_AXIS = %i;\n", SPA_S_AXIS);
fprintf(f, "const float SPA_T_AXIS = %i;\n", SPA_T_AXIS);
fprintf(f, "const float SPA_R_AXIS = %i;\n", SPA_R_AXIS);
fprintf(f, "const float SPA_TEXCOORDS0 = %i;\n", SPA_TEXCOORDS0);
fprintf(f, "const float SPA_LIGHTMAP0_TEXCOORDS = %i;\n", SPA_LIGHTMAP0_TEXCOORDS);
fprintf(f, "const float SPA_LIGHTMAP0_COLOR = %i;\n", SPA_LIGHTMAP0_COLOR);
}
if (targs & (CS|MN))

View file

@ -205,24 +205,36 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define DPSU_VIEWZOOM (1<<19) // byte factor (0 = 0.0 (not valid), 255 = 1.0)
//spike
#define DEFAULT_SOUND_PACKET_VOLUME 255
#define DEFAULT_SOUND_PACKET_ATTENUATION 1.0
// a sound with no channel is a local only sound
#define SND_VOLUME (1<<0) // a byte
#define SND_ATTENUATION (1<<1) // a byte
//#define SND_LOOPING (1<<2) // a long (unused in vanilla)
#define DEFAULT_SOUND_PACKET_VOLUME 255
#define DEFAULT_SOUND_PACKET_ATTENUATION 1.0
//spike -- parsing, but not using at this time
#define SND_FTE_MOREFLAGS (1<<2) // a byte, for channel flags
//johnfitz -- PROTOCOL_FITZQUAKE -- new bits
#define SND_LARGEENTITY (1<<3) // a short + byte (instead of just a short)
#define SND_LARGESOUND (1<<4) // a short soundindex (instead of a byte)
//johnfitz
//spike -- parsing, but not using at this time
#define SND_FTE_MOREFLAGS (1<<2) // a byte, for channel flags
#define SND_DP_PITCH (1<<5) //dp uses this for pitch...
#define SND_FTE_TIMEOFS (1<<6) //signed short, in milliseconds.
#define SND_FTE_PITCHADJ (1<<7) //a byte (speed percent (0=100%))
#define SND_FTE_VELOCITY (1<<8) //3 shorts (1/8th), for doppler or whatever.
#define SND_FTE_FORCELOOP (1<<9) //flag
#define SND_FTE_NOSPACIALISE (1<<10)//flag
#define SND_FTE_NOREVERB (1<<13) //flat
#define SND_FTE_FOLLOW (1<<14) //flag only
#define SND_FTE_NOREPLACE (1<<15) //flag only
#define CF_RELIABLE (1<<0) //send over reliable channel
#define CF_FORCELOOP (1<<1) //force looping
#define CF_NOSPACIALISE (1<<2) //mono-ize. play on the local player to avoid distance fading.
#define CF_NOREVERB (1<<5) //disable reverb effects (for music, QS doesn't have reverb)
#define CF_FOLLOW (1<<6) //sound origin follows entity
#define CF_NOREPLACE (1<<7) //drop the sound if it would replace one.
#define CF_UNICAST (1<<8) //send only to msg_entity
#define CF_SENDVELOCITY (1<<9) //include the velocity, for doppler effects.
//spike
//johnfitz -- PROTOCOL_FITZQUAKE -- flags for entity baseline messages

View file

@ -308,8 +308,8 @@ extern edict_t *sv_player;
void SV_Init (void);
void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count);
void SV_StartSound (edict_t *entity, float *origin, int channel,
const char *sample, int volume, float attenuation);
void SV_StartSound (edict_t *entity, float *origin, int channel, const char *sample, int volume, float attenuation);
void SV_StartSound2 (edict_t *entity, float *origin, int channel, const char *sample, int volume, float attenuation, float speed, int flags, float timeoffset);
void SV_DropClient (qboolean crash);

View file

@ -1587,12 +1587,13 @@ Larger attenuations will drop off. (max 4 attenuation)
==================
*/
void SV_StartSound (edict_t *entity, float *origin, int channel, const char *sample, int volume, float attenuation)
void SV_StartSound2 (edict_t *entity, float *origin, int channel, const char *sample, int volume, float attenuation, float speed, int flags, float timeoffset)
{
unsigned int sound_num, ent;
int i, field_mask;
int i, field_mask, client_mask;
int p;
client_t *cl;
sizebuf_t *msg;
if (volume < 0)
Host_Error ("SV_StartSound: volume = %i", volume);
@ -1641,6 +1642,19 @@ void SV_StartSound (edict_t *entity, float *origin, int channel, const char *sam
field_mask |= SND_LARGESOUND;
//johnfitz
//spike
if (flags & CF_FORCELOOP) field_mask |= SND_FTE_FORCELOOP;
if (flags & CF_NOSPACIALISE) field_mask |= SND_FTE_NOSPACIALISE;
// if (flags & CF_PAUSED) field_mask |= SND_FTE_PAUSED;
// if (flags & CF_ABSVOLUME) field_mask |= SND_FTE_ABSVOLUME;
if (flags & CF_NOREVERB) field_mask |= SND_FTE_NOREVERB;
if (flags & CF_FOLLOW) field_mask |= SND_FTE_FOLLOW;
if (flags & CF_NOREPLACE) field_mask |= SND_FTE_NOREPLACE;
if (flags & CF_SENDVELOCITY) field_mask |= SND_FTE_VELOCITY;
if (speed && speed != 1) field_mask |= SND_FTE_PITCHADJ;
if (timeoffset) field_mask |= SND_FTE_TIMEOFS;
//
for (p = 0; p < svs.maxclients; p++)
{
cl = &svs.clients[p];
@ -1654,43 +1668,74 @@ void SV_StartSound (edict_t *entity, float *origin, int channel, const char *sam
if ((field_mask & (SND_LARGEENTITY|SND_LARGESOUND)) && (!cl->protocol_pext2 || sv.protocol == PROTOCOL_NETQUAKE))
continue;
if (flags & CF_UNICAST && cl->edict != PROG_TO_EDICT(pr_global_struct->msg_entity))
continue;
if (flags & CF_RELIABLE)
msg = &cl->message;
else
msg = &cl->datagram;
client_mask = field_mask;
if (!(cl->protocol_pext2&PEXT2_REPLACEMENTDELTAS))
client_mask &= (SND_VOLUME|SND_ATTENUATION|SND_LARGEENTITY|SND_LARGESOUND);
// directed messages go only to the entity the are targeted on
MSG_WriteByte (&cl->datagram, svc_sound);
MSG_WriteByte (&cl->datagram, field_mask);
if (field_mask & SND_VOLUME)
MSG_WriteByte (&cl->datagram, volume);
if (field_mask & SND_ATTENUATION)
MSG_WriteByte (&cl->datagram, attenuation*64);
MSG_WriteByte (msg, svc_sound);
MSG_WriteByte (msg, client_mask&0xff);
if (client_mask & SND_FTE_MOREFLAGS)
MSG_WriteUInt64 (msg, client_mask>>8);
if (client_mask & SND_VOLUME)
MSG_WriteByte (msg, volume);
if (client_mask & SND_ATTENUATION)
MSG_WriteByte (msg, attenuation*64);
//spike -- stuff
if (client_mask & SND_FTE_PITCHADJ)
MSG_WriteByte (msg, CLAMP(1, speed*100, 255));
if (client_mask & SND_FTE_TIMEOFS)
MSG_WriteShort (msg, CLAMP(-32768, timeoffset*1000, 32767));
if (client_mask & SND_FTE_VELOCITY)
{
MSG_WriteShort (msg, CLAMP(-32768, entity->v.velocity[0]*8, 32767));
MSG_WriteShort (msg, CLAMP(-32768, entity->v.velocity[1]*8, 32767));
MSG_WriteShort (msg, CLAMP(-32768, entity->v.velocity[2]*8, 32767));
}
if (client_mask & SND_DP_PITCH)
MSG_WriteShort (msg, CLAMP(-32768, speed*4000, 32767));
//end spike
//johnfitz -- PROTOCOL_FITZQUAKE
if (field_mask & SND_LARGEENTITY)
if (client_mask & SND_LARGEENTITY)
{
if ((cl->protocol_pext2 & PEXT2_REPLACEMENTDELTAS) && ent > 0x7fff)
{
MSG_WriteShort(&cl->datagram, (ent>>8) | 0x8000);
MSG_WriteByte(&cl->datagram, ent & 0xff);
MSG_WriteShort(msg, (ent>>8) | 0x8000);
MSG_WriteByte(msg, ent & 0xff);
}
else
MSG_WriteShort (&cl->datagram, ent);
MSG_WriteByte (&cl->datagram, channel);
MSG_WriteShort (msg, ent);
MSG_WriteByte (msg, channel);
}
else
MSG_WriteShort (&cl->datagram, (ent<<3) | channel);
if ((field_mask & SND_LARGESOUND) || sv.protocol == PROTOCOL_VERSION_BJP3)
MSG_WriteShort (&cl->datagram, sound_num);
MSG_WriteShort (msg, (ent<<3) | channel);
if ((client_mask & SND_LARGESOUND) || sv.protocol == PROTOCOL_VERSION_BJP3)
MSG_WriteShort (msg, sound_num);
else
MSG_WriteByte (&cl->datagram, sound_num);
MSG_WriteByte (msg, sound_num);
//johnfitz
for (i = 0; i < 3; i++)
{
if (origin)
MSG_WriteCoord (&cl->datagram, origin[i], sv.protocolflags);
MSG_WriteCoord (msg, origin[i], sv.protocolflags);
else
MSG_WriteCoord (&cl->datagram, entity->v.origin[i]+0.5*(entity->v.mins[i]+entity->v.maxs[i]), sv.protocolflags);
MSG_WriteCoord (msg, entity->v.origin[i]+0.5*(entity->v.mins[i]+entity->v.maxs[i]), sv.protocolflags);
}
}
}
void SV_StartSound (edict_t *entity, float *origin, int channel, const char *sample, int volume, float attenuation)
{
SV_StartSound2 (entity, origin, channel, sample, volume, attenuation, 100, 0, 0);
}
/*
==============================================================================