mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 22:51:57 +00:00
Voice activation detection for voicechat, with a few cvars for it.
Added mic level indicator. Able to record voice into mvds. Fixed mvd recording. Fixed mvd player sizes. Fixed interpolation. git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3665 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
4d145039d2
commit
540830d955
20 changed files with 488 additions and 234 deletions
|
@ -2330,7 +2330,7 @@ void CL_ParsePlayerinfo (void)
|
||||||
state->weaponframe = MSG_ReadByte ();
|
state->weaponframe = MSG_ReadByte ();
|
||||||
|
|
||||||
state->hullnum = 1;
|
state->hullnum = 1;
|
||||||
state->scale = 1*16;
|
state->scale = 1;
|
||||||
state->alpha = 255;
|
state->alpha = 255;
|
||||||
state->fatness = 0;
|
state->fatness = 0;
|
||||||
|
|
||||||
|
|
|
@ -1460,14 +1460,6 @@ void CL_SendCmd (double frametime, qboolean mainloop)
|
||||||
curtime = Sys_DoubleTime();
|
curtime = Sys_DoubleTime();
|
||||||
frametime = curtime - lasttime;
|
frametime = curtime - lasttime;
|
||||||
lasttime = curtime;
|
lasttime = curtime;
|
||||||
|
|
||||||
/* for (plnum = 0; plnum < cl.splitclients; plnum++)
|
|
||||||
{
|
|
||||||
CL_AdjustAngles(plnum, frametime);
|
|
||||||
IN_Move(mousemovements[plnum], plnum);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CL_ProxyMenuHooks();
|
CL_ProxyMenuHooks();
|
||||||
|
@ -1492,7 +1484,11 @@ void CL_SendCmd (double frametime, qboolean mainloop)
|
||||||
cmd = &cl.frames[i].cmd[0];
|
cmd = &cl.frames[i].cmd[0];
|
||||||
|
|
||||||
memset(cmd, 0, sizeof(*cmd));
|
memset(cmd, 0, sizeof(*cmd));
|
||||||
cmd->msec = frametime*1000;
|
msecs += frametime*1000;
|
||||||
|
if (msecs > 50)
|
||||||
|
msecs = 50;
|
||||||
|
cmd->msec = msecs;
|
||||||
|
msecs -= cmd->msec;
|
||||||
independantphysics[0].msec = 0;
|
independantphysics[0].msec = 0;
|
||||||
|
|
||||||
CL_AdjustAngles (plnum, frametime);
|
CL_AdjustAngles (plnum, frametime);
|
||||||
|
@ -1510,7 +1506,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
|
||||||
if (cl.spectator)
|
if (cl.spectator)
|
||||||
Cam_Track(plnum, cmd);
|
Cam_Track(plnum, cmd);
|
||||||
|
|
||||||
CL_FinishMove(cmd, (int)(frametime*1000), plnum);
|
CL_FinishMove(cmd, cmd->msec, plnum);
|
||||||
|
|
||||||
Cam_FinishMove(plnum, cmd);
|
Cam_FinishMove(plnum, cmd);
|
||||||
}
|
}
|
||||||
|
@ -1770,7 +1766,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
|
||||||
|
|
||||||
#ifdef PEXT2_VOICECHAT
|
#ifdef PEXT2_VOICECHAT
|
||||||
if (cls.fteprotocolextensions2 & PEXT2_VOICECHAT)
|
if (cls.fteprotocolextensions2 & PEXT2_VOICECHAT)
|
||||||
S_TransmitVoiceChat(clc_voicechat, &buf);
|
S_Voip_Transmit(clc_voicechat, &buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -4967,7 +4967,7 @@ void CL_ParseServerMessage (void)
|
||||||
|
|
||||||
#ifdef PEXT2_VOICECHAT
|
#ifdef PEXT2_VOICECHAT
|
||||||
case svcfte_voicechat:
|
case svcfte_voicechat:
|
||||||
S_ParseVoiceChat();
|
S_Voip_Parse();
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -823,7 +823,7 @@ void CL_PredictMovePNum (int pnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (((cl_nopred.value && cls.demoplayback!=DPB_MVD && cls.demoplayback != DPB_EZTV)|| cl.fixangle))
|
if (((cl_nopred.value && cls.demoplayback!=DPB_MVD && cls.demoplayback != DPB_EZTV)|| cl.fixangle[pnum]))
|
||||||
{
|
{
|
||||||
fixedorg:
|
fixedorg:
|
||||||
VectorCopy (vel, cl.simvel[pnum]);
|
VectorCopy (vel, cl.simvel[pnum]);
|
||||||
|
|
|
@ -2204,6 +2204,49 @@ qboolean Sbar_UpdateTeamStatus(player_info_t *player, char *status)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void Sbar_Voice(int y)
|
||||||
|
{
|
||||||
|
#ifdef VOICECHAT
|
||||||
|
char st[64];
|
||||||
|
int loudness;
|
||||||
|
if (!cl_voip_showmeter.ival)
|
||||||
|
return;
|
||||||
|
loudness = S_Voip_Loudness(cl_voip_showmeter.ival==2);
|
||||||
|
if (loudness >= 0)
|
||||||
|
{
|
||||||
|
int x=0,t;
|
||||||
|
int s, i;
|
||||||
|
float range = loudness/100.0f;
|
||||||
|
Font_BeginString(font_conchar, x, y, &t, &t);
|
||||||
|
x = vid.width;
|
||||||
|
x -= Font_CharWidth(0xe080 | CON_WHITEMASK);
|
||||||
|
x -= Font_CharWidth(0xe081 | CON_WHITEMASK)*16;
|
||||||
|
x -= Font_CharWidth(0xe082 | CON_WHITEMASK);
|
||||||
|
x /= 2;
|
||||||
|
x -= Font_CharWidth('M' | CON_WHITEMASK);
|
||||||
|
x -= Font_CharWidth('i' | CON_WHITEMASK);
|
||||||
|
x -= Font_CharWidth('c' | CON_WHITEMASK);
|
||||||
|
x -= Font_CharWidth(' ' | CON_WHITEMASK);
|
||||||
|
|
||||||
|
y = sbar_rect.y + y+ sbar_rect.height-SBAR_HEIGHT;
|
||||||
|
Font_BeginString(font_conchar, x, y, &x, &y);
|
||||||
|
x = Font_DrawChar(x, y, 'M' | CON_WHITEMASK);
|
||||||
|
x = Font_DrawChar(x, y, 'i' | CON_WHITEMASK);
|
||||||
|
x = Font_DrawChar(x, y, 'c' | CON_WHITEMASK);
|
||||||
|
x = Font_DrawChar(x, y, ' ' | CON_WHITEMASK);
|
||||||
|
x = Font_DrawChar(x, y, 0xe080 | CON_WHITEMASK);
|
||||||
|
s = x;
|
||||||
|
for (i=0 ; i<16 ; i++)
|
||||||
|
x = Font_DrawChar(x, y, 0xe081 | CON_WHITEMASK);
|
||||||
|
Font_DrawChar(x, y, 0xe082 | CON_WHITEMASK);
|
||||||
|
Font_DrawChar(s + (x-s) * range - Font_CharWidth(0xe083 | CON_WHITEMASK)/2, y, 0xe083 | CON_WHITEMASK);
|
||||||
|
Font_EndString(font_conchar);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============
|
===============
|
||||||
Sbar_Draw
|
Sbar_Draw
|
||||||
|
@ -2297,6 +2340,8 @@ void Sbar_Draw (void)
|
||||||
|
|
||||||
Sbar_DrawString (0, -8, va("Health: %i", cl.stats[pnum][STAT_HEALTH]));
|
Sbar_DrawString (0, -8, va("Health: %i", cl.stats[pnum][STAT_HEALTH]));
|
||||||
Sbar_DrawString (0, -16, va(" Armor: %i", cl.stats[pnum][STAT_ARMOR]));
|
Sbar_DrawString (0, -16, va(" Armor: %i", cl.stats[pnum][STAT_ARMOR]));
|
||||||
|
|
||||||
|
Sbar_Voice(-24);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2352,6 +2397,13 @@ void Sbar_Draw (void)
|
||||||
else
|
else
|
||||||
Sbar_DrawNormal (pnum);
|
Sbar_DrawNormal (pnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sb_lines > 24)
|
||||||
|
Sbar_Voice(-32);
|
||||||
|
else if (sb_lines > 0)
|
||||||
|
Sbar_Voice(-8);
|
||||||
|
else
|
||||||
|
Sbar_Voice(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GLQUAKE
|
#ifdef GLQUAKE
|
||||||
|
@ -2790,7 +2842,9 @@ if (showcolumns & (1<<COLUMN##title)) \
|
||||||
// Electro's scoreboard eyecandy: red vs blue are common teams, force the colours
|
// Electro's scoreboard eyecandy: red vs blue are common teams, force the colours
|
||||||
Q_strncpyz (team, Info_ValueForKey(s->userinfo, "team"), sizeof(team));
|
Q_strncpyz (team, Info_ValueForKey(s->userinfo, "team"), sizeof(team));
|
||||||
|
|
||||||
if (!(strcmp("red", team)))
|
if (S_Voip_Speaking(k))
|
||||||
|
background_color = 0x00ff00;
|
||||||
|
else if (!(strcmp("red", team)))
|
||||||
background_color = 4; // forced red
|
background_color = 4; // forced red
|
||||||
else if (!(strcmp("blue", team)))
|
else if (!(strcmp("blue", team)))
|
||||||
background_color = 13; // forced blue
|
background_color = 13; // forced blue
|
||||||
|
@ -2799,6 +2853,8 @@ if (showcolumns & (1<<COLUMN##title)) \
|
||||||
|
|
||||||
Sbar_FillPCDark (startx - 2, y, rank_width - 3, skip, background_color);
|
Sbar_FillPCDark (startx - 2, y, rank_width - 3, skip, background_color);
|
||||||
}
|
}
|
||||||
|
else if (S_Voip_Speaking(k))
|
||||||
|
Sbar_FillPCDark (startx - 2, y, rank_width - 3, skip, 0x00ff00);
|
||||||
else
|
else
|
||||||
Draw_Fill (startx - 2, y, rank_width - 3, skip, 2);
|
Draw_Fill (startx - 2, y, rank_width - 3, skip, 2);
|
||||||
|
|
||||||
|
|
|
@ -893,24 +893,26 @@ int (*pDSOUND_InitCard) (soundcardinfo_t *sc, int cardnum) = &DSOUND_InitCard;
|
||||||
#if defined(VOICECHAT) && defined(AVAIL_DSOUND) && !defined(__MINGW32__)
|
#if defined(VOICECHAT) && defined(AVAIL_DSOUND) && !defined(__MINGW32__)
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct
|
||||||
LPDIRECTSOUNDCAPTURE DSCapture;
|
|
||||||
LPDIRECTSOUNDCAPTUREBUFFER DSCaptureBuffer;
|
|
||||||
long lastreadpos;
|
|
||||||
long bufferbytes = 1024*1024;
|
|
||||||
|
|
||||||
long inputwidth = 2;
|
|
||||||
|
|
||||||
static WAVEFORMATEX wfxFormat;
|
|
||||||
|
|
||||||
qboolean SNDDMA_InitCapture (void)
|
|
||||||
{
|
{
|
||||||
DWORD capturePos;
|
LPDIRECTSOUNDCAPTURE DSCapture;
|
||||||
|
LPDIRECTSOUNDCAPTUREBUFFER DSCaptureBuffer;
|
||||||
|
long lastreadpos;
|
||||||
|
} dsndcapture_t;
|
||||||
|
const long bufferbytes = 1024*1024;
|
||||||
|
|
||||||
|
const long inputwidth = 2;
|
||||||
|
|
||||||
|
void *DSOUND_Capture_Init (int rate)
|
||||||
|
{
|
||||||
|
dsndcapture_t *result;
|
||||||
DSCBUFFERDESC bufdesc;
|
DSCBUFFERDESC bufdesc;
|
||||||
|
|
||||||
|
WAVEFORMATEX wfxFormat;
|
||||||
|
|
||||||
wfxFormat.wFormatTag = WAVE_FORMAT_PCM;
|
wfxFormat.wFormatTag = WAVE_FORMAT_PCM;
|
||||||
wfxFormat.nChannels = 1;
|
wfxFormat.nChannels = 1;
|
||||||
wfxFormat.nSamplesPerSec = 11025;
|
wfxFormat.nSamplesPerSec = rate;
|
||||||
wfxFormat.wBitsPerSample = 8*inputwidth;
|
wfxFormat.wBitsPerSample = 8*inputwidth;
|
||||||
wfxFormat.nBlockAlign = wfxFormat.nChannels * (wfxFormat.wBitsPerSample / 8);
|
wfxFormat.nBlockAlign = wfxFormat.nChannels * (wfxFormat.wBitsPerSample / 8);
|
||||||
wfxFormat.nAvgBytesPerSec = wfxFormat.nSamplesPerSec * wfxFormat.nBlockAlign;
|
wfxFormat.nAvgBytesPerSec = wfxFormat.nSamplesPerSec * wfxFormat.nBlockAlign;
|
||||||
|
@ -922,19 +924,7 @@ qboolean SNDDMA_InitCapture (void)
|
||||||
bufdesc.dwReserved = 0;
|
bufdesc.dwReserved = 0;
|
||||||
bufdesc.lpwfxFormat = &wfxFormat;
|
bufdesc.lpwfxFormat = &wfxFormat;
|
||||||
|
|
||||||
if (DSCaptureBuffer)
|
/*probably already inited*/
|
||||||
{
|
|
||||||
IDirectSoundCaptureBuffer_Stop(DSCaptureBuffer);
|
|
||||||
IDirectSoundCaptureBuffer_Release(DSCaptureBuffer);
|
|
||||||
DSCaptureBuffer=NULL;
|
|
||||||
}
|
|
||||||
if (DSCapture)
|
|
||||||
{
|
|
||||||
IDirectSoundCapture_Release(DSCapture);
|
|
||||||
DSCapture=NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!hInstDS)
|
if (!hInstDS)
|
||||||
{
|
{
|
||||||
hInstDS = LoadLibrary("dsound.dll");
|
hInstDS = LoadLibrary("dsound.dll");
|
||||||
|
@ -942,10 +932,10 @@ qboolean SNDDMA_InitCapture (void)
|
||||||
if (hInstDS == NULL)
|
if (hInstDS == NULL)
|
||||||
{
|
{
|
||||||
Con_SafePrintf ("Couldn't load dsound.dll\n");
|
Con_SafePrintf ("Couldn't load dsound.dll\n");
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
/*global pointer, used only in this function*/
|
||||||
if (!pDirectSoundCaptureCreate)
|
if (!pDirectSoundCaptureCreate)
|
||||||
{
|
{
|
||||||
pDirectSoundCaptureCreate = (void *)GetProcAddress(hInstDS,"DirectSoundCaptureCreate");
|
pDirectSoundCaptureCreate = (void *)GetProcAddress(hInstDS,"DirectSoundCaptureCreate");
|
||||||
|
@ -953,31 +943,61 @@ qboolean SNDDMA_InitCapture (void)
|
||||||
if (!pDirectSoundCaptureCreate)
|
if (!pDirectSoundCaptureCreate)
|
||||||
{
|
{
|
||||||
Con_SafePrintf ("Couldn't get DS proc addr\n");
|
Con_SafePrintf ("Couldn't get DS proc addr\n");
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pDirectSoundCaptureEnumerate = (void *)GetProcAddress(hInstDS,"DirectSoundCaptureEnumerateA");
|
// pDirectSoundCaptureEnumerate = (void *)GetProcAddress(hInstDS,"DirectSoundCaptureEnumerateA");
|
||||||
}
|
}
|
||||||
pDirectSoundCaptureCreate(NULL, &DSCapture, NULL);
|
|
||||||
|
|
||||||
if (FAILED(IDirectSoundCapture_CreateCaptureBuffer(DSCapture, &bufdesc, &DSCaptureBuffer, NULL)))
|
result = Z_Malloc(sizeof(*result));
|
||||||
|
if (!FAILED(pDirectSoundCaptureCreate(NULL, &result->DSCapture, NULL)))
|
||||||
{
|
{
|
||||||
|
if (!FAILED(IDirectSoundCapture_CreateCaptureBuffer(result->DSCapture, &bufdesc, &result->DSCaptureBuffer, NULL)))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
IDirectSoundCapture_Release(result->DSCapture);
|
||||||
Con_SafePrintf ("Couldn't create a capture buffer\n");
|
Con_SafePrintf ("Couldn't create a capture buffer\n");
|
||||||
IDirectSoundCapture_Release(DSCapture);
|
|
||||||
DSCapture=NULL;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
Z_Free(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
IDirectSoundCaptureBuffer_Start(DSCaptureBuffer, DSBPLAY_LOOPING);
|
void DSOUND_Capture_Start(void *ctx)
|
||||||
|
{
|
||||||
|
DWORD capturePos;
|
||||||
|
dsndcapture_t *c = ctx;
|
||||||
|
IDirectSoundCaptureBuffer_Start(c->DSCaptureBuffer, DSBPLAY_LOOPING);
|
||||||
|
|
||||||
lastreadpos = 0;
|
c->lastreadpos = 0;
|
||||||
IDirectSoundCaptureBuffer_GetCurrentPosition(DSCaptureBuffer, &capturePos, &lastreadpos);
|
IDirectSoundCaptureBuffer_GetCurrentPosition(c->DSCaptureBuffer, &capturePos, &c->lastreadpos);
|
||||||
return true;
|
}
|
||||||
|
|
||||||
|
void DSOUND_Capture_Stop(void *ctx)
|
||||||
|
{
|
||||||
|
dsndcapture_t *c = ctx;
|
||||||
|
IDirectSoundCaptureBuffer_Stop(c->DSCaptureBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DSOUND_Capture_Shutdown(void *ctx)
|
||||||
|
{
|
||||||
|
dsndcapture_t *c = ctx;
|
||||||
|
if (c->DSCaptureBuffer)
|
||||||
|
{
|
||||||
|
IDirectSoundCaptureBuffer_Stop(c->DSCaptureBuffer);
|
||||||
|
IDirectSoundCaptureBuffer_Release(c->DSCaptureBuffer);
|
||||||
|
}
|
||||||
|
if (c->DSCapture)
|
||||||
|
{
|
||||||
|
IDirectSoundCapture_Release(c->DSCapture);
|
||||||
|
}
|
||||||
|
Z_Free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*minsamples is a hint*/
|
/*minsamples is a hint*/
|
||||||
unsigned int DSOUND_UpdateCapture(qboolean enable, unsigned char *buffer, unsigned int minbytes, unsigned int maxbytes)
|
unsigned int DSOUND_Capture_Update(void *ctx, unsigned char *buffer, unsigned int minbytes, unsigned int maxbytes)
|
||||||
{
|
{
|
||||||
|
dsndcapture_t *c = ctx;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
LPBYTE lpbuf1 = NULL;
|
LPBYTE lpbuf1 = NULL;
|
||||||
LPBYTE lpbuf2 = NULL;
|
LPBYTE lpbuf2 = NULL;
|
||||||
|
@ -988,35 +1008,15 @@ unsigned int DSOUND_UpdateCapture(qboolean enable, unsigned char *buffer, unsign
|
||||||
DWORD readPos;
|
DWORD readPos;
|
||||||
long filled;
|
long filled;
|
||||||
|
|
||||||
if (!enable)
|
|
||||||
{
|
|
||||||
if (DSCaptureBuffer)
|
|
||||||
{
|
|
||||||
IDirectSoundCaptureBuffer_Stop(DSCaptureBuffer);
|
|
||||||
IDirectSoundCaptureBuffer_Release(DSCaptureBuffer);
|
|
||||||
DSCaptureBuffer=NULL;
|
|
||||||
}
|
|
||||||
if (DSCapture)
|
|
||||||
{
|
|
||||||
IDirectSoundCapture_Release(DSCapture);
|
|
||||||
DSCapture=NULL;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if (!DSCaptureBuffer)
|
|
||||||
{
|
|
||||||
SNDDMA_InitCapture();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Query to see how much data is in buffer.
|
// Query to see how much data is in buffer.
|
||||||
hr = IDirectSoundCaptureBuffer_GetCurrentPosition( DSCaptureBuffer, &capturePos, &readPos );
|
hr = IDirectSoundCaptureBuffer_GetCurrentPosition(c->DSCaptureBuffer, &capturePos, &readPos);
|
||||||
if( hr != DS_OK )
|
if (hr != DS_OK)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
filled = readPos - lastreadpos;
|
filled = readPos - c->lastreadpos;
|
||||||
if( filled < 0 ) filled += bufferbytes; // unwrap offset
|
if (filled < 0)
|
||||||
|
filled += bufferbytes; // unwrap offset
|
||||||
|
|
||||||
if (filled > maxbytes) //figure out how much we need to empty it by, and if that's enough to be worthwhile.
|
if (filled > maxbytes) //figure out how much we need to empty it by, and if that's enough to be worthwhile.
|
||||||
filled = maxbytes;
|
filled = maxbytes;
|
||||||
|
@ -1027,7 +1027,7 @@ unsigned int DSOUND_UpdateCapture(qboolean enable, unsigned char *buffer, unsign
|
||||||
// filled *= inputwidth;
|
// filled *= inputwidth;
|
||||||
|
|
||||||
// Lock free space in the DS
|
// Lock free space in the DS
|
||||||
hr = IDirectSoundCaptureBuffer_Lock(DSCaptureBuffer, lastreadpos, filled, (void **) &lpbuf1, &dwsize1, (void **) &lpbuf2, &dwsize2, 0);
|
hr = IDirectSoundCaptureBuffer_Lock(c->DSCaptureBuffer, c->lastreadpos, filled, (void **) &lpbuf1, &dwsize1, (void **) &lpbuf2, &dwsize2, 0);
|
||||||
if (hr == DS_OK)
|
if (hr == DS_OK)
|
||||||
{
|
{
|
||||||
// Copy from DS to the buffer
|
// Copy from DS to the buffer
|
||||||
|
@ -1037,8 +1037,8 @@ unsigned int DSOUND_UpdateCapture(qboolean enable, unsigned char *buffer, unsign
|
||||||
memcpy(buffer+dwsize1, lpbuf2, dwsize2);
|
memcpy(buffer+dwsize1, lpbuf2, dwsize2);
|
||||||
}
|
}
|
||||||
// Update our buffer offset and unlock sound buffer
|
// Update our buffer offset and unlock sound buffer
|
||||||
lastreadpos = (lastreadpos + dwsize1 + dwsize2) % bufferbytes;
|
c->lastreadpos = (c->lastreadpos + dwsize1 + dwsize2) % bufferbytes;
|
||||||
IDirectSoundCaptureBuffer_Unlock(DSCaptureBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);
|
IDirectSoundCaptureBuffer_Unlock(c->DSCaptureBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1046,5 +1046,12 @@ unsigned int DSOUND_UpdateCapture(qboolean enable, unsigned char *buffer, unsign
|
||||||
}
|
}
|
||||||
return filled;
|
return filled;
|
||||||
}
|
}
|
||||||
unsigned int (*pDSOUND_UpdateCapture) (qboolean enable, unsigned char *buffer, unsigned int minbytes, unsigned int maxbytes) = &DSOUND_UpdateCapture;
|
snd_capture_driver_t DSOUND_Capture =
|
||||||
|
{
|
||||||
|
DSOUND_Capture_Init,
|
||||||
|
DSOUND_Capture_Start,
|
||||||
|
DSOUND_Capture_Update,
|
||||||
|
DSOUND_Capture_Stop,
|
||||||
|
DSOUND_Capture_Shutdown
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -82,7 +82,7 @@ cvar_t snd_khz = CVARAF( "s_khz", "11",
|
||||||
"snd_khz", CVAR_ARCHIVE);
|
"snd_khz", CVAR_ARCHIVE);
|
||||||
cvar_t snd_inactive = CVARAF( "s_inactive", "0",
|
cvar_t snd_inactive = CVARAF( "s_inactive", "0",
|
||||||
"snd_inactive", 0); //set if you want sound even when tabbed out.
|
"snd_inactive", 0); //set if you want sound even when tabbed out.
|
||||||
cvar_t _snd_mixahead = CVARAF( "s_mixahead", "0.2",
|
cvar_t _snd_mixahead = CVARAF( "s_mixahead", "0.08",
|
||||||
"_snd_mixahead", CVAR_ARCHIVE);
|
"_snd_mixahead", CVAR_ARCHIVE);
|
||||||
cvar_t snd_leftisright = CVARAF( "s_swapstereo", "0",
|
cvar_t snd_leftisright = CVARAF( "s_swapstereo", "0",
|
||||||
"snd_leftisright", CVAR_ARCHIVE);
|
"snd_leftisright", CVAR_ARCHIVE);
|
||||||
|
@ -107,9 +107,14 @@ cvar_t snd_usemultipledevices = CVARAF( "s_multipledevices", "0",
|
||||||
|
|
||||||
#ifdef VOICECHAT
|
#ifdef VOICECHAT
|
||||||
static void S_Voip_Play_Callback(cvar_t *var, char *oldval);
|
static void S_Voip_Play_Callback(cvar_t *var, char *oldval);
|
||||||
cvar_t cl_voip_send = CVAR("cl_voip_send", "0");
|
cvar_t cl_voip_send = CVARD("cl_voip_send", "0", "Sends voice-over-ip data to the server whenever it is set");
|
||||||
cvar_t cl_voip_play = CVARC("cl_voip_play", "1", S_Voip_Play_Callback);
|
cvar_t cl_voip_vad_threshhold = CVARD("cl_voip_vad_threshhold", "15", "This is the threshhold for voice-activation-detection when sending voip data");
|
||||||
cvar_t cl_voip_micamp = CVAR("cl_voip_micamp", "2");
|
cvar_t cl_voip_vad_delay = CVARD("cl_voip_vad_delay", "0.3", "Keeps sending voice data for this many seconds after voice activation would normally stop");
|
||||||
|
cvar_t cl_voip_capturingvol = CVARD("cl_voip_capturingvol", "0.5", "Volume multiplier applied while capturing, to avoid your audio from being heard by others");
|
||||||
|
cvar_t cl_voip_showmeter = CVARD("cl_voip_showmeter", "1", "Shows your speach volume above the hud. 0=hide, 1=show when transmitting, 2=ignore voice-activation disable");
|
||||||
|
|
||||||
|
cvar_t cl_voip_play = CVARCD("cl_voip_play", "1", S_Voip_Play_Callback, "Enables voip playback.");
|
||||||
|
cvar_t cl_voip_micamp = CVARD("cl_voip_micamp", "2", "Amplifies your microphone when using voip.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern vfsfile_t *rawwritefile;
|
extern vfsfile_t *rawwritefile;
|
||||||
|
@ -175,8 +180,22 @@ static struct
|
||||||
|
|
||||||
SpeexBits decbits[MAX_CLIENTS];
|
SpeexBits decbits[MAX_CLIENTS];
|
||||||
void *decoder[MAX_CLIENTS];
|
void *decoder[MAX_CLIENTS];
|
||||||
unsigned char decseq[MAX_CLIENTS];
|
unsigned char decseq[MAX_CLIENTS]; /*sender's sequence, to detect+cover minor packetloss*/
|
||||||
float decamp[MAX_CLIENTS];
|
unsigned char decgen[MAX_CLIENTS]; /*last generation. if it changes, we flush speex to reset packet loss*/
|
||||||
|
float decamp[MAX_CLIENTS]; /*amplify them by this*/
|
||||||
|
float lastspoke[MAX_CLIENTS]; /*time when they're no longer considered talking. if future, they're talking*/
|
||||||
|
|
||||||
|
unsigned char capturebuf[32768]; /*pending data*/
|
||||||
|
unsigned int capturepos;/*amount of pending data*/
|
||||||
|
unsigned int encsequence;/*the outgoing sequence count*/
|
||||||
|
unsigned int generation;/*incremented whenever capture is restarted*/
|
||||||
|
qboolean wantsend; /*set if we're capturing data to send*/
|
||||||
|
float voiplevel; /*your own voice level*/
|
||||||
|
unsigned int dumps; /*trigger a new generation thing after a bit*/
|
||||||
|
unsigned int keeps; /*for vad_delay*/
|
||||||
|
|
||||||
|
snd_capture_driver_t *driver;/*capture driver's functions*/
|
||||||
|
void *driverctx; /*capture driver context*/
|
||||||
} s_speex;
|
} s_speex;
|
||||||
|
|
||||||
static const SpeexMode *(VARGS *qspeex_lib_get_mode)(int mode);
|
static const SpeexMode *(VARGS *qspeex_lib_get_mode)(int mode);
|
||||||
|
@ -222,6 +241,8 @@ static dllfunction_t qspeexdspfuncs[] =
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
snd_capture_driver_t DSOUND_Capture;
|
||||||
|
|
||||||
static qboolean S_Speex_Init(void)
|
static qboolean S_Speex_Init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -254,6 +275,8 @@ static qboolean S_Speex_Init(void)
|
||||||
|
|
||||||
qspeex_encoder_ctl(s_speex.encoder, SPEEX_GET_FRAME_SIZE, &s_speex.framesize);
|
qspeex_encoder_ctl(s_speex.encoder, SPEEX_GET_FRAME_SIZE, &s_speex.framesize);
|
||||||
qspeex_encoder_ctl(s_speex.encoder, SPEEX_GET_SAMPLING_RATE, &s_speex.samplerate);
|
qspeex_encoder_ctl(s_speex.encoder, SPEEX_GET_SAMPLING_RATE, &s_speex.samplerate);
|
||||||
|
s_speex.samplerate = 11025;
|
||||||
|
qspeex_encoder_ctl(s_speex.encoder, SPEEX_SET_SAMPLING_RATE, &s_speex.samplerate);
|
||||||
|
|
||||||
s_speex.preproc = qspeex_preprocess_state_init(s_speex.framesize, s_speex.samplerate);
|
s_speex.preproc = qspeex_preprocess_state_init(s_speex.framesize, s_speex.samplerate);
|
||||||
|
|
||||||
|
@ -274,19 +297,22 @@ static qboolean S_Speex_Init(void)
|
||||||
return s_speex.loaded;
|
return s_speex.loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S_ParseVoiceChat(void)
|
void S_Voip_Parse(void)
|
||||||
{
|
{
|
||||||
unsigned int sender = MSG_ReadByte();
|
unsigned int sender;
|
||||||
int bytes;
|
int bytes;
|
||||||
unsigned char data[1024], *start;
|
unsigned char data[1024], *start;
|
||||||
short decodebuf[1024];
|
short decodebuf[1024];
|
||||||
unsigned int decodesamps, len, newseq, drops;
|
unsigned int decodesamps, len, newseq, drops;
|
||||||
unsigned char seq;
|
unsigned char seq, gen;
|
||||||
float amp = 1;
|
float amp = 1;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
sender = MSG_ReadByte();
|
||||||
|
gen = MSG_ReadByte();
|
||||||
seq = MSG_ReadByte();
|
seq = MSG_ReadByte();
|
||||||
bytes = MSG_ReadShort();
|
bytes = MSG_ReadShort();
|
||||||
if (bytes > sizeof(data) || !cl_voip_play.ival)
|
if (bytes > sizeof(data) || !cl_voip_play.ival || !S_Speex_Init() || (sender & 0xc0))
|
||||||
{
|
{
|
||||||
MSG_ReadSkip(bytes);
|
MSG_ReadSkip(bytes);
|
||||||
return;
|
return;
|
||||||
|
@ -301,11 +327,20 @@ void S_ParseVoiceChat(void)
|
||||||
newseq = 0;
|
newseq = 0;
|
||||||
drops = 0;
|
drops = 0;
|
||||||
start = data;
|
start = data;
|
||||||
|
|
||||||
|
s_speex.lastspoke[sender] = realtime + 0.5;
|
||||||
|
if (s_speex.decgen[sender] != gen)
|
||||||
|
{
|
||||||
|
qspeex_bits_reset(&s_speex.decbits[sender]);
|
||||||
|
s_speex.decgen[sender] = gen;
|
||||||
|
s_speex.decseq[sender] = seq;
|
||||||
|
}
|
||||||
|
|
||||||
while (bytes > 0)
|
while (bytes > 0)
|
||||||
{
|
{
|
||||||
if (decodesamps + s_speex.framesize > sizeof(decodebuf)/sizeof(decodebuf[0]))
|
if (decodesamps + s_speex.framesize > sizeof(decodebuf)/sizeof(decodebuf[0]))
|
||||||
{
|
{
|
||||||
S_RawAudio(sender, (qbyte*)decodebuf, 11025, decodesamps, 1, 2);
|
S_RawAudio(sender, (qbyte*)decodebuf, s_speex.samplerate, decodesamps, 1, 2);
|
||||||
decodesamps = 0;
|
decodesamps = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,88 +373,191 @@ void S_ParseVoiceChat(void)
|
||||||
Con_DPrintf("%i dropped audio frames\n", drops);
|
Con_DPrintf("%i dropped audio frames\n", drops);
|
||||||
|
|
||||||
if (decodesamps > 0)
|
if (decodesamps > 0)
|
||||||
S_RawAudio(sender, (qbyte*)decodebuf, 11025, decodesamps, 1, 2);
|
S_RawAudio(sender, (qbyte*)decodebuf, s_speex.samplerate, decodesamps, 1, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int (*pDSOUND_UpdateCapture) (qboolean enable, unsigned char *buffer, unsigned int minbytes, unsigned int maxbytes);
|
void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf)
|
||||||
void S_TransmitVoiceChat(unsigned char clc, sizebuf_t *buf)
|
|
||||||
{
|
{
|
||||||
static unsigned char capturebuf[32768];
|
|
||||||
static unsigned int capturepos;//in bytes
|
|
||||||
static unsigned int encsequence;//in frames
|
|
||||||
unsigned char outbuf[1024];
|
unsigned char outbuf[1024];
|
||||||
unsigned int outpos;//in bytes
|
unsigned int outpos;//in bytes
|
||||||
unsigned int encpos;//in bytes
|
unsigned int encpos;//in bytes
|
||||||
unsigned short *start;
|
short *start;
|
||||||
unsigned char initseq;//in frames
|
unsigned char initseq;//in frames
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
unsigned int samps;
|
||||||
|
float level, f;
|
||||||
float micamp = cl_voip_micamp.value;
|
float micamp = cl_voip_micamp.value;
|
||||||
|
qboolean voipsendenable = true;
|
||||||
|
|
||||||
//add new drivers in order or desirability.
|
/*if you're sending sound, you should be prepared to accept others yelling at you to shut up*/
|
||||||
if (pDSOUND_UpdateCapture)
|
if (!cl_voip_play.ival)
|
||||||
|
voipsendenable = false;
|
||||||
|
if (!(cls.fteprotocolextensions2 & PEXT2_VOICECHAT))
|
||||||
|
voipsendenable = false;
|
||||||
|
|
||||||
|
if (!voipsendenable)
|
||||||
{
|
{
|
||||||
capturepos += pDSOUND_UpdateCapture(1, (unsigned char*)capturebuf + capturepos, 64, sizeof(capturebuf) - capturepos);
|
if (s_speex.driver)
|
||||||
|
{
|
||||||
|
if (s_speex.wantsend)
|
||||||
|
s_speex.driver->Stop(s_speex.driverctx);
|
||||||
|
s_speex.driver->Shutdown(s_speex.driverctx);
|
||||||
|
s_speex.driverctx = NULL;
|
||||||
|
s_speex.driver = NULL;
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
voipsendenable = cl_voip_send.ival>0;
|
||||||
|
|
||||||
|
if (!s_speex.driver)
|
||||||
|
{
|
||||||
|
s_speex.voiplevel = -1;
|
||||||
|
/*only init the first time capturing is requested*/
|
||||||
|
if (!voipsendenable)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*Add new drivers in order of priority*/
|
||||||
|
if (!s_speex.driver)
|
||||||
|
s_speex.driver = &DSOUND_Capture;
|
||||||
|
|
||||||
|
/*no way to capture audio, give up*/
|
||||||
|
if (!s_speex.driver)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*see if we can init speex...*/
|
||||||
|
if (!S_Speex_Init())
|
||||||
|
return;
|
||||||
|
|
||||||
|
s_speex.driverctx = s_speex.driver->Init(s_speex.samplerate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*couldn't init a driver?*/
|
||||||
|
if (!s_speex.driverctx)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cl_voip_send.ival)
|
if (!voipsendenable && s_speex.wantsend)
|
||||||
{
|
{
|
||||||
capturepos = 0;
|
s_speex.wantsend = false;
|
||||||
|
s_speex.capturepos += s_speex.driver->Update(s_speex.driverctx, (unsigned char*)s_speex.capturebuf + s_speex.capturepos, 1, sizeof(s_speex.capturebuf) - s_speex.capturepos);
|
||||||
|
s_speex.driver->Stop(s_speex.driverctx);
|
||||||
|
/*note: we still grab audio to flush everything that was captured while it was active*/
|
||||||
|
}
|
||||||
|
else if (voipsendenable && !s_speex.wantsend)
|
||||||
|
{
|
||||||
|
s_speex.wantsend = true;
|
||||||
|
if (!s_speex.capturepos)
|
||||||
|
{ /*if we were actually still sending, it was probably only off for a single frame, in which case don't reset it*/
|
||||||
|
s_speex.dumps = 0;
|
||||||
|
s_speex.generation++;
|
||||||
|
s_speex.encsequence = 0;
|
||||||
|
qspeex_bits_reset(&s_speex.encbits);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s_speex.capturepos += s_speex.driver->Update(s_speex.driverctx, (unsigned char*)s_speex.capturebuf + s_speex.capturepos, 1, sizeof(s_speex.capturebuf) - s_speex.capturepos);
|
||||||
|
}
|
||||||
|
s_speex.driver->Start(s_speex.driverctx);
|
||||||
|
|
||||||
|
voicevolumemod = cl_voip_capturingvol.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_speex.capturepos += s_speex.driver->Update(s_speex.driverctx, (unsigned char*)s_speex.capturebuf + s_speex.capturepos, s_speex.framesize*2, sizeof(s_speex.capturebuf) - s_speex.capturepos);
|
||||||
|
|
||||||
|
if (!s_speex.wantsend && s_speex.capturepos < s_speex.framesize*2)
|
||||||
|
{
|
||||||
|
s_speex.voiplevel = -1;
|
||||||
|
s_speex.capturepos = 0;
|
||||||
|
voicevolumemod = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!S_Speex_Init())
|
initseq = s_speex.encsequence;
|
||||||
return;
|
level = 0;
|
||||||
|
samps=0;
|
||||||
initseq = encsequence;
|
for (encpos = 0, outpos = 0; s_speex.capturepos-encpos >= s_speex.framesize*2 && sizeof(outbuf)-outpos > 64; s_speex.encsequence++)
|
||||||
for (encpos = 0, outpos = 0; capturepos-encpos >= s_speex.framesize*2 && sizeof(outbuf)-outpos > 64; )
|
|
||||||
{
|
{
|
||||||
start = (short*)(capturebuf + encpos);
|
start = (short*)(s_speex.capturebuf + encpos);
|
||||||
|
|
||||||
qspeex_preprocess_run(s_speex.preproc, start);
|
qspeex_preprocess_run(s_speex.preproc, start);
|
||||||
|
|
||||||
if (micamp != 1)
|
for (i = 0; i < s_speex.framesize; i++)
|
||||||
{
|
{
|
||||||
for (i = 0; i < s_speex.framesize; i++)
|
f = start[i] * micamp;
|
||||||
{
|
start[i] = f;
|
||||||
start[i] *= micamp;
|
f = fabs(start[i]);
|
||||||
}
|
level += f*f;
|
||||||
}
|
}
|
||||||
|
samps+=s_speex.framesize;
|
||||||
|
|
||||||
qspeex_bits_reset(&s_speex.encbits);
|
qspeex_bits_reset(&s_speex.encbits);
|
||||||
qspeex_encode_int(s_speex.encoder, start, &s_speex.encbits);
|
qspeex_encode_int(s_speex.encoder, start, &s_speex.encbits);
|
||||||
outbuf[outpos] = qspeex_bits_write(&s_speex.encbits, outbuf+outpos+1, sizeof(outbuf) - (outpos+1));
|
outbuf[outpos] = qspeex_bits_write(&s_speex.encbits, outbuf+outpos+1, sizeof(outbuf) - (outpos+1));
|
||||||
outpos += 1+outbuf[outpos];
|
outpos += 1+outbuf[outpos];
|
||||||
encpos += s_speex.framesize*2;
|
encpos += s_speex.framesize*2;
|
||||||
encsequence++;
|
}
|
||||||
|
if (samps)
|
||||||
|
{
|
||||||
|
float nl;
|
||||||
|
nl = (3000*level) / (32767.0f*32767*samps);
|
||||||
|
s_speex.voiplevel = (s_speex.voiplevel*7 + nl)/8;
|
||||||
|
if (s_speex.voiplevel < cl_voip_vad_threshhold.ival && !(cl_voip_send.ival & 2))
|
||||||
|
{
|
||||||
|
/*try and dump it, it was too quiet, and they're not pressing +voip*/
|
||||||
|
if (s_speex.keeps > samps)
|
||||||
|
{
|
||||||
|
/*but not instantly*/
|
||||||
|
s_speex.keeps -= samps;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outpos = 0;
|
||||||
|
s_speex.dumps += samps;
|
||||||
|
s_speex.keeps = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s_speex.keeps = s_speex.samplerate * cl_voip_vad_delay.value;
|
||||||
|
if (outpos)
|
||||||
|
{
|
||||||
|
if (s_speex.dumps > s_speex.samplerate/4)
|
||||||
|
s_speex.generation++;
|
||||||
|
s_speex.dumps = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outpos && buf->maxsize - buf->cursize >= outpos+4)
|
if (outpos && buf->maxsize - buf->cursize >= outpos+4)
|
||||||
{
|
{
|
||||||
MSG_WriteByte(buf, clc);
|
MSG_WriteByte(buf, clc);
|
||||||
|
MSG_WriteByte(buf, (s_speex.generation & 0x3f)); /*gonna leave two bits clear here...*/
|
||||||
MSG_WriteByte(buf, initseq);
|
MSG_WriteByte(buf, initseq);
|
||||||
MSG_WriteShort(buf, outpos);
|
MSG_WriteShort(buf, outpos);
|
||||||
SZ_Write(buf, outbuf, outpos);
|
SZ_Write(buf, outbuf, outpos);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*remove sent data*/
|
/*remove sent data*/
|
||||||
memmove(capturebuf, capturebuf + encpos, capturepos-encpos);
|
memmove(s_speex.capturebuf, s_speex.capturebuf + encpos, s_speex.capturepos-encpos);
|
||||||
capturepos -= encpos;
|
s_speex.capturepos -= encpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void S_Voip_Enable_f(void)
|
static void S_Voip_Enable_f(void)
|
||||||
{
|
{
|
||||||
Cvar_Set(&cl_voip_send, "1");
|
Cvar_SetValue(&cl_voip_send, cl_voip_send.ival | 2);
|
||||||
}
|
}
|
||||||
static void S_Voip_Disable_f(void)
|
static void S_Voip_Disable_f(void)
|
||||||
{
|
{
|
||||||
Cvar_Set(&cl_voip_send, "0");
|
Cvar_SetValue(&cl_voip_send, cl_voip_send.ival & ~2);
|
||||||
}
|
}
|
||||||
static void S_Voip_f(void)
|
static void S_Voip_f(void)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
if (!strcmp(Cmd_Argv(1), "maxgain"))
|
||||||
|
{
|
||||||
|
i = atoi(Cmd_Argv(2));
|
||||||
|
qspeex_preprocess_ctl(s_speex.preproc, SPEEX_PREPROCESS_SET_AGC_MAX_GAIN, &i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static void S_Voip_Play_Callback(cvar_t *var, char *oldval)
|
static void S_Voip_Play_Callback(cvar_t *var, char *oldval)
|
||||||
{
|
{
|
||||||
|
@ -435,6 +573,20 @@ void S_Voip_MapChange(void)
|
||||||
{
|
{
|
||||||
Cvar_ForceCallback(&cl_voip_play);
|
Cvar_ForceCallback(&cl_voip_play);
|
||||||
}
|
}
|
||||||
|
int S_Voip_Loudness(qboolean ignorevad)
|
||||||
|
{
|
||||||
|
if (s_speex.voiplevel > 100)
|
||||||
|
return 100;
|
||||||
|
if (!s_speex.driverctx || (!ignorevad && s_speex.dumps))
|
||||||
|
return -1;
|
||||||
|
return s_speex.voiplevel;
|
||||||
|
}
|
||||||
|
qboolean S_Voip_Speaking(unsigned int plno)
|
||||||
|
{
|
||||||
|
if (plno >= MAX_CLIENTS)
|
||||||
|
return false;
|
||||||
|
return s_speex.lastspoke[plno] > realtime;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -839,10 +991,15 @@ void S_Init (void)
|
||||||
|
|
||||||
#ifdef VOICECHAT
|
#ifdef VOICECHAT
|
||||||
Cvar_Register(&cl_voip_send, "Voice Chat");
|
Cvar_Register(&cl_voip_send, "Voice Chat");
|
||||||
|
Cvar_Register(&cl_voip_vad_threshhold, "Voice Chat");
|
||||||
|
Cvar_Register(&cl_voip_vad_delay, "Voice Chat");
|
||||||
|
Cvar_Register(&cl_voip_capturingvol, "Voice Chat");
|
||||||
|
Cvar_Register(&cl_voip_showmeter, "Voice Chat");
|
||||||
Cvar_Register(&cl_voip_play, "Voice Chat");
|
Cvar_Register(&cl_voip_play, "Voice Chat");
|
||||||
Cvar_Register(&cl_voip_micamp, "Voice Chat");
|
Cvar_Register(&cl_voip_micamp, "Voice Chat");
|
||||||
Cmd_AddCommand("+voip", S_Voip_Enable_f);
|
Cmd_AddCommand("+voip", S_Voip_Enable_f);
|
||||||
Cmd_AddCommand("-voip", S_Voip_Disable_f);
|
Cmd_AddCommand("-voip", S_Voip_Disable_f);
|
||||||
|
Cmd_AddCommand("voip", S_Voip_f);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Cvar_Register(&snd_inactive, "Sound controls");
|
Cvar_Register(&snd_inactive, "Sound controls");
|
||||||
|
@ -1201,7 +1358,7 @@ void S_StartSoundCard(soundcardinfo_t *sc, int entnum, int entchannel, sfx_t *sf
|
||||||
startpos = scache->length - snd_speed*10;
|
startpos = scache->length - snd_speed*10;
|
||||||
}
|
}
|
||||||
target_chan->sfx = sfx;
|
target_chan->sfx = sfx;
|
||||||
target_chan->rate = ((1<<PITCHSHIFT) * pitchadj) / 100;
|
target_chan->rate = ((1<<PITCHSHIFT) * pitchadj) / 100; /*pitchadj is a percentage*/
|
||||||
target_chan->pos = startpos*target_chan->rate;
|
target_chan->pos = startpos*target_chan->rate;
|
||||||
target_chan->end = sc->paintedtime + ((scache->length - startpos)<<PITCHSHIFT)/target_chan->rate;
|
target_chan->end = sc->paintedtime + ((scache->length - startpos)<<PITCHSHIFT)/target_chan->rate;
|
||||||
target_chan->looping = false;
|
target_chan->looping = false;
|
||||||
|
@ -1439,7 +1596,7 @@ void S_Music_Seek(float time)
|
||||||
|
|
||||||
if (sc->channel[i].pos < 0)
|
if (sc->channel[i].pos < 0)
|
||||||
{ //clamp to the start of the track
|
{ //clamp to the start of the track
|
||||||
sc->channel[i].end -= sc->channel[i].pos;
|
sc->channel[i].end -= sc->channel[i].pos/sc->channel[i].rate;
|
||||||
sc->channel[i].pos=0;
|
sc->channel[i].pos=0;
|
||||||
}
|
}
|
||||||
//if we seek over the end, ignore it. The sound playing code will spot that.
|
//if we seek over the end, ignore it. The sound playing code will spot that.
|
||||||
|
@ -1895,21 +2052,6 @@ typedef struct {
|
||||||
#define MAX_RAW_SOURCES (MAX_CLIENTS+1)
|
#define MAX_RAW_SOURCES (MAX_CLIENTS+1)
|
||||||
streaming_t s_streamers[MAX_RAW_SOURCES];
|
streaming_t s_streamers[MAX_RAW_SOURCES];
|
||||||
|
|
||||||
/*
|
|
||||||
qboolean S_IsPlayingSomewhere(sfx_t *s)
|
|
||||||
{
|
|
||||||
soundcardinfo_t *si;
|
|
||||||
int i;
|
|
||||||
for (si = sndcardinfo; si; si=si->next)
|
|
||||||
{
|
|
||||||
for (i = 0; i < scard->total_chans; i++)
|
|
||||||
if (si->channel[i].sfx == s)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}*/
|
|
||||||
#undef free
|
|
||||||
|
|
||||||
void S_ClearRaw(void)
|
void S_ClearRaw(void)
|
||||||
{
|
{
|
||||||
memset(s_streamers, 0, sizeof(s_streamers));
|
memset(s_streamers, 0, sizeof(s_streamers));
|
||||||
|
@ -1996,8 +2138,8 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
|
||||||
for (i = 0; i < si->total_chans; i++)
|
for (i = 0; i < si->total_chans; i++)
|
||||||
if (si->channel[i].sfx == &s->sfx)
|
if (si->channel[i].sfx == &s->sfx)
|
||||||
{
|
{
|
||||||
if (prepadl > (si->channel[i].pos>>8))
|
if (prepadl > (si->channel[i].pos>>PITCHSHIFT))
|
||||||
prepadl = (si->channel[i].pos>>8);
|
prepadl = (si->channel[i].pos>>PITCHSHIFT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2007,7 +2149,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
|
||||||
if (snd_show.ival)
|
if (snd_show.ival)
|
||||||
Con_Printf("Wasn't playing\n");
|
Con_Printf("Wasn't playing\n");
|
||||||
prepadl = 0;
|
prepadl = 0;
|
||||||
spare = s->sfxcache->length;
|
spare = 0;
|
||||||
if (spare > snd_speed)
|
if (spare > snd_speed)
|
||||||
{
|
{
|
||||||
Con_DPrintf("Sacrificed raw sound stream\n");
|
Con_DPrintf("Sacrificed raw sound stream\n");
|
||||||
|
@ -2016,11 +2158,13 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (prepadl < 0)
|
||||||
|
prepadl = 0;
|
||||||
spare = s->sfxcache->length - prepadl;
|
spare = s->sfxcache->length - prepadl;
|
||||||
if (spare < 0) //remaining samples since last time
|
if (spare < 0) //remaining samples since last time
|
||||||
spare = 0;
|
spare = 0;
|
||||||
|
|
||||||
if (s->sfxcache->length > snd_speed*2) // more than 2 seconds of sound
|
if (spare > snd_speed*2) // more than 2 seconds of sound
|
||||||
{
|
{
|
||||||
Con_DPrintf("Sacrificed raw sound stream\n");
|
Con_DPrintf("Sacrificed raw sound stream\n");
|
||||||
spare = 0; //too far out. sacrifice it all
|
spare = 0; //too far out. sacrifice it all
|
||||||
|
@ -2051,7 +2195,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
|
||||||
snd_linearresample_stream.ival);
|
snd_linearresample_stream.ival);
|
||||||
}
|
}
|
||||||
|
|
||||||
s->sfxcache->loopstart = s->sfxcache->length;
|
s->sfxcache->loopstart = -1;//s->sfxcache->length;
|
||||||
|
|
||||||
for (si = sndcardinfo; si; si=si->next)
|
for (si = sndcardinfo; si; si=si->next)
|
||||||
{
|
{
|
||||||
|
@ -2059,7 +2203,6 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
|
||||||
if (si->channel[i].sfx == &s->sfx)
|
if (si->channel[i].sfx == &s->sfx)
|
||||||
{
|
{
|
||||||
si->channel[i].pos -= prepadl*si->channel[i].rate;
|
si->channel[i].pos -= prepadl*si->channel[i].rate;
|
||||||
// si->channel[i].end -= prepadl;
|
|
||||||
si->channel[i].end += outsamples;
|
si->channel[i].end += outsamples;
|
||||||
|
|
||||||
if (si->channel[i].end < si->paintedtime)
|
if (si->channel[i].end < si->paintedtime)
|
||||||
|
@ -2071,10 +2214,8 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
|
||||||
}
|
}
|
||||||
if (i == si->total_chans) //this one wasn't playing.
|
if (i == si->total_chans) //this one wasn't playing.
|
||||||
{
|
{
|
||||||
S_StartSoundCard(si, -1, 0, &s->sfx, r_origin, 1, 32767, 500, 0);
|
/*slight delay to try to avoid frame rate/etc stops/starts*/
|
||||||
// Con_Printf("Restarted\n");
|
S_StartSoundCard(si, -1, 0, &s->sfx, r_origin, 1, 32767, -snd_speed*0.02, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Con_Printf("Stripped %i, added %i (length %i)\n", prepadl, samples, s->sfxcache->length);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#define PAINTBUFFER_SIZE 2048
|
#define PAINTBUFFER_SIZE 2048
|
||||||
|
|
||||||
|
float voicevolumemod = 1;
|
||||||
portable_samplegroup_t paintbuffer[PAINTBUFFER_SIZE];
|
portable_samplegroup_t paintbuffer[PAINTBUFFER_SIZE];
|
||||||
|
|
||||||
int *snd_p, snd_vol;
|
int *snd_p, snd_vol;
|
||||||
|
@ -70,7 +71,7 @@ void S_TransferPaintBuffer(soundcardinfo_t *sc, int endtime)
|
||||||
count = (endtime - sc->paintedtime) * sc->sn.numchannels;
|
count = (endtime - sc->paintedtime) * sc->sn.numchannels;
|
||||||
outlimit = sc->sn.samples;
|
outlimit = sc->sn.samples;
|
||||||
startidx = out_idx = (sc->paintedtime * sc->sn.numchannels) % outlimit;
|
startidx = out_idx = (sc->paintedtime * sc->sn.numchannels) % outlimit;
|
||||||
snd_vol = volume.value*256;
|
snd_vol = (volume.value*voicevolumemod)*256;
|
||||||
|
|
||||||
pbuf = sc->Lock(sc);
|
pbuf = sc->Lock(sc);
|
||||||
if (!pbuf)
|
if (!pbuf)
|
||||||
|
@ -169,7 +170,7 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
|
||||||
if ((ch->pos>>PITCHSHIFT) > scache->length) //cache was flushed and gamedir changed.
|
if ((ch->pos>>PITCHSHIFT) > scache->length) //cache was flushed and gamedir changed.
|
||||||
{
|
{
|
||||||
ch->pos = scache->length*ch->rate;
|
ch->pos = scache->length*ch->rate;
|
||||||
ch->end = scache->length;
|
ch->end = sc->paintedtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -148,9 +148,15 @@ void S_DefaultSpeakerConfiguration(soundcardinfo_t *sc);
|
||||||
void S_ResetFailedLoad(void);
|
void S_ResetFailedLoad(void);
|
||||||
|
|
||||||
#ifdef VOICECHAT
|
#ifdef VOICECHAT
|
||||||
void S_ParseVoiceChat(void);
|
extern cvar_t cl_voip_showmeter;
|
||||||
void S_TransmitVoiceChat(unsigned char clc, sizebuf_t *buf);
|
void S_Voip_Parse(void);
|
||||||
|
void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf);
|
||||||
void S_Voip_MapChange(void);
|
void S_Voip_MapChange(void);
|
||||||
|
int S_Voip_Loudness(qboolean ignorevad); //-1 for not capturing, otherwise between 0 and 100
|
||||||
|
qboolean S_Voip_Speaking(unsigned int plno);
|
||||||
|
#else
|
||||||
|
#define S_Voip_Loudness() -1
|
||||||
|
#define S_Voip_Speaking(p) false
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
qboolean S_IsPlayingSomewhere(sfx_t *s);
|
qboolean S_IsPlayingSomewhere(sfx_t *s);
|
||||||
|
@ -222,6 +228,8 @@ extern cvar_t bgmvolume;
|
||||||
extern cvar_t volume;
|
extern cvar_t volume;
|
||||||
extern cvar_t snd_capture;
|
extern cvar_t snd_capture;
|
||||||
|
|
||||||
|
extern float voicevolumemod;
|
||||||
|
|
||||||
extern qboolean snd_initialized;
|
extern qboolean snd_initialized;
|
||||||
extern cvar_t snd_usemultipledevices;
|
extern cvar_t snd_usemultipledevices;
|
||||||
|
|
||||||
|
@ -294,6 +302,13 @@ struct soundcardinfo_s { //windows has one defined AFTER directsound
|
||||||
|
|
||||||
extern soundcardinfo_t *sndcardinfo;
|
extern soundcardinfo_t *sndcardinfo;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *(*Init) (int samplerate); /*create a new context*/
|
||||||
|
void (*Start) (void *ctx); /*begin grabbing new data, old data is potentially flushed*/
|
||||||
|
unsigned int (*Update) (void *ctx, unsigned char *buffer, unsigned int minbytes, unsigned int maxbytes); /*grab the data into a different buffer*/
|
||||||
|
void (*Stop) (void *ctx); /*stop grabbing new data, old data may remain*/
|
||||||
|
void (*Shutdown) (void *ctx); /*destroy everything*/
|
||||||
|
} snd_capture_driver_t;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1336,6 +1336,8 @@ char *MSG_ReadStringLine (void)
|
||||||
float MSG_ReadCoord (void)
|
float MSG_ReadCoord (void)
|
||||||
{
|
{
|
||||||
coorddata c = {{0}};
|
coorddata c = {{0}};
|
||||||
|
if (!net_message.prim.coordsize)
|
||||||
|
net_message.prim.coordsize = 2;
|
||||||
MSG_ReadData(&c, net_message.prim.coordsize);
|
MSG_ReadData(&c, net_message.prim.coordsize);
|
||||||
return MSG_FromCoord(c, net_message.prim.coordsize);
|
return MSG_FromCoord(c, net_message.prim.coordsize);
|
||||||
}
|
}
|
||||||
|
@ -1401,6 +1403,9 @@ float MSG_ReadAngle16 (void)
|
||||||
}
|
}
|
||||||
float MSG_ReadAngle (void)
|
float MSG_ReadAngle (void)
|
||||||
{
|
{
|
||||||
|
if (!net_message.prim.anglesize)
|
||||||
|
net_message.prim.anglesize = 1;
|
||||||
|
|
||||||
switch(net_message.prim.anglesize)
|
switch(net_message.prim.anglesize)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
|
|
|
@ -85,13 +85,14 @@ typedef struct cvar_s
|
||||||
} cvar_t;
|
} cvar_t;
|
||||||
|
|
||||||
#define CVARAFDC(ConsoleName,Value,ConsoleName2,Flags,Description,Callback) {ConsoleName, Value, NULL, Flags, 0, 0, 0, ConsoleName2, Callback, Description}
|
#define CVARAFDC(ConsoleName,Value,ConsoleName2,Flags,Description,Callback) {ConsoleName, Value, NULL, Flags, 0, 0, 0, ConsoleName2, Callback, Description}
|
||||||
#define CVARAFC(ConsoleName,Value,ConsoleName2,Flags,Callback) CVARAFC(ConsoleName, Value, ConsoleName2, Flags, NULL, Callback)
|
|
||||||
#define CVARAFD(ConsoleName,Value,ConsoleName2,Flags,Description)CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, Description, NULL)
|
#define CVARAFD(ConsoleName,Value,ConsoleName2,Flags,Description)CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, Description, NULL)
|
||||||
|
#define CVARAFC(ConsoleName,Value,ConsoleName2,Flags,Callback) CVARAFC(ConsoleName, Value, ConsoleName2, Flags, NULL, Callback)
|
||||||
#define CVARAF(ConsoleName,Value,ConsoleName2,Flags) CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, NULL, NULL)
|
#define CVARAF(ConsoleName,Value,ConsoleName2,Flags) CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, NULL, NULL)
|
||||||
#define CVARFC(ConsoleName,Value,Flags,Callback) CVARAFDC(ConsoleName, Value, NULL, Flags, NULL, Callback)
|
#define CVARFC(ConsoleName,Value,Flags,Callback) CVARAFDC(ConsoleName, Value, NULL, Flags, NULL, Callback)
|
||||||
#define CVARFD(ConsoleName,Value,Flags,Description) CVARAFDC(ConsoleName, Value, NULL, Flags, Description, NULL)
|
#define CVARFD(ConsoleName,Value,Flags,Description) CVARAFDC(ConsoleName, Value, NULL, Flags, Description, NULL)
|
||||||
#define CVARF(ConsoleName,Value,Flags) CVARFC(ConsoleName, Value, Flags, NULL)
|
#define CVARF(ConsoleName,Value,Flags) CVARFC(ConsoleName, Value, Flags, NULL)
|
||||||
#define CVARC(ConsoleName,Value,Callback) CVARFC(ConsoleName, Value, 0, Callback)
|
#define CVARC(ConsoleName,Value,Callback) CVARFC(ConsoleName, Value, 0, Callback)
|
||||||
|
#define CVARCD(ConsoleName,Value,Callback,Description) CVARAFDC(ConsoleName, Value, NULL, 0, Description, Callback)
|
||||||
#define CVARD(ConsoleName,Value,Description) CVARAFDC(ConsoleName, Value, NULL, 0, Description, NULL)
|
#define CVARD(ConsoleName,Value,Description) CVARAFDC(ConsoleName, Value, NULL, 0, Description, NULL)
|
||||||
#define CVAR(ConsoleName,Value) CVARD(ConsoleName, Value, NULL)
|
#define CVAR(ConsoleName,Value) CVARD(ConsoleName, Value, NULL)
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ inrange:
|
||||||
if (reliable)
|
if (reliable)
|
||||||
{
|
{
|
||||||
MVDWrite_Begin(dem_all, 0, sv.multicast.cursize);
|
MVDWrite_Begin(dem_all, 0, sv.multicast.cursize);
|
||||||
SZ_Write((sizebuf_t*)demo.dbuf, sv.multicast.data, sv.multicast.cursize);
|
SZ_Write(&demo.dbuf->sb, sv.multicast.data, sv.multicast.cursize);
|
||||||
} else
|
} else
|
||||||
SZ_Write(&demo.datagram, sv.multicast.data, sv.multicast.cursize);
|
SZ_Write(&demo.datagram, sv.multicast.data, sv.multicast.cursize);
|
||||||
}*/
|
}*/
|
||||||
|
|
|
@ -3209,8 +3209,8 @@ void PF_stuffcmd (progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
MVDWrite_Begin (dem_single, entnum - 1, 2 + slen);
|
MVDWrite_Begin (dem_single, entnum - 1, 2 + slen);
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, svc_stufftext);
|
MSG_WriteByte (&demo.dbuf->sb, svc_stufftext);
|
||||||
MSG_WriteString ((sizebuf_t*)demo.dbuf, str);
|
MSG_WriteString (&demo.dbuf->sb, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -593,11 +593,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
qboolean allowoverflow; // if false, do a Sys_Error
|
sizebuf_t sb;
|
||||||
qboolean overflowed; // set to true if the buffer size failed
|
|
||||||
qbyte *data;
|
|
||||||
int maxsize;
|
|
||||||
int cursize;
|
|
||||||
int bufsize;
|
int bufsize;
|
||||||
header_t *h;
|
header_t *h;
|
||||||
} demobuf_t;
|
} demobuf_t;
|
||||||
|
@ -607,7 +603,6 @@ typedef struct
|
||||||
demo_client_t clients[MAX_CLIENTS];
|
demo_client_t clients[MAX_CLIENTS];
|
||||||
double time;
|
double time;
|
||||||
demobuf_t buf;
|
demobuf_t buf;
|
||||||
|
|
||||||
} demo_frame_t;
|
} demo_frame_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
@ -1556,9 +1556,9 @@ void SV_ConSay_f(void)
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
MVDWrite_Begin (dem_all, 0, strlen(text)+3);
|
MVDWrite_Begin (dem_all, 0, strlen(text)+3);
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, svc_print);
|
MSG_WriteByte (&demo.dbuf->sb, svc_print);
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, PRINT_CHAT);
|
MSG_WriteByte (&demo.dbuf->sb, PRINT_CHAT);
|
||||||
MSG_WriteString ((sizebuf_t*)demo.dbuf, text);
|
MSG_WriteString (&demo.dbuf->sb, text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,7 +153,6 @@ cvar_t sv_pupglow = CVARF("sv_pupglow", "", CVAR_SERVERINFO);
|
||||||
cvar_t sv_master = CVAR("sv_master", "0");
|
cvar_t sv_master = CVAR("sv_master", "0");
|
||||||
cvar_t sv_masterport = CVAR("sv_masterport", "0");
|
cvar_t sv_masterport = CVAR("sv_masterport", "0");
|
||||||
|
|
||||||
cvar_t sv_voicechat = CVAR("sv_voicechat", "0"); //still development.
|
|
||||||
cvar_t sv_gamespeed = CVAR("sv_gamespeed", "1");
|
cvar_t sv_gamespeed = CVAR("sv_gamespeed", "1");
|
||||||
cvar_t sv_csqcdebug = CVAR("sv_csqcdebug", "0");
|
cvar_t sv_csqcdebug = CVAR("sv_csqcdebug", "0");
|
||||||
cvar_t sv_csqc_progname = CVAR("sv_csqc_progname", "csprogs.dat");
|
cvar_t sv_csqc_progname = CVAR("sv_csqc_progname", "csprogs.dat");
|
||||||
|
@ -3774,7 +3773,6 @@ void SV_InitLocal (void)
|
||||||
|
|
||||||
Cvar_Register (&pausable, cvargroup_servercontrol);
|
Cvar_Register (&pausable, cvargroup_servercontrol);
|
||||||
|
|
||||||
Cvar_Register (&sv_voicechat, cvargroup_servercontrol);
|
|
||||||
Cvar_Register (&sv_maxrate, cvargroup_servercontrol);
|
Cvar_Register (&sv_maxrate, cvargroup_servercontrol);
|
||||||
Cvar_Register (&sv_maxdrate, cvargroup_servercontrol);
|
Cvar_Register (&sv_maxdrate, cvargroup_servercontrol);
|
||||||
Cvar_Register (&sv_minping, cvargroup_servercontrol);
|
Cvar_Register (&sv_minping, cvargroup_servercontrol);
|
||||||
|
|
|
@ -766,12 +766,12 @@ void SV_MVDPings (void)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MVDWrite_Begin (dem_all, 0, 7);
|
MVDWrite_Begin (dem_all, 0, 7);
|
||||||
MSG_WriteByte((sizebuf_t*)demo.dbuf, svc_updateping);
|
MSG_WriteByte(&demo.dbuf->sb, svc_updateping);
|
||||||
MSG_WriteByte((sizebuf_t*)demo.dbuf, j);
|
MSG_WriteByte(&demo.dbuf->sb, j);
|
||||||
MSG_WriteShort((sizebuf_t*)demo.dbuf, SV_CalcPing(client, false));
|
MSG_WriteShort(&demo.dbuf->sb, SV_CalcPing(client, false));
|
||||||
MSG_WriteByte((sizebuf_t*)demo.dbuf, svc_updatepl);
|
MSG_WriteByte(&demo.dbuf->sb, svc_updatepl);
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, j);
|
MSG_WriteByte (&demo.dbuf->sb, j);
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, client->lossage);
|
MSG_WriteByte (&demo.dbuf->sb, client->lossage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -799,13 +799,14 @@ void MVDSetMsgBuf(demobuf_t *prev,demobuf_t *cur)
|
||||||
// fix the maxsize of previous msg buffer,
|
// fix the maxsize of previous msg buffer,
|
||||||
// we won't be able to write there anymore
|
// we won't be able to write there anymore
|
||||||
if (prev != NULL)
|
if (prev != NULL)
|
||||||
prev->maxsize = prev->bufsize;
|
prev->sb.maxsize = prev->bufsize;
|
||||||
|
|
||||||
demo.dbuf = cur;
|
demo.dbuf = cur;
|
||||||
memset(demo.dbuf, 0, sizeof(*demo.dbuf));
|
memset(demo.dbuf, 0, sizeof(*demo.dbuf));
|
||||||
|
|
||||||
demo.dbuf->data = demobuffer->data + demobuffer->end;
|
demo.dbuf->sb.data = demobuffer->data + demobuffer->end;
|
||||||
demo.dbuf->maxsize = MAXSIZE;
|
demo.dbuf->sb.maxsize = MAXSIZE;
|
||||||
|
demo.dbuf->sb.prim = demo.recorder.netchan.netprim;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -825,7 +826,7 @@ void SV_MVDWriteToDisk(int type, int to, float time)
|
||||||
int size;
|
int size;
|
||||||
sizebuf_t msg;
|
sizebuf_t msg;
|
||||||
|
|
||||||
p = (header_t *)demo.dbuf->data;
|
p = (header_t *)demo.dbuf->sb.data;
|
||||||
demo.dbuf->h = NULL;
|
demo.dbuf->h = NULL;
|
||||||
|
|
||||||
oldm = demo.dbuf->bufsize;
|
oldm = demo.dbuf->bufsize;
|
||||||
|
@ -847,13 +848,13 @@ void SV_MVDWriteToDisk(int type, int to, float time)
|
||||||
}
|
}
|
||||||
|
|
||||||
// data is written so it need to be cleard from demobuf
|
// data is written so it need to be cleard from demobuf
|
||||||
if (demo.dbuf->data != (qbyte*)p)
|
if (demo.dbuf->sb.data != (qbyte*)p)
|
||||||
memmove(demo.dbuf->data + size + header, demo.dbuf->data, (qbyte*)p - demo.dbuf->data);
|
memmove(demo.dbuf->sb.data + size + header, demo.dbuf->sb.data, (qbyte*)p - demo.dbuf->sb.data);
|
||||||
|
|
||||||
demo.dbuf->bufsize -= size + header;
|
demo.dbuf->bufsize -= size + header;
|
||||||
demo.dbuf->data += size + header;
|
demo.dbuf->sb.data += size + header;
|
||||||
pos -= size + header;
|
pos -= size + header;
|
||||||
demo.dbuf->maxsize -= size + header;
|
demo.dbuf->sb.maxsize -= size + header;
|
||||||
demobuffer->start += size + header;
|
demobuffer->start += size + header;
|
||||||
}
|
}
|
||||||
// move along
|
// move along
|
||||||
|
@ -865,7 +866,7 @@ void SV_MVDWriteToDisk(int type, int to, float time)
|
||||||
if (demobuffer->start == demobuffer->end)
|
if (demobuffer->start == demobuffer->end)
|
||||||
{
|
{
|
||||||
demobuffer->end = 0; // demobuffer is empty
|
demobuffer->end = 0; // demobuffer is empty
|
||||||
demo.dbuf->data = demobuffer->data;
|
demo.dbuf->sb.data = demobuffer->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// go back to begining of the buffer
|
// go back to begining of the buffer
|
||||||
|
@ -887,7 +888,7 @@ static void MVDSetBuf(qbyte type, int to)
|
||||||
header_t *p;
|
header_t *p;
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
p = (header_t *)demo.dbuf->data;
|
p = (header_t *)demo.dbuf->sb.data;
|
||||||
|
|
||||||
while (pos < demo.dbuf->bufsize)
|
while (pos < demo.dbuf->bufsize)
|
||||||
{
|
{
|
||||||
|
@ -895,7 +896,7 @@ static void MVDSetBuf(qbyte type, int to)
|
||||||
|
|
||||||
if (type == p->type && to == p->to && !p->full)
|
if (type == p->type && to == p->to && !p->full)
|
||||||
{
|
{
|
||||||
demo.dbuf->cursize = pos;
|
demo.dbuf->sb.cursize = pos;
|
||||||
demo.dbuf->h = p;
|
demo.dbuf->h = p;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -910,7 +911,7 @@ static void MVDSetBuf(qbyte type, int to)
|
||||||
p->full = 0;
|
p->full = 0;
|
||||||
|
|
||||||
demo.dbuf->bufsize += header;
|
demo.dbuf->bufsize += header;
|
||||||
demo.dbuf->cursize = demo.dbuf->bufsize;
|
demo.dbuf->sb.cursize = demo.dbuf->bufsize;
|
||||||
demobuffer->end += header;
|
demobuffer->end += header;
|
||||||
demo.dbuf->h = p;
|
demo.dbuf->h = p;
|
||||||
}
|
}
|
||||||
|
@ -921,11 +922,11 @@ void MVDMoveBuf(void)
|
||||||
demobuffer->last = demobuffer->end - demo.dbuf->bufsize;
|
demobuffer->last = demobuffer->end - demo.dbuf->bufsize;
|
||||||
|
|
||||||
// move buffer to the begining of demo buffer
|
// move buffer to the begining of demo buffer
|
||||||
memmove(demobuffer->data, demo.dbuf->data, demo.dbuf->bufsize);
|
memmove(demobuffer->data, demo.dbuf->sb.data, demo.dbuf->bufsize);
|
||||||
demo.dbuf->data = demobuffer->data;
|
demo.dbuf->sb.data = demobuffer->data;
|
||||||
demobuffer->end = demo.dbuf->bufsize;
|
demobuffer->end = demo.dbuf->bufsize;
|
||||||
demo.dbuf->h = NULL; // it will be setup again
|
demo.dbuf->h = NULL; // it will be setup again
|
||||||
demo.dbuf->maxsize = MAXSIZE + demo.dbuf->bufsize;
|
demo.dbuf->sb.maxsize = MAXSIZE + demo.dbuf->bufsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean MVDWrite_Begin(qbyte type, int to, int size)
|
qboolean MVDWrite_Begin(qbyte type, int to, int size)
|
||||||
|
@ -934,7 +935,7 @@ qboolean MVDWrite_Begin(qbyte type, int to, int size)
|
||||||
qboolean move = false;
|
qboolean move = false;
|
||||||
|
|
||||||
// will it fit?
|
// will it fit?
|
||||||
while (demo.dbuf->bufsize + size + header > demo.dbuf->maxsize)
|
while (demo.dbuf->bufsize + size + header > demo.dbuf->sb.maxsize)
|
||||||
{
|
{
|
||||||
// if we reached the end of buffer move msgbuf to the begining
|
// if we reached the end of buffer move msgbuf to the begining
|
||||||
if (!move && demobuffer->end > demobuffer->start)
|
if (!move && demobuffer->end > demobuffer->start)
|
||||||
|
@ -958,9 +959,9 @@ qboolean MVDWrite_Begin(qbyte type, int to, int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
// we have to make room for new data
|
// we have to make room for new data
|
||||||
if (demo.dbuf->cursize != demo.dbuf->bufsize) {
|
if (demo.dbuf->sb.cursize != demo.dbuf->bufsize) {
|
||||||
p = demo.dbuf->data + demo.dbuf->cursize;
|
p = demo.dbuf->sb.data + demo.dbuf->sb.cursize;
|
||||||
memmove(p+size, p, demo.dbuf->bufsize - demo.dbuf->cursize);
|
memmove(p+size, p, demo.dbuf->bufsize - demo.dbuf->sb.cursize);
|
||||||
}
|
}
|
||||||
|
|
||||||
demo.dbuf->bufsize += size;
|
demo.dbuf->bufsize += size;
|
||||||
|
@ -1092,6 +1093,7 @@ qboolean SV_MVDWritePackets (int num)
|
||||||
if (!sv.mvdrecording)
|
if (!sv.mvdrecording)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
msg.prim = svs.netprim;
|
||||||
msg.data = msg_buf;
|
msg.data = msg_buf;
|
||||||
msg.maxsize = sizeof(msg_buf);
|
msg.maxsize = sizeof(msg_buf);
|
||||||
|
|
||||||
|
@ -1228,7 +1230,7 @@ qboolean SV_MVDWritePackets (int num)
|
||||||
demo.lastwritten = demo.parsecount;
|
demo.lastwritten = demo.parsecount;
|
||||||
|
|
||||||
demo.dbuf = &demo.frames[demo.parsecount&DEMO_FRAMES_MASK].buf;
|
demo.dbuf = &demo.frames[demo.parsecount&DEMO_FRAMES_MASK].buf;
|
||||||
demo.dbuf->maxsize = MAXSIZE + demo.dbuf->bufsize;
|
demo.dbuf->sb.maxsize = MAXSIZE + demo.dbuf->bufsize;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1384,6 +1386,7 @@ mvddest_t *SV_InitRecordFile (char *name)
|
||||||
else
|
else
|
||||||
FS_Remove(path, FS_GAMEONLY);
|
FS_Remove(path, FS_GAMEONLY);
|
||||||
|
|
||||||
|
FS_FlushFSHash();
|
||||||
|
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
@ -1458,12 +1461,12 @@ void SV_MVDStop (int reason, qboolean mvdonly)
|
||||||
// write a disconnect message to the demo file
|
// write a disconnect message to the demo file
|
||||||
|
|
||||||
// clearup to be sure message will fit
|
// clearup to be sure message will fit
|
||||||
demo.dbuf->cursize = 0;
|
demo.dbuf->sb.cursize = 0;
|
||||||
demo.dbuf->h = NULL;
|
demo.dbuf->h = NULL;
|
||||||
demo.dbuf->bufsize = 0;
|
demo.dbuf->bufsize = 0;
|
||||||
MVDWrite_Begin(dem_all, 0, 2+strlen("EndOfDemo"));
|
MVDWrite_Begin(dem_all, 0, 2+strlen("EndOfDemo"));
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, svc_disconnect);
|
MSG_WriteByte (&demo.dbuf->sb, svc_disconnect);
|
||||||
MSG_WriteString ((sizebuf_t*)demo.dbuf, "EndOfDemo");
|
MSG_WriteString (&demo.dbuf->sb, "EndOfDemo");
|
||||||
|
|
||||||
SV_MVDWritePackets(demo.parsecount - demo.lastwritten + 1);
|
SV_MVDWritePackets(demo.parsecount - demo.lastwritten + 1);
|
||||||
// finish up
|
// finish up
|
||||||
|
@ -1587,17 +1590,20 @@ static qboolean SV_MVD_Record (mvddest_t *dest)
|
||||||
memset(&demo, 0, sizeof(demo));
|
memset(&demo, 0, sizeof(demo));
|
||||||
demo.recorder.frameunion.frames = demo_frames;
|
demo.recorder.frameunion.frames = demo_frames;
|
||||||
demo.recorder.protocol = SCP_QUAKEWORLD;
|
demo.recorder.protocol = SCP_QUAKEWORLD;
|
||||||
|
demo.recorder.netchan.netprim = sv.datagram.prim;
|
||||||
for (i = 0; i < UPDATE_BACKUP; i++)
|
for (i = 0; i < UPDATE_BACKUP; i++)
|
||||||
{
|
{
|
||||||
demo.recorder.frameunion.frames[i].entities.max_entities = MAX_MVDPACKET_ENTITIES;
|
demo.recorder.frameunion.frames[i].entities.max_entities = MAX_MVDPACKET_ENTITIES;
|
||||||
demo.recorder.frameunion.frames[i].entities.entities = demo_entities[i];
|
demo.recorder.frameunion.frames[i].entities.entities = demo_entities[i];
|
||||||
}
|
}
|
||||||
|
demo.recorder.max_net_ents = MAX_MVDPACKET_ENTITIES;
|
||||||
|
|
||||||
MVDBuffer_Init(&demo.dbuffer, demo.buffer, sizeof(demo.buffer));
|
MVDBuffer_Init(&demo.dbuffer, demo.buffer, sizeof(demo.buffer));
|
||||||
MVDSetMsgBuf(NULL, &demo.frames[0].buf);
|
MVDSetMsgBuf(NULL, &demo.frames[0].buf);
|
||||||
|
|
||||||
demo.datagram.maxsize = sizeof(demo.datagram_data);
|
demo.datagram.maxsize = sizeof(demo.datagram_data);
|
||||||
demo.datagram.data = demo.datagram_data;
|
demo.datagram.data = demo.datagram_data;
|
||||||
|
demo.datagram.prim = demo.recorder.netchan.netprim;
|
||||||
}
|
}
|
||||||
// else
|
// else
|
||||||
// SV_WriteRecordMVDMessage(&buf, dem_read);
|
// SV_WriteRecordMVDMessage(&buf, dem_read);
|
||||||
|
@ -1637,6 +1643,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
||||||
memset(&buf, 0, sizeof(buf));
|
memset(&buf, 0, sizeof(buf));
|
||||||
buf.data = buf_data;
|
buf.data = buf_data;
|
||||||
buf.maxsize = sizeof(buf_data);
|
buf.maxsize = sizeof(buf_data);
|
||||||
|
buf.prim = svs.netprim;
|
||||||
|
|
||||||
// send the serverdata
|
// send the serverdata
|
||||||
|
|
||||||
|
@ -1645,7 +1652,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
|
||||||
gamedir = "qw";
|
gamedir = "qw";
|
||||||
|
|
||||||
MSG_WriteByte (&buf, svc_serverdata);
|
MSG_WriteByte (&buf, svc_serverdata);
|
||||||
if (svs.netprim.coordsize == 4) //sorry.
|
if (buf.prim.coordsize == 4) //sorry.
|
||||||
{
|
{
|
||||||
MSG_WriteLong (&buf, PROTOCOL_VERSION_FTE);
|
MSG_WriteLong (&buf, PROTOCOL_VERSION_FTE);
|
||||||
MSG_WriteLong (&buf, PEXT_FLOATCOORDS);
|
MSG_WriteLong (&buf, PEXT_FLOATCOORDS);
|
||||||
|
|
|
@ -2175,7 +2175,7 @@ qboolean SV_Physics (void)
|
||||||
SV_RunEntity (ent);
|
SV_RunEntity (ent);
|
||||||
SV_RunNewmis ();
|
SV_RunNewmis ();
|
||||||
|
|
||||||
if (ent->solidtype != ent->v->solid)
|
if (ent->solidtype != ent->v->solid && !ent->isfree)
|
||||||
{
|
{
|
||||||
Con_DPrintf("Entity \"%s\" improperly changed solid type\n", PR_GetString(svprogfuncs, ent->v->classname));
|
Con_DPrintf("Entity \"%s\" improperly changed solid type\n", PR_GetString(svprogfuncs, ent->v->classname));
|
||||||
World_LinkEdict (&sv.world, (wedict_t*)ent, true); // a change of solidity should always relink the edict. someone messed up.
|
World_LinkEdict (&sv.world, (wedict_t*)ent, true); // a change of solidity should always relink the edict. someone messed up.
|
||||||
|
|
|
@ -292,9 +292,9 @@ void VARGS SV_ClientPrintf (client_t *cl, int level, char *fmt, ...)
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
MVDWrite_Begin (dem_single, cl - svs.clients, strlen(string)+3);
|
MVDWrite_Begin (dem_single, cl - svs.clients, strlen(string)+3);
|
||||||
MSG_WriteByte ((sizebuf_t *)demo.dbuf, svc_print);
|
MSG_WriteByte (&demo.dbuf->sb, svc_print);
|
||||||
MSG_WriteByte ((sizebuf_t *)demo.dbuf, level);
|
MSG_WriteByte (&demo.dbuf->sb, level);
|
||||||
MSG_WriteString ((sizebuf_t *)demo.dbuf, string);
|
MSG_WriteString (&demo.dbuf->sb, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cl->controller)
|
if (cl->controller)
|
||||||
|
@ -322,9 +322,9 @@ void VARGS SV_ClientTPrintf (client_t *cl, int level, translation_t stringnum, .
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
MVDWrite_Begin (dem_single, cl - svs.clients, strlen(string)+3);
|
MVDWrite_Begin (dem_single, cl - svs.clients, strlen(string)+3);
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, svc_print);
|
MSG_WriteByte (&demo.dbuf->sb, svc_print);
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, level);
|
MSG_WriteByte (&demo.dbuf->sb, level);
|
||||||
MSG_WriteString ((sizebuf_t*)demo.dbuf, string);
|
MSG_WriteString (&demo.dbuf->sb, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
SV_PrintToClient(cl, level, string);
|
SV_PrintToClient(cl, level, string);
|
||||||
|
@ -371,9 +371,9 @@ void VARGS SV_BroadcastPrintf (int level, char *fmt, ...)
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
MVDWrite_Begin (dem_all, 0, strlen(string)+3);
|
MVDWrite_Begin (dem_all, 0, strlen(string)+3);
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, svc_print);
|
MSG_WriteByte (&demo.dbuf->sb, svc_print);
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, level);
|
MSG_WriteByte (&demo.dbuf->sb, level);
|
||||||
MSG_WriteString ((sizebuf_t*)demo.dbuf, string);
|
MSG_WriteString (&demo.dbuf->sb, string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -755,7 +755,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int
|
||||||
if (reliable)
|
if (reliable)
|
||||||
{
|
{
|
||||||
MVDWrite_Begin(dem_all, 0, sv.multicast.cursize);
|
MVDWrite_Begin(dem_all, 0, sv.multicast.cursize);
|
||||||
SZ_Write((sizebuf_t*)demo.dbuf, sv.multicast.data, sv.multicast.cursize);
|
SZ_Write(&demo.dbuf->sb, sv.multicast.data, sv.multicast.cursize);
|
||||||
} else
|
} else
|
||||||
SZ_Write(&demo.datagram, sv.multicast.data, sv.multicast.cursize);
|
SZ_Write(&demo.datagram, sv.multicast.data, sv.multicast.cursize);
|
||||||
}
|
}
|
||||||
|
@ -1069,8 +1069,8 @@ void SV_WriteCenterPrint(client_t *cl, char *s)
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
MVDWrite_Begin (dem_single, cl - svs.clients, 2 + strlen(s));
|
MVDWrite_Begin (dem_single, cl - svs.clients, 2 + strlen(s));
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, svc_centerprint);
|
MSG_WriteByte (&demo.dbuf->sb, svc_centerprint);
|
||||||
MSG_WriteString ((sizebuf_t*)demo.dbuf, s);
|
MSG_WriteString (&demo.dbuf->sb, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1871,9 +1871,9 @@ void SV_UpdateToReliableMessages (void)
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
MVDWrite_Begin(dem_all, 0, 4);
|
MVDWrite_Begin(dem_all, 0, 4);
|
||||||
MSG_WriteByte((sizebuf_t*)demo.dbuf, svc_updatefrags);
|
MSG_WriteByte(&demo.dbuf->sb, svc_updatefrags);
|
||||||
MSG_WriteByte((sizebuf_t*)demo.dbuf, i);
|
MSG_WriteByte(&demo.dbuf->sb, i);
|
||||||
MSG_WriteShort((sizebuf_t*)demo.dbuf, host_client->edict->v->frags);
|
MSG_WriteShort(&demo.dbuf->sb, host_client->edict->v->frags);
|
||||||
}
|
}
|
||||||
|
|
||||||
host_client->old_frags = host_client->edict->v->frags;
|
host_client->old_frags = host_client->edict->v->frags;
|
||||||
|
@ -1932,9 +1932,9 @@ void SV_UpdateToReliableMessages (void)
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
MVDWrite_Begin(dem_all, 0, 4);
|
MVDWrite_Begin(dem_all, 0, 4);
|
||||||
MSG_WriteByte((sizebuf_t*)demo.dbuf, svc_updatefrags);
|
MSG_WriteByte(&demo.dbuf->sb, svc_updatefrags);
|
||||||
MSG_WriteByte((sizebuf_t*)demo.dbuf, i);
|
MSG_WriteByte(&demo.dbuf->sb, i);
|
||||||
MSG_WriteShort((sizebuf_t*)demo.dbuf, curfrags);
|
MSG_WriteShort(&demo.dbuf->sb, curfrags);
|
||||||
}
|
}
|
||||||
|
|
||||||
host_client->old_frags = curfrags;
|
host_client->old_frags = curfrags;
|
||||||
|
@ -2363,16 +2363,16 @@ void SV_SendMVDMessage(void)
|
||||||
if (stats[j] >=0 && stats[j] <= 255)
|
if (stats[j] >=0 && stats[j] <= 255)
|
||||||
{
|
{
|
||||||
MVDWrite_Begin(dem_stats, i, 3);
|
MVDWrite_Begin(dem_stats, i, 3);
|
||||||
MSG_WriteByte((sizebuf_t*)demo.dbuf, svc_updatestat);
|
MSG_WriteByte(&demo.dbuf->sb, svc_updatestat);
|
||||||
MSG_WriteByte((sizebuf_t*)demo.dbuf, j);
|
MSG_WriteByte(&demo.dbuf->sb, j);
|
||||||
MSG_WriteByte((sizebuf_t*)demo.dbuf, stats[j]);
|
MSG_WriteByte(&demo.dbuf->sb, stats[j]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MVDWrite_Begin(dem_stats, i, 6);
|
MVDWrite_Begin(dem_stats, i, 6);
|
||||||
MSG_WriteByte((sizebuf_t*)demo.dbuf, svc_updatestatlong);
|
MSG_WriteByte(&demo.dbuf->sb, svc_updatestatlong);
|
||||||
MSG_WriteByte((sizebuf_t*)demo.dbuf, j);
|
MSG_WriteByte(&demo.dbuf->sb, j);
|
||||||
MSG_WriteLong((sizebuf_t*)demo.dbuf, stats[j]);
|
MSG_WriteLong(&demo.dbuf->sb, stats[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2381,6 +2381,7 @@ void SV_SendMVDMessage(void)
|
||||||
// this will include clients, a packetentities, and
|
// this will include clients, a packetentities, and
|
||||||
// possibly a nails update
|
// possibly a nails update
|
||||||
msg.cursize = 0;
|
msg.cursize = 0;
|
||||||
|
msg.prim = demo.recorder.netchan.netprim;
|
||||||
if (!demo.recorder.delta_sequence)
|
if (!demo.recorder.delta_sequence)
|
||||||
demo.recorder.delta_sequence = -1;
|
demo.recorder.delta_sequence = -1;
|
||||||
|
|
||||||
|
@ -2389,12 +2390,12 @@ void SV_SendMVDMessage(void)
|
||||||
if (!MVDWrite_Begin(dem_all, 0, msg.cursize))
|
if (!MVDWrite_Begin(dem_all, 0, msg.cursize))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SZ_Write ((sizebuf_t*)demo.dbuf, msg.data, msg.cursize);
|
SZ_Write (&demo.dbuf->sb, msg.data, msg.cursize);
|
||||||
// copy the accumulated multicast datagram
|
// copy the accumulated multicast datagram
|
||||||
// for this client out to the message
|
// for this client out to the message
|
||||||
if (demo.datagram.cursize) {
|
if (demo.datagram.cursize) {
|
||||||
MVDWrite_Begin(dem_all, 0, demo.datagram.cursize);
|
MVDWrite_Begin(dem_all, 0, demo.datagram.cursize);
|
||||||
SZ_Write ((sizebuf_t*)demo.dbuf, demo.datagram.data, demo.datagram.cursize);
|
SZ_Write (&demo.dbuf->sb, demo.datagram.data, demo.datagram.cursize);
|
||||||
SZ_Clear (&demo.datagram);
|
SZ_Clear (&demo.datagram);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,6 +96,7 @@ cvar_t sv_realip_timeout = SCVAR("sv_realip_timeout", "10");
|
||||||
|
|
||||||
#ifdef VOICECHAT
|
#ifdef VOICECHAT
|
||||||
cvar_t sv_voip = CVARD("sv_voip", "1", "Enable reception of voice packets.");
|
cvar_t sv_voip = CVARD("sv_voip", "1", "Enable reception of voice packets.");
|
||||||
|
cvar_t sv_voip_record = CVARD("sv_voip_record", "0", "Record voicechat into mvds. Requires player support.");
|
||||||
cvar_t sv_voip_echo = CVARD("sv_voip_echo", "0", "Echo voice packets back to their sender, a debug/test setting.");
|
cvar_t sv_voip_echo = CVARD("sv_voip_echo", "0", "Echo voice packets back to their sender, a debug/test setting.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2100,6 +2101,7 @@ struct
|
||||||
{
|
{
|
||||||
unsigned int sender;
|
unsigned int sender;
|
||||||
unsigned char receiver[MAX_CLIENTS/8];
|
unsigned char receiver[MAX_CLIENTS/8];
|
||||||
|
unsigned char gen;
|
||||||
unsigned char seq;
|
unsigned char seq;
|
||||||
unsigned int datalen;
|
unsigned int datalen;
|
||||||
unsigned char data[1024];
|
unsigned char data[1024];
|
||||||
|
@ -2112,6 +2114,7 @@ void SV_VoiceReadPacket(void)
|
||||||
struct voice_ring_s *ring;
|
struct voice_ring_s *ring;
|
||||||
unsigned short bytes;
|
unsigned short bytes;
|
||||||
client_t *cl;
|
client_t *cl;
|
||||||
|
unsigned char gen = MSG_ReadByte();
|
||||||
unsigned char seq = MSG_ReadByte();
|
unsigned char seq = MSG_ReadByte();
|
||||||
/*read the data from the client*/
|
/*read the data from the client*/
|
||||||
bytes = MSG_ReadShort();
|
bytes = MSG_ReadShort();
|
||||||
|
@ -2126,8 +2129,10 @@ void SV_VoiceReadPacket(void)
|
||||||
voice.write++;
|
voice.write++;
|
||||||
MSG_ReadData(ring->data, bytes);
|
MSG_ReadData(ring->data, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
ring->datalen = bytes;
|
ring->datalen = bytes;
|
||||||
ring->sender = host_client - svs.clients;
|
ring->sender = host_client - svs.clients;
|
||||||
|
ring->gen = gen;
|
||||||
ring->seq = seq;
|
ring->seq = seq;
|
||||||
|
|
||||||
/*figure out which team members are meant to receive it*/
|
/*figure out which team members are meant to receive it*/
|
||||||
|
@ -2167,6 +2172,31 @@ void SV_VoiceReadPacket(void)
|
||||||
|
|
||||||
ring->receiver[cln>>3] |= 1<<(cln&3);
|
ring->receiver[cln>>3] |= 1<<(cln&3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sv.mvdrecording && sv_voip_record.ival)
|
||||||
|
{
|
||||||
|
// non-team messages should be seen always, even if not tracking any player
|
||||||
|
if (!teamplay.ival)
|
||||||
|
{
|
||||||
|
MVDWrite_Begin (dem_all, 0, ring->datalen+6);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int cls;
|
||||||
|
cls = ring->receiver[0] |
|
||||||
|
(ring->receiver[1]<<8) |
|
||||||
|
(ring->receiver[2]<<16) |
|
||||||
|
(ring->receiver[3]<<24);
|
||||||
|
MVDWrite_Begin (dem_multiple, cls, ring->datalen+6);
|
||||||
|
}
|
||||||
|
|
||||||
|
MSG_WriteByte( &demo.dbuf->sb, svcfte_voicechat);
|
||||||
|
MSG_WriteByte( &demo.dbuf->sb, ring->sender);
|
||||||
|
MSG_WriteByte( &demo.dbuf->sb, ring->gen);
|
||||||
|
MSG_WriteByte( &demo.dbuf->sb, ring->seq);
|
||||||
|
MSG_WriteShort(&demo.dbuf->sb, ring->datalen);
|
||||||
|
SZ_Write( &demo.dbuf->sb, ring->data, ring->datalen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void SV_VoiceInitClient(client_t *client)
|
void SV_VoiceInitClient(client_t *client)
|
||||||
{
|
{
|
||||||
|
@ -2215,6 +2245,7 @@ void SV_VoiceSendPacket(client_t *client, sizebuf_t *buf)
|
||||||
break;
|
break;
|
||||||
MSG_WriteByte(buf, svcfte_voicechat);
|
MSG_WriteByte(buf, svcfte_voicechat);
|
||||||
MSG_WriteByte(buf, ring->sender);
|
MSG_WriteByte(buf, ring->sender);
|
||||||
|
MSG_WriteByte(buf, ring->gen);
|
||||||
MSG_WriteByte(buf, ring->seq);
|
MSG_WriteByte(buf, ring->seq);
|
||||||
MSG_WriteShort(buf, ring->datalen);
|
MSG_WriteShort(buf, ring->datalen);
|
||||||
SZ_Write(buf, ring->data, ring->datalen);
|
SZ_Write(buf, ring->data, ring->datalen);
|
||||||
|
@ -2899,9 +2930,9 @@ void SV_Say (qboolean team)
|
||||||
else
|
else
|
||||||
MVDWrite_Begin (dem_multiple, cls, strlen(text)+3);
|
MVDWrite_Begin (dem_multiple, cls, strlen(text)+3);
|
||||||
|
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, svc_print);
|
MSG_WriteByte (&demo.dbuf->sb, svc_print);
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, PRINT_CHAT);
|
MSG_WriteByte (&demo.dbuf->sb, PRINT_CHAT);
|
||||||
MSG_WriteString ((sizebuf_t*)demo.dbuf, text);
|
MSG_WriteString (&demo.dbuf->sb, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3324,10 +3355,10 @@ void SV_SetInfo_f (void)
|
||||||
if (sv.mvdrecording)
|
if (sv.mvdrecording)
|
||||||
{
|
{
|
||||||
MVDWrite_Begin (dem_all, 0, strlen(key)+strlen(val)+4);
|
MVDWrite_Begin (dem_all, 0, strlen(key)+strlen(val)+4);
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, svc_setinfo);
|
MSG_WriteByte (&demo.dbuf->sb, svc_setinfo);
|
||||||
MSG_WriteByte ((sizebuf_t*)demo.dbuf, i);
|
MSG_WriteByte (&demo.dbuf->sb, i);
|
||||||
MSG_WriteString ((sizebuf_t*)demo.dbuf, key);
|
MSG_WriteString (&demo.dbuf->sb, key);
|
||||||
MSG_WriteString ((sizebuf_t*)demo.dbuf, val);
|
MSG_WriteString (&demo.dbuf->sb, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue